Remove this step from 9.3.3 CreateOwnDataProperty (O, P, V):
3. Assert: O does not have an own property whose key is P
Test case which triggers the assertion:
js> Reflect.set({}, "foo", 0, {foo: 0})
Exception in thread "main" java.lang.AssertionError
at com.github.anba.es6draft.runtime.AbstractOperations.CreateOwnDataProperty(AbstractOperations.java:516)
at com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject.set(OrdinaryObject.java:470)
at com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject.set(OrdinaryObject.java:465)
at com.github.anba.es6draft.runtime.objects.reflect.Reflect$ReflectedFunctions.set(Reflect.java:183)
The stack trace corresponds to the following methods:
15.17.1.9 Reflect.set (target, propertyKey, V, receiver=target), step 6
-> 8.3.10 [[Set]] (P, V, Receiver), step 4.c.i
--> 8.3.10 [[Set]] (P, V, Receiver), step 4.d.ii
---> 9.3.3 CreateOwnDataProperty (O, P, V), step 3
Interesting misuse of Reflect.set
Instead of eliminating the assertion (which really is intended to be the case, it caught this issue....) I restructured ordinary [[Put]] so that step 4.d.i sets ownDesc to the default data property descriptor. It then falls into step 5.
This way the same semantics apply to setting a receiver data property, regardless of whether or not it physically inherits from O (passing an object as the receiver means that it logically inherits from O).
fixed in rev 16 editor's draft.
I think you meant step 4.d.i. in "ordinary [[Set]]" rather than "ordinary [[Put]]".
I like this change: it removes some redundancy in the [[Set]] algorithm.
IIUC, the code snippet above would now be accepted. And if the property already exists on the receiver, it will now be *updated* rather than *overridden* with a new data property.
IIUC, the following tests should now pass (please correct me if I'm wrong):
var target = {};
var receiver = {};
Reflect.set(target, "foo", 1, receiver);
assert(target.foo === undefined);
assert(receiver.foo === 1); // new property added to receiver
Object.defineProperty(receiver, "bar",
{ value: 0,
writable: true,
enumerable: false,
configurable: true });
Reflect.set(target, "bar", 1, receiver);
assert(receiver.bar === 1); // value of existing receiver property updated
assert(Object.getOwnPropertyDescriptor(receiver,"bar").enumerable === false); // enumerability was not overridden
The test in comment 2 as well as the original test case both succeed the proposed update. Also no regressions from test262.
fixed in rev16 draft. July 15, 2013