Fri, 01 Nov 2013 19:54:48 +0530
8027700: function redeclaration checks missing for declaration binding instantiation
Reviewed-by: jlaskey, lagergren
1.1 --- a/src/jdk/nashorn/internal/codegen/Attr.java Wed Oct 30 20:09:44 2013 +0530 1.2 +++ b/src/jdk/nashorn/internal/codegen/Attr.java Fri Nov 01 19:54:48 2013 +0530 1.3 @@ -271,6 +271,7 @@ 1.4 functionNode.addDeclaredSymbol(symbol); 1.5 if (varNode.isFunctionDeclaration()) { 1.6 newType(symbol, FunctionNode.FUNCTION_TYPE); 1.7 + symbol.setIsFunctionDeclaration(); 1.8 } 1.9 return varNode.setName((IdentNode)ident.setSymbol(lc, symbol)); 1.10 }
2.1 --- a/src/jdk/nashorn/internal/codegen/MapCreator.java Wed Oct 30 20:09:44 2013 +0530 2.2 +++ b/src/jdk/nashorn/internal/codegen/MapCreator.java Fri Nov 01 19:54:48 2013 +0530 2.3 @@ -134,6 +134,10 @@ 2.4 flags |= Property.CAN_BE_UNDEFINED; 2.5 } 2.6 2.7 + if (symbol.isFunctionDeclaration()) { 2.8 + flags |= Property.IS_FUNCTION_DECLARATION; 2.9 + } 2.10 + 2.11 return flags; 2.12 } 2.13
3.1 --- a/src/jdk/nashorn/internal/ir/Symbol.java Wed Oct 30 20:09:44 2013 +0530 3.2 +++ b/src/jdk/nashorn/internal/ir/Symbol.java Fri Nov 01 19:54:48 2013 +0530 3.3 @@ -75,6 +75,8 @@ 3.4 public static final int IS_SPECIALIZED_PARAM = 1 << 13; 3.5 /** Is this symbol a shared temporary? */ 3.6 public static final int IS_SHARED = 1 << 14; 3.7 + /** Is this a function declaration? */ 3.8 + public static final int IS_FUNCTION_DECLARATION = 1 << 15; 3.9 3.10 /** Null or name identifying symbol. */ 3.11 private final String name; 3.12 @@ -360,6 +362,14 @@ 3.13 } 3.14 3.15 /** 3.16 + * Check if this symbol is a function declaration 3.17 + * @return true if a function declaration 3.18 + */ 3.19 + public boolean isFunctionDeclaration() { 3.20 + return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION; 3.21 + } 3.22 + 3.23 + /** 3.24 * Creates an unshared copy of a symbol. The symbol must be currently shared. 3.25 * @param newName the name for the new symbol. 3.26 * @return a new, unshared symbol. 3.27 @@ -396,6 +406,16 @@ 3.28 3.29 3.30 /** 3.31 + * Mark this symbol as a function declaration. 3.32 + */ 3.33 + public void setIsFunctionDeclaration() { 3.34 + if (!isFunctionDeclaration()) { 3.35 + trace("SET IS FUNCTION DECLARATION"); 3.36 + flags |= IS_FUNCTION_DECLARATION; 3.37 + } 3.38 + } 3.39 + 3.40 + /** 3.41 * Check if this symbol is a variable 3.42 * @return true if variable 3.43 */
4.1 --- a/src/jdk/nashorn/internal/runtime/Property.java Wed Oct 30 20:09:44 2013 +0530 4.2 +++ b/src/jdk/nashorn/internal/runtime/Property.java Fri Nov 01 19:54:48 2013 +0530 4.3 @@ -56,33 +56,36 @@ 4.4 public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000; 4.5 4.6 /** ECMA 8.6.1 - Is this property not writable? */ 4.7 - public static final int NOT_WRITABLE = 0b0000_0000_0001; 4.8 + public static final int NOT_WRITABLE = 1 << 0; 4.9 4.10 /** ECMA 8.6.1 - Is this property not enumerable? */ 4.11 - public static final int NOT_ENUMERABLE = 0b0000_0000_0010; 4.12 + public static final int NOT_ENUMERABLE = 1 << 1; 4.13 4.14 /** ECMA 8.6.1 - Is this property not configurable? */ 4.15 - public static final int NOT_CONFIGURABLE = 0b0000_0000_0100; 4.16 + public static final int NOT_CONFIGURABLE = 1 << 2; 4.17 4.18 - private static final int MODIFY_MASK = 0b0000_0000_1111; 4.19 + private static final int MODIFY_MASK = (NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE); 4.20 4.21 /** Is this a spill property? See {@link AccessorProperty} */ 4.22 - public static final int IS_SPILL = 0b0000_0001_0000; 4.23 + public static final int IS_SPILL = 1 << 3; 4.24 4.25 /** Is this a function parameter? */ 4.26 - public static final int IS_PARAMETER = 0b0000_0010_0000; 4.27 + public static final int IS_PARAMETER = 1 << 4; 4.28 4.29 /** Is parameter accessed thru arguments? */ 4.30 - public static final int HAS_ARGUMENTS = 0b0000_0100_0000; 4.31 + public static final int HAS_ARGUMENTS = 1 << 5; 4.32 4.33 /** Is this property always represented as an Object? See {@link ObjectClassGenerator} and dual fields flag. */ 4.34 - public static final int IS_ALWAYS_OBJECT = 0b0000_1000_0000; 4.35 + public static final int IS_ALWAYS_OBJECT = 1 << 6; 4.36 4.37 /** Can this property be primitive? */ 4.38 - public static final int CAN_BE_PRIMITIVE = 0b0001_0000_0000; 4.39 + public static final int CAN_BE_PRIMITIVE = 1 << 7; 4.40 4.41 /** Can this property be undefined? */ 4.42 - public static final int CAN_BE_UNDEFINED = 0b0010_0000_0000; 4.43 + public static final int CAN_BE_UNDEFINED = 1 << 8; 4.44 + 4.45 + /* Is this a function declaration property ? */ 4.46 + public static final int IS_FUNCTION_DECLARATION = 1 << 9; 4.47 4.48 /** Property key. */ 4.49 private final String key; 4.50 @@ -522,4 +525,12 @@ 4.51 public boolean canBeUndefined() { 4.52 return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED; 4.53 } 4.54 + 4.55 + /** 4.56 + * Check whether this property represents a function declaration. 4.57 + * @return whether this property is a function declaration or not. 4.58 + */ 4.59 + public boolean isFunctionDeclaration() { 4.60 + return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION; 4.61 + } 4.62 }
5.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Oct 30 20:09:44 2013 +0530 5.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Nov 01 19:54:48 2013 +0530 5.3 @@ -226,14 +226,23 @@ 5.4 5.5 for (final Property property : properties) { 5.6 final String key = property.getKey(); 5.7 - 5.8 - if (newMap.findProperty(key) == null) { 5.9 + final Property oldProp = newMap.findProperty(key); 5.10 + if (oldProp == null) { 5.11 if (property instanceof UserAccessorProperty) { 5.12 final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source)); 5.13 newMap = newMap.addProperty(prop); 5.14 } else { 5.15 newMap = newMap.addPropertyBind((AccessorProperty)property, source); 5.16 } 5.17 + } else { 5.18 + // See ECMA section 10.5 Declaration Binding Instantiation 5.19 + // step 5 processing each function declaration. 5.20 + if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) { 5.21 + if (oldProp instanceof UserAccessorProperty || 5.22 + !(oldProp.isWritable() && oldProp.isEnumerable())) { 5.23 + throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this)); 5.24 + } 5.25 + } 5.26 } 5.27 } 5.28
6.1 --- a/test/script/basic/JDK-8015355.js Wed Oct 30 20:09:44 2013 +0530 6.2 +++ b/test/script/basic/JDK-8015355.js Fri Nov 01 19:54:48 2013 +0530 6.3 @@ -28,10 +28,6 @@ 6.4 * @run 6.5 */ 6.6 6.7 -function fail(msg) { 6.8 - print(msg); 6.9 -} 6.10 - 6.11 function check(callback) { 6.12 try { 6.13 callback();
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/script/basic/JDK-8027700.js Fri Nov 01 19:54:48 2013 +0530 7.3 @@ -0,0 +1,54 @@ 7.4 +/* 7.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. 7.11 + * 7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.15 + * version 2 for more details (a copy is included in the LICENSE file that 7.16 + * accompanied this code). 7.17 + * 7.18 + * You should have received a copy of the GNU General Public License version 7.19 + * 2 along with this work; if not, write to the Free Software Foundation, 7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.21 + * 7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.23 + * or visit www.oracle.com if you need additional information or have any 7.24 + * questions. 7.25 + */ 7.26 + 7.27 +/** 7.28 + * JDK-8027700: function redeclaration checks missing for declaration binding instantiation 7.29 + * 7.30 + * @test 7.31 + * @run 7.32 + */ 7.33 + 7.34 +Object.defineProperty(this,"x", { 7.35 + value:0, 7.36 + writable:true, 7.37 + enumerable:false 7.38 +}) 7.39 + 7.40 +try { 7.41 + eval("function x() {}"); 7.42 + fail("should have thrown TypeError"); 7.43 +} catch (e) { 7.44 + if (! (e instanceof TypeError)) { 7.45 + fail("TypeError expected but got " + e); 7.46 + } 7.47 +} 7.48 + 7.49 +Object.defineProperty(this, "foo", { value:0 }) 7.50 +try { 7.51 + eval("function foo() {}"); 7.52 + fail("should have thrown TypeError"); 7.53 +} catch (e) { 7.54 + if (! (e instanceof TypeError)) { 7.55 + fail("TypeError expected but got " + e); 7.56 + } 7.57 +}