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

📄 codegen.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        if (op != NOP)            bytecode.addOpcode(op);        if (op == NOP || op == L2I || op == F2I || op == D2I)            if (op2 != NOP)                bytecode.addOpcode(op2);    }    public void atExpr(Expr expr) throws CompileError {        // array access, member access,        // (unary) +, (unary) -, ++, --, !, ~        int token = expr.getOperator();        ASTree oprand = expr.oprand1();        if (token == '.') {            String member = ((Symbol)expr.oprand2()).get();            if (member.equals("class"))                                atClassObject(expr);  // .class            else                atFieldRead(expr);        }        else if (token == MEMBER) {     // field read            /* MEMBER ('#') is an extension by Javassist.             * The compiler internally uses # for compiling .class             * expressions such as "int.class".             */            atFieldRead(expr);        }        else if (token == ARRAY)            atArrayRead(oprand, expr.oprand2());        else if (token == PLUSPLUS || token == MINUSMINUS)            atPlusPlus(token, oprand, expr, true);        else if (token == '!') {            booleanExpr(false, expr);            bytecode.addIndex(7);            bytecode.addIconst(1);            bytecode.addOpcode(Opcode.GOTO);            bytecode.addIndex(4);            bytecode.addIconst(0);        }        else if (token == CALL)         // method call            fatal();        else {            expr.oprand1().accept(this);            int type = typePrecedence(exprType);            if (arrayDim > 0)                badType(expr);            if (token == '-') {                if (type == P_DOUBLE)                    bytecode.addOpcode(DNEG);                else if (type == P_FLOAT)                    bytecode.addOpcode(FNEG);                else if (type == P_LONG)                    bytecode.addOpcode(LNEG);                else if (type == P_INT) {                    bytecode.addOpcode(INEG);                    exprType = INT;     // type may be BYTE, ...                }                else                    badType(expr);            }            else if (token == '~') {                if (type == P_INT) {                    bytecode.addIconst(-1);                    bytecode.addOpcode(IXOR);                    exprType = INT;     // type may be BYTE. ...                }                else if (type == P_LONG) {                    bytecode.addLconst(-1);                    bytecode.addOpcode(LXOR);                }                else                    badType(expr);            }            else if (token == '+') {                if (type == P_OTHER)                    badType(expr);                // do nothing. ignore.            }            else                fatal();        }    }    protected static void badType(Expr expr) throws CompileError {        throw new CompileError("invalid type for " + expr.getName());    }    public abstract void atCallExpr(CallExpr expr) throws CompileError;    protected abstract void atFieldRead(ASTree expr) throws CompileError;    public void atClassObject(Expr expr) throws CompileError {        ASTree op1 = expr.oprand1();        if (!(op1 instanceof Symbol))            throw new CompileError("fatal error: badly parsed .class expr");        String cname = ((Symbol)op1).get();        if (cname.startsWith("[")) {            int i = cname.indexOf("[L");            if (i >= 0) {                String name = cname.substring(i + 2, cname.length() - 1);                String name2 = resolveClassName(name);                if (!name.equals(name2)) {                    /* For example, to obtain String[].class,                     * "[Ljava.lang.String;" (not "[Ljava/lang/String"!)                     * must be passed to Class.forName().                     */                    name2 = MemberResolver.jvmToJavaName(name2);                    StringBuffer sbuf = new StringBuffer();                    while (i-- >= 0)                        sbuf.append('[');                    sbuf.append('L').append(name2).append(';');                    cname = sbuf.toString();                }            }        }        else {            cname = resolveClassName(MemberResolver.javaToJvmName(cname));            cname = MemberResolver.jvmToJavaName(cname);        }        int start = bytecode.currentPc();        bytecode.addLdc(cname);        bytecode.addInvokestatic("java.lang.Class", "forName",                                 "(Ljava/lang/String;)Ljava/lang/Class;");        int end = bytecode.currentPc();        bytecode.addOpcode(Opcode.GOTO);        int pc = bytecode.currentPc();        bytecode.addIndex(0);   // correct later        bytecode.addExceptionHandler(start, end, bytecode.currentPc(),                                     "java.lang.ClassNotFoundException");        /* -- the following code is for inlining a call to DotClass.fail().        int var = getMaxLocals();        incMaxLocals(1);        bytecode.growStack(1);        bytecode.addAstore(var);        bytecode.addNew("java.lang.NoClassDefFoundError");        bytecode.addOpcode(DUP);        bytecode.addAload(var);        bytecode.addInvokevirtual("java.lang.ClassNotFoundException",                                  "getMessage", "()Ljava/lang/String;");        bytecode.addInvokespecial("java.lang.NoClassDefFoundError", "<init>",                                  "(Ljava/lang/String;)V");        */        bytecode.growStack(1);        bytecode.addInvokestatic("javassist.runtime.DotClass", "fail",                                 "(Ljava/lang/ClassNotFoundException;)"                                 + "Ljava/lang/NoClassDefFoundError;");        bytecode.addOpcode(ATHROW);        bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);        exprType = CLASS;        arrayDim = 0;        className = "java/lang/Class";    }    public void atArrayRead(ASTree array, ASTree index)        throws CompileError    {        arrayAccess(array, index);        bytecode.addOpcode(getArrayReadOp(exprType, arrayDim));    }    protected void arrayAccess(ASTree array, ASTree index)        throws CompileError    {        array.accept(this);        int type = exprType;        int dim = arrayDim;        if (dim == 0)            throw new CompileError("bad array access");        String cname = className;        index.accept(this);        if (typePrecedence(exprType) != P_INT || arrayDim > 0)            throw new CompileError("bad array index");        exprType = type;        arrayDim = dim - 1;        className = cname;    }    protected static int getArrayReadOp(int type, int dim) {        if (dim > 0)            return AALOAD;        switch (type) {        case DOUBLE :            return DALOAD;        case FLOAT :            return FALOAD;        case LONG :            return LALOAD;        case INT :            return IALOAD;        case SHORT :            return SALOAD;        case CHAR :            return CALOAD;        case BYTE :        case BOOLEAN :            return BALOAD;        default :            return AALOAD;        }    }    protected static int getArrayWriteOp(int type, int dim) {        if (dim > 0)            return AASTORE;        switch (type) {        case DOUBLE :            return DASTORE;        case FLOAT :            return FASTORE;        case LONG :            return LASTORE;        case INT :            return IASTORE;        case SHORT :            return SASTORE;        case CHAR :            return CASTORE;        case BYTE :        case BOOLEAN :            return BASTORE;        default :            return AASTORE;        }    }    private void atPlusPlus(int token, ASTree oprand, Expr expr,                            boolean doDup) throws CompileError    {        boolean isPost = oprand == null;        // ++i or i++?        if (isPost)            oprand = expr.oprand2();        if (oprand instanceof Variable) {            Declarator d = ((Variable)oprand).getDeclarator();            int t = exprType = d.getType();            arrayDim = d.getArrayDim();            int var = getLocalVar(d);            if (arrayDim > 0)                badType(expr);            if (t == DOUBLE) {                bytecode.addDload(var);                if (doDup && isPost)                    bytecode.addOpcode(DUP2);                bytecode.addDconst(1.0);                bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB);                if (doDup && !isPost)                    bytecode.addOpcode(DUP2);                bytecode.addDstore(var);            }            else if (t == LONG) {                bytecode.addLload(var);                if (doDup && isPost)                    bytecode.addOpcode(DUP2);                bytecode.addLconst((long)1);                bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB);                if (doDup && !isPost)                    bytecode.addOpcode(DUP2);                bytecode.addLstore(var);            }            else if (t == FLOAT) {                bytecode.addFload(var);                if (doDup && isPost)                    bytecode.addOpcode(DUP);                bytecode.addFconst(1.0f);                bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB);                if (doDup && !isPost)                    bytecode.addOpcode(DUP);                bytecode.addFstore(var);            }            else if (t == BYTE || t == CHAR || t == SHORT || t == INT) {                if (doDup && isPost)                    bytecode.addIload(var);                bytecode.addOpcode(IINC);                bytecode.add(var);                bytecode.add(token == PLUSPLUS ? 1 : -1);                if (doDup && !isPost)                    bytecode.addIload(var);            }            else                badType(expr);        }        else {            if (oprand instanceof Expr) {                Expr e = (Expr)oprand;                if (e.getOperator() == ARRAY) {                    atArrayPlusPlus(token, isPost, e, doDup);                    return;                }            }            atFieldPlusPlus(token, isPost, oprand, expr, doDup);        }    }    public void atArrayPlusPlus(int token, boolean isPost,                        Expr expr, boolean doDup) throws CompileError    {        arrayAccess(expr.oprand1(), expr.oprand2());        int t = exprType;        int dim = arrayDim;        if (dim > 0)            badType(expr);        bytecode.addOpcode(DUP2);        bytecode.addOpcode(getArrayReadOp(t, arrayDim));        int dup_code = is2word(t, dim) ? DUP2_X2 : DUP_X2;        atPlusPlusCore(dup_code, doDup, token, isPost, expr);        bytecode.addOpcode(getArrayWriteOp(t, dim));    }    protected void atPlusPlusCore(int dup_code, boolean doDup,                                  int token, boolean isPost,                                  Expr expr) throws CompileError    {        int t = exprType;        if (doDup && isPost)            bytecode.addOpcode(dup_code);        if (t == INT || t == BYTE || t == CHAR || t == SHORT) {            bytecode.addIconst(1);            bytecode.addOpcode(token == PLUSPLUS ? IADD : ISUB);            exprType = INT;        }        else if (t == LONG) {            bytecode.addLconst((long)1);            bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB);        }        else if (t == FLOAT) {            bytecode.addFconst(1.0f);            bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB);        }        else if (t == DOUBLE) {            bytecode.addDconst(1.0);            bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB);        }        else            badType(expr);        if (doDup && !isPost)            bytecode.addOpcode(dup_code);    }    protected abstract void atFieldPlusPlus(int token, boolean isPost,                ASTree oprand, Expr expr, boolean doDup) throws CompileError;    public abstract void atMember(Member n) throws CompileError;    public void atVariable(Variable v) throws CompileError {        Declarator d = v.getDeclarator();        exprType = d.getType();        arrayDim = d.getArrayDim();        className = d.getClassName();        int var = getLocalVar(d);        if (arrayDim > 0)            bytecode.addAload(var);        else            switch (exprType) {            case CLASS :                bytecode.addAload(var);                break;            case LONG :                bytecode.addLload(var);                break;            case FLOAT :                bytecode.addFload(var);                break;            case DOUBLE :                bytecode.addDload(var);                break;            default :   // BOOLEAN, BYTE, CHAR, SHORT, INT                bytecode.addIload(var);                break;            }    }    public void atKeyword(Keyword k) throws CompileError {        arrayDim = 0;        int token = k.get();        switch (token) {        case TRUE :            bytecode.addIconst(1);            exprType = BOOLEAN;            break;        case FALSE :            bytecode.addIconst(0);            exprType = BOOLEAN;            break;        case NULL :            bytecode.addOpcode(ACONST_NULL);            exprType = NULL;            break;        case THIS :        case SUPER :            if (inStaticMethod)                throw new CompileError("not-available: "                                       + (token == THIS ? "this" : "super"));            bytecode.addAload(0);            exprType = CLASS;            if (token == THIS)                className = getThisName();            else                className = getSuperName();                         break;        default :            fatal();        }    }    public void atStringL(StringL s) throws CompileError {        exprType = CLASS;        arrayDim = 0;        className = jvmJavaLangString;        bytecode.addLdc(s.get());    }    public void atIntConst(IntConst i) throws CompileError {        arrayDim = 0;        long value = i.get();        int type = i.getType();        if (type == IntConstant || type == CharConstant) {            exprType = (type == IntConstant ? INT : CHAR);            bytecode.addIconst((int)value);        }        else {            exprType = LONG;            bytecode.addLconst(value);        }    }    public void atDoubleConst(DoubleConst d) throws CompileError {        arrayDim = 0;        if (d.getType() == DoubleConstant) {            exprType = DOUBLE;            bytecode.addDconst(d.get());        }        else {            exprType = FLOAT;            bytecode.addFconst((float)d.get());        }    }}

⌨️ 快捷键说明

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