Example #1
0
  /** 12.6.4 end of loop of 'for-in' statement. */
  @Override
  public void visit(EndForInNode n, State state) {
    if (!Options.get().isForInSpecializationDisabled()) {
      if (!c.isScanning()) {
        // 1. Find successor block, context and base-state
        BasicBlock successor = state.getBasicBlock().getSingleSuccessor();
        for (Pair<NodeAndContext<Context>, Context> ncc :
            c.getAnalysisLatticeElement()
                .getCallGraph()
                .getSources(BlockAndContext.makeEntry(n.getBlock(), state.getContext()))) {
          State nonSpecializedMergeState = state.clone();
          Context nonSpecializedContext = ncc.getFirst().getContext();

          // 2. Use State.mergeFunctionReturn to do the merge
          State forInBeginState =
              c.getAnalysisLatticeElement()
                  .getState(
                      n.getBlock().getEntryBlock().getEntryPredecessorBlock(),
                      nonSpecializedContext);
          State forInEntryState =
              c.getAnalysisLatticeElement()
                  .getState(n.getBlock().getEntryBlock(), state.getContext());
          Value returnValue =
              nonSpecializedMergeState.mergeFunctionReturn(
                  forInBeginState,
                  forInBeginState,
                  forInEntryState,
                  nonSpecializedMergeState.getSummarized(),
                  nonSpecializedMergeState.readRegister(AbstractNode.RETURN_REG));
          nonSpecializedMergeState.setContext(nonSpecializedContext);
          nonSpecializedMergeState.writeRegister(AbstractNode.RETURN_REG, returnValue);
          if (state.hasExceptionRegisterValue()) {
            nonSpecializedMergeState.writeRegister(
                AbstractNode.EXCEPTION_REG, state.readRegister(AbstractNode.EXCEPTION_REG));
          }

          // 3. Propagate only to the non-specialized successor
          nonSpecializedMergeState.setBasicBlock(n.getBlock().getSingleSuccessor());
          c.propagateToBasicBlock(nonSpecializedMergeState, successor, nonSpecializedContext);
        }
        state.setToNone();
      }
    }
  }
Example #2
0
 /** Transfer ordinary and exceptional return for the given call node and callee entry. */
 public void transferReturn(
     AbstractNode call_node,
     BasicBlock callee_entry,
     Context caller_context,
     Context callee_context,
     Context edge_context) {
   if (call_node instanceof BeginForInNode) {
     for (EndForInNode endNode : ((BeginForInNode) call_node).getEndNodes()) {
       BasicBlock end_block = endNode.getBlock();
       if (c.getAnalysisLatticeElement().getState(end_block, callee_context)
           != null) // (EndForInNode uses same context as corresponding BeginForInNode)
       c.addToWorklist(end_block, callee_context);
     }
   } else { // call_node is an ordinary call node
     Function callee = callee_entry.getFunction();
     BasicBlock ordinary_exit = callee.getOrdinaryExit();
     BasicBlock exceptional_exit = callee.getExceptionalExit();
     State ordinary_exit_state =
         c.getAnalysisLatticeElement()
             .getState(
                 ordinary_exit,
                 callee_context); // (ReturnNode uses same context as corresponding function entry
     // node)
     State exceptional_exit_state =
         c.getAnalysisLatticeElement().getState(exceptional_exit, callee_context);
     NodeAndContext<Context> caller = new NodeAndContext<>(call_node, caller_context);
     if (ordinary_exit_state != null) {
       if (ordinary_exit.getFirstNode() instanceof ReturnNode) {
         ReturnNode returnNode = (ReturnNode) ordinary_exit.getFirstNode();
         transferReturn(
             returnNode.getReturnValueRegister(),
             ordinary_exit,
             ordinary_exit_state.clone(),
             caller,
             edge_context);
       } else throw new AnalysisException("ReturnNode expected");
     }
     if (exceptional_exit_state != null) {
       transferExceptionalReturn(
           exceptional_exit, exceptional_exit_state.clone(), caller, edge_context);
     }
   }
 }