Пример #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 void printLiveOnEntrySet(OptFunctionNode fn) {
   if (DEBUG) {
     for (int i = 0; i < fn.getVarCount(); i++) {
       String name = fn.fnode.getParamOrVarName(i);
       if (itsUseBeforeDefSet.test(i)) System.out.println(name + " is used before def'd");
       if (itsNotDefSet.test(i)) System.out.println(name + " is not def'd");
       if (itsLiveOnEntrySet.test(i)) System.out.println(name + " is live on entry");
       if (itsLiveOnExitSet.test(i)) System.out.println(name + " is live on exit");
     }
   }
 }
Пример #3
0
 /*
     build the live on entry/exit sets.
     Then walk the trees looking for defs/uses of variables
     and build the def and useBeforeDef sets.
 */
 private void initLiveOnEntrySets(OptFunctionNode fn, Node[] statementNodes) {
   int listLength = fn.getVarCount();
   itsUseBeforeDefSet = new DataFlowBitSet(listLength);
   itsNotDefSet = new DataFlowBitSet(listLength);
   itsLiveOnEntrySet = new DataFlowBitSet(listLength);
   itsLiveOnExitSet = new DataFlowBitSet(listLength);
   for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) {
     Node n = statementNodes[i];
     lookForVariableAccess(fn, n);
   }
   itsNotDefSet.not(); // truth in advertising
 }
Пример #4
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;
 }
Пример #5
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;
    }
  }
Пример #6
0
  static void runFlowAnalyzes(OptFunctionNode fn, Node[] statementNodes) {
    int paramCount = fn.fnode.getParamCount();
    int varCount = fn.fnode.getParamAndVarCount();
    int[] varTypes = new int[varCount];
    // If the variable is a parameter, it could have any type.
    for (int i = 0; i != paramCount; ++i) {
      varTypes[i] = Optimizer.AnyType;
    }
    // If the variable is from a "var" statement, its typeEvent will be set
    // when we see the setVar node.
    for (int i = paramCount; i != varCount; ++i) {
      varTypes[i] = Optimizer.NoType;
    }

    Block[] theBlocks = buildBlocks(statementNodes);

    if (DEBUG) {
      ++debug_blockCount;
      System.out.println(
          "-------------------"
              + fn.fnode.getFunctionName()
              + "  "
              + debug_blockCount
              + "--------");
      System.out.println(toString(theBlocks, statementNodes));
    }

    reachingDefDataFlow(fn, statementNodes, theBlocks, varTypes);
    typeFlow(fn, statementNodes, theBlocks, varTypes);

    if (DEBUG) {
      for (int i = 0; i < theBlocks.length; i++) {
        System.out.println("For block " + theBlocks[i].itsBlockID);
        theBlocks[i].printLiveOnEntrySet(fn);
      }
      System.out.println("Variable Table, size = " + varCount);
      for (int i = 0; i != varCount; i++) {
        System.out.println("[" + i + "] type: " + varTypes[i]);
      }
    }

    for (int i = paramCount; i != varCount; i++) {
      if (varTypes[i] == Optimizer.NumberType) {
        fn.setIsNumberVar(i);
      }
    }
  }