__proto__ implementation does not quite match proposed ES6 spec

André Bargull andrebargull at googlemail.com
Wed Sep 18 05:24:41 PDT 2013


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


More information about the nashorn-dev mailing list