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

📄 irfactory.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        }        return new Node(Token.GET_REF, ref);    }    /**     * Binary     */    Node createBinary(int nodeType, Node left, Node right)    {        switch (nodeType) {          case Token.ADD:            // numerical addition and string concatenation            if (left.type == Token.STRING) {                String s2;                if (right.type == Token.STRING) {                    s2 = right.getString();                } else if (right.type == Token.NUMBER) {                    s2 = ScriptRuntime.numberToString(right.getDouble(), 10);                } else {                    break;                }                String s1 = left.getString();                left.setString(s1.concat(s2));                return left;            } else if (left.type == Token.NUMBER) {                if (right.type == Token.NUMBER) {                    left.setDouble(left.getDouble() + right.getDouble());                    return left;                } else if (right.type == Token.STRING) {                    String s1, s2;                    s1 = ScriptRuntime.numberToString(left.getDouble(), 10);                    s2 = right.getString();                    right.setString(s1.concat(s2));                    return right;                }            }            // can't do anything if we don't know  both types - since            // 0 + object is supposed to call toString on the object and do            // string concantenation rather than addition            break;          case Token.SUB:            // numerical subtraction            if (left.type == Token.NUMBER) {                double ld = left.getDouble();                if (right.type == Token.NUMBER) {                    //both numbers                    left.setDouble(ld - right.getDouble());                    return left;                } else if (ld == 0.0) {                    // first 0: 0-x -> -x                    return new Node(Token.NEG, right);                }            } else if (right.type == Token.NUMBER) {                if (right.getDouble() == 0.0) {                    //second 0: x - 0 -> +x                    // can not make simply x because x - 0 must be number                    return new Node(Token.POS, left);                }            }            break;          case Token.MUL:            // numerical multiplication            if (left.type == Token.NUMBER) {                double ld = left.getDouble();                if (right.type == Token.NUMBER) {                    //both numbers                    left.setDouble(ld * right.getDouble());                    return left;                } else if (ld == 1.0) {                    // first 1: 1 *  x -> +x                    return new Node(Token.POS, right);                }            } else if (right.type == Token.NUMBER) {                if (right.getDouble() == 1.0) {                    //second 1: x * 1 -> +x                    // can not make simply x because x - 0 must be number                    return new Node(Token.POS, left);                }            }            // can't do x*0: Infinity * 0 gives NaN, not 0            break;          case Token.DIV:            // number division            if (right.type == Token.NUMBER) {                double rd = right.getDouble();                if (left.type == Token.NUMBER) {                    // both constants -- just divide, trust Java to handle x/0                    left.setDouble(left.getDouble() / rd);                    return left;               } else if (rd == 1.0) {                    // second 1: x/1 -> +x                    // not simply x to force number convertion                    return new Node(Token.POS, left);                }            }            break;          case Token.AND: {            // Since x && y gives x, not false, when Boolean(x) is false,            // and y, not Boolean(y), when Boolean(x) is true, x && y            // can only be simplified if x is defined. See bug 309957.            int leftStatus = isAlwaysDefinedBoolean(left);            if (leftStatus == ALWAYS_FALSE_BOOLEAN) {                // if the first one is false, just return it                return left;            } else if (leftStatus == ALWAYS_TRUE_BOOLEAN) {                // if first is true, set to second                return right;            }            break;          }          case Token.OR: {            // Since x || y gives x, not true, when Boolean(x) is true,            // and y, not Boolean(y), when Boolean(x) is false, x || y            // can only be simplified if x is defined. See bug 309957.            int leftStatus = isAlwaysDefinedBoolean(left);            if (leftStatus == ALWAYS_TRUE_BOOLEAN) {                // if the first one is true, just return it                return left;            } else if (leftStatus == ALWAYS_FALSE_BOOLEAN) {                // if first is false, set to second                return right;            }            break;          }        }        return new Node(nodeType, left, right);    }    private Node simpleAssignment(Node left, Node right)    {        int nodeType = left.getType();        switch (nodeType) {          case Token.NAME:            left.setType(Token.BINDNAME);            return new Node(Token.SETNAME, left, right);          case Token.GETPROP:          case Token.GETELEM: {            Node obj = left.getFirstChild();            Node id = left.getLastChild();            int type;            if (nodeType == Token.GETPROP) {                type = Token.SETPROP;            } else {                type = Token.SETELEM;            }            return new Node(type, obj, id, right);          }          case Token.GET_REF: {            Node ref = left.getFirstChild();            checkMutableReference(ref);            return new Node(Token.SET_REF, ref, right);          }        }        throw Kit.codeBug();    }    private void checkMutableReference(Node n)    {        int memberTypeFlags = n.getIntProp(Node.MEMBER_TYPE_PROP, 0);        if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {            parser.reportError("msg.bad.assign.left");        }    }    Node createAssignment(int assignType, Node left, Node right)    {        left = makeReference(left);        if (left == null) {            parser.reportError("msg.bad.assign.left");            return right;        }        int assignOp;        switch (assignType) {          case Token.ASSIGN:            return simpleAssignment(left, right);          case Token.ASSIGN_BITOR:  assignOp = Token.BITOR;  break;          case Token.ASSIGN_BITXOR: assignOp = Token.BITXOR; break;          case Token.ASSIGN_BITAND: assignOp = Token.BITAND; break;          case Token.ASSIGN_LSH:    assignOp = Token.LSH;    break;          case Token.ASSIGN_RSH:    assignOp = Token.RSH;    break;          case Token.ASSIGN_URSH:   assignOp = Token.URSH;   break;          case Token.ASSIGN_ADD:    assignOp = Token.ADD;    break;          case Token.ASSIGN_SUB:    assignOp = Token.SUB;    break;          case Token.ASSIGN_MUL:    assignOp = Token.MUL;    break;          case Token.ASSIGN_DIV:    assignOp = Token.DIV;    break;          case Token.ASSIGN_MOD:    assignOp = Token.MOD;    break;          default: throw Kit.codeBug();        }        int nodeType = left.getType();        switch (nodeType) {          case Token.NAME: {            String s = left.getString();            Node opLeft = Node.newString(Token.NAME, s);            Node op = new Node(assignOp, opLeft, right);            Node lvalueLeft = Node.newString(Token.BINDNAME, s);            return new Node(Token.SETNAME, lvalueLeft, op);          }          case Token.GETPROP:          case Token.GETELEM: {            Node obj = left.getFirstChild();            Node id = left.getLastChild();            int type = nodeType == Token.GETPROP                       ? Token.SETPROP_OP                       : Token.SETELEM_OP;            Node opLeft = new Node(Token.USE_STACK);            Node op = new Node(assignOp, opLeft, right);            return new Node(type, obj, id, op);          }          case Token.GET_REF: {            Node ref = left.getFirstChild();            checkMutableReference(ref);            Node opLeft = new Node(Token.USE_STACK);            Node op = new Node(assignOp, opLeft, right);            return new Node(Token.SET_REF_OP, ref, op);          }        }        throw Kit.codeBug();    }    Node createUseLocal(Node localBlock)    {        if (Token.LOCAL_BLOCK != localBlock.getType()) throw Kit.codeBug();        Node result = new Node(Token.LOCAL_LOAD);        result.putProp(Node.LOCAL_BLOCK_PROP, localBlock);        return result;    }    private Node.Jump makeJump(int type, Node target)    {        Node.Jump n = new Node.Jump(type);        n.target = target;        return n;    }    private Node makeReference(Node node)    {        int type = node.getType();        switch (type) {          case Token.NAME:          case Token.GETPROP:          case Token.GETELEM:          case Token.GET_REF:            return node;          case Token.CALL:            node.setType(Token.REF_CALL);            return new Node(Token.GET_REF, node);        }        // Signal caller to report error        return null;    }    // Check if Node always mean true or false in boolean context    private static int isAlwaysDefinedBoolean(Node node)    {        switch (node.getType()) {          case Token.FALSE:          case Token.NULL:            return ALWAYS_FALSE_BOOLEAN;          case Token.TRUE:            return ALWAYS_TRUE_BOOLEAN;          case Token.NUMBER: {            double num = node.getDouble();            if (num == num && num != 0.0) {                return ALWAYS_TRUE_BOOLEAN;            } else {                return ALWAYS_FALSE_BOOLEAN;            }          }        }        return 0;    }// Commented-out: no longer used    //     private static boolean hasSideEffects(Node exprTree)//     {//         switch (exprTree.getType()) {//           case Token.INC://           case Token.DEC://           case Token.SETPROP://           case Token.SETELEM://           case Token.SETNAME://           case Token.CALL://           case Token.NEW://             return true;//           default://             Node child = exprTree.getFirstChild();//             while (child != null) {//                 if (hasSideEffects(child))//                     return true;//                 child = child.getNext();//             }//             break;//         }//         return false;//     }        private void checkActivationName(String name, int token)    {        if (parser.insideFunction()) {            boolean activation = false;            if ("arguments".equals(name)                || (parser.compilerEnv.activationNames != null                    && parser.compilerEnv.activationNames.containsKey(name)))            {                activation = true;            } else if ("length".equals(name)) {                if (token == Token.GETPROP                    && parser.compilerEnv.getLanguageVersion()                       == Context.VERSION_1_2)                {                    // Use of "length" in 1.2 requires an activation object.                    activation = true;                }            }            if (activation) {                setRequiresActivation();            }        }    }    private void setRequiresActivation()    {        if (parser.insideFunction()) {            ((FunctionNode)parser.currentScriptOrFn).itsNeedsActivation = true;        }    }    private Parser parser;    private static final int LOOP_DO_WHILE = 0;    private static final int LOOP_WHILE    = 1;    private static final int LOOP_FOR      = 2;    private static final int ALWAYS_TRUE_BOOLEAN = 1;    private static final int ALWAYS_FALSE_BOOLEAN = -1;}

⌨️ 快捷键说明

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