8024174: Setting __proto__ property in Object literal should be supported
authorsundar
Wed, 04 Sep 2013 19:58:16 +0530
changeset 19881 d92851923f86
parent 19880 ba17a955c28b
child 19882 331df558032c
child 19883 aae0838ac6ee
8024174: Setting __proto__ property in Object literal should be supported Reviewed-by: jlaskey, lagergren
nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
nashorn/test/script/basic/JDK-8024174.js
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Sep 04 14:29:07 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Sep 04 19:58:16 2013 +0530
@@ -1361,6 +1361,7 @@
         final List<Expression> values  = new ArrayList<>();
 
         boolean hasGettersSetters = false;
+        Expression protoNode = null;
 
         for (PropertyNode propertyNode: elements) {
             final Expression   value        = propertyNode.getValue();
@@ -1369,6 +1370,9 @@
 
             if (value == null) {
                 hasGettersSetters = true;
+            } else if (key.equals(ScriptObject.PROTO_PROPERTY_NAME)) {
+                protoNode = value;
+                continue;
             }
 
             keys.add(key);
@@ -1410,8 +1414,13 @@
         }
 
         method.dup();
-        globalObjectPrototype();
-        method.invoke(ScriptObject.SET_PROTO);
+        if (protoNode != null) {
+            load(protoNode);
+            method.invoke(ScriptObject.SET_PROTO_CHECK);
+        } else {
+            globalObjectPrototype();
+            method.invoke(ScriptObject.SET_PROTO);
+        }
 
         if (hasGettersSetters) {
             for (final PropertyNode propertyNode : elements) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Sep 04 14:29:07 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Sep 04 19:58:16 2013 +0530
@@ -88,7 +88,7 @@
 
 public abstract class ScriptObject extends PropertyListenerManager implements PropertyAccess {
     /** __proto__ special property name */
-    static final String PROTO_PROPERTY_NAME   = "__proto__";
+    public static final String PROTO_PROPERTY_NAME   = "__proto__";
 
     /** Search fall back routine name for "no such method" */
     static final String NO_SUCH_METHOD_NAME   = "__noSuchMethod__";
@@ -155,6 +155,9 @@
     /** Method handle for setting the proto of a ScriptObject */
     public static final Call SET_PROTO          = virtualCallNoLookup(ScriptObject.class, "setProto", void.class, ScriptObject.class);
 
+    /** Method handle for setting the proto of a ScriptObject after checking argument */
+    public static final Call SET_PROTO_CHECK    = virtualCallNoLookup(ScriptObject.class, "setProtoCheck", void.class, Object.class);
+
     /** Method handle for setting the user accessors of a ScriptObject */
     public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024174.js	Wed Sep 04 19:58:16 2013 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8024174: Setting __proto__ property in Object literal should be supported *
+ * @test
+ * @run
+ */
+
+var p = { foo: function() { print("p.foo"); } };
+
+var obj = {
+    __proto__ : p,
+    bar: 44
+};
+
+if (obj.__proto__ !== p || Object.getPrototypeOf(obj) !== p) {
+    fail("obj.__proto__ was not set inside literal");
+}
+
+if (typeof(obj.foo) !== 'function' || obj.foo !== p.foo) {
+    fail("'obj' failed to inherit 'foo' from 'p'");
+}
+
+var obj2 = {
+    __proto__: null
+};
+
+if (obj2.__proto__ !== null || Object.getPrototypeOf(obj2) !== null) {
+    fail("obj2.__proto__ was not set to null inside literal");
+}