author | attila |
Wed, 01 Oct 2014 10:26:53 +0200 | |
changeset 26889 | dba314d7a634 |
parent 26504 | ed05e2f4c2db |
child 27206 | d4a707c9db5a |
permissions | -rw-r--r-- |
16147 | 1 |
/* |
16151 | 2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
16147 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package jdk.nashorn.internal.codegen; |
|
27 |
||
28 |
import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL; |
|
17233 | 29 |
import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN; |
24751 | 30 |
import static jdk.nashorn.internal.ir.Expression.isAlwaysTrue; |
16147 | 31 |
|
32 |
import java.util.ArrayList; |
|
33 |
import java.util.Arrays; |
|
24719 | 34 |
import java.util.Collections; |
16147 | 35 |
import java.util.List; |
18848
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
36 |
import java.util.ListIterator; |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
37 |
import jdk.nashorn.internal.ir.BaseNode; |
16147 | 38 |
import jdk.nashorn.internal.ir.BinaryNode; |
39 |
import jdk.nashorn.internal.ir.Block; |
|
17233 | 40 |
import jdk.nashorn.internal.ir.BlockLexicalContext; |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
41 |
import jdk.nashorn.internal.ir.BlockStatement; |
16147 | 42 |
import jdk.nashorn.internal.ir.BreakNode; |
43 |
import jdk.nashorn.internal.ir.CallNode; |
|
24751 | 44 |
import jdk.nashorn.internal.ir.CaseNode; |
16147 | 45 |
import jdk.nashorn.internal.ir.CatchNode; |
46 |
import jdk.nashorn.internal.ir.ContinueNode; |
|
47 |
import jdk.nashorn.internal.ir.EmptyNode; |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
48 |
import jdk.nashorn.internal.ir.Expression; |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
49 |
import jdk.nashorn.internal.ir.ExpressionStatement; |
16147 | 50 |
import jdk.nashorn.internal.ir.ForNode; |
51 |
import jdk.nashorn.internal.ir.FunctionNode; |
|
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
52 |
import jdk.nashorn.internal.ir.FunctionNode.CompilationState; |
16147 | 53 |
import jdk.nashorn.internal.ir.IdentNode; |
54 |
import jdk.nashorn.internal.ir.IfNode; |
|
26889
dba314d7a634
8059371: Code duplication in handling of break and continue
attila
parents:
26504
diff
changeset
|
55 |
import jdk.nashorn.internal.ir.JumpStatement; |
16147 | 56 |
import jdk.nashorn.internal.ir.LabelNode; |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
57 |
import jdk.nashorn.internal.ir.LexicalContext; |
16147 | 58 |
import jdk.nashorn.internal.ir.LiteralNode; |
17233 | 59 |
import jdk.nashorn.internal.ir.LoopNode; |
16147 | 60 |
import jdk.nashorn.internal.ir.Node; |
61 |
import jdk.nashorn.internal.ir.ReturnNode; |
|
24751 | 62 |
import jdk.nashorn.internal.ir.RuntimeNode; |
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
63 |
import jdk.nashorn.internal.ir.Statement; |
16147 | 64 |
import jdk.nashorn.internal.ir.SwitchNode; |
65 |
import jdk.nashorn.internal.ir.Symbol; |
|
66 |
import jdk.nashorn.internal.ir.ThrowNode; |
|
67 |
import jdk.nashorn.internal.ir.TryNode; |
|
68 |
import jdk.nashorn.internal.ir.VarNode; |
|
69 |
import jdk.nashorn.internal.ir.WhileNode; |
|
70 |
import jdk.nashorn.internal.ir.WithNode; |
|
71 |
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; |
|
72 |
import jdk.nashorn.internal.ir.visitor.NodeVisitor; |
|
73 |
import jdk.nashorn.internal.parser.Token; |
|
74 |
import jdk.nashorn.internal.parser.TokenType; |
|
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
75 |
import jdk.nashorn.internal.runtime.Context; |
24751 | 76 |
import jdk.nashorn.internal.runtime.JSType; |
16147 | 77 |
import jdk.nashorn.internal.runtime.Source; |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
78 |
import jdk.nashorn.internal.runtime.logging.DebugLogger; |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
79 |
import jdk.nashorn.internal.runtime.logging.Loggable; |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
80 |
import jdk.nashorn.internal.runtime.logging.Logger; |
16147 | 81 |
|
82 |
/** |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
83 |
* Lower to more primitive operations. After lowering, an AST still has no symbols |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
84 |
* and types, but several nodes have been turned into more low level constructs |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
85 |
* and control flow termination criteria have been computed. |
16147 | 86 |
* |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
87 |
* We do things like code copying/inlining of finallies here, as it is much |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
88 |
* harder and context dependent to do any code copying after symbols have been |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
89 |
* finalized. |
16147 | 90 |
*/ |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
91 |
@Logger(name="lower") |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
92 |
final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Loggable { |
16147 | 93 |
|
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
94 |
private final DebugLogger log; |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
95 |
|
16147 | 96 |
/** |
97 |
* Constructor. |
|
98 |
*/ |
|
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
99 |
Lower(final Compiler compiler) { |
17233 | 100 |
super(new BlockLexicalContext() { |
101 |
||
102 |
@Override |
|
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
103 |
public List<Statement> popStatements() { |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
104 |
final List<Statement> newStatements = new ArrayList<>(); |
17233 | 105 |
boolean terminated = false; |
106 |
||
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
107 |
final List<Statement> statements = super.popStatements(); |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
108 |
for (final Statement statement : statements) { |
17233 | 109 |
if (!terminated) { |
110 |
newStatements.add(statement); |
|
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
111 |
if (statement.isTerminal() || statement instanceof BreakNode || statement instanceof ContinueNode) { //TODO hasGoto? But some Loops are hasGoto too - why? |
17233 | 112 |
terminated = true; |
113 |
} |
|
114 |
} else { |
|
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
115 |
statement.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { |
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
116 |
@Override |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
117 |
public boolean enterVarNode(final VarNode varNode) { |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
118 |
newStatements.add(varNode.setInit(null)); |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
119 |
return false; |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
120 |
} |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
121 |
}); |
17233 | 122 |
} |
123 |
} |
|
124 |
return newStatements; |
|
125 |
} |
|
18848
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
126 |
|
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
127 |
@Override |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
128 |
protected Block afterSetStatements(final Block block) { |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
129 |
final List<Statement> stmts = block.getStatements(); |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
130 |
for(final ListIterator<Statement> li = stmts.listIterator(stmts.size()); li.hasPrevious();) { |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
131 |
final Statement stmt = li.previous(); |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
132 |
// popStatements() guarantees that the only thing after a terminal statement are uninitialized |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
133 |
// VarNodes. We skip past those, and set the terminal state of the block to the value of the |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
134 |
// terminal state of the first statement that is not an uninitialized VarNode. |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
135 |
if(!(stmt instanceof VarNode && ((VarNode)stmt).getInit() == null)) { |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
136 |
return block.setIsTerminal(this, stmt.isTerminal()); |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
137 |
} |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
138 |
} |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
139 |
return block.setIsTerminal(this, false); |
e64943db2b06
8019809: return after break incorrectly sets the block as terminal
attila
parents:
17982
diff
changeset
|
140 |
} |
17233 | 141 |
}); |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
142 |
|
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
143 |
this.log = initLogger(compiler.getContext()); |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
144 |
} |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
145 |
|
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
146 |
@Override |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
147 |
public DebugLogger getLogger() { |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
148 |
return log; |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
149 |
} |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
150 |
|
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
151 |
@Override |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
152 |
public DebugLogger initLogger(final Context context) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
153 |
return context.getLogger(this.getClass()); |
17233 | 154 |
} |
155 |
||
156 |
@Override |
|
157 |
public boolean enterBreakNode(final BreakNode breakNode) { |
|
158 |
addStatement(breakNode); |
|
159 |
return false; |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
160 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
161 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
162 |
@Override |
17233 | 163 |
public Node leaveCallNode(final CallNode callNode) { |
164 |
return checkEval(callNode.setFunction(markerFunction(callNode.getFunction()))); |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
165 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
166 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
167 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
168 |
public Node leaveCatchNode(final CatchNode catchNode) { |
17233 | 169 |
return addStatement(catchNode); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
170 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
171 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
172 |
@Override |
17233 | 173 |
public boolean enterContinueNode(final ContinueNode continueNode) { |
174 |
addStatement(continueNode); |
|
175 |
return false; |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
176 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
177 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
178 |
@Override |
17233 | 179 |
public boolean enterEmptyNode(final EmptyNode emptyNode) { |
180 |
return false; |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
181 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
182 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
183 |
@Override |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
184 |
public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) { |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
185 |
final Expression expr = expressionStatement.getExpression(); |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
186 |
ExpressionStatement node = expressionStatement; |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
187 |
|
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
188 |
final FunctionNode currentFunction = lc.getCurrentFunction(); |
17233 | 189 |
|
190 |
if (currentFunction.isProgram()) { |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
191 |
if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) { |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
192 |
node = expressionStatement.setExpression( |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
193 |
new BinaryNode( |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
194 |
Token.recast( |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
195 |
expressionStatement.getToken(), |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
196 |
TokenType.ASSIGN), |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
197 |
compilerConstant(RETURN), |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
198 |
expr)); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
199 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
200 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
201 |
|
17233 | 202 |
return addStatement(node); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
203 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
204 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
205 |
@Override |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
206 |
public Node leaveBlockStatement(final BlockStatement blockStatement) { |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
207 |
return addStatement(blockStatement); |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
208 |
} |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
209 |
|
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
210 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
211 |
public Node leaveForNode(final ForNode forNode) { |
17233 | 212 |
ForNode newForNode = forNode; |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
213 |
|
24751 | 214 |
final Expression test = forNode.getTest(); |
215 |
if (!forNode.isForIn() && isAlwaysTrue(test)) { |
|
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
216 |
newForNode = forNode.setTest(lc, null); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
217 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
218 |
|
24719 | 219 |
newForNode = checkEscape(newForNode); |
220 |
if(newForNode.isForIn()) { |
|
221 |
// Wrap it in a block so its internally created iterator is restricted in scope |
|
24751 | 222 |
addStatementEnclosedInBlock(newForNode); |
24719 | 223 |
} else { |
224 |
addStatement(newForNode); |
|
225 |
} |
|
226 |
return newForNode; |
|
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
227 |
} |
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
228 |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
229 |
@Override |
17233 | 230 |
public Node leaveFunctionNode(final FunctionNode functionNode) { |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
231 |
log.info("END FunctionNode: ", functionNode.getName()); |
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
232 |
return functionNode.setState(lc, CompilationState.LOWERED); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
233 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
234 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
235 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
236 |
public Node leaveIfNode(final IfNode ifNode) { |
17233 | 237 |
return addStatement(ifNode); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
238 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
239 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
240 |
@Override |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
241 |
public Node leaveIN(final BinaryNode binaryNode) { |
24751 | 242 |
return new RuntimeNode(binaryNode); |
243 |
} |
|
244 |
||
245 |
@Override |
|
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
246 |
public Node leaveINSTANCEOF(final BinaryNode binaryNode) { |
24751 | 247 |
return new RuntimeNode(binaryNode); |
248 |
} |
|
249 |
||
250 |
@Override |
|
17233 | 251 |
public Node leaveLabelNode(final LabelNode labelNode) { |
252 |
return addStatement(labelNode); |
|
253 |
} |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
254 |
|
17233 | 255 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
256 |
public Node leaveReturnNode(final ReturnNode returnNode) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
257 |
addStatement(returnNode); //ReturnNodes are always terminal, marked as such in constructor |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
258 |
return returnNode; |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
259 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
260 |
|
24751 | 261 |
@Override |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
262 |
public Node leaveCaseNode(final CaseNode caseNode) { |
24751 | 263 |
// Try to represent the case test as an integer |
264 |
final Node test = caseNode.getTest(); |
|
265 |
if (test instanceof LiteralNode) { |
|
266 |
final LiteralNode<?> lit = (LiteralNode<?>)test; |
|
267 |
if (lit.isNumeric() && !(lit.getValue() instanceof Integer)) { |
|
268 |
if (JSType.isRepresentableAsInt(lit.getNumber())) { |
|
269 |
return caseNode.setTest((Expression)LiteralNode.newInstance(lit, lit.getInt32()).accept(this)); |
|
270 |
} |
|
271 |
} |
|
272 |
} |
|
273 |
return caseNode; |
|
274 |
} |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
275 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
276 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
277 |
public Node leaveSwitchNode(final SwitchNode switchNode) { |
24751 | 278 |
if(!switchNode.isInteger()) { |
279 |
// Wrap it in a block so its internally created tag is restricted in scope |
|
280 |
addStatementEnclosedInBlock(switchNode); |
|
281 |
} else { |
|
282 |
addStatement(switchNode); |
|
283 |
} |
|
284 |
return switchNode; |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
285 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
286 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
287 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
288 |
public Node leaveThrowNode(final ThrowNode throwNode) { |
24751 | 289 |
return addStatement(throwNode); //ThrowNodes are always terminal, marked as such in constructor |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
290 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
291 |
|
17982 | 292 |
private static Node ensureUniqueNamesIn(final Node node) { |
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
293 |
return node.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { |
17752
9d2d0e74a833
8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents:
17745
diff
changeset
|
294 |
@Override |
9d2d0e74a833
8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents:
17745
diff
changeset
|
295 |
public Node leaveFunctionNode(final FunctionNode functionNode) { |
9d2d0e74a833
8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents:
17745
diff
changeset
|
296 |
final String name = functionNode.getName(); |
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
297 |
return functionNode.setName(lc, lc.getCurrentFunction().uniqueName(name)); |
17752
9d2d0e74a833
8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents:
17745
diff
changeset
|
298 |
} |
9d2d0e74a833
8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents:
17745
diff
changeset
|
299 |
|
9d2d0e74a833
8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents:
17745
diff
changeset
|
300 |
@Override |
9d2d0e74a833
8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents:
17745
diff
changeset
|
301 |
public Node leaveDefault(final Node labelledNode) { |
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
302 |
return labelledNode.ensureUniqueLabels(lc); |
17752
9d2d0e74a833
8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents:
17745
diff
changeset
|
303 |
} |
17233 | 304 |
}); |
305 |
} |
|
306 |
||
17982 | 307 |
private static List<Statement> copyFinally(final Block finallyBody) { |
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
308 |
final List<Statement> newStatements = new ArrayList<>(); |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
309 |
for (final Statement statement : finallyBody.getStatements()) { |
17982 | 310 |
newStatements.add((Statement)ensureUniqueNamesIn(statement)); |
17233 | 311 |
if (statement.hasTerminalFlags()) { |
312 |
return newStatements; |
|
313 |
} |
|
314 |
} |
|
315 |
return newStatements; |
|
316 |
} |
|
317 |
||
318 |
private Block catchAllBlock(final TryNode tryNode) { |
|
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
319 |
final int lineNumber = tryNode.getLineNumber(); |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
320 |
final long token = tryNode.getToken(); |
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
321 |
final int finish = tryNode.getFinish(); |
17233 | 322 |
|
24719 | 323 |
final IdentNode exception = new IdentNode(token, finish, lc.getCurrentFunction().uniqueName(CompilerConstants.EXCEPTION_PREFIX.symbolName())); |
17233 | 324 |
|
24751 | 325 |
final Block catchBody = new Block(token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), true)); |
19100
62d400be5b44
8021244: Inconsistent stackmap with splitter threshold set very low
hannesw
parents:
18867
diff
changeset
|
326 |
assert catchBody.isTerminal(); //ends with throw, so terminal |
17233 | 327 |
|
24751 | 328 |
final CatchNode catchAllNode = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody, true); |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
329 |
final Block catchAllBlock = new Block(token, finish, catchAllNode); |
17233 | 330 |
|
331 |
//catchallblock -> catchallnode (catchnode) -> exception -> throw |
|
332 |
||
333 |
return (Block)catchAllBlock.accept(this); //not accepted. has to be accepted by lower |
|
334 |
} |
|
335 |
||
336 |
private IdentNode compilerConstant(final CompilerConstants cc) { |
|
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
337 |
final FunctionNode functionNode = lc.getCurrentFunction(); |
17523
cb4a7c901e0d
8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents:
17233
diff
changeset
|
338 |
return new IdentNode(functionNode.getToken(), functionNode.getFinish(), cc.symbolName()); |
17233 | 339 |
} |
340 |
||
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
341 |
private static boolean isTerminal(final List<Statement> statements) { |
17233 | 342 |
return !statements.isEmpty() && statements.get(statements.size() - 1).hasTerminalFlags(); |
343 |
} |
|
344 |
||
345 |
/** |
|
346 |
* Splice finally code into all endpoints of a trynode |
|
347 |
* @param tryNode the try node |
|
19100
62d400be5b44
8021244: Inconsistent stackmap with splitter threshold set very low
hannesw
parents:
18867
diff
changeset
|
348 |
* @param rethrows list of rethrowing throw nodes from synthetic catch blocks |
17233 | 349 |
* @param finallyBody the code in the original finally block |
350 |
* @return new try node after splicing finally code (same if nop) |
|
351 |
*/ |
|
352 |
private Node spliceFinally(final TryNode tryNode, final List<ThrowNode> rethrows, final Block finallyBody) { |
|
353 |
assert tryNode.getFinallyBody() == null; |
|
354 |
||
24719 | 355 |
final LexicalContext lowerLc = lc; |
356 |
||
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
357 |
final TryNode newTryNode = (TryNode)tryNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { |
17233 | 358 |
final List<Node> insideTry = new ArrayList<>(); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
359 |
|
17233 | 360 |
@Override |
361 |
public boolean enterDefault(final Node node) { |
|
362 |
insideTry.add(node); |
|
363 |
return true; |
|
364 |
} |
|
365 |
||
366 |
@Override |
|
367 |
public boolean enterFunctionNode(final FunctionNode functionNode) { |
|
368 |
// do not enter function nodes - finally code should not be inlined into them |
|
369 |
return false; |
|
370 |
} |
|
371 |
||
372 |
@Override |
|
373 |
public Node leaveThrowNode(final ThrowNode throwNode) { |
|
374 |
if (rethrows.contains(throwNode)) { |
|
17982 | 375 |
final List<Statement> newStatements = copyFinally(finallyBody); |
17233 | 376 |
if (!isTerminal(newStatements)) { |
377 |
newStatements.add(throwNode); |
|
378 |
} |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
379 |
return BlockStatement.createReplacement(throwNode, newStatements); |
17233 | 380 |
} |
381 |
return throwNode; |
|
382 |
} |
|
383 |
||
384 |
@Override |
|
385 |
public Node leaveBreakNode(final BreakNode breakNode) { |
|
26889
dba314d7a634
8059371: Code duplication in handling of break and continue
attila
parents:
26504
diff
changeset
|
386 |
return leaveJumpStatement(breakNode); |
17233 | 387 |
} |
388 |
||
389 |
@Override |
|
390 |
public Node leaveContinueNode(final ContinueNode continueNode) { |
|
26889
dba314d7a634
8059371: Code duplication in handling of break and continue
attila
parents:
26504
diff
changeset
|
391 |
return leaveJumpStatement(continueNode); |
dba314d7a634
8059371: Code duplication in handling of break and continue
attila
parents:
26504
diff
changeset
|
392 |
} |
dba314d7a634
8059371: Code duplication in handling of break and continue
attila
parents:
26504
diff
changeset
|
393 |
|
dba314d7a634
8059371: Code duplication in handling of break and continue
attila
parents:
26504
diff
changeset
|
394 |
private Node leaveJumpStatement(final JumpStatement jump) { |
dba314d7a634
8059371: Code duplication in handling of break and continue
attila
parents:
26504
diff
changeset
|
395 |
return copy(jump, (Node)jump.getTarget(Lower.this.lc)); |
17233 | 396 |
} |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
397 |
|
17233 | 398 |
@Override |
399 |
public Node leaveReturnNode(final ReturnNode returnNode) { |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
400 |
final Expression expr = returnNode.getExpression(); |
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
401 |
final List<Statement> newStatements = new ArrayList<>(); |
17233 | 402 |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
403 |
final Expression resultNode; |
17233 | 404 |
if (expr != null) { |
405 |
//we need to evaluate the result of the return in case it is complex while |
|
406 |
//still in the try block, store it in a result value and return it afterwards |
|
407 |
resultNode = new IdentNode(Lower.this.compilerConstant(RETURN)); |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
408 |
newStatements.add(new ExpressionStatement(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr))); |
24719 | 409 |
lowerLc.setFlag(lowerLc.getCurrentFunction(), FunctionNode.USES_RETURN_SYMBOL); |
17233 | 410 |
} else { |
411 |
resultNode = null; |
|
412 |
} |
|
413 |
||
17982 | 414 |
newStatements.addAll(copyFinally(finallyBody)); |
17233 | 415 |
if (!isTerminal(newStatements)) { |
416 |
newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode)); |
|
417 |
} |
|
418 |
||
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
419 |
return BlockStatement.createReplacement(returnNode, lc.getCurrentBlock().getFinish(), newStatements); |
17233 | 420 |
} |
421 |
||
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
422 |
private Node copy(final Statement endpoint, final Node targetNode) { |
17233 | 423 |
if (!insideTry.contains(targetNode)) { |
17982 | 424 |
final List<Statement> newStatements = copyFinally(finallyBody); |
17233 | 425 |
if (!isTerminal(newStatements)) { |
426 |
newStatements.add(endpoint); |
|
427 |
} |
|
19100
62d400be5b44
8021244: Inconsistent stackmap with splitter threshold set very low
hannesw
parents:
18867
diff
changeset
|
428 |
return BlockStatement.createReplacement(endpoint, tryNode.getFinish(), newStatements); |
17233 | 429 |
} |
430 |
return endpoint; |
|
431 |
} |
|
432 |
}); |
|
433 |
||
434 |
addStatement(newTryNode); |
|
435 |
for (final Node statement : finallyBody.getStatements()) { |
|
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
436 |
addStatement((Statement)statement); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
437 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
438 |
|
17233 | 439 |
return newTryNode; |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
440 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
441 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
442 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
443 |
public Node leaveTryNode(final TryNode tryNode) { |
17233 | 444 |
final Block finallyBody = tryNode.getFinallyBody(); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
445 |
|
17233 | 446 |
if (finallyBody == null) { |
24751 | 447 |
return addStatement(ensureUnconditionalCatch(tryNode)); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
448 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
449 |
|
17233 | 450 |
/* |
451 |
* create a new trynode |
|
452 |
* if we have catches: |
|
453 |
* |
|
454 |
* try try |
|
455 |
* x try |
|
456 |
* catch x |
|
457 |
* y catch |
|
458 |
* finally z y |
|
459 |
* catchall |
|
460 |
* rethrow |
|
461 |
* |
|
462 |
* otheriwse |
|
463 |
* |
|
464 |
* try try |
|
465 |
* x x |
|
466 |
* finally catchall |
|
467 |
* y rethrow |
|
468 |
* |
|
469 |
* |
|
470 |
* now splice in finally code wherever needed |
|
471 |
* |
|
472 |
*/ |
|
473 |
TryNode newTryNode; |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
474 |
|
17233 | 475 |
final Block catchAll = catchAllBlock(tryNode); |
476 |
||
477 |
final List<ThrowNode> rethrows = new ArrayList<>(); |
|
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
478 |
catchAll.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { |
17233 | 479 |
@Override |
480 |
public boolean enterThrowNode(final ThrowNode throwNode) { |
|
481 |
rethrows.add(throwNode); |
|
482 |
return true; |
|
483 |
} |
|
484 |
}); |
|
485 |
assert rethrows.size() == 1; |
|
486 |
||
487 |
if (tryNode.getCatchBlocks().isEmpty()) { |
|
488 |
newTryNode = tryNode.setFinallyBody(null); |
|
489 |
} else { |
|
24751 | 490 |
final Block outerBody = new Block(tryNode.getToken(), tryNode.getFinish(), ensureUnconditionalCatch(tryNode.setFinallyBody(null))); |
17233 | 491 |
newTryNode = tryNode.setBody(outerBody).setCatchBlocks(null); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
492 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
493 |
|
17233 | 494 |
newTryNode = newTryNode.setCatchBlocks(Arrays.asList(catchAll)).setFinallyBody(null); |
495 |
||
496 |
/* |
|
497 |
* Now that the transform is done, we have to go into the try and splice |
|
498 |
* the finally block in front of any statement that is outside the try |
|
499 |
*/ |
|
500 |
return spliceFinally(newTryNode, rethrows, finallyBody); |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
501 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
502 |
|
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
503 |
private TryNode ensureUnconditionalCatch(final TryNode tryNode) { |
24751 | 504 |
final List<CatchNode> catches = tryNode.getCatches(); |
505 |
if(catches == null || catches.isEmpty() || catches.get(catches.size() - 1).getExceptionCondition() == null) { |
|
506 |
return tryNode; |
|
507 |
} |
|
508 |
// If the last catch block is conditional, add an unconditional rethrow block |
|
509 |
final List<Block> newCatchBlocks = new ArrayList<>(tryNode.getCatchBlocks()); |
|
510 |
||
511 |
newCatchBlocks.add(catchAllBlock(tryNode)); |
|
512 |
return tryNode.setCatchBlocks(newCatchBlocks); |
|
513 |
} |
|
514 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
515 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
516 |
public Node leaveVarNode(final VarNode varNode) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
517 |
addStatement(varNode); |
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
518 |
if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && lc.getCurrentFunction().isProgram()) { |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
519 |
new ExpressionStatement(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this); |
17233 | 520 |
} |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
521 |
return varNode; |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
522 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
523 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
524 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
525 |
public Node leaveWhileNode(final WhileNode whileNode) { |
24751 | 526 |
final Expression test = whileNode.getTest(); |
17233 | 527 |
final Block body = whileNode.getBody(); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
528 |
|
24751 | 529 |
if (isAlwaysTrue(test)) { |
17233 | 530 |
//turn it into a for node without a test. |
24751 | 531 |
final ForNode forNode = (ForNode)new ForNode(whileNode.getLineNumber(), whileNode.getToken(), whileNode.getFinish(), body, ForNode.IS_FOR).accept(this); |
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
532 |
lc.replace(whileNode, forNode); |
17233 | 533 |
return forNode; |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
534 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
535 |
|
17233 | 536 |
return addStatement(checkEscape(whileNode)); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
537 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
538 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
539 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
540 |
public Node leaveWithNode(final WithNode withNode) { |
17233 | 541 |
return addStatement(withNode); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
542 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
543 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
544 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
545 |
* Given a function node that is a callee in a CallNode, replace it with |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
546 |
* the appropriate marker function. This is used by {@link CodeGenerator} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
547 |
* for fast scope calls |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
548 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
549 |
* @param function function called by a CallNode |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
550 |
* @return transformed node to marker function or identity if not ident/access/indexnode |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
551 |
*/ |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
552 |
private static Expression markerFunction(final Expression function) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
553 |
if (function instanceof IdentNode) { |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
554 |
return ((IdentNode)function).setIsFunction(); |
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
555 |
} else if (function instanceof BaseNode) { |
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
556 |
return ((BaseNode)function).setIsFunction(); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
557 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
558 |
return function; |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
559 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
560 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
561 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
562 |
* Calculate a synthetic eval location for a node for the stacktrace, for example src#17<eval> |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
563 |
* @param node a node |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
564 |
* @return eval location |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
565 |
*/ |
17523
cb4a7c901e0d
8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents:
17233
diff
changeset
|
566 |
private String evalLocation(final IdentNode node) { |
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
567 |
final Source source = lc.getCurrentFunction().getSource(); |
20929
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
19100
diff
changeset
|
568 |
final int pos = node.position(); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
569 |
return new StringBuilder(). |
17523
cb4a7c901e0d
8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents:
17233
diff
changeset
|
570 |
append(source.getName()). |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
571 |
append('#'). |
20929
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
19100
diff
changeset
|
572 |
append(source.getLine(pos)). |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
19100
diff
changeset
|
573 |
append(':'). |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
19100
diff
changeset
|
574 |
append(source.getColumn(pos)). |
26504 | 575 |
append("<eval>"). |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
576 |
toString(); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
577 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
578 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
579 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
580 |
* Check whether a call node may be a call to eval. In that case we |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
581 |
* clone the args in order to create the following construct in |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
582 |
* {@link CodeGenerator} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
583 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
584 |
* <pre> |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
585 |
* if (calledFuntion == buildInEval) { |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
586 |
* eval(cloned arg); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
587 |
* } else { |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
588 |
* cloned arg; |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
589 |
* } |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
590 |
* </pre> |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
591 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
592 |
* @param callNode call node to check if it's an eval |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
593 |
*/ |
17233 | 594 |
private CallNode checkEval(final CallNode callNode) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
595 |
if (callNode.getFunction() instanceof IdentNode) { |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
596 |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
597 |
final List<Expression> args = callNode.getArgs(); |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
598 |
final IdentNode callee = (IdentNode)callNode.getFunction(); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
599 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
600 |
// 'eval' call with at least one argument |
17233 | 601 |
if (args.size() >= 1 && EVAL.symbolName().equals(callee.getName())) { |
25423
ca63828cf996
8047067: all eval arguments need to be copied in Lower
attila
parents:
25244
diff
changeset
|
602 |
final List<Expression> evalArgs = new ArrayList<>(args.size()); |
ca63828cf996
8047067: all eval arguments need to be copied in Lower
attila
parents:
25244
diff
changeset
|
603 |
for(final Expression arg: args) { |
ca63828cf996
8047067: all eval arguments need to be copied in Lower
attila
parents:
25244
diff
changeset
|
604 |
evalArgs.add((Expression)ensureUniqueNamesIn(arg).accept(this)); |
ca63828cf996
8047067: all eval arguments need to be copied in Lower
attila
parents:
25244
diff
changeset
|
605 |
} |
ca63828cf996
8047067: all eval arguments need to be copied in Lower
attila
parents:
25244
diff
changeset
|
606 |
return callNode.setEvalArgs(new CallNode.EvalArgs(evalArgs, evalLocation(callee))); |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
607 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
608 |
} |
17233 | 609 |
|
610 |
return callNode; |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
611 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
612 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
613 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
614 |
* Helper that given a loop body makes sure that it is not terminal if it |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
615 |
* has a continue that leads to the loop header or to outer loops' loop |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
616 |
* headers. This means that, even if the body ends with a terminal |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
617 |
* statement, we cannot tag it as terminal |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
618 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
619 |
* @param loopBody the loop body to check |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
620 |
* @return true if control flow may escape the loop |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
621 |
*/ |
17233 | 622 |
private static boolean controlFlowEscapes(final LexicalContext lex, final Block loopBody) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
623 |
final List<Node> escapes = new ArrayList<>(); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
624 |
|
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
625 |
loopBody.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
626 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
627 |
public Node leaveBreakNode(final BreakNode node) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
628 |
escapes.add(node); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
629 |
return node; |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
630 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
631 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
632 |
@Override |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16524
diff
changeset
|
633 |
public Node leaveContinueNode(final ContinueNode node) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
634 |
// all inner loops have been popped. |
26889
dba314d7a634
8059371: Code duplication in handling of break and continue
attila
parents:
26504
diff
changeset
|
635 |
if (lex.contains(node.getTarget(lex))) { |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
636 |
escapes.add(node); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
637 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
638 |
return node; |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
639 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
640 |
}); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
641 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
642 |
return !escapes.isEmpty(); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
643 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
644 |
|
24719 | 645 |
@SuppressWarnings("unchecked") |
646 |
private <T extends LoopNode> T checkEscape(final T loopNode) { |
|
17233 | 647 |
final boolean escapes = controlFlowEscapes(lc, loopNode.getBody()); |
648 |
if (escapes) { |
|
24719 | 649 |
return (T)loopNode. |
17233 | 650 |
setBody(lc, loopNode.getBody().setIsTerminal(lc, false)). |
651 |
setControlFlowEscapes(lc, escapes); |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
652 |
} |
17233 | 653 |
return loopNode; |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
654 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
655 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
656 |
|
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17523
diff
changeset
|
657 |
private Node addStatement(final Statement statement) { |
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17752
diff
changeset
|
658 |
lc.appendStatement(statement); |
17233 | 659 |
return statement; |
16147 | 660 |
} |
661 |
||
24751 | 662 |
private void addStatementEnclosedInBlock(final Statement stmt) { |
663 |
BlockStatement b = BlockStatement.createReplacement(stmt, Collections.<Statement>singletonList(stmt)); |
|
664 |
if(stmt.isTerminal()) { |
|
665 |
b = b.setBlock(b.getBlock().setIsTerminal(null, true)); |
|
666 |
} |
|
667 |
addStatement(b); |
|
668 |
} |
|
669 |
||
16147 | 670 |
/** |
671 |
* An internal expression has a symbol that is tagged internal. Check if |
|
672 |
* this is such a node |
|
673 |
* |
|
674 |
* @param expression expression to check for internal symbol |
|
675 |
* @return true if internal, false otherwise |
|
676 |
*/ |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
18848
diff
changeset
|
677 |
private static boolean isInternalExpression(final Expression expression) { |
24751 | 678 |
if (!(expression instanceof IdentNode)) { |
679 |
return false; |
|
680 |
} |
|
681 |
final Symbol symbol = ((IdentNode)expression).getSymbol(); |
|
16147 | 682 |
return symbol != null && symbol.isInternal(); |
683 |
} |
|
684 |
||
685 |
/** |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
686 |
* Is this an assignment to the special variable that hosts scripting eval |
17233 | 687 |
* results, i.e. __return__? |
16147 | 688 |
* |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
689 |
* @param expression expression to check whether it is $evalresult = X |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
690 |
* @return true if an assignment to eval result, false otherwise |
16147 | 691 |
*/ |
17233 | 692 |
private static boolean isEvalResultAssignment(final Node expression) { |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24719
diff
changeset
|
693 |
final Node e = expression; |
17233 | 694 |
if (e instanceof BinaryNode) { |
695 |
final Node lhs = ((BinaryNode)e).lhs(); |
|
696 |
if (lhs instanceof IdentNode) { |
|
697 |
return ((IdentNode)lhs).getName().equals(RETURN.symbolName()); |
|
16206
83069fa0935b
8006529: Methods always get callee - it should be conditional
attila
parents:
16201
diff
changeset
|
698 |
} |
83069fa0935b
8006529: Methods always get callee - it should be conditional
attila
parents:
16201
diff
changeset
|
699 |
} |
17233 | 700 |
return false; |
16147 | 701 |
} |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16188
diff
changeset
|
702 |
} |