Ejemplo n.º 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());
 }
Ejemplo n.º 2
0
  /** Assumption. */
  @Override
  public void visit(AssumeNode n, State state) {
    if (Options.get().isControlSensitivityDisabled()) return;
    switch (n.getKind()) {
      case VARIABLE_NON_NULL_UNDEF:
        {
          Value v = state.readVariable(n.getVariableName(), null);
          v =
              UnknownValueResolver.getRealValue(
                  v, state); // TODO: limits use of polymorphic values?
          v = v.restrictToNotNullNotUndef().restrictToNotAbsent();
          if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) state.setToNone();
          else state.writeVariable(n.getVariableName(), v, false);
          break;
        }

      case PROPERTY_NON_NULL_UNDEF:
        {
          String propname;
          if (n.isPropertyFixed()) propname = n.getPropertyString();
          else {
            Value propval = state.readRegister(n.getPropertyRegister());
            propval =
                UnknownValueResolver.getRealValue(
                    propval, state); // TODO: limits use of polymorphic values?
            if (!propval.isMaybeSingleStr() || propval.isMaybeOtherThanStr())
              break; // safe to do nothing here if it gets complicated
            propname = propval.getStr();
          }
          Set<ObjectLabel> baseobjs =
              Conversion.toObjectLabels(
                  state,
                  n,
                  state.readRegister(n.getBaseRegister()),
                  null); // TODO: omitting side-effects here
          Value v = state.readPropertyWithAttributes(baseobjs, propname);
          if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) state.setToNone();
          else if (baseobjs.size() == 1 && baseobjs.iterator().next().isSingleton()) {
            v =
                UnknownValueResolver.getRealValue(
                    v, state); // TODO: limits use of polymorphic values?
            v = v.restrictToNotNullNotUndef().restrictToNotAbsent();
            state.writePropertyWithAttributes(baseobjs, propname, v, false);
          }
          break;
        }

      case UNREACHABLE:
        {
          if (Options.get().isIgnoreUnreachableEnabled()) {
            state.setToNone();
          }
          break;
        }

      default:
        throw new AnalysisException("Unhandled AssumeNode kind: " + n.getKind());
    }
  }
Ejemplo n.º 3
0
 /** 11.13 and 11.4 assignment with unary operator. */
 @Override
 public void visit(UnaryOperatorNode n, State state) {
   Value arg = state.readRegister(n.getArgRegister());
   arg = UnknownValueResolver.getRealValue(arg, state);
   Value v;
   switch (n.getOperator()) {
     case COMPLEMENT:
       v = Operators.complement(arg, n.getArgRegister(), c);
       break;
     case MINUS:
       v = Operators.uminus(arg, n.getArgRegister(), c);
       break;
     case NOT:
       v = Operators.not(arg, c);
       break;
     case PLUS:
       v = Operators.uplus(arg, n.getArgRegister(), c);
       break;
     default:
       throw new AnalysisException();
   }
   if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) {
     state.setToNone();
     return;
   }
   if (n.getResultRegister() != AbstractNode.NO_VALUE)
     state.writeRegister(n.getResultRegister(), v);
 }
Ejemplo n.º 4
0
 /** 11.13 and 11.4.1 assignment with 'delete' operator. */
 @Override
 public void visit(DeletePropertyNode n, State state) {
   Value v;
   if (n.isVariable()) {
     v = state.deleteVariable(n.getVariableName());
     m.visitVariableOrProperty(
         n.getVariableName(), n.getSourceLocation(), v, state.getContext(), state);
   } else {
     Value baseval = state.readRegister(n.getBaseRegister());
     baseval = UnknownValueResolver.getRealValue(baseval, state);
     m.visitPropertyAccess(n, baseval);
     if (baseval.isMaybeNull() || baseval.isMaybeUndef()) {
       Exceptions.throwTypeError(state, c);
       if (baseval.isNullOrUndef() && !Options.get().isPropagateDeadFlow()) {
         state.setToNone();
         return;
       }
     }
     baseval = baseval.restrictToNotNullNotUndef();
     state.writeRegister(n.getBaseRegister(), baseval);
     Set<ObjectLabel> objlabels = Conversion.toObjectLabels(state, n, baseval, c);
     if (objlabels.isEmpty() && !Options.get().isPropagateDeadFlow()) {
       state.setToNone();
       return;
     }
     Str propertystr;
     if (n.isPropertyFixed()) {
       propertystr = Value.makeStr(n.getPropertyString());
     } else {
       Value propertyval = state.readRegister(n.getPropertyRegister());
       propertystr = Conversion.toString(propertyval, n.getPropertyRegister(), c);
     }
     v = state.deleteProperty(objlabels, propertystr, false);
   }
   if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) {
     state.setToNone();
     return;
   }
   if (n.getResultRegister() != AbstractNode.NO_VALUE)
     state.writeRegister(n.getResultRegister(), v);
 }
Ejemplo n.º 5
0
 /** 11.13 and 11.4.3 assignment with 'typeof' operator. */
 @Override
 public void visit(TypeofNode n, State state) {
   Value v;
   if (n.isVariable()) {
     Value val =
         state.readVariable(
             n.getVariableName(),
             null); // TODO: should also count as a variable read in Monitoring?
     val = UnknownValueResolver.getRealValue(val, state);
     v = Operators.typeof(val, val.isMaybeAbsent());
     m.visitVariableOrProperty(
         n.getVariableName(), n.getOperandSourceLocation(), val, state.getContext(), state);
   } else {
     Value val = state.readRegister(n.getArgRegister());
     val = UnknownValueResolver.getRealValue(val, state);
     v = Operators.typeof(val, false);
   }
   if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) {
     state.setToNone();
     return;
   }
   if (n.getResultRegister() != AbstractNode.NO_VALUE)
     state.writeRegister(n.getResultRegister(), v);
 }
Ejemplo n.º 6
0
 /** 11.2.1 assignment with right-hand-side property accessor. */
 @Override
 public void visit(ReadPropertyNode n, State state) {
   // get the base value, coerce with ToObject
   Value baseval = state.readRegister(n.getBaseRegister());
   baseval = UnknownValueResolver.getRealValue(baseval, state);
   m.visitPropertyAccess(n, baseval);
   Set<ObjectLabel> objlabels = Conversion.toObjectLabels(state, n, baseval, c);
   if (objlabels.isEmpty() && !Options.get().isPropagateDeadFlow()) {
     state.setToNone();
     return;
   }
   state.writeRegister(
       n.getBaseRegister(),
       Value.makeObject(objlabels)); // if null/undefined, an exception would have been thrown via
   // toObjectLabels
   // get the property name value, separate the undefined/null/NaN components, coerce with ToString
   Value propertyval;
   int propertyreg;
   if (n.isPropertyFixed()) {
     propertyreg = AbstractNode.NO_VALUE;
     propertyval = Value.makeStr(n.getPropertyString());
   } else {
     propertyreg = n.getPropertyRegister();
     propertyval = state.readRegister(propertyreg);
     propertyval = UnknownValueResolver.getRealValue(propertyval, state);
   }
   boolean maybe_undef = propertyval.isMaybeUndef();
   boolean maybe_null = propertyval.isMaybeNull();
   boolean maybe_nan = propertyval.isMaybeNaN();
   propertyval = propertyval.restrictToNotNullNotUndef().restrictToNotNaN();
   Str propertystr = Conversion.toString(propertyval, propertyreg, c);
   // read the object property value, as fixed property name or unknown property name, and
   // separately for "undefined"/"null"/"NaN"
   Value v;
   boolean read_undefined = false;
   boolean read_null = false;
   boolean read_nan = false;
   if (propertystr.isMaybeSingleStr()) {
     String propertyname = propertystr.getStr();
     m.visitReadProperty(n, objlabels, propertystr, maybe_undef || maybe_null || maybe_nan, state);
     v = state.readPropertyValue(objlabels, propertyname);
     m.visitPropertyRead(n, objlabels, propertystr, state, true);
   } else if (!propertystr.isNotStr()) {
     m.visitReadProperty(n, objlabels, propertystr, true, state);
     m.visitPropertyRead(n, objlabels, propertystr, state, true);
     v = state.readPropertyValue(objlabels, propertystr);
     read_undefined = propertystr.isMaybeStr("undefined");
     read_null = propertystr.isMaybeStr("null");
     read_nan = propertystr.isMaybeStr("NaN");
   } else v = Value.makeNone();
   if (maybe_undef && !read_undefined) {
     m.visitReadProperty(n, objlabels, Value.makeTemporaryStr("undefined"), true, state);
     v = UnknownValueResolver.join(v, state.readPropertyValue(objlabels, "undefined"), state);
   }
   if (maybe_null && !read_null) {
     m.visitReadProperty(n, objlabels, Value.makeTemporaryStr("null"), true, state);
     v = UnknownValueResolver.join(v, state.readPropertyValue(objlabels, "null"), state);
   }
   if (maybe_nan && !read_nan) {
     m.visitReadProperty(n, objlabels, Value.makeTemporaryStr("NaN"), true, state);
     v = UnknownValueResolver.join(v, state.readPropertyValue(objlabels, "NaN"), state);
   }
   // remove all the TAJS hooks, which are spurious if accessed through a dynamic property
   if (!n.isPropertyFixed()) {
     v = JSGlobal.removeTAJSSpecificFunctions(v);
   }
   m.visitVariableOrProperty(
       n.getPropertyString(), n.getSourceLocation(), v, state.getContext(), state);
   m.visitRead(n, v, state);
   if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) {
     state.setToNone();
     return;
   }
   // store the resulting value
   if (n.getResultRegister() != AbstractNode.NO_VALUE)
     state.writeRegister(n.getResultRegister(), v);
 }
Ejemplo n.º 7
0
 /** 11.13 and 11.5/6/7/8 assignment with binary operator. */
 @Override
 public void visit(BinaryOperatorNode n, State state) {
   Value arg1 = state.readRegister(n.getArg1Register());
   Value arg2 = state.readRegister(n.getArg2Register());
   arg1 = UnknownValueResolver.getRealValue(arg1, state);
   arg2 = UnknownValueResolver.getRealValue(arg2, state);
   Value v;
   switch (n.getOperator()) {
     case ADD:
       v =
           Operators.add(
               arg1,
               n.getArg1Register(),
               arg2,
               n.getArg2Register(),
               c); // TODO: test07.js could improve messages if keeping conversions of the two args
       // separate
       break;
     case AND:
       v = Operators.and(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case DIV:
       v = Operators.div(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case EQ:
       v = Operators.eq(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case GE:
       v = Operators.ge(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case GT:
       v = Operators.gt(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case IN:
       v = Operators.in(state, arg1, n.getArg1Register(), arg2, c);
       break;
     case INSTANCEOF:
       v = Operators.instof(state, arg1, arg2, c);
       break;
     case LE:
       v = Operators.le(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case LT:
       v = Operators.lt(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case MUL:
       v = Operators.mul(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case NE:
       v = Operators.neq(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case OR:
       v = Operators.or(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case REM:
       v = Operators.rem(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case SEQ:
       v = Operators.stricteq(arg1, arg2, c);
       break;
     case SHL:
       v = Operators.shl(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case SHR:
       v = Operators.shr(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case SNE:
       v = Operators.strictneq(arg1, arg2, c);
       break;
     case SUB:
       v = Operators.sub(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case USHR:
       v = Operators.ushr(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     case XOR:
       v = Operators.xor(arg1, n.getArg1Register(), arg2, n.getArg2Register(), c);
       break;
     default:
       throw new AnalysisException();
   }
   if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) {
     state.setToNone();
     return;
   }
   if (n.getResultRegister() != AbstractNode.NO_VALUE)
     state.writeRegister(n.getResultRegister(), v);
 }