83 import jdk.nashorn.internal.ir.BaseNode; |
83 import jdk.nashorn.internal.ir.BaseNode; |
84 import jdk.nashorn.internal.ir.BinaryNode; |
84 import jdk.nashorn.internal.ir.BinaryNode; |
85 import jdk.nashorn.internal.ir.Block; |
85 import jdk.nashorn.internal.ir.Block; |
86 import jdk.nashorn.internal.ir.BlockStatement; |
86 import jdk.nashorn.internal.ir.BlockStatement; |
87 import jdk.nashorn.internal.ir.BreakNode; |
87 import jdk.nashorn.internal.ir.BreakNode; |
88 import jdk.nashorn.internal.ir.BreakableNode; |
|
89 import jdk.nashorn.internal.ir.CallNode; |
88 import jdk.nashorn.internal.ir.CallNode; |
90 import jdk.nashorn.internal.ir.CaseNode; |
89 import jdk.nashorn.internal.ir.CaseNode; |
91 import jdk.nashorn.internal.ir.CatchNode; |
90 import jdk.nashorn.internal.ir.CatchNode; |
92 import jdk.nashorn.internal.ir.ContinueNode; |
91 import jdk.nashorn.internal.ir.ContinueNode; |
93 import jdk.nashorn.internal.ir.EmptyNode; |
92 import jdk.nashorn.internal.ir.EmptyNode; |
100 import jdk.nashorn.internal.ir.IdentNode; |
99 import jdk.nashorn.internal.ir.IdentNode; |
101 import jdk.nashorn.internal.ir.IfNode; |
100 import jdk.nashorn.internal.ir.IfNode; |
102 import jdk.nashorn.internal.ir.IndexNode; |
101 import jdk.nashorn.internal.ir.IndexNode; |
103 import jdk.nashorn.internal.ir.JoinPredecessorExpression; |
102 import jdk.nashorn.internal.ir.JoinPredecessorExpression; |
104 import jdk.nashorn.internal.ir.JumpStatement; |
103 import jdk.nashorn.internal.ir.JumpStatement; |
|
104 import jdk.nashorn.internal.ir.JumpToInlinedFinally; |
105 import jdk.nashorn.internal.ir.LabelNode; |
105 import jdk.nashorn.internal.ir.LabelNode; |
106 import jdk.nashorn.internal.ir.LexicalContext; |
106 import jdk.nashorn.internal.ir.LexicalContext; |
107 import jdk.nashorn.internal.ir.LexicalContextNode; |
107 import jdk.nashorn.internal.ir.LexicalContextNode; |
108 import jdk.nashorn.internal.ir.LiteralNode; |
108 import jdk.nashorn.internal.ir.LiteralNode; |
109 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; |
109 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; |
1108 } |
1108 } |
1109 } |
1109 } |
1110 |
1110 |
1111 @Override |
1111 @Override |
1112 public boolean enterBlock(final Block block) { |
1112 public boolean enterBlock(final Block block) { |
1113 method.label(block.getEntryLabel()); |
1113 final Label entryLabel = block.getEntryLabel(); |
|
1114 if (entryLabel.isBreakTarget()) { |
|
1115 // Entry label is a break target only for an inlined finally block. |
|
1116 assert !method.isReachable(); |
|
1117 method.breakLabel(entryLabel, lc.getUsedSlotCount()); |
|
1118 } else { |
|
1119 method.label(entryLabel); |
|
1120 } |
1114 if(!method.isReachable()) { |
1121 if(!method.isReachable()) { |
1115 return false; |
1122 return false; |
1116 } |
1123 } |
1117 if(lc.isFunctionBody() && emittedMethods.contains(lc.getCurrentFunction().getName())) { |
1124 if(lc.isFunctionBody() && emittedMethods.contains(lc.getCurrentFunction().getName())) { |
1118 return false; |
1125 return false; |
1238 @Override |
1245 @Override |
1239 public boolean enterBreakNode(final BreakNode breakNode) { |
1246 public boolean enterBreakNode(final BreakNode breakNode) { |
1240 return enterJumpStatement(breakNode); |
1247 return enterJumpStatement(breakNode); |
1241 } |
1248 } |
1242 |
1249 |
|
1250 @Override |
|
1251 public boolean enterJumpToInlinedFinally(final JumpToInlinedFinally jumpToInlinedFinally) { |
|
1252 return enterJumpStatement(jumpToInlinedFinally); |
|
1253 } |
|
1254 |
1243 private boolean enterJumpStatement(final JumpStatement jump) { |
1255 private boolean enterJumpStatement(final JumpStatement jump) { |
1244 if(!method.isReachable()) { |
1256 if(!method.isReachable()) { |
1245 return false; |
1257 return false; |
1246 } |
1258 } |
1247 enterStatement(jump); |
1259 enterStatement(jump); |
1248 |
1260 |
1249 method.beforeJoinPoint(jump); |
1261 method.beforeJoinPoint(jump); |
1250 final BreakableNode target = jump.getTarget(lc); |
1262 popScopesUntil(jump.getPopScopeLimit(lc)); |
1251 popScopesUntil(target); |
1263 final Label targetLabel = jump.getTargetLabel(lc); |
1252 final Label targetLabel = jump.getTargetLabel(target); |
|
1253 targetLabel.markAsBreakTarget(); |
1264 targetLabel.markAsBreakTarget(); |
1254 method._goto(targetLabel); |
1265 method._goto(targetLabel); |
1255 |
1266 |
1256 return false; |
1267 return false; |
1257 } |
1268 } |
3051 method._try(entry, exit, recovery, Throwable.class); |
3062 method._try(entry, exit, recovery, Throwable.class); |
3052 |
3063 |
3053 if (method.isReachable()) { |
3064 if (method.isReachable()) { |
3054 method._goto(skip); |
3065 method._goto(skip); |
3055 } |
3066 } |
|
3067 |
|
3068 for (final Block inlinedFinally : tryNode.getInlinedFinallies()) { |
|
3069 TryNode.getLabelledInlinedFinallyBlock(inlinedFinally).accept(this); |
|
3070 // All inlined finallies end with a jump or a return |
|
3071 assert !method.isReachable(); |
|
3072 } |
|
3073 |
|
3074 |
3056 method._catch(recovery); |
3075 method._catch(recovery); |
3057 method.store(vmException, EXCEPTION_TYPE); |
3076 method.store(vmException, EXCEPTION_TYPE); |
3058 |
3077 |
3059 final int catchBlockCount = catchBlocks.size(); |
3078 final int catchBlockCount = catchBlocks.size(); |
3060 final Label afterCatch = new Label("after_catch"); |
3079 final Label afterCatch = new Label("after_catch"); |
3110 } |
3129 } |
3111 |
3130 |
3112 catchBody.accept(this); |
3131 catchBody.accept(this); |
3113 leaveBlock(catchBlock); |
3132 leaveBlock(catchBlock); |
3114 lc.pop(catchBlock); |
3133 lc.pop(catchBlock); |
3115 if(method.isReachable()) { |
|
3116 method._goto(afterCatch); |
|
3117 } |
|
3118 if(nextCatch != null) { |
3134 if(nextCatch != null) { |
|
3135 if(method.isReachable()) { |
|
3136 method._goto(afterCatch); |
|
3137 } |
3119 method.breakLabel(nextCatch, lc.getUsedSlotCount()); |
3138 method.breakLabel(nextCatch, lc.getUsedSlotCount()); |
3120 } |
3139 } |
3121 } |
3140 } |
3122 |
3141 |
3123 assert !method.isReachable(); |
|
3124 // afterCatch could be the same as skip, except that we need to establish that the vmException is dead. |
3142 // afterCatch could be the same as skip, except that we need to establish that the vmException is dead. |
3125 method.label(afterCatch); |
3143 method.label(afterCatch); |
3126 if(method.isReachable()) { |
3144 if(method.isReachable()) { |
3127 method.markDeadLocalVariable(vmException); |
3145 method.markDeadLocalVariable(vmException); |
3128 } |
3146 } |
3129 method.label(skip); |
3147 method.label(skip); |
3130 |
3148 |
3131 // Finally body is always inlined elsewhere so it doesn't need to be emitted |
3149 // Finally body is always inlined elsewhere so it doesn't need to be emitted |
|
3150 assert tryNode.getFinallyBody() == null; |
|
3151 |
3132 return false; |
3152 return false; |
3133 } |
3153 } |
3134 |
3154 |
3135 @Override |
3155 @Override |
3136 public boolean enterVarNode(final VarNode varNode) { |
3156 public boolean enterVarNode(final VarNode varNode) { |