Wed, 04 Sep 2013 14:29:07 +0530
8024120: Setting __proto__ to null removes the __proto__ property
Reviewed-by: lagergren, attila
1.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Aug 27 19:26:48 2013 +0530 1.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Sep 04 14:29:07 2013 +0530 1.3 @@ -87,6 +87,8 @@ 1.4 */ 1.5 1.6 public abstract class ScriptObject extends PropertyListenerManager implements PropertyAccess { 1.7 + /** __proto__ special property name */ 1.8 + static final String PROTO_PROPERTY_NAME = "__proto__"; 1.9 1.10 /** Search fall back routine name for "no such method" */ 1.11 static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__"; 1.12 @@ -130,6 +132,9 @@ 1.13 /** Indexed array data. */ 1.14 private ArrayData arrayData; 1.15 1.16 + static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class); 1.17 + static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class); 1.18 + 1.19 static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class); 1.20 static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); 1.21 static final MethodHandle SETSPILLWITHNEW = findOwnMH("setSpillWithNew", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); 1.22 @@ -1745,6 +1750,10 @@ 1.23 MethodHandle methodHandle; 1.24 1.25 if (find == null) { 1.26 + if (PROTO_PROPERTY_NAME.equals(name)) { 1.27 + return new GuardedInvocation(GETPROTO, NashornGuards.getScriptObjectGuard()); 1.28 + } 1.29 + 1.30 if ("getProp".equals(operator)) { 1.31 return noSuchProperty(desc, request); 1.32 } else if ("getMethod".equals(operator)) { 1.33 @@ -1851,6 +1860,7 @@ 1.34 * toString = function() { print("global toString"); } // don't affect Object.prototype.toString 1.35 */ 1.36 FindProperty find = findProperty(name, true, scope, this); 1.37 + 1.38 // If it's not a scope search, then we don't want any inherited properties except those with user defined accessors. 1.39 if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { 1.40 // We should still check if inherited data property is not writable 1.41 @@ -1866,9 +1876,12 @@ 1.42 // Existing, non-writable property 1.43 return createEmptySetMethod(desc, "property.not.writable", true); 1.44 } 1.45 - } else if (!isExtensible()) { 1.46 - // Non-existing property on a non-extensible object 1.47 - return createEmptySetMethod(desc, "object.non.extensible", false); 1.48 + } else { 1.49 + if (PROTO_PROPERTY_NAME.equals(name)) { 1.50 + return new GuardedInvocation(SETPROTOCHECK, NashornGuards.getScriptObjectGuard()); 1.51 + } else if (! isExtensible()) { 1.52 + return createEmptySetMethod(desc, "object.non.extensible", false); 1.53 + } 1.54 } 1.55 1.56 return new SetMethodCreator(this, find, desc).createGuardedInvocation();
2.1 --- a/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Tue Aug 27 19:26:48 2013 +0530 2.2 +++ b/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Wed Sep 04 14:29:07 2013 +0530 2.3 @@ -137,17 +137,6 @@ 2.4 } 2.5 }); 2.6 2.7 -// Object.prototype.__proto__ (read-only) 2.8 -Object.defineProperty(Object.prototype, "__proto__", { 2.9 - configurable: true, enumerable: false, 2.10 - get: function() { 2.11 - return Object.getPrototypeOf(this); 2.12 - }, 2.13 - set: function(x) { 2.14 - Object.setPrototypeOf(this, x); 2.15 - } 2.16 -}); 2.17 - 2.18 // Object.prototype.toSource 2.19 Object.defineProperty(Object.prototype, "toSource", { 2.20 configurable: true, enumerable: false, writable: true,
3.1 --- a/test/script/basic/JDK-8023368.js Tue Aug 27 19:26:48 2013 +0530 3.2 +++ b/test/script/basic/JDK-8023368.js Wed Sep 04 14:29:07 2013 +0530 3.3 @@ -28,8 +28,6 @@ 3.4 * @run 3.5 */ 3.6 3.7 -load("nashorn:mozilla_compat.js"); 3.8 - 3.9 // function to force same callsites 3.10 function check(obj) { 3.11 print(obj.func());
4.1 --- a/test/script/basic/JDK-8023368.js.EXPECTED Tue Aug 27 19:26:48 2013 +0530 4.2 +++ b/test/script/basic/JDK-8023368.js.EXPECTED Wed Sep 04 14:29:07 2013 +0530 4.3 @@ -4,15 +4,15 @@ 4.4 Func.prototype.func 4.5 hello 4.6 [object Object] 4.7 -obj.__proto__.func @ 57 4.8 +obj.__proto__.func @ 55 4.9 344 4.10 [object Object] 4.11 -obj.__proto__.func @ 57 4.12 +obj.__proto__.func @ 55 4.13 344 4.14 [object Object] 4.15 -obj.__proto__.func @ 57 4.16 +obj.__proto__.func @ 55 4.17 344 4.18 new object.toString 4.19 -obj.__proto__.func @ 57 4.20 +obj.__proto__.func @ 55 4.21 344 4.22 new object.toString
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/script/basic/JDK-8024120.js Wed Sep 04 14:29:07 2013 +0530 5.3 @@ -0,0 +1,42 @@ 5.4 +/* 5.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 + * or visit www.oracle.com if you need additional information or have any 5.24 + * questions. 5.25 + */ 5.26 + 5.27 +/** 5.28 + * JDK-8024120: Setting __proto__ to null removes the __proto__ property 5.29 + * 5.30 + * @test 5.31 + * @run 5.32 + */ 5.33 + 5.34 +var obj = {}; 5.35 + 5.36 +obj.__proto__ = null; 5.37 + 5.38 +if (obj.__proto__ !== null || typeof(obj.__proto__) != 'object') { 5.39 + fail("obj.__proto__ is expected to be null"); 5.40 +} 5.41 + 5.42 +var p = Object.getPrototypeOf(obj); 5.43 +if (p !== null || typeof(p) != 'object') { 5.44 + fail("Object.getPrototypeOf(obj) is expected to be null"); 5.45 +}
6.1 --- a/test/script/basic/circular_proto.js Tue Aug 27 19:26:48 2013 +0530 6.2 +++ b/test/script/basic/circular_proto.js Wed Sep 04 14:29:07 2013 +0530 6.3 @@ -29,7 +29,6 @@ 6.4 */ 6.5 6.6 // check that we cannot create __proto__ cycle 6.7 -load("nashorn:mozilla_compat.js"); 6.8 6.9 var obj = {}; 6.10 var obj2 = Object.create(obj);
7.1 --- a/test/script/basic/nonextensible_proto_assign.js Tue Aug 27 19:26:48 2013 +0530 7.2 +++ b/test/script/basic/nonextensible_proto_assign.js Wed Sep 04 14:29:07 2013 +0530 7.3 @@ -28,8 +28,6 @@ 7.4 * @run 7.5 */ 7.6 7.7 -load("nashorn:mozilla_compat.js") 7.8 - 7.9 // check that we cannot assign to __proto__ of a non-extensible object 7.10 try { 7.11 var obj = {}