mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-30 04:58:25 +00:00
8066222: too strong assertion on function expression names
Reviewed-by: hannesw, lagergren
This commit is contained in:
parent
8d3af43a7c
commit
deabb040d5
@ -135,15 +135,11 @@ final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggabl
|
||||
functionNode.compilerConstant(SCOPE).setNeedsSlot(false);
|
||||
}
|
||||
// Named function expressions that end up not referencing themselves won't need a local slot for the self symbol.
|
||||
if(!functionNode.isDeclared() && !functionNode.usesSelfSymbol() && !functionNode.isAnonymous()) {
|
||||
if(functionNode.isNamedFunctionExpression() && !functionNode.usesSelfSymbol()) {
|
||||
final Symbol selfSymbol = functionNode.getBody().getExistingSymbol(functionNode.getIdent().getName());
|
||||
if(selfSymbol != null) {
|
||||
if(selfSymbol.isFunctionSelf()) {
|
||||
selfSymbol.setNeedsSlot(false);
|
||||
selfSymbol.clearFlag(Symbol.IS_VAR);
|
||||
}
|
||||
} else {
|
||||
assert functionNode.isProgram();
|
||||
if(selfSymbol != null && selfSymbol.isFunctionSelf()) {
|
||||
selfSymbol.setNeedsSlot(false);
|
||||
selfSymbol.clearFlag(Symbol.IS_VAR);
|
||||
}
|
||||
}
|
||||
return functionNode;
|
||||
@ -490,20 +486,31 @@ final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggabl
|
||||
final Block body = lc.getCurrentBlock();
|
||||
|
||||
initFunctionWideVariables(functionNode, body);
|
||||
acceptDeclarations(functionNode, body);
|
||||
defineFunctionSelfSymbol(functionNode, body);
|
||||
}
|
||||
|
||||
if (!functionNode.isProgram() && !functionNode.isDeclared() && !functionNode.isAnonymous()) {
|
||||
// It's neither declared nor program - it's a function expression then; assign it a self-symbol unless it's
|
||||
// anonymous.
|
||||
final String name = functionNode.getIdent().getName();
|
||||
assert name != null;
|
||||
assert body.getExistingSymbol(name) == null;
|
||||
defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
|
||||
if(functionNode.allVarsInScope()) { // basically, has deep eval
|
||||
lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
|
||||
}
|
||||
private void defineFunctionSelfSymbol(final FunctionNode functionNode, final Block body) {
|
||||
// Function self-symbol is only declared as a local variable for named function expressions. Declared functions
|
||||
// don't need it as they are local variables in their declaring scope.
|
||||
if (!functionNode.isNamedFunctionExpression()) {
|
||||
return;
|
||||
}
|
||||
|
||||
acceptDeclarations(functionNode, body);
|
||||
final String name = functionNode.getIdent().getName();
|
||||
assert name != null; // As it's a named function expression.
|
||||
|
||||
if (body.getExistingSymbol(name) != null) {
|
||||
// Body already has a declaration for the name. It's either a parameter "function x(x)" or a
|
||||
// top-level variable "function x() { ... var x; ... }".
|
||||
return;
|
||||
}
|
||||
|
||||
defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
|
||||
if(functionNode.allVarsInScope()) { // basically, has deep eval
|
||||
// We must conservatively presume that eval'd code can dynamically use the function symbol.
|
||||
lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1091,6 +1091,15 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
return getFlag(USES_SELF_SYMBOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a named function expression (that is, it isn't a declared function, it isn't an
|
||||
* anonymous function expression, and it isn't a program).
|
||||
* @return true if this is a named function expression
|
||||
*/
|
||||
public boolean isNamedFunctionExpression() {
|
||||
return !getFlag(IS_PROGRAM | IS_ANONYMOUS | IS_DECLARED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType(final Function<Symbol, Type> localVariableTypes) {
|
||||
return FUNCTION_TYPE;
|
||||
|
||||
35
nashorn/test/script/basic/JDK-8066222.js
Normal file
35
nashorn/test/script/basic/JDK-8066222.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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-8066222: too strong assertion on function expression names
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
// Has to print "SUCCESS"
|
||||
(function x (x){print(x)})("SUCCESS");
|
||||
|
||||
// Has to print "undefined" and "1", not the function source in any case.
|
||||
(function x(){print(x); var x=1; print(x)})();
|
||||
3
nashorn/test/script/basic/JDK-8066222.js.EXPECTED
Normal file
3
nashorn/test/script/basic/JDK-8066222.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
||||
SUCCESS
|
||||
undefined
|
||||
1
|
||||
Loading…
x
Reference in New Issue
Block a user