Lazily resolved properties for functions break expected property order
Categories
(Core :: JavaScript Engine, defect, P3)
Tracking
()
People
(Reporter: anba, Unassigned)
References
(Blocks 1 open bug)
Details
Test262 failures because we're lazily creating the "name"
and "length"
properties of functions, which breaks the expected property iteration order:
test262/built-ins/Object/keys/order-after-define-property.js
test262/built-ins/Object/entries/order-after-define-property.js
test262/language/computed-property-names/class/static/method-number.js
test262/language/computed-property-names/class/static/method-string.js
test262/language/computed-property-names/class/static/method-symbol.js
Comment 1•5 years ago
|
||
Yes... we used to have a lot of resolve hooks and they all had this problem.
The general fix (apart from doing away with resolve hooks) would be to keep these properties lazy, but lazily create them in the right order, so that the list of properties physically present is always a prefix of what the spec says and what users must observe to be there.
Updated•5 years ago
|
Do we just change the order in which they are called here in the FunctionEmitter constructor?
https://searchfox.org/mozilla-central/source/js/src/frontend/FunctionEmitter.cpp#40
Noob question: In which file would the work be done for this bug?
Comment 3•4 years ago
|
||
I think the change needs to be made in fun_resolve
, in vm/JSFunction.cpp.
Updated•3 years ago
|
Reporter | ||
Comment 5•2 years ago
|
||
The same behaviour is observable for other types of objects which are using lazily resolved properties, for example arguments objects:
js> Object.getOwnPropertyNames(function(){ var args = arguments; return args; }())
["length", "callee"]
js> Object.getOwnPropertyNames(function(){ var args = arguments; args.callee; return args; }())
["callee", "length"]
js> Object.getOwnPropertyNames(function(){ var args = arguments; args.a = 0; return args; }())
["a", "length", "callee"]
RecordObject
andTupleObject
also defineresolve
hooks, but both are already special-cased inEnumerateNativeProperties
.StringObject
defines aresolve
hook, but only lazily resolves indexed properties, which are sorted inEnumerate
anyway, soStringObject
should work correctly.
We could add additional flags to JSFunction
and ArgumentsObject
to record if the "name"
, "length"
, etc. haven't been deleted and then special-case both objects in EnumerateNativeProperties
to append the names at the front unless they've been already deleted. ArgumentsObject
has plenty of free space for more flags, but JSFunction
already uses all free bits in JSFunction::FlagsAndArgCountSlot
. Well, we could add a new PrivateUint48Value
to gain 16 more bits for flags. But I'm not sure whether it's worth it to spend that much time for this issue.
Description
•