# HG changeset patch # User sundar # Date 1383315888 -19800 # Node ID ae5f2130c3b991bfff59aab114ce6f169f618873 # Parent a002c1bb88f9fc1931642b62aaa73f73e5f39334 8027700: function redeclaration checks missing for declaration binding instantiation Reviewed-by: jlaskey, lagergren diff -r a002c1bb88f9 -r ae5f2130c3b9 src/jdk/nashorn/internal/codegen/Attr.java --- a/src/jdk/nashorn/internal/codegen/Attr.java Wed Oct 30 20:09:44 2013 +0530 +++ b/src/jdk/nashorn/internal/codegen/Attr.java Fri Nov 01 19:54:48 2013 +0530 @@ -271,6 +271,7 @@ functionNode.addDeclaredSymbol(symbol); if (varNode.isFunctionDeclaration()) { newType(symbol, FunctionNode.FUNCTION_TYPE); + symbol.setIsFunctionDeclaration(); } return varNode.setName((IdentNode)ident.setSymbol(lc, symbol)); } diff -r a002c1bb88f9 -r ae5f2130c3b9 src/jdk/nashorn/internal/codegen/MapCreator.java --- a/src/jdk/nashorn/internal/codegen/MapCreator.java Wed Oct 30 20:09:44 2013 +0530 +++ b/src/jdk/nashorn/internal/codegen/MapCreator.java Fri Nov 01 19:54:48 2013 +0530 @@ -134,6 +134,10 @@ flags |= Property.CAN_BE_UNDEFINED; } + if (symbol.isFunctionDeclaration()) { + flags |= Property.IS_FUNCTION_DECLARATION; + } + return flags; } diff -r a002c1bb88f9 -r ae5f2130c3b9 src/jdk/nashorn/internal/ir/Symbol.java --- a/src/jdk/nashorn/internal/ir/Symbol.java Wed Oct 30 20:09:44 2013 +0530 +++ b/src/jdk/nashorn/internal/ir/Symbol.java Fri Nov 01 19:54:48 2013 +0530 @@ -75,6 +75,8 @@ public static final int IS_SPECIALIZED_PARAM = 1 << 13; /** Is this symbol a shared temporary? */ public static final int IS_SHARED = 1 << 14; + /** Is this a function declaration? */ + public static final int IS_FUNCTION_DECLARATION = 1 << 15; /** Null or name identifying symbol. */ private final String name; @@ -360,6 +362,14 @@ } /** + * Check if this symbol is a function declaration + * @return true if a function declaration + */ + public boolean isFunctionDeclaration() { + return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION; + } + + /** * Creates an unshared copy of a symbol. The symbol must be currently shared. * @param newName the name for the new symbol. * @return a new, unshared symbol. @@ -396,6 +406,16 @@ /** + * Mark this symbol as a function declaration. + */ + public void setIsFunctionDeclaration() { + if (!isFunctionDeclaration()) { + trace("SET IS FUNCTION DECLARATION"); + flags |= IS_FUNCTION_DECLARATION; + } + } + + /** * Check if this symbol is a variable * @return true if variable */ diff -r a002c1bb88f9 -r ae5f2130c3b9 src/jdk/nashorn/internal/runtime/Property.java --- a/src/jdk/nashorn/internal/runtime/Property.java Wed Oct 30 20:09:44 2013 +0530 +++ b/src/jdk/nashorn/internal/runtime/Property.java Fri Nov 01 19:54:48 2013 +0530 @@ -56,33 +56,36 @@ public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000; /** ECMA 8.6.1 - Is this property not writable? */ - public static final int NOT_WRITABLE = 0b0000_0000_0001; + public static final int NOT_WRITABLE = 1 << 0; /** ECMA 8.6.1 - Is this property not enumerable? */ - public static final int NOT_ENUMERABLE = 0b0000_0000_0010; + public static final int NOT_ENUMERABLE = 1 << 1; /** ECMA 8.6.1 - Is this property not configurable? */ - public static final int NOT_CONFIGURABLE = 0b0000_0000_0100; + public static final int NOT_CONFIGURABLE = 1 << 2; - private static final int MODIFY_MASK = 0b0000_0000_1111; + private static final int MODIFY_MASK = (NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE); /** Is this a spill property? See {@link AccessorProperty} */ - public static final int IS_SPILL = 0b0000_0001_0000; + public static final int IS_SPILL = 1 << 3; /** Is this a function parameter? */ - public static final int IS_PARAMETER = 0b0000_0010_0000; + public static final int IS_PARAMETER = 1 << 4; /** Is parameter accessed thru arguments? */ - public static final int HAS_ARGUMENTS = 0b0000_0100_0000; + public static final int HAS_ARGUMENTS = 1 << 5; /** Is this property always represented as an Object? See {@link ObjectClassGenerator} and dual fields flag. */ - public static final int IS_ALWAYS_OBJECT = 0b0000_1000_0000; + public static final int IS_ALWAYS_OBJECT = 1 << 6; /** Can this property be primitive? */ - public static final int CAN_BE_PRIMITIVE = 0b0001_0000_0000; + public static final int CAN_BE_PRIMITIVE = 1 << 7; /** Can this property be undefined? */ - public static final int CAN_BE_UNDEFINED = 0b0010_0000_0000; + public static final int CAN_BE_UNDEFINED = 1 << 8; + + /* Is this a function declaration property ? */ + public static final int IS_FUNCTION_DECLARATION = 1 << 9; /** Property key. */ private final String key; @@ -522,4 +525,12 @@ public boolean canBeUndefined() { return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED; } + + /** + * Check whether this property represents a function declaration. + * @return whether this property is a function declaration or not. + */ + public boolean isFunctionDeclaration() { + return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION; + } } diff -r a002c1bb88f9 -r ae5f2130c3b9 src/jdk/nashorn/internal/runtime/ScriptObject.java --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Oct 30 20:09:44 2013 +0530 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Nov 01 19:54:48 2013 +0530 @@ -226,14 +226,23 @@ for (final Property property : properties) { final String key = property.getKey(); - - if (newMap.findProperty(key) == null) { + final Property oldProp = newMap.findProperty(key); + if (oldProp == null) { if (property instanceof UserAccessorProperty) { final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source)); newMap = newMap.addProperty(prop); } else { newMap = newMap.addPropertyBind((AccessorProperty)property, source); } + } else { + // See ECMA section 10.5 Declaration Binding Instantiation + // step 5 processing each function declaration. + if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) { + if (oldProp instanceof UserAccessorProperty || + !(oldProp.isWritable() && oldProp.isEnumerable())) { + throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this)); + } + } } } diff -r a002c1bb88f9 -r ae5f2130c3b9 test/script/basic/JDK-8015355.js --- a/test/script/basic/JDK-8015355.js Wed Oct 30 20:09:44 2013 +0530 +++ b/test/script/basic/JDK-8015355.js Fri Nov 01 19:54:48 2013 +0530 @@ -28,10 +28,6 @@ * @run */ -function fail(msg) { - print(msg); -} - function check(callback) { try { callback(); diff -r a002c1bb88f9 -r ae5f2130c3b9 test/script/basic/JDK-8027700.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8027700.js Fri Nov 01 19:54:48 2013 +0530 @@ -0,0 +1,54 @@ +/* + * 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-8027700: function redeclaration checks missing for declaration binding instantiation + * + * @test + * @run + */ + +Object.defineProperty(this,"x", { + value:0, + writable:true, + enumerable:false +}) + +try { + eval("function x() {}"); + fail("should have thrown TypeError"); +} catch (e) { + if (! (e instanceof TypeError)) { + fail("TypeError expected but got " + e); + } +} + +Object.defineProperty(this, "foo", { value:0 }) +try { + eval("function foo() {}"); + fail("should have thrown TypeError"); +} catch (e) { + if (! (e instanceof TypeError)) { + fail("TypeError expected but got " + e); + } +}