-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add JS_TryGetProperty #337
Conversation
chqrlie
commented
Mar 28, 2024
- add wrapper around JS_HasProperty / JS_GetProperty
- further optimisation does not seem useful in the general case
- optimize JS_TryGetPropertyInt64 for fast arrays
- add wrapper around JS_HasProperty / JS_GetProperty - further optimisation does not seem useful in the general case - optimize JS_TryGetPropertyInt64 for fast arrays
IIRC Ben mentioned avoiding to walk the prototype chain twice. Is that still not worth pursuing? |
As I wrote in the commit comment, avoiding the redundant prototype chain walk is left out for now because the use cases are not critical, except for array indexing, which I address separately in this patch. Some Array methods should special case fast arrays: I am investigating 3 other ways to improve property access:
|
- add wrapper around `JS_HasProperty` / `JS_GetProperty` - further optimisation does not seem useful in the general case - optimize `JS_TryGetPropertyInt64` for fast arrays - add `js_get_fast_array_element()` to special case arrays and typed arrays - use `js_get_fast_array_element()` in `JS_GetPropertyValue()`, `JS_TryGetPropertyInt64()` and `JS_GetPropertyInt64()`. - simplify `js_array_at()`
case JS_CLASS_ARRAY: | ||
case JS_CLASS_ARGUMENTS: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might make sense to put these together next to the typed array constants inside the enum so they make up a dense range.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point, but it justifies a separate commit as changing the class ID order has subtle implications, among which all array initializers that use class IDs as index values and possibly other ones too.
quickjs.c
Outdated
if (res == FALSE) { | ||
*pval = JS_UNDEFINED; | ||
return FALSE; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is correct, although the problem is probably more with JS_HasProperty.
JS_GetProperty(obj, prop)
with obj="bar" and prop=1 returns "a", whereas JS_HasProperty claims the property doesn't exist.
In a similar vein, obj="foo" and prop="length" should produce 3, not property-not-found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, JS_HasProperty
ignores properties of values that are not objects, which is the semantics of ECMA 7.3.12 HasProperty ( O, P ) that requires O to be an Object.
Similarly, JS_TryGetProperty()
and JS_TryGetPropertyInt64()
must only be called for Objects. These APIs should probably take a JSObject *
but changing that would have caused too many modifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure JS_TryGetProperty()
is useful after all. Optimizing JS_TryGetPropertyInt64()
is definitely a good idea for array methods, but a more general function does not seem to provide a real advantage and may create some confusion. I shall investigate some more and post and updated patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main motivation for #105 is to avoid looking up the property twice. In that respect a JS_TryGetProperty that's just JS_HasProperty + JS_GetProperty without caching the lookup indeed isn't useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better approach to avoiding the double lookup is to use an alternate JS_GetPropertyInternal
function that would update a structure argument with the location of the property found: prototype level, fast_array / shape entry, getter?, exotic method call...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's pretty much what I was thinking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I shall simplify this PR and keep only the JS_TryGetPropertyInt64
.
- add `js_get_fast_array_element()` to special case arrays and typed arrays - use `js_get_fast_array_element()` in `JS_GetPropertyValue()`, `JS_TryGetPropertyInt64()` and `JS_GetPropertyInt64()`. - simplify `js_array_at()`