nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java
changeset 28690 78317797ab62
parent 28320 bbf9cfde97f6
child 29281 8cc2618a07aa
equal deleted inserted replaced
28597:b2f9702efbe9 28690:78317797ab62
    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) {