archives

« Bugzilla Issues Index

#1549 — 9.3.3: Remove step 3 from CreateOwnDataProperty


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