Hello,

the issues described below also affect compatibility with other Javascript engines. In fact when testing these with SpiderMonkey, V8 or JavascriptCore, you'll see all of them report the expected results. More inline...


On 9/18/2013 3:01 PM, A. Sundararajan wrote:
Hi,

Thanks for writing. We are aware of current start of draft spec on this. But, the issue is that if Object.prototype.__proto__ is the way to implement, how will setting __proto__ to null or undefined do?
Do you mean executing `Object.prototype.__proto__ = null`? This will execute the __proto__ [[Set]] accessor property, which then sets [[Prototype]] of Object.prototype to `null`. Or do you mean to delete the __proto__ accessor on Object.prototype?


If Object.prototype is not in proto chain of an object, what happens to __proto__ for such objects?
Nothing ;-) `o = Object.create(null); o.__proto__ = 123;` creates a normal data property, no special [[Prototype]] changes whatsoever, i.e. `Object.getOwnPropertyDescriptor(o, "__proto__")` returns `{value:123, writable:true, enumerable:true, configurable:true}`.



Current __proto__ impl is more of a fall back for scripts that do use __proto__. Since there is no definitive spec yet, it is going to be "wrong" one way or other. If it is finalized by ES6, we'll follow it. For now, I think we'll leave it "as is".
Yeah sure, always hard to tell how TC39 will act. One day feature X is the best one ever, next day it's the worst... -_- I think the best way to solve this, is to ensure the implementation follows the other Javascript engines as much as possible.


- André



Thanks,
-Sundar

On Wednesday 18 September 2013 05:54 PM, André Bargull wrote:
Official support for __proto__ was added recently, but the implementation does not quite match the proposed ECMAScript 6 specification (rev18).

The current consensus in TC39 is as follows:

(1) __proto__ in object literals is treated as a special form to set the [[Prototype]] internal data property of a new object. It is not possible to disable this functionality (*).

(2) Object.prototype.__proto__ is an accessor property with [[Get]] and [[Set]] accessors. Also [[Enumerable]] is false, [[Configurable]] is true.

(*) Previously it was possible to disable it, see ES6 draft rev14.

Certain details may still change over time when the ES6 spec gets finalized, e.g. should `Object.setPrototypeOf(1,null)` throw a TypeError because 1 is not an object or should this just perform argument checks and then return (as proposed in rev18). Also see https://bugs.ecmascript.org/show_bug.cgi?id=1586 for some recent changes on this topic.


- André


Current issues for (1):

1.1:
jjs> ({__proto__: (print("first"),{}), a: (print("second"),0)})

Expected: print "first" and then "second"
Actual: "second" and then "first"

1.2:
jjs> ({__proto__: null})

Expected: [[Prototype]] is set to null
Actual: jjs is terminated (also reproducible with `jjs> Object.create(null)`) Exception in thread "main" ECMAScript Exception: TypeError: Cannot get default string value
    at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:56)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:212) at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:184) at jdk.nashorn.internal.objects.Global.getDefaultValue(Global.java:585) at jdk.nashorn.internal.runtime.ScriptObject.getDefaultValue(ScriptObject.java:1243)
    ...

1.3:
jjs> ({__proto__: void 0}).__proto__ === Object.prototype

Expected: returns true
Actual: TypeError: undefined is not an Object
(Only Objects or null are allowed, other types are simply ignored. This was changed in rev17 for backward compatibility reasons)

1.4:
jjs> ({__proto__: 0})
Exception in thread "main" java.lang.AssertionError: int is not compatible with object at jdk.nashorn.internal.codegen.MethodEmitter.popType(MethodEmitter.java:235) at jdk.nashorn.internal.codegen.MethodEmitter.fixParamStack(MethodEmitter.java:1109) at jdk.nashorn.internal.codegen.MethodEmitter.invoke(MethodEmitter.java:1128) at jdk.nashorn.internal.codegen.MethodEmitter.invokevirtual(MethodEmitter.java:1168) at jdk.nashorn.internal.codegen.CompilerConstants$3.invoke(CompilerConstants.java:394)
    ...


Current issues for (2):

2.1:
jjs> Object.getOwnPropertyDescriptor(Object.prototype, "__proto__")

Expected: return accessor property descriptor
Actual: returns undefined

2.2:
jjs> (o = {}, o.__proto__ = void 0, o.__proto__ === Object.prototype)

Expected: returns true
Actual: returns false
(Only Objects or null are allowed, other types are simply ignored. This was changed in rev17 for backward compatibility reasons)

2.3:
jjs> (o = {}, o.__proto__ = 0, o)

Expected: returns o
Actual: jjs is terminated
jjs> (o = {}, o.__proto__ = 0, o)
Exception in thread "main" ECMAScript Exception: TypeError: [object Object] is not a Number
    at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:56)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:212) at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:184) at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:171) at jdk.nashorn.internal.objects.NativeNumber.getNumberValue(NativeNumber.java:341)
    ...

2.4:
jjs> 12["__proto__"] === Number.prototype

Expected: returns true
Actual: returns false



Reply via email to