예제 #1
0
  /*
      the type of an expression is relatively unknown. Cases we can be sure
      about are -
          Literals,
          Arithmetic operations - always return a Number
  */
  private static int findExpressionType(OptFunctionNode fn, Node n, int[] varTypes) {
    switch (n.getType()) {
      case Token.NUMBER:
        return Optimizer.NumberType;

      case Token.CALL:
      case Token.NEW:
      case Token.REF_CALL:
        return Optimizer.AnyType;

      case Token.GETELEM:
        return Optimizer.AnyType;

      case Token.GETVAR:
        return varTypes[fn.getVarIndex(n)];

      case Token.INC:
      case Token.DEC:
      case Token.MUL:
      case Token.DIV:
      case Token.MOD:
      case Token.BITOR:
      case Token.BITXOR:
      case Token.BITAND:
      case Token.LSH:
      case Token.RSH:
      case Token.URSH:
      case Token.SUB:
      case Token.POS:
      case Token.NEG:
        return Optimizer.NumberType;

      case Token.ARRAYLIT:
      case Token.OBJECTLIT:
        return Optimizer.AnyType; // XXX: actually, we know it's not
        // number, but no type yet for that

      case Token.ADD:
        {
          // if the lhs & rhs are known to be numbers, we can be sure that's
          // the result, otherwise it could be a string.
          Node child = n.getFirstChild();
          int lType = findExpressionType(fn, child, varTypes);
          int rType = findExpressionType(fn, child.getNext(), varTypes);
          return lType | rType; // we're not distinguishing strings yet
        }
    }

    Node child = n.getFirstChild();
    if (child == null) {
      return Optimizer.AnyType;
    } else {
      int result = Optimizer.NoType;
      while (child != null) {
        result |= findExpressionType(fn, child, varTypes);
        child = child.getNext();
      }
      return result;
    }
  }
예제 #2
0
 private static boolean findDefPoints(OptFunctionNode fn, Node n, int[] varTypes) {
   boolean result = false;
   Node child = n.getFirstChild();
   switch (n.getType()) {
     default:
       while (child != null) {
         result |= findDefPoints(fn, child, varTypes);
         child = child.getNext();
       }
       break;
     case Token.DEC:
     case Token.INC:
       if (child.getType() == Token.GETVAR) {
         // theVar is a Number now
         int i = fn.getVarIndex(child);
         result |= assignType(varTypes, i, Optimizer.NumberType);
       }
       break;
     case Token.SETPROP:
     case Token.SETPROP_OP:
       if (child.getType() == Token.GETVAR) {
         int i = fn.getVarIndex(child);
         assignType(varTypes, i, Optimizer.AnyType);
       }
       while (child != null) {
         result |= findDefPoints(fn, child, varTypes);
         child = child.getNext();
       }
       break;
     case Token.SETVAR:
       {
         Node rValue = child.getNext();
         int theType = findExpressionType(fn, rValue, varTypes);
         int i = fn.getVarIndex(n);
         result |= assignType(varTypes, i, theType);
         break;
       }
   }
   return result;
 }
예제 #3
0
  /*
      We're tracking uses and defs - in order to
      build the def set and to identify the last use
      nodes.

      The itsNotDefSet is built reversed then flipped later.

  */
  private void lookForVariableAccess(OptFunctionNode fn, Node n) {
    switch (n.getType()) {
      case Token.DEC:
      case Token.INC:
        {
          Node child = n.getFirstChild();
          if (child.getType() == Token.GETVAR) {
            int varIndex = fn.getVarIndex(child);
            if (!itsNotDefSet.test(varIndex)) itsUseBeforeDefSet.set(varIndex);
            itsNotDefSet.set(varIndex);
          }
        }
        break;
      case Token.SETVAR:
        {
          Node lhs = n.getFirstChild();
          Node rhs = lhs.getNext();
          lookForVariableAccess(fn, rhs);
          itsNotDefSet.set(fn.getVarIndex(n));
        }
        break;
      case Token.GETVAR:
        {
          int varIndex = fn.getVarIndex(n);
          if (!itsNotDefSet.test(varIndex)) itsUseBeforeDefSet.set(varIndex);
        }
        break;
      default:
        Node child = n.getFirstChild();
        while (child != null) {
          lookForVariableAccess(fn, child);
          child = child.getNext();
        }
        break;
    }
  }