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

📄 gen.java

📁 GJC(Generic Java Compiler)编译器
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    public void visitIf(If tree) {        int limit = code.nextreg;        Chain thenExit = null;        CondItem c = genCond(TreeInfo.skipParens(tree.cond), CRT_FLOW_CONTROLLER);        Chain elseChain = c.jumpFalse();        if (!c.isFalse()) {            code.resolve(c.trueJumps);            genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET);            thenExit = code.branch(goto_);        }        if (elseChain != null) {            code.resolve(elseChain);            if (tree.elsepart != null)                genStat(tree.elsepart, env, CRT_STATEMENT | CRT_FLOW_TARGET);        }        code.resolve(thenExit);        code.endScopes(limit);    }    public void visitExec(Exec tree) {        if (tree.expr.tag == Tree.POSTINC)            tree.expr.tag = Tree.PREINC;        else if (tree.expr.tag == Tree.POSTDEC)            tree.expr.tag = Tree.PREDEC;        genExpr(tree.expr, tree.expr.type).drop();    }    public void visitBreak(Break tree) {        Env targetEnv = unwind(tree.target, env);        assert code.stacksize == 0;        ((Gen.GenContext) targetEnv.info).addExit(code.branch(goto_));        endFinalizerGaps(env, targetEnv);    }    public void visitContinue(Continue tree) {        Env targetEnv = unwind(tree.target, env);        assert code.stacksize == 0;        ((Gen.GenContext) targetEnv.info).addCont(code.branch(goto_));        endFinalizerGaps(env, targetEnv);    }    public void visitReturn(Return tree) {        int limit = code.nextreg;        final Env targetEnv;        if (tree.expr != null) {            Item r = genExpr(tree.expr, pt).load();            if (hasFinally(env.enclMethod, env)) {                r = makeTemp(pt);                r.store();            }            targetEnv = unwind(env.enclMethod, env);            r.load();            code.emitop(ireturn + Code.truncate(Code.typecode(pt)));        } else {            targetEnv = unwind(env.enclMethod, env);            code.emitop(return_);        }        endFinalizerGaps(env, targetEnv);        code.endScopes(limit);    }    public void visitThrow(Throw tree) {        genExpr(tree.expr, tree.expr.type).load();        code.emitop(athrow);    }    public void visitApply(Apply tree) {        Item m = genExpr(tree.meth, methodType);        genArgs(tree.args, TreeInfo.symbol(tree.meth).externalType().argtypes());        result = m.invoke();    }    public void visitConditional(Conditional tree) {        Chain thenExit = null;        CondItem c = genCond(tree.cond, CRT_FLOW_CONTROLLER);        Chain elseChain = c.jumpFalse();        if (!c.isFalse()) {            code.resolve(c.trueJumps);            int startpc = genCrt ? code.curPc() : 0;            genExpr(tree.truepart, pt).load();            if (genCrt)                code.crt.put(tree.truepart, CRT_FLOW_TARGET, startpc, code.curPc());            thenExit = code.branch(goto_);        }        if (elseChain != null) {            code.resolve(elseChain);            int startpc = genCrt ? code.curPc() : 0;            genExpr(tree.falsepart, pt).load();            if (genCrt)                code.crt.put(tree.falsepart, CRT_FLOW_TARGET, startpc, code.curPc());        }        code.resolve(thenExit);        result = items.makeStackItem(pt);    }    public void visitNewClass(NewClass tree) {        assert tree.encl == null && tree.def == null;        code.emitop2(new_, makeRef(tree.pos, tree.type));        code.emitop(dup);        genArgs(tree.args, tree.constructor.externalType().argtypes());        items.makeMemberItem(tree.constructor, true).invoke();        result = items.makeStackItem(tree.type);    }    public void visitNewArray(NewArray tree) {        if (tree.elems != null) {            Type elemtype = tree.type.elemtype();            loadIntConst(tree.elems.length());            Item arr = makeNewArray(tree.pos, tree.type, 1);            int i = 0;            for (List l = tree.elems; l.nonEmpty(); l = l.tail) {                arr.duplicate();                loadIntConst(i);                i++;                genExpr((Tree) l.head, elemtype).load();                items.makeIndexedItem(elemtype).store();            }            result = arr;        } else {            for (List l = tree.dims; l.nonEmpty(); l = l.tail) {                genExpr((Tree) l.head, syms.intType).load();            }            result = makeNewArray(tree.pos, tree.type, tree.dims.length());        }    }    /**      * Generate code to create an array with given element type and number      *  of dimensions.      */    Item makeNewArray(int pos, Type type, int ndims) {        Type elemtype = type.elemtype();        if (elemtype.dimensions() + ndims > ClassFile.MAX_DIMENSIONS) {            log.error(pos, "limit.dimensions");            nerrs++;        }        int elemcode = Code.arraycode(elemtype);        if (elemcode == 0 || (elemcode == 1 && ndims == 1)) {            code.emitop2(anewarray, makeRef(pos, elemtype));        } else if (elemcode == 1) {            code.emitop(multianewarray, 1 - ndims);            code.emit2(makeRef(pos, type));            code.emit1(ndims);        } else {            code.emitop1(newarray, elemcode);        }        return items.makeStackItem(type);    }    public void visitParens(Parens tree) {        result = genExpr(tree.expr, tree.expr.type);    }    public void visitAssign(Assign tree) {        Item l = genExpr(tree.lhs, tree.lhs.type);        genExpr(tree.rhs, tree.lhs.type).load();        result = items.makeAssignItem(l);    }    public void visitAssignop(Assignop tree) {        OperatorSymbol operator = (OperatorSymbol) tree.operator;        Item l;        if (operator.opcode == string_add) {            makeStringBuffer(tree.pos);            l = genExpr(tree.lhs, tree.lhs.type);            if (l.width() > 0) {                code.emitop(dup_x1 + 3 * (l.width() - 1));            }            l.load();            appendString(tree.lhs);            appendStrings(tree.rhs);            bufferToString(tree.pos);        } else {            l = genExpr(tree.lhs, tree.lhs.type);            if ((tree.tag == Tree.PLUS_ASG || tree.tag == Tree.MINUS_ASG) &&                    l instanceof LocalItem && tree.lhs.type.tag <= INT &&                    tree.rhs.type.tag <= INT && tree.rhs.type.constValue != null) {                int ival = ((Number) tree.rhs.type.constValue).intValue();                if (tree.tag == Tree.MINUS_ASG)                    ival = -ival;                if (-128 <= ival && ival <= 127) {                    ((LocalItem) l).incr(ival);                    result = l;                    return;                }            }            l.duplicate();            l.coerce((Type) operator.type.argtypes().head).load();            completeBinop(tree.lhs, tree.rhs, operator).coerce(tree.lhs.type);        }        result = items.makeAssignItem(l);    }    public void visitUnary(Unary tree) {        OperatorSymbol operator = (OperatorSymbol) tree.operator;        if (tree.tag == Tree.NOT) {            CondItem od = genCond(tree.arg, false);            result = od.negate();        } else {            Item od = genExpr(tree.arg, (Type) operator.type.argtypes().head);            switch (tree.tag) {            case Tree.POS:                result = od.load();                break;            case Tree.NEG:                result = od.load();                code.emitop(operator.opcode);                break;            case Tree.COMPL:                result = od.load();                emitMinusOne(od.typecode);                code.emitop(operator.opcode);                break;            case Tree.PREINC:            case Tree.PREDEC:                od.duplicate();                if (od instanceof LocalItem &&                        (operator.opcode == iadd || operator.opcode == isub)) {                    ((LocalItem) od).incr(tree.tag == Tree.PREINC ? 1 : -1);                    result = od;                } else {                    od.load();                    code.emitop(one(od.typecode));                    code.emitop(operator.opcode);                    if (od.typecode != INTcode &&                            Code.truncate(od.typecode) == INTcode)                        code.emitop(int2byte + od.typecode - BYTEcode);                    result = items.makeAssignItem(od);                }                break;            case Tree.POSTINC:            case Tree.POSTDEC:                od.duplicate();                if (od instanceof LocalItem && operator.opcode == iadd) {                    Item res = od.load();                    ((LocalItem) od).incr(tree.tag == Tree.POSTINC ? 1 : -1);                    result = res;                } else {                    Item res = od.load();                    od.stash(od.typecode);                    code.emitop(one(od.typecode));                    code.emitop(operator.opcode);                    if (od.typecode != INTcode &&                            Code.truncate(od.typecode) == INTcode)                        code.emitop(int2byte + od.typecode - BYTEcode);                    od.store();                    result = res;                }                break;            case Tree.NULLCHK:                result = od.load();                code.emitop(dup);                genNullCheck(tree.pos);                break;            default:                assert false;            }        }    }    /**      * Generate a null check from the object value at stack top.      */    private void genNullCheck(int pos) {        callMethod(pos, syms.objectType, names.getClass, Type.emptyList, false);        code.emitop(pop);    }    public void visitBinary(Binary tree) {        OperatorSymbol operator = (OperatorSymbol) tree.operator;        if (operator.opcode == string_add) {            makeStringBuffer(tree.pos);            appendStrings(tree);            bufferToString(tree.pos);            result = items.makeStackItem(syms.stringType);        } else if (tree.tag == Tree.AND) {            CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER);            if (!lcond.isFalse()) {                Chain falseJumps = lcond.jumpFalse();                code.resolve(lcond.trueJumps);                CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);                result = items.makeCondItem(rcond.opcode, rcond.trueJumps,                        code.mergeChains(falseJumps, rcond.falseJumps));            } else {                result = lcond;            }        } else if (tree.tag == Tree.OR) {            CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER);            if (!lcond.isTrue()) {                Chain trueJumps = lcond.jumpTrue();                code.resolve(lcond.falseJumps);                CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);                result = items.makeCondItem(rcond.opcode,                        code.mergeChains(trueJumps, rcond.trueJumps),                        rcond.falseJumps);            } else {                result = lcond;            }        } else {            Item od = genExpr(tree.lhs, (Type) operator.type.argtypes().head);            od.load();            result = completeBinop(tree.lhs, tree.rhs, operator);        }    }    /**      * Make a new string buffer.      */    void makeStringBuffer(int pos) {        code.emitop2(new_, makeRef(pos, syms.stringBufferType));        code.emitop(dup);        callMethod(pos, syms.stringBufferType, names.init, Type.emptyList, false);    }    /**      * Append value (on tos) to string buffer (on tos - 1).      */    void appendString(Tree tree) {        Type t = tree.type;        if (t.tag > lastBaseTag && t.tsym != syms.stringType.tsym) {            t = syms.objectType;        }        callMethod(tree.pos, syms.stringBufferType, names.append,                Type.emptyList.prepend(t), false);    }    /**      * Add all strings in tree to string buffer.      */    void appendStrings(Tree tree) {        tree = TreeInfo.skipParens(tree);        if (tree.tag == Tree.PLUS && tree.type.constValue == null) {            Binary op = (Binary) tree;            if (op.operator.kind == MTH &&                    ((OperatorSymbol) op.operator).opcode == string_add) {                appendStrings(op.lhs);                appendStrings(op.rhs);                return;            }        }        genExpr(tree, tree.type).load();        appendString(tree);    }    /**      * Convert string buffer on tos to string.      */    void bufferToString(int pos) {        callMethod(pos, syms.stringBufferType, names.toString, Type.emptyList, false);    }    /**      * Complete

⌨️ 快捷键说明

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