src/jdk/nashorn/internal/codegen/CompilationPhase.java

changeset 247
5a3f7867e19c
parent 211
3a209cbd1d8f
child 254
d28180d97c61
equal deleted inserted replaced
246:c8023561505b 247:5a3f7867e19c
40 * default policy. The will get trampolines and only be generated when 40 * default policy. The will get trampolines and only be generated when
41 * called 41 * called
42 */ 42 */
43 LAZY_INITIALIZATION_PHASE(EnumSet.of(INITIALIZED, PARSED)) { 43 LAZY_INITIALIZATION_PHASE(EnumSet.of(INITIALIZED, PARSED)) {
44 @Override 44 @Override
45 FunctionNode transform(final Compiler compiler, final FunctionNode fn0) { 45 FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
46 46
47 /* 47 /*
48 * For lazy compilation, we might be given a node previously marked 48 * For lazy compilation, we might be given a node previously marked
49 * as lazy to compile as the outermost function node in the 49 * as lazy to compile as the outermost function node in the
50 * compiler. Unmark it so it can be compiled and not cause 50 * compiler. Unmark it so it can be compiled and not cause
56 * TODO: in the future specializations from a callsite will be 56 * TODO: in the future specializations from a callsite will be
57 * passed here so we can generate a better non-lazy version of a 57 * passed here so we can generate a better non-lazy version of a
58 * function from a trampoline 58 * function from a trampoline
59 */ 59 */
60 60
61 final FunctionNode outermostFunctionNode = compiler.getFunctionNode(); 61 final FunctionNode outermostFunctionNode = fn;
62 assert outermostFunctionNode == fn0;
63 62
64 final Set<FunctionNode> neverLazy = new HashSet<>(); 63 final Set<FunctionNode> neverLazy = new HashSet<>();
65 final Set<FunctionNode> lazy = new HashSet<>(); 64 final Set<FunctionNode> lazy = new HashSet<>();
66 65
67 FunctionNode newFunctionNode = outermostFunctionNode; 66 FunctionNode newFunctionNode = outermostFunctionNode;
170 * Attribution Assign symbols and types to all nodes. 169 * Attribution Assign symbols and types to all nodes.
171 */ 170 */
172 ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED)) { 171 ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED)) {
173 @Override 172 @Override
174 FunctionNode transform(final Compiler compiler, final FunctionNode fn) { 173 FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
175 return (FunctionNode)initReturnTypes(fn).accept(new Attr()); 174 return (FunctionNode)enterAttr(fn).accept(new Attr());
176 } 175 }
177 176
178 /** 177 /**
179 * Pessimistically set all lazy functions' return types to Object 178 * Pessimistically set all lazy functions' return types to Object
179 * and the function symbols to object
180 * @param functionNode node where to start iterating 180 * @param functionNode node where to start iterating
181 */ 181 */
182 private FunctionNode initReturnTypes(final FunctionNode functionNode) { 182 private FunctionNode enterAttr(final FunctionNode functionNode) {
183 return (FunctionNode)functionNode.accept(new NodeVisitor() { 183 return (FunctionNode)functionNode.accept(new NodeVisitor() {
184 @Override 184 @Override
185 public Node leaveFunctionNode(final FunctionNode node) { 185 public Node leaveFunctionNode(final FunctionNode node) {
186 return node.isLazy() ? 186 final LexicalContext lc = getLexicalContext();
187 node.setReturnType(getLexicalContext(), Type.OBJECT) : 187 if (node.isLazy()) {
188 node.setReturnType(getLexicalContext(), Type.UNKNOWN); 188 FunctionNode newNode = node.setReturnType(getLexicalContext(), Type.OBJECT);
189 return Attr.ensureSymbol(lc, lc.getCurrentBlock(), Type.OBJECT, newNode);
190 }
191 //node may have a reference here that needs to be nulled if it was referred to by
192 //its outer context, if it is lazy and not attributed
193 return node.setReturnType(lc, Type.UNKNOWN).setSymbol(lc, null);
189 } 194 }
190 }); 195 });
191 } 196 }
192 197
193 @Override 198 @Override
205 SPLITTING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR)) { 210 SPLITTING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR)) {
206 @Override 211 @Override
207 FunctionNode transform(final Compiler compiler, final FunctionNode fn) { 212 FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
208 final CompileUnit outermostCompileUnit = compiler.addCompileUnit(compiler.firstCompileUnitName()); 213 final CompileUnit outermostCompileUnit = compiler.addCompileUnit(compiler.firstCompileUnitName());
209 214
215 // assert fn.isProgram() ;
210 final FunctionNode newFunctionNode = new Splitter(compiler, fn, outermostCompileUnit).split(fn); 216 final FunctionNode newFunctionNode = new Splitter(compiler, fn, outermostCompileUnit).split(fn);
211 217
212 assert newFunctionNode.getCompileUnit() == outermostCompileUnit : "fn.compileUnit (" + newFunctionNode.getCompileUnit() + ") != " + outermostCompileUnit; 218 assert newFunctionNode.getCompileUnit() == outermostCompileUnit : "fn.compileUnit (" + newFunctionNode.getCompileUnit() + ") != " + outermostCompileUnit;
213 219
214 if (newFunctionNode.isStrict()) { 220 if (newFunctionNode.isStrict()) {
215 assert compiler.getStrictMode(); 221 assert compiler.getStrictMode();
216 compiler.setStrictMode(true); 222 compiler.setStrictMode(true);
217 } 223 }
218
219 /*
220 newFunctionNode.accept(new NodeVisitor() {
221 @Override
222 public boolean enterFunctionNode(final FunctionNode functionNode) {
223 assert functionNode.getCompileUnit() != null : functionNode.getName() + " " + Debug.id(functionNode) + " has no compile unit";
224 return true;
225 }
226 });*/
227 224
228 return newFunctionNode; 225 return newFunctionNode;
229 } 226 }
230 227
231 @Override 228 @Override

mercurial