diff --git a/src/org/mozilla/javascript/CodeGenerator.java b/src/org/mozilla/javascript/CodeGenerator.java index 9093ab0af2..158a83b9d7 100644 --- a/src/org/mozilla/javascript/CodeGenerator.java +++ b/src/org/mozilla/javascript/CodeGenerator.java @@ -8,15 +8,10 @@ import java.math.BigInteger; import java.util.List; -import org.mozilla.javascript.ast.AstNode; -import org.mozilla.javascript.ast.AstRoot; -import org.mozilla.javascript.ast.Block; import org.mozilla.javascript.ast.FunctionNode; import org.mozilla.javascript.ast.Jump; -import org.mozilla.javascript.ast.Scope; import org.mozilla.javascript.ast.ScriptNode; import org.mozilla.javascript.ast.TemplateCharacters; -import org.mozilla.javascript.ast.VariableInitializer; /** Generates bytecode for the Interpreter. */ class CodeGenerator extends Icode { @@ -115,8 +110,6 @@ private void generateFunctionICode() { itsData.isES6Generator = true; } - itsData.declaredAsVar = (theFunction.getParent() instanceof VariableInitializer); - generateICodeFromTree(theFunction.getLastChild()); } @@ -210,13 +203,6 @@ private void generateNestedFunctions() { gen.itsData = new InterpreterData(itsData); gen.generateFunctionICode(); array[i] = gen.itsData; - - final AstNode fnParent = fn.getParent(); - if (!(fnParent instanceof AstRoot - || fnParent instanceof Scope - || fnParent instanceof Block)) { - gen.itsData.declaredAsFunctionExpression = true; - } } itsData.itsNestedFunctions = array; } diff --git a/src/org/mozilla/javascript/InterpretedFunction.java b/src/org/mozilla/javascript/InterpretedFunction.java index aeb660ba01..238f91a98b 100644 --- a/src/org/mozilla/javascript/InterpretedFunction.java +++ b/src/org/mozilla/javascript/InterpretedFunction.java @@ -150,15 +150,4 @@ protected String getParamOrVarName(int index) { protected boolean getParamOrVarConst(int index) { return idata.argIsConst[index]; } - - boolean hasFunctionNamed(String name) { - for (int f = 0; f < idata.getFunctionCount(); f++) { - InterpreterData functionData = (InterpreterData) idata.getFunction(f); - if (!functionData.declaredAsFunctionExpression - && name.equals(functionData.getFunctionName())) { - return false; - } - } - return true; - } } diff --git a/src/org/mozilla/javascript/InterpreterData.java b/src/org/mozilla/javascript/InterpreterData.java index 8e95210d0f..a3ee0bfa6f 100644 --- a/src/org/mozilla/javascript/InterpreterData.java +++ b/src/org/mozilla/javascript/InterpreterData.java @@ -93,12 +93,6 @@ private void init() { private int icodeHashCode = 0; - /** true if the function has been declared like "var foo = function() {...}" */ - boolean declaredAsVar; - - /** true if the function has been declared like "!function() {}". */ - boolean declaredAsFunctionExpression; - @Override public boolean isTopLevel() { return topLevel; diff --git a/src/org/mozilla/javascript/NativeCall.java b/src/org/mozilla/javascript/NativeCall.java index 33e9a4cc8b..d00ca5aee9 100644 --- a/src/org/mozilla/javascript/NativeCall.java +++ b/src/org/mozilla/javascript/NativeCall.java @@ -64,8 +64,7 @@ static void init(Scriptable scope, boolean sealed) { if (!super.has(name, this)) { if (function.getParamOrVarConst(i)) { defineProperty(name, Undefined.instance, CONST); - } else if (!(function instanceof InterpretedFunction) - || ((InterpretedFunction) function).hasFunctionNamed(name)) { + } else { defineProperty(name, Undefined.instance, PERMANENT); } } diff --git a/src/org/mozilla/javascript/ScriptRuntime.java b/src/org/mozilla/javascript/ScriptRuntime.java index 0a5dfea781..80437f905c 100644 --- a/src/org/mozilla/javascript/ScriptRuntime.java +++ b/src/org/mozilla/javascript/ScriptRuntime.java @@ -3940,12 +3940,9 @@ public static void initScript( if (isConst) { ScriptableObject.defineConstProperty(varScope, name); } else if (!evalScript) { - if (!(funObj instanceof InterpretedFunction) - || ((InterpretedFunction) funObj).hasFunctionNamed(name)) { - // Global var definitions are supposed to be DONTDELETE - ScriptableObject.defineProperty( - varScope, name, Undefined.instance, ScriptableObject.PERMANENT); - } + // Global var definitions are supposed to be DONTDELETE + ScriptableObject.defineProperty( + varScope, name, Undefined.instance, ScriptableObject.PERMANENT); } else { varScope.put(name, varScope, Undefined.instance); } diff --git a/testsrc/org/mozilla/javascript/tests/FunctionTest.java b/testsrc/org/mozilla/javascript/tests/FunctionTest.java index 6243cdf3c0..cf025076ac 100644 --- a/testsrc/org/mozilla/javascript/tests/FunctionTest.java +++ b/testsrc/org/mozilla/javascript/tests/FunctionTest.java @@ -30,8 +30,7 @@ public void testFunctionWithSlashSlash() { @Test public void functionHasNameOfVarStrictMode() throws Exception { final String script = - "" - + "'use strict';\n" + "'use strict';\n" + "var result = '';\n" + "var abc = 1;\n" + "var foo = function abc() { result += '-inner abc = ' + typeof abc; };\n" @@ -45,8 +44,7 @@ public void functionHasNameOfVarStrictMode() throws Exception { @Test public void innerFunctionWithSameName() throws Exception { final String script = - "" - + "var result = '';\n" + "var result = '';\n" + "var a = function () {\n" + " var x = (function x () { result += 'a'; });\n" + " return function () { x(); };\n" @@ -65,8 +63,7 @@ public void innerFunctionWithSameName() throws Exception { @Test public void innerFunctionWithSameNameAsOutsideStrict() throws Exception { final String script = - "" - + "var result = '';\n" + "var result = '';\n" + "'use strict';\n" + "var a = function () {\n" + " var x = (function x () { result += 'a'; });\n" @@ -82,8 +79,7 @@ public void innerFunctionWithSameNameAsOutsideStrict() throws Exception { @Test public void secondFunctionWithSameNameStrict() throws Exception { final String script = - "" - + "var result = '';\n" + "var result = '';\n" + "'use strict';\n" + "function norm(foo) { return ('' + foo).replace(/(\\s)/gm,''); }\n" + "function func () { result += 'outer'; }\n" @@ -140,7 +136,18 @@ public void functioNamesExceptionsStrict() throws Exception { assertEvaluates("f1f2f3!f4f5!f6!f7!f8f10f11f12f11f12f13", script); } - private void assertEvaluates(final Object expected, final String source) { + @Test + public void conditionallyCreatedFunction() { + final String script = + "var log = 'foo = ' + foo;\n" + + "if (false) {\n" + + " function foo() { return 1; }\n" + + "}\n" + + "log"; + assertEvaluates("foo = undefined", script); + } + + private static void assertEvaluates(final Object expected, final String source) { Utils.runWithAllOptimizationLevels( cx -> { final Scriptable scope = cx.initStandardObjects();