aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/codegen/FinalizeTypes.java')
-rw-r--r--src/jdk/nashorn/internal/codegen/FinalizeTypes.java212
1 files changed, 90 insertions, 122 deletions
diff --git a/src/jdk/nashorn/internal/codegen/FinalizeTypes.java b/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
index cd185240..5f6a63dc 100644
--- a/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
+++ b/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
@@ -25,7 +25,12 @@
package jdk.nashorn.internal.codegen;
+import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.AccessNode;
@@ -33,10 +38,8 @@ import jdk.nashorn.internal.ir.Assignment;
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
import jdk.nashorn.internal.ir.CallNode;
-import jdk.nashorn.internal.ir.CallNode.EvalArgs;
import jdk.nashorn.internal.ir.CaseNode;
import jdk.nashorn.internal.ir.CatchNode;
-import jdk.nashorn.internal.ir.DoWhileNode;
import jdk.nashorn.internal.ir.ExecuteNode;
import jdk.nashorn.internal.ir.ForNode;
import jdk.nashorn.internal.ir.FunctionNode;
@@ -85,18 +88,11 @@ final class FinalizeTypes extends NodeOperatorVisitor {
private static final DebugLogger LOG = new DebugLogger("finalize");
- private final LexicalContext lexicalContext = new LexicalContext();
-
FinalizeTypes() {
}
@Override
public Node leaveCallNode(final CallNode callNode) {
- final EvalArgs evalArgs = callNode.getEvalArgs();
- if (evalArgs != null) {
- evalArgs.setCode(evalArgs.getCode().accept(this));
- }
-
// AccessSpecializer - call return type may change the access for this location
final Node function = callNode.getFunction();
if (function instanceof FunctionNode) {
@@ -133,8 +129,7 @@ final class FinalizeTypes extends NodeOperatorVisitor {
@Override
public Node leaveNEW(final UnaryNode unaryNode) {
assert unaryNode.getSymbol() != null && unaryNode.getSymbol().getSymbolType().isObject();
- ((CallNode)unaryNode.rhs()).setIsNew();
- return unaryNode;
+ return unaryNode.setRHS(((CallNode)unaryNode.rhs()).setIsNew());
}
@Override
@@ -254,7 +249,7 @@ final class FinalizeTypes extends NodeOperatorVisitor {
@Override
public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
assert binaryNode.getSymbol() != null;
- final BinaryNode newBinaryNode = (BinaryNode)binaryNode.setRHS(discard(binaryNode.rhs()));
+ final BinaryNode newBinaryNode = binaryNode.setRHS(discard(binaryNode.rhs()));
// AccessSpecializer - the type of lhs, which is the remaining value of this node may have changed
// in that case, update the node type as well
propagateType(newBinaryNode, newBinaryNode.lhs().getType());
@@ -354,41 +349,30 @@ final class FinalizeTypes extends NodeOperatorVisitor {
}
@Override
- public Node enterBlock(final Block block) {
- lexicalContext.push(block);
+ public boolean enterBlock(final Block block) {
updateSymbols(block);
- return block;
+ return true;
}
+ /*
@Override
- public Node leaveBlock(Block block) {
- lexicalContext.pop(block);
- return super.leaveBlock(block);
- }
+ public Node leaveBlock(final Block block) {
+ final LexicalContext lc = getLexicalContext();
+ return block;//.setFlag(lc, lc.getFlags(block));
+ }*/
@Override
public Node leaveCatchNode(final CatchNode catchNode) {
final Node exceptionCondition = catchNode.getExceptionCondition();
if (exceptionCondition != null) {
- catchNode.setExceptionCondition(convert(exceptionCondition, Type.BOOLEAN));
+ return catchNode.setExceptionCondition(convert(exceptionCondition, Type.BOOLEAN));
}
return catchNode;
}
@Override
- public Node enterDoWhileNode(final DoWhileNode doWhileNode) {
- return enterWhileNode(doWhileNode);
- }
-
- @Override
- public Node leaveDoWhileNode(final DoWhileNode doWhileNode) {
- return leaveWhileNode(doWhileNode);
- }
-
- @Override
public Node leaveExecuteNode(final ExecuteNode executeNode) {
- executeNode.setExpression(discard(executeNode.getExpression()));
- return executeNode;
+ return executeNode.setExpression(discard(executeNode.getExpression()));
}
@Override
@@ -397,69 +381,54 @@ final class FinalizeTypes extends NodeOperatorVisitor {
final Node test = forNode.getTest();
final Node modify = forNode.getModify();
- if (forNode.isForIn()) {
- forNode.setModify(convert(forNode.getModify(), Type.OBJECT)); // NASHORN-400
- return forNode;
- }
+ final LexicalContext lc = getLexicalContext();
- if (init != null) {
- forNode.setInit(discard(init));
- }
-
- if (test != null) {
- forNode.setTest(convert(test, Type.BOOLEAN));
- } else {
- assert forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + getCurrentFunctionNode();
- }
-
- if (modify != null) {
- forNode.setModify(discard(modify));
+ if (forNode.isForIn()) {
+ return forNode.setModify(lc, convert(forNode.getModify(), Type.OBJECT)); // NASHORN-400
}
+ assert test != null || forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + getLexicalContext().getCurrentFunction();
- return forNode;
+ return forNode.
+ setInit(lc, init == null ? null : discard(init)).
+ setTest(lc, test == null ? null : convert(test, Type.BOOLEAN)).
+ setModify(lc, modify == null ? null : discard(modify));
}
@Override
- public Node enterFunctionNode(final FunctionNode functionNode) {
+ public boolean enterFunctionNode(final FunctionNode functionNode) {
if (functionNode.isLazy()) {
- return null;
+ return false;
}
- lexicalContext.push(functionNode);
// If the function doesn't need a callee, we ensure its __callee__ symbol doesn't get a slot. We can't do
// this earlier, as access to scoped variables, self symbol, etc. in previous phases can all trigger the
// need for the callee.
if (!functionNode.needsCallee()) {
- functionNode.getCalleeNode().getSymbol().setNeedsSlot(false);
+ functionNode.compilerConstant(CALLEE).setNeedsSlot(false);
}
// Similar reasoning applies to __scope__ symbol: if the function doesn't need either parent scope or its
// own scope, we ensure it doesn't get a slot, but we can't determine whether it needs a scope earlier than
// this phase.
- if (!(functionNode.needsScope() || functionNode.needsParentScope())) {
- functionNode.getScopeNode().getSymbol().setNeedsSlot(false);
+ if (!(functionNode.getBody().needsScope() || functionNode.needsParentScope())) {
+ functionNode.compilerConstant(SCOPE).setNeedsSlot(false);
}
- updateSymbols(functionNode);
- functionNode.setState(CompilationState.FINALIZED);
-
- return functionNode;
+ return true;
}
@Override
- public Node leaveFunctionNode(FunctionNode functionNode) {
- lexicalContext.pop(functionNode);
- return super.leaveFunctionNode(functionNode);
+ public Node leaveFunctionNode(final FunctionNode functionNode) {
+ return functionNode.setState(getLexicalContext(), CompilationState.FINALIZED);
}
@Override
public Node leaveIfNode(final IfNode ifNode) {
- ifNode.setTest(convert(ifNode.getTest(), Type.BOOLEAN));
- return ifNode;
+ return ifNode.setTest(convert(ifNode.getTest(), Type.BOOLEAN));
}
@SuppressWarnings("rawtypes")
@Override
- public Node enterLiteralNode(final LiteralNode literalNode) {
+ public boolean enterLiteralNode(final LiteralNode literalNode) {
if (literalNode instanceof ArrayLiteralNode) {
final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode;
final Node[] array = arrayLiteralNode.getValue();
@@ -473,14 +442,14 @@ final class FinalizeTypes extends NodeOperatorVisitor {
}
}
- return null;
+ return false;
}
@Override
public Node leaveReturnNode(final ReturnNode returnNode) {
final Node expr = returnNode.getExpression();
if (expr != null) {
- returnNode.setExpression(convert(expr, getCurrentFunctionNode().getReturnType()));
+ return returnNode.setExpression(convert(expr, getLexicalContext().getCurrentFunction().getReturnType()));
}
return returnNode;
}
@@ -496,21 +465,24 @@ final class FinalizeTypes extends NodeOperatorVisitor {
@Override
public Node leaveSwitchNode(final SwitchNode switchNode) {
+ final boolean allInteger = switchNode.getTag().getSymbolType().isInteger();
+
+ if (allInteger) {
+ return switchNode;
+ }
+
final Node expression = switchNode.getExpression();
final List<CaseNode> cases = switchNode.getCases();
- final boolean allInteger = switchNode.getTag().getSymbolType().isInteger();
-
- if (!allInteger) {
- switchNode.setExpression(convert(expression, Type.OBJECT));
- for (final CaseNode caseNode : cases) {
- final Node test = caseNode.getTest();
- if (test != null) {
- caseNode.setTest(convert(test, Type.OBJECT));
- }
- }
+ final List<CaseNode> newCases = new ArrayList<>();
+
+ for (final CaseNode caseNode : cases) {
+ final Node test = caseNode.getTest();
+ newCases.add(test != null ? caseNode.setTest(convert(test, Type.OBJECT)) : caseNode);
}
- return switchNode;
+ return switchNode.
+ setExpression(getLexicalContext(), convert(expression, Type.OBJECT)).
+ setCases(getLexicalContext(), newCases);
}
@Override
@@ -520,8 +492,7 @@ final class FinalizeTypes extends NodeOperatorVisitor {
@Override
public Node leaveThrowNode(final ThrowNode throwNode) {
- throwNode.setExpression(convert(throwNode.getExpression(), Type.OBJECT));
- return throwNode;
+ return throwNode.setExpression(convert(throwNode.getExpression(), Type.OBJECT));
}
@Override
@@ -544,23 +515,24 @@ final class FinalizeTypes extends NodeOperatorVisitor {
public Node leaveWhileNode(final WhileNode whileNode) {
final Node test = whileNode.getTest();
if (test != null) {
- whileNode.setTest(convert(test, Type.BOOLEAN));
+ return whileNode.setTest(getLexicalContext(), convert(test, Type.BOOLEAN));
}
return whileNode;
}
@Override
public Node leaveWithNode(final WithNode withNode) {
- withNode.setExpression(convert(withNode.getExpression(), Type.OBJECT));
- return withNode;
+ return withNode.setExpression(getLexicalContext(), convert(withNode.getExpression(), Type.OBJECT));
}
private static void updateSymbolsLog(final FunctionNode functionNode, final Symbol symbol, final boolean loseSlot) {
- if (!symbol.isScope()) {
- LOG.finest("updateSymbols: " + symbol + " => scope, because all vars in " + functionNode.getName() + " are in scope");
- }
- if (loseSlot && symbol.hasSlot()) {
- LOG.finest("updateSymbols: " + symbol + " => no slot, because all vars in " + functionNode.getName() + " are in scope");
+ if (LOG.isEnabled()) {
+ if (!symbol.isScope()) {
+ LOG.finest("updateSymbols: ", symbol, " => scope, because all vars in ", functionNode.getName(), " are in scope");
+ }
+ if (loseSlot && symbol.hasSlot()) {
+ LOG.finest("updateSymbols: ", symbol, " => no slot, because all vars in ", functionNode.getName(), " are in scope");
+ }
}
}
@@ -574,29 +546,28 @@ final class FinalizeTypes extends NodeOperatorVisitor {
return; // nothing to do
}
- final FunctionNode functionNode = lexicalContext.getFunction(block);
- assert !(block instanceof FunctionNode) || functionNode == block;
+ final LexicalContext lc = getLexicalContext();
+ final FunctionNode functionNode = lc.getFunction(block);
+ final boolean allVarsInScope = functionNode.allVarsInScope();
+ final boolean isVarArg = functionNode.isVarArg();
- final List<Symbol> symbols = block.getFrame().getSymbols();
- final boolean allVarsInScope = functionNode.allVarsInScope();
- final boolean isVarArg = functionNode.isVarArg();
-
- for (final Symbol symbol : symbols) {
- if (symbol.isInternal() || symbol.isThis()) {
+ for (final Iterator<Symbol> iter = block.symbolIterator(); iter.hasNext(); ) {
+ final Symbol symbol = iter.next();
+ if (symbol.isInternal() || symbol.isThis() || symbol.isTemp()) {
continue;
}
if (symbol.isVar()) {
if (allVarsInScope || symbol.isScope()) {
updateSymbolsLog(functionNode, symbol, true);
- symbol.setIsScope();
+ Symbol.setSymbolIsScope(lc, symbol);
symbol.setNeedsSlot(false);
} else {
assert symbol.hasSlot() : symbol + " should have a slot only, no scope";
}
} else if (symbol.isParam() && (allVarsInScope || isVarArg || symbol.isScope())) {
updateSymbolsLog(functionNode, symbol, isVarArg);
- symbol.setIsScope();
+ Symbol.setSymbolIsScope(lc, symbol);
symbol.setNeedsSlot(!isVarArg);
}
}
@@ -636,11 +607,7 @@ final class FinalizeTypes extends NodeOperatorVisitor {
//fallthru
default:
if (newRuntimeNode || widest.isObject()) {
- final RuntimeNode runtimeNode = new RuntimeNode(binaryNode, request);
- if (finalized) {
- runtimeNode.setIsFinal();
- }
- return runtimeNode;
+ return new RuntimeNode(binaryNode, request).setIsFinal(finalized);
}
break;
}
@@ -667,7 +634,8 @@ final class FinalizeTypes extends NodeOperatorVisitor {
}
private Node leaveBinary(final BinaryNode binaryNode, final Type lhsType, final Type rhsType) {
- return binaryNode.setLHS(convert(binaryNode.lhs(), lhsType)).setRHS(convert(binaryNode.rhs(), rhsType));
+ Node b = binaryNode.setLHS(convert(binaryNode.lhs(), lhsType)).setRHS(convert(binaryNode.rhs(), rhsType));
+ return b;
}
/**
@@ -683,28 +651,28 @@ final class FinalizeTypes extends NodeOperatorVisitor {
node.accept(new NodeVisitor() {
private void setCanBePrimitive(final Symbol symbol) {
- LOG.info("*** can be primitive symbol " + symbol + " " + Debug.id(symbol));
+ LOG.info("*** can be primitive symbol ", symbol, " ", Debug.id(symbol));
symbol.setCanBePrimitive(to);
}
@Override
- public Node enterIdentNode(final IdentNode identNode) {
+ public boolean enterIdentNode(final IdentNode identNode) {
if (!exclude.contains(identNode)) {
setCanBePrimitive(identNode.getSymbol());
}
- return null;
+ return false;
}
@Override
- public Node enterAccessNode(final AccessNode accessNode) {
+ public boolean enterAccessNode(final AccessNode accessNode) {
setCanBePrimitive(accessNode.getProperty().getSymbol());
- return null;
+ return false;
}
@Override
- public Node enterIndexNode(final IndexNode indexNode) {
+ public boolean enterIndexNode(final IndexNode indexNode) {
exclude.add(indexNode.getBase()); //prevent array base node to be flagged as primitive, but k in a[k++] is fine
- return indexNode;
+ return true;
}
});
}
@@ -785,12 +753,12 @@ final class FinalizeTypes extends NodeOperatorVisitor {
private static <T extends Node> T setTypeOverride(final T node, final Type to) {
final Type from = node.getType();
if (!node.getType().equals(to)) {
- LOG.info("Changing call override type for '" + node + "' from " + node.getType() + " to " + to);
+ LOG.info("Changing call override type for '", node, "' from ", node.getType(), " to ", to);
if (!to.isObject() && from.isObject()) {
setCanBePrimitive(node, to);
}
}
- LOG.info("Type override for lhs in '" + node + "' => " + to);
+ LOG.info("Type override for lhs in '", node, "' => ", to);
return ((TypeOverride<T>)node).setType(to);
}
@@ -814,8 +782,8 @@ final class FinalizeTypes extends NodeOperatorVisitor {
private Node convert(final Node node, final Type to) {
assert !to.isUnknown() : "unknown type for " + node + " class=" + node.getClass();
assert node != null : "node is null";
- assert node.getSymbol() != null : "node " + node + " has no symbol!";
- assert node.tokenType() != TokenType.CONVERT : "assert convert in convert " + node + " in " + getCurrentFunctionNode();
+ assert node.getSymbol() != null : "node " + node + " " + node.getClass() + " has no symbol! " + getLexicalContext().getCurrentFunction() + " " + node.getSource();
+ assert node.tokenType() != TokenType.CONVERT : "assert convert in convert " + node + " in " + getLexicalContext().getCurrentFunction();
final Type from = node.getType();
@@ -842,23 +810,23 @@ final class FinalizeTypes extends NodeOperatorVisitor {
resultNode = new UnaryNode(node.getSource(), Token.recast(node.getToken(), TokenType.CONVERT), node);
}
- LOG.info("CONVERT('" + node + "', " + to + ") => '" + resultNode + "'");
+ LOG.info("CONVERT('", node, "', ", to, ") => '", resultNode, "'");
+ final LexicalContext lc = getLexicalContext();
//This is the only place in this file that can create new temporaries
//FinalizeTypes may not introduce ANY node that is not a conversion.
- getCurrentFunctionNode().newTemporary(getCurrentBlock().getFrame(), to, resultNode);
- resultNode.copyTerminalFlags(node);
+ lc.getCurrentFunction().ensureSymbol(lc.getCurrentBlock(), to, resultNode);
+
+ assert !node.isTerminal();
return resultNode;
}
private static Node discard(final Node node) {
- node.setDiscard(true);
-
if (node.getSymbol() != null) {
final Node discard = new UnaryNode(node.getSource(), Token.recast(node.getToken(), TokenType.DISCARD), node);
//discard never has a symbol in the discard node - then it would be a nop
- discard.copyTerminalFlags(node);
+ assert !node.isTerminal();
return discard;
}
@@ -883,7 +851,7 @@ final class FinalizeTypes extends NodeOperatorVisitor {
final Symbol symbol = node.getSymbol();
if (symbol.isTemp()) {
symbol.setTypeOverride(to);
- LOG.info("Type override for temporary in '" + node + "' => " + to);
+ LOG.info("Type override for temporary in '", node, "' => ", to);
}
}