Conversation
Codecov Report
@@ Coverage Diff @@
## master #5774 +/- ##
=======================================
Coverage 84.79% 84.79%
=======================================
Files 204 204
Lines 9607 9607
Branches 2701 2701
=======================================
Hits 8146 8146
Misses 977 977
Partials 484 484
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Let's add the code from #5769 as a new exec.js test case.
|
@jridgewell test case added. |
| if (parent !== null) { | ||
| set(parent, property, value, receiver); | ||
| } else { | ||
| receiver[property] = value; |
There was a problem hiding this comment.
https://tc39.github.io/ecma262/#sec-ordinaryset
This combines steps 3.c.i (overwriting desc with a new descriptor) and the steps under 4. Looks fine.
There was a problem hiding this comment.
Hm... looks like this is not fine.
receiver[property] = value will execute setters defined in the receiver's prototype, even though they should not be executed (the setter from super should be executed instead).
There was a problem hiding this comment.
Reading spec is hard. So I just add another test case for accessors. This test case pass in V8, WebKit and Firefox so I assume it's correct.
| receiver[property] = value; | ||
| } | ||
| } else if ("value" in desc && desc.writable) { | ||
| desc.value = value; |
There was a problem hiding this comment.
I am confused about this, though, but hopefully this is not broken as it is here. Step 4.d.iv does a [[DefineOwnProperty]] call, but this just directly updates the .value in the descriptor without calling Object.defineProperty.
var o = { foo: 'bar' }; Object.getOwnPropertyDescriptor(o, 'foo').value = 'baz'is not sufficient to change the value of o.foo.
There was a problem hiding this comment.
The helper also just silently does nothing if not writable (needs to throw in strict mode), but solving that is a harder problem.
There was a problem hiding this comment.
I think the right way to solve it is also to replace it with basically receiver[property] = value. This will also execute the OrdinarySet algorithm. However, there needs to be a check for 'value' in Object.getOwnPropertyDescriptor(receiver, property) (if there is a pre-existing descriptor). It needs to fail if the receiver[property] is a setter.
There was a problem hiding this comment.
Yes, the silent fail in sloopy mode or throw in strict mode for writeable: false and no setter is a hard problem, that's why I do not want to deal with it in this PR. Let's just do one thing in one time.
There was a problem hiding this comment.
IMHO DefineOwnProperty is not the same with receiver[property] = value.
Think this example.
class A {
}
class B extends A {
constructor() {
super()
super.x = 3
console.log(this.x)
console.log(super.x)
}
set x(v) {
console.log('i am invoked!') // will not invoked
this._x = v
}
get x() {
return this._x
}
}
new B()
| if (parent !== null) { | ||
| set(parent, property, value, receiver); | ||
| } else { | ||
| Object.defineProperty(receiver, property, {value: value}); |
There was a problem hiding this comment.
This needs writable: true, enumerable: true, configurable: true?
|
This is part of #7553 . Closing |
This PR fixes #5769 .
This PR also revise an unrelated testcase which embed
_setcode, I add external-helpers to its conf to remove _set/_get implementation details from it.