-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Typed array instance used as prototype incorrect perform [[Get]]/[[Set]] #1541
Comments
With this code: let o = new Int8Array(1)
Object.setPrototypeOf(Array.prototype, o);
const a = []; //a inherits indirectly from o
a[0] = 4; //according to current spec. this will set o[0] to 4.
print(a[0], o[0]); I get these results from #### Chakra
4 0
#### JavaScriptCore
4 0
#### SpiderMonkey
4 0
#### V8
4 0
#### V8 --harmony
4 0 This suggests that engines are already doing the correct thing, so it's just a bug in the spec. |
That means reverting #347, so we'd again get what was originally specified in ES6. |
Does that imply that engines implemented it after #347 landed but with the prior behavior? |
I guess SpiderMonkey follows what the current spec (including #347) has for 9.4.5.4 [[Get]], but SpiderMonkey's implementation for 9.4.5.5 [[Set]] doesn't seem to comply to the current spec. LookupOwnPropertyInline returns So basically the primary reason for any differences in SpiderMonkey's implementation, is that we inspect the [[ArrayLength]] internal slot of the TypedArrray object earlier than specified in the spec. |
OK, so I guess the real questions here imo are in this order:
|
I think I tried to implement the spec behavior for [[Set]] and it's not web compatible: https://bugzilla.mozilla.org/show_bug.cgi?id=1502889 |
I've totally forgotten about the web-compatibility issue encountered in Firefox.
I guess the [[Get]] part is still okay, but [[Set]] will need to be changed. And then we need to decide if consistency between [[Get]] and [[Set]] (*) or between [[Get]] and [[HasProperty]] (**) is more important, because we can't get both. (*) That means consistent |
What about just adding a branch for into 2 (if SameValue(O,Receiver)) so we don't fall to 3, but still don't set the value onto the prototype? |
@rkirsling this might be relevant to you, considering that you worked on #2164. |
@evilpie I've updated #1556 to align the spec with V8, fixing the web-compatibility issue that is still present. I will update the summary and submit thorough test262 coverage within few days. @rkirsling would you please consider presenting it at the next TC39 meeting? |
I got consensus for this back in Dec 2019, but embarrassingly forgot to ever write up a normative PR for it. Is this the same issue or a different one? |
Oh nice! I am pretty sure the [[Set]] issue is the same. You are even showing the Vector example that I found. |
This comment has been minimized.
This comment has been minimized.
@syg It is definitely the same issue, yet with a bit different solution for
Taking into account Slide 12, it translates to normative change like: 1. Assert: IsPropertyKey(_P_) is *true*.
- 1. If Type(_P_) is String, then
+ 1. If SameValue(_O_, _Receiver_) is *true* and Type(_P_) is String, then
1. Let _numericIndex_ be ! CanonicalNumericIndexString(_P_).
1. If _numericIndex_ is not *undefined*, then
1. Perform ? IntegerIndexedElementSet(_O_, _numericIndex_, _V_).
1. Return *true*.
1. Return ? OrdinarySet(_O_, _P_, _V_, _Receiver_). Which would break consistency with TypedArray's Object.defineProperty(Int8Array.prototype, -1, {
get() { throw new Error("-1 getter should be unreachable!"); },
set(-v) { throw new Error("-1 setter should be unreachable!"); },
});
const tA = new Int8Array(10);
-1 in tA; // => false
tA[-1]; // => undefined
tA[-1] = 1; // => throws Error #1556 aligns |
Using a Typed Array (or most any exotic object) as as a prototype is weird. But their specification
of [[Get]] and [[Set]] does not correctly deal with the case where the Rceiver argument is not the same object as the exotic array. In this case, a [[Put]] can actually mutate the prototype type object. Consider:
The problem is that 9.4.5.5 does not check if O is different from Receiver and calls IntegerIndexElementSet to mutate O rather than Receiver (which would also be wrong, but for other reasons.
The fix is to change step 2 to:
The same change should also be made to 9.4.5.4
The text was updated successfully, but these errors were encountered: