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

📄 gen.java

📁 GJC编译器的源代码。是一个开放源代码的工业级编译器。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            }

            public void visitBinary(Binary tree) {
                complexity += 1;
                if (tree.type.constValue == null)
                    super.visitBinary(tree);
            }

            public void visitTypeTest(TypeTest tree) {
                super.visitTypeTest(tree);
                complexity += 1;
            }

            public void visitIndexed(Indexed tree) {
                super.visitIndexed(tree);
                complexity += 1;
            }

            public void visitSelect(Select tree) {
                super.visitSelect(tree);
                if (tree.sym.kind == VAR)
                    complexity += 1;
            }

            public void visitIdent(Ident tree) {
                if (tree.sym.kind == VAR) {
                    complexity += 1;
                    if (tree.type.constValue == null && tree.sym.owner.kind == TYP)
                        complexity += 1;
                }
            }

            public void visitLiteral(Literal tree) {
                complexity += 1;
            }

            public void visitTree(Tree tree) {
            }
        }
        ComplexityScanner scanner = new ComplexityScanner();
        tree.accept(scanner);
        return scanner.complexity;
    }

    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),

⌨️ 快捷键说明

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