-
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
Normative: Guard IntegerIndexedElementSet with receiver check #1556
Conversation
EDIT: Type checking |
b26eacb
to
80546f0
Compare
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]);
let target = [0]
let receiver = [0]
Reflect.set(target, 0, 1, receiver)
print(target, receiver)
let typedTarget = new Int8Array(1)
let typedReceiver = new Int8Array(1)
Reflect.set(typedTarget, 0, 1, typedReceiver)
print(typedTarget, typedReceiver) i get these results: #### Chakra
4 0
0 1
0 1
#### JavaScriptCore
4 0
0 1
1 0
#### SpiderMonkey
4 0
0 1
0 1
#### V8
4 0
0 1
0 1
#### V8 --harmony
4 0
0 1
0 1 so there's actually a variance in the latter case - only JSC returns |
80546f0
to
7a98ef3
Compare
I am probably misreading the change, but doesn't the return in Step 2.b.ii mean we never set anything in this case? |
This comment has been minimized.
This comment has been minimized.
Oops, my mistake: while always returning w/o setting anything would be a desired change, it is not web-compatible. Fixed to fall back to |
7a98ef3
to
7531185
Compare
7531185
to
8539513
Compare
3d0c24c
to
7a79833
Compare
spec.html
Outdated
1. If ! SameValue(_O_, _Receiver_) is *true*, then | ||
1. Perform ? IntegerIndexedElementSet(_O_, _numericIndex_, _V_). | ||
1. Return *true*. | ||
1. If ! IsValidIntegerIndex(_O_, _numericIndex_) is *false*, return *true*. |
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.
So if you have an integer index which is in bounds for O, but O and Receiver are different values, you'll now fall through to OrdinarySet. Is that intended?
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.
Honestly I don't remember what the behavior we got consensus for was, but this PR currently doesn't have interop wrt in-bounds/OOB accesses.
In-bounds falls through to OrdinarySet in SM and V8. OOB falls through to OrdinarySet in SM only. JSC currently always sets the value on the target instead of the receiver.
// test-iieo-receiver-mismatch.js
let target = new Int8Array(1);
let receiver = [0];
// In-bounds
Reflect.set(target, 0, 1, receiver);
print('after in-bounds set:', target, receiver);
// OOB
Reflect.set(target, 2, 1, receiver);
print('after OOB set:', target, receiver);
$ eshost ./test-iieo-receiver-mismatch.js
#### ch
after in-bounds set: 0 1
after OOB set: 0 1,,1
#### jsc
after in-bounds set: 1 0
after OOB set: 1 0
#### sm
after in-bounds set: 0 1
after OOB set: 0 1,,1
#### v8
after in-bounds set: 0 1
after OOB set: 0 1
#### xs
after in-bounds set: 1 0
after OOB set: 1 0
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.
Hm, it looks like both chakra and SM had the same behavior. Whats the usecase? This only impacts reflect api iiuc, so tooling?
I'll try to jog my memory for what the consensus was. Failing that we might need to relitigate this, unfortunately. |
removing pending reconfirming what consensus is
@syg The consensus for TypedArray's EDIT: found meeting notes for that meeting: https://github.com/tc39/notes/blob/167155eeb708d84e1758d99c88b15670f9b81f75/meetings/2019-12/december-3.md#normative-typedarray-on-prototypes-web-reality. EDIT 2: actually, the presentation that got consensus doesn't seem to include semantics for OOB indices. As for non-canonical keys, this PR and the presentation agree to invoke That matches SpiderMonkey behaviour, while this PR matches V8's. Neither proposals have interop, but both are web-compatible, so in this PR I'm suggesting to match TypedArray's So formally this PR must receive committee's approval. @codehag Not only the |
8539513
to
55ee72d
Compare
55ee72d
to
3620f11
Compare
Closes #1339.
Closes #1541.
Recap
In ES6, both
[[Get]]
and[[Set]]
TypedArray methods had the receiver checks, which were removed in #347 due to consistency with[[HasProperty]]
. Removing receiver check from[[Set]]
turned out to be web-incompatible (SM bug), breaking the 🚀 NASA's WorldWind web app and SDK.I've just checked the links in Firefox 63 (release binaries): the web app and SDK examples still don't work. While there are no other sites that are broken, we can't just fix the WorldWind: it's an educational material that is also distributed offline and viewed via
file:///
protocol.The breakage was caused by TypedArray instances being in
[[Prototype]]
chain (presumably, for default values) of various objects likeMatrix
orVector
instances.Proposed change
This PR attempts to specify the most desired behavior while providing the minimum required for web-compatibility:
OrdinarySet
is performed for canonical numeric strings that are valid indices only.[[Get]]
and[[HasProperty]]
TypedArray methods regarding invalid indices: prototype traversal in stopped.[[Set]]
overrides like of mapped arguments or legacy platform objects regarding altered receivers: a simple reference check is performed.[[Set]]
as well.Implementation status
[[Set]]
overrides during prototype chain traversal, and getsReflect.set
wrong for non-ordinary[[Set]]
. This bug will fix non-index[[Set]]
, including canonical numeric strings that are invalid indices. Indexed[[Set]]
will be adjusted in a follow-up, as it's quite different and unaware of receiver.