예제 #1
0
 /** 11.1.2 assignment with right-hand-side identifier reference. */
 @Override
 public void visit(ReadVariableNode n, State state) {
   String varname = n.getVariableName();
   Value v;
   if (varname.equals("this")) {
     // 11.1.1 read 'this' from the execution context
     v = state.readThis();
     m.visitReadThis(n, v, state, InitialStateBuilder.GLOBAL);
   } else { // ordinary variable
     int result_base_reg = n.getResultBaseRegister();
     Set<ObjectLabel> base_objs = null;
     if (c.isScanning() || result_base_reg != AbstractNode.NO_VALUE) base_objs = newSet();
     v = state.readVariable(varname, base_objs);
     m.visitPropertyRead(n, base_objs, Value.makeTemporaryStr(varname), state, true);
     m.visitVariableAsRead(n, v, state);
     m.visitVariableOrProperty(varname, n.getSourceLocation(), v, state.getContext(), state);
     m.visitReadNonThisVariable(n, v);
     if (v.isMaybeAbsent()) Exceptions.throwReferenceError(state, c);
     if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) {
       state.setToNone();
       return;
     }
     if (result_base_reg != AbstractNode.NO_VALUE)
       state.writeRegister(result_base_reg, Value.makeObject(base_objs)); // see 10.1.4
     m.visitRead(n, v, state);
     m.visitReadVariable(n, v, state); // TODO: combine some of these m.visitXYZ methods?
   }
   if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) {
     state.setToNone();
     return;
   }
   if (n.getResultRegister() != AbstractNode.NO_VALUE)
     state.writeRegister(n.getResultRegister(), v.restrictToNotAbsent());
 }
예제 #2
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();
      }
    }
  }
예제 #3
0
  /** 12.6.4 begin 'for-in' statement. */
  @Override
  public void visit(BeginForInNode n, State state) {
    if (!Options.get().isForInSpecializationDisabled()) {
      // 1. Find properties to iterate through
      Value v1 = state.readRegister(n.getObjectRegister());
      state.writeRegister(
          n.getObjectRegister(), v1.makeExtendedScope()); // preserve the register value
      v1 = UnknownValueResolver.getRealValue(v1, state);
      Set<ObjectLabel> objs = Conversion.toObjectLabels(state, n, v1, c);
      State.Properties p = state.getEnumProperties(objs);
      Collection<Value> propertyNameValues = newList(p.toValues());

      // Add the no-iteration case
      propertyNameValues.add(Value.makeNull().makeExtendedScope());

      // 2. Make specialized context for each iteration
      int it = n.getPropertyListRegister();
      //            List<Context> specialized_contexts = newList();
      BasicBlock successor = n.getBlock().getSingleSuccessor();
      for (Value k : propertyNameValues) {
        m.visitPropertyRead(n, objs, k, state, true);
        if (!c.isScanning()) {
          // 2.1 Make specialized context
          State specialized_state = state.clone();
          specialized_state.writeRegister(it, k);
          Context specialized_context =
              c.getAnalysis()
                  .getContextSensitivityStrategy()
                  .makeForInEntryContext(state.getContext(), n, k);
          //                    specialized_contexts.add(specialized_context);
          specialized_state.setContext(specialized_context);
          specialized_state.setBasicBlock(successor);
          // 2.2  Propagate specialized context
          c.propagateToFunctionEntry(
              n, state.getContext(), specialized_state, specialized_context, successor);
        }
      }
      if (!c.isScanning()) {
        // TODO: could kill flow to specializations if covered by other context
        // List<Context> previousSpecializations = c.getAnalysis().getForInSpecializations(n,
        // s.getContext());
        // if (previousSpecializations != null && (p.isArray() || p.isNonArray())) {
        //    previousSpecializations.forEach(c -> {
        //        // covered.setToNone();
        //    });
        //  }

        // TODO: could kill null flow unless all iterations has reached at least one EndForInNode
      }
      state.setToNone();
    } else { // fall back to simple mode without context specialization
      Value v1 = state.readRegister(n.getObjectRegister());
      state.writeRegister(
          n.getObjectRegister(), v1.makeExtendedScope()); // preserve the register value
      v1 = UnknownValueResolver.getRealValue(v1, state);
      Set<ObjectLabel> objs = Conversion.toObjectLabels(state, n, v1, c);
      Properties p = state.getEnumProperties(objs);
      Value proplist = p.toValue().joinNull();
      m.visitPropertyRead(n, objs, proplist, state, true);
      state.writeRegister(n.getPropertyListRegister(), proplist);
    }
  }