⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 node.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    }    /**     * A general block of code is examined statement by statement. If any     * statement (even compound ones) returns in all branches, then subsequent     * statements are not examined.     * @return logical OR of END_* flags     */    private int endCheckBlock()    {        Node n;        int rv = END_DROPS_OFF;        // check each statment and if the statement can continue onto the next        // one, then check the next statement        for (n=first; ((rv & END_DROPS_OFF) != 0) && n != null; n = n.next)        {            rv &= ~END_DROPS_OFF;            rv |= n.endCheck();        }        return rv;    }    /**     * A labelled statement implies that there maybe a break to the label. The     * function processes the labelled statement and then checks the     * CONTROL_BLOCK_PROP property to see if there is ever a break to the     * particular label.     * @return logical OR of END_* flags     */    private int endCheckLabel()    {        int rv = END_UNREACHED;        rv = next.endCheck();        rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);        return rv;    }    /**     * When a break is encountered annotate the statement being broken     * out of by setting its CONTROL_BLOCK_PROP property.     * @return logical OR of END_* flags     */    private int endCheckBreak()    {        Node n = ((Jump) this).jumpNode;        n.putIntProp(CONTROL_BLOCK_PROP, END_DROPS_OFF);        return END_UNREACHED;    }    /**     * endCheck() examines the body of a function, doing a basic reachability     * analysis and returns a combination of flags END_* flags that indicate     * how the function execution can terminate. These constitute only the     * pessimistic set of termination conditions. It is possible that at     * runtime certain code paths will never be actually taken. Hence this     * analysis will flag errors in cases where there may not be errors.     * @return logical OR of END_* flags     */    private int endCheck()    {        switch(type)        {            case Token.BREAK:                return endCheckBreak();            case Token.EXPR_VOID:                if (this.first != null)                    return first.endCheck();                return END_DROPS_OFF;            case Token.YIELD:                return END_YIELDS;            case Token.CONTINUE:            case Token.THROW:                return END_UNREACHED;            case Token.RETURN:                if (this.first != null)                    return END_RETURNS_VALUE;                else                    return END_RETURNS;            case Token.TARGET:                if (next != null)                    return next.endCheck();                else                    return END_DROPS_OFF;            case Token.LOOP:                return endCheckLoop();            case Token.LOCAL_BLOCK:            case Token.BLOCK:                // there are several special kinds of blocks                if (first == null)                    return END_DROPS_OFF;                switch(first.type) {                    case Token.LABEL:                        return first.endCheckLabel();                    case Token.IFNE:                        return first.endCheckIf();                    case Token.SWITCH:                        return first.endCheckSwitch();                    case Token.TRY:                        return first.endCheckTry();                    default:                        return endCheckBlock();                }            default:                return END_DROPS_OFF;        }    }    public boolean hasSideEffects()    {        switch (type) {          case Token.EXPR_VOID:          case Token.COMMA:            if (last != null)                return last.hasSideEffects();            else                return true;          case Token.HOOK:            if (first == null ||                first.next == null ||                first.next.next == null)                Kit.codeBug();            return first.next.hasSideEffects() &&                   first.next.next.hasSideEffects();          case Token.ERROR:         // Avoid cascaded error messages          case Token.EXPR_RESULT:          case Token.ASSIGN:          case Token.ASSIGN_ADD:          case Token.ASSIGN_SUB:          case Token.ASSIGN_MUL:          case Token.ASSIGN_DIV:          case Token.ASSIGN_MOD:          case Token.ASSIGN_BITOR:          case Token.ASSIGN_BITXOR:          case Token.ASSIGN_BITAND:          case Token.ASSIGN_LSH:          case Token.ASSIGN_RSH:          case Token.ASSIGN_URSH:          case Token.ENTERWITH:          case Token.LEAVEWITH:          case Token.RETURN:          case Token.GOTO:          case Token.IFEQ:          case Token.IFNE:          case Token.NEW:          case Token.DELPROP:          case Token.SETNAME:          case Token.SETPROP:          case Token.SETELEM:          case Token.CALL:          case Token.THROW:          case Token.RETHROW:          case Token.SETVAR:          case Token.CATCH_SCOPE:          case Token.RETURN_RESULT:          case Token.SET_REF:          case Token.DEL_REF:          case Token.REF_CALL:          case Token.TRY:          case Token.SEMI:          case Token.INC:          case Token.DEC:          case Token.EXPORT:          case Token.IMPORT:          case Token.IF:          case Token.ELSE:          case Token.SWITCH:          case Token.WHILE:          case Token.DO:          case Token.FOR:          case Token.BREAK:          case Token.CONTINUE:          case Token.VAR:          case Token.CONST:          case Token.LET:          case Token.LETEXPR:          case Token.WITH:          case Token.WITHEXPR:          case Token.CATCH:          case Token.FINALLY:          case Token.BLOCK:          case Token.LABEL:          case Token.TARGET:          case Token.LOOP:          case Token.JSR:          case Token.SETPROP_OP:          case Token.SETELEM_OP:          case Token.LOCAL_BLOCK:          case Token.SET_REF_OP:          case Token.YIELD:            return true;          default:            return false;        }    }    public String toString()    {        if (Token.printTrees) {            StringBuffer sb = new StringBuffer();            toString(new ObjToIntMap(), sb);            return sb.toString();        }        return String.valueOf(type);    }    private void toString(ObjToIntMap printIds, StringBuffer sb)    {        if (Token.printTrees) {            sb.append(Token.name(type));            if (this instanceof StringNode) {                sb.append(' ');                sb.append(getString());                Scope scope = getScope();                if (scope != null) {                    sb.append("[scope: ");                    appendPrintId(scope, printIds, sb);                    sb.append("]");                }            } else if (this instanceof Node.Scope) {                if (this instanceof ScriptOrFnNode) {                    ScriptOrFnNode sof = (ScriptOrFnNode)this;                    if (this instanceof FunctionNode) {                        FunctionNode fn = (FunctionNode)this;                        sb.append(' ');                        sb.append(fn.getFunctionName());                    }                    sb.append(" [source name: ");                    sb.append(sof.getSourceName());                    sb.append("] [encoded source length: ");                    sb.append(sof.getEncodedSourceEnd()                              - sof.getEncodedSourceStart());                    sb.append("] [base line: ");                    sb.append(sof.getBaseLineno());                    sb.append("] [end line: ");                    sb.append(sof.getEndLineno());                    sb.append(']');                }                if (((Node.Scope)this).symbolTable != null) {                    sb.append(" [scope ");                    appendPrintId(this, printIds, sb);                    sb.append(": ");                    Iterator iter = ((Node.Scope) this).symbolTable.keySet()                        .iterator();                    while (iter.hasNext()) {                        sb.append(iter.next());                        sb.append(" ");                    }                    sb.append("]");                }            } else if (this instanceof Jump) {                Jump jump = (Jump)this;                if (type == Token.BREAK || type == Token.CONTINUE) {                    sb.append(" [label: ");                    appendPrintId(jump.getJumpStatement(), printIds, sb);                    sb.append(']');                } else if (type == Token.TRY) {                    Node catchNode = jump.target;                    Node finallyTarget = jump.getFinally();                    if (catchNode != null) {                        sb.append(" [catch: ");                        appendPrintId(catchNode, printIds, sb);                        sb.append(']');                    }                    if (finallyTarget != null) {                        sb.append(" [finally: ");                        appendPrintId(finallyTarget, printIds, sb);                        sb.append(']');                    }                } else if (type == Token.LABEL || type == Token.LOOP                           || type == Token.SWITCH)                {                    sb.append(" [break: ");                    appendPrintId(jump.target, printIds, sb);                    sb.append(']');                    if (type == Token.LOOP) {                        sb.append(" [continue: ");                        appendPrintId(jump.getContinue(), printIds, sb);                        sb.append(']');                    }                } else {                    sb.append(" [target: ");                    appendPrintId(jump.target, printIds, sb);                    sb.append(']');                }            } else if (type == Token.NUMBER) {                sb.append(' ');                sb.append(getDouble());            } else if (type == Token.TARGET) {                sb.append(' ');                appendPrintId(this, printIds, sb);            }            if (lineno != -1) {                sb.append(' ');                sb.append(lineno);            }            for (PropListItem x = propListHead; x != null; x = x.next) {                int type = x.type;                sb.append(" [");                sb.append(propToString(type));                sb.append(": ");                String value;                switch (type) {                  case TARGETBLOCK_PROP : // can't add this as it recurses                    value = "target block property";                    break;                  case LOCAL_BLOCK_PROP :     // can't add this as it is dull                    value = "last local block";                    break;                  case ISNUMBER_PROP:                    switch (x.intValue) {                      case BOTH:                        value = "both";                        break;                      case RIGHT:                        value = "right";                        break;                      case LEFT:                        value = "left";                        break;                      default:                        throw Kit.codeBug();                    }                    break;                  case SPECIALCALL_PROP:                    switch (x.intValue) {                      case SPECIALCALL_EVAL:                        value = "eval";                        break;                      case SPECIALCALL_WITH:                        value = "with";                        break;                      default:                        // NON_SPECIALCALL should not be stored                        throw Kit.codeBug();                    }                    break;                  case OBJECT_IDS_PROP: {                    Object[] a = (Object[]) x.objectValue;                    value = "[";                    for (int i=0; i < a.length; i++) {                        value += a[i].toString();                        if (i+1 < a.length)                            value += ", ";                    }                    value += "]";                    break;                  }                  default :                    Object obj = x.objectValue;                    if (obj != null) {                        value = obj.toString();                    } else {                        value = String.valueOf(x.intValue);                    }                    break;                }                sb.append(value);                sb.append(']');            }        }    }    public String toStringTree(ScriptOrFnNode treeTop) {        if (Token.printTrees) {            StringBuffer sb = new StringBuffer();            toStringTreeHelper(treeTop, this, null, 0, sb);            return sb.toString();        }        return null;    }    private static void toStringTreeHelper(ScriptOrFnNode treeTop, Node n,                                           ObjToIntMap printIds,                                           int level, StringBuffer sb)    {        if (Token.printTrees) {            if (printIds == null) {                printIds = new ObjToIntMap();                generatePrintIds(treeTop, printIds);            }            for (int i = 0; i != level; ++i) {                sb.append("    ");            }            n.toString(printIds, sb);            sb.append('\n');            for (Node cursor = n.getFirstChild(); cursor != null;                 cursor = cursor.getNext())            {                if (cursor.getType() == Token.FUNCTION) {                    int fnIndex = cursor.getExistingIntProp(Node.FUNCTION_PROP);                    FunctionNode fn = treeTop.getFunctionNode(fnIndex);                    toStringTreeHelper(fn, fn, null, level + 1, sb);                } else {                    toStringTreeHelper(treeTop, cursor, printIds, level + 1, sb);                }            }        }    }    private static void generatePrintIds(Node n, ObjToIntMap map)    {        if (Token.printTrees) {            map.put(n, map.size());            for (Node cursor = n.getFirstChild(); cursor != null;                 cursor = cursor.getNext())            {                generatePrintIds(cursor, map);            }        }    }    private static void appendPrintId(Node n, ObjToIntMap printIds,                                      StringBuffer sb)    {        if (Token.printTrees) {            if (n != null) {                int id = printIds.get(n, -1);                sb.append('#');                if (id != -1) {                    sb.append(id + 1);                } else {                    sb.append("<not_available>");                }            }        }    }    int type;              // type of the node; Token.NAME for example    Node next;             // next sibling    private Node first;    // first element of a linked list of children    private Node last;     // last element of a linked list of children    protected int lineno = -1;    /**     * Linked list of properties. Since vast majority of nodes would have     * no more then 2 properties, linked list saves memory and provides     * fast lookup. If this does not holds, propListHead can be replaced     * by UintMap.     */    private PropListItem propListHead;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -