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

📄 jvstcodegen.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            else {                a.accept(this);                types[i] = exprType;                dims[i] = arrayDim;                cnames[i] = className;                ++i;            }            args = args.tail();        }    }    /*    public void atMethodArgs(ASTList args, int[] types, int[] dims,                                String[] cnames) throws CompileError {        if (!isParamListName(args)) {            super.atMethodArgs(args, types, dims, cnames);            return;        }        CtClass[] params = paramTypeList;        if (params == null)            return;        int n = params.length;        int regno = indexOfParam1();        for (int i = 0; i < n; ++i) {            CtClass p = params[i];            regno += bytecode.addLoad(regno, p);            setType(p);            types[i] = exprType;            dims[i] = arrayDim;            cnames[i] = className;        }    }    */    /* called by Javac#recordSpecialProceed().     */    void compileInvokeSpecial(ASTree target, String classname,                              String methodname, String descriptor,                              ASTList args)        throws CompileError    {        target.accept(this);        int nargs = getMethodArgsLength(args);        atMethodArgs(args, new int[nargs], new int[nargs],                     new String[nargs]);        bytecode.addInvokespecial(classname, methodname, descriptor);        setReturnType(descriptor, false, false);        addNullIfVoid();    }    /*     * Makes it valid to write "return <expr>;" for a void method.     */    protected void atReturnStmnt(Stmnt st) throws CompileError {        ASTree result = st.getLeft();        if (result != null && returnType == CtClass.voidType) {            compileExpr(result);            if (is2word(exprType, arrayDim))                bytecode.addOpcode(POP2);            else if (exprType != VOID)                bytecode.addOpcode(POP);            result = null;        }        atReturnStmnt2(result);    }    /**     * Makes a cast to the return type ($r) available.     * It also enables $_.     *     * <p>If the return type is void, ($r) does nothing.     * The type of $_ is java.lang.Object.     *     * @param resultName        null if $_ is not used.     * @return          -1 or the variable index assigned to $_.     */    public int recordReturnType(CtClass type, String castName,                 String resultName, SymbolTable tbl) throws CompileError    {        returnType = type;        returnCastName = castName;        returnVarName = resultName;        if (resultName == null)            return -1;        else {            int varNo = getMaxLocals();            int locals = varNo + recordVar(type, resultName, varNo, tbl);            setMaxLocals(locals);            return varNo;        }    }    /**     * Makes $type available.     */    public void recordType(CtClass t) {        dollarType = t;    }    /**     * Makes method parameters $0, $1, ..., $args, $$, and $class available.     * $0 is equivalent to THIS if the method is not static.  Otherwise,     * if the method is static, then $0 is not available.     */    public int recordParams(CtClass[] params, boolean isStatic,                             String prefix, String paramVarName,                             String paramsName, SymbolTable tbl)        throws CompileError    {        return recordParams(params, isStatic, prefix, paramVarName,                            paramsName, !isStatic, 0, getThisName(), tbl);    }    /**     * Makes method parameters $0, $1, ..., $args, $$, and $class available.     * $0 is available only if use0 is true.  It might not be equivalent     * to THIS.     *     * @param params    the parameter types (the types of $1, $2, ..)     * @param prefix    it must be "$" (the first letter of $0, $1, ...)     * @param paramVarName      it must be "$args"     * @param paramsName        it must be "$$"     * @param use0      true if $0 is used.     * @param paramBase the register number of $0 (use0 is true)     *                          or $1 (otherwise).     * @param target    the class of $0.  If use0 is false, target     *                  can be null.  The value of "target" is also used     *                  as the name of the type represented by $class.     * @param isStatic  true if the method in which the compiled bytecode     *                  is embedded is static.     */    public int recordParams(CtClass[] params, boolean isStatic,                            String prefix, String paramVarName,                            String paramsName, boolean use0,                            int paramBase, String target,                            SymbolTable tbl)        throws CompileError    {        int varNo;        paramTypeList = params;        paramArrayName = paramVarName;        paramListName = paramsName;        paramVarBase = paramBase;        useParam0 = use0;        if (target != null)            param0Type = MemberResolver.jvmToJavaName(target);        inStaticMethod = isStatic;        varNo = paramBase;        if (use0) {            String varName = prefix + "0";            Declarator decl                = new Declarator(CLASS, MemberResolver.javaToJvmName(target),                                 0, varNo++, new Symbol(varName));            tbl.append(varName, decl);        }        for (int i = 0; i < params.length; ++i)            varNo += recordVar(params[i], prefix + (i + 1), varNo, tbl);        if (getMaxLocals() < varNo)            setMaxLocals(varNo);        return varNo;    }    /**     * Makes the given variable name available.     *     * @param type      variable type     * @param varName   variable name     */    public int recordVariable(CtClass type, String varName, SymbolTable tbl)        throws CompileError    {        if (varName == null)            return -1;        else {            int varNo = getMaxLocals();            int locals = varNo + recordVar(type, varName, varNo, tbl);            setMaxLocals(locals);            return varNo;        }    }    private int recordVar(CtClass cc, String varName, int varNo,                          SymbolTable tbl) throws CompileError    {        if (cc == CtClass.voidType) {            exprType = CLASS;            arrayDim = 0;            className = jvmJavaLangObject;        }        else            setType(cc);        Declarator decl            = new Declarator(exprType, className, arrayDim,                             varNo, new Symbol(varName));        tbl.append(varName, decl);        return is2word(exprType, arrayDim) ? 2 : 1;    }    /**     * Makes the given variable name available.     *     * @param typeDesc  the type descriptor of the variable     * @param varName   variable name     * @param varNo     an index into the local variable array     */    public void recordVariable(String typeDesc, String varName, int varNo,                               SymbolTable tbl) throws CompileError    {        char c;        int dim = 0;        while ((c = typeDesc.charAt(dim)) == '[')            ++dim;        int type = MemberResolver.descToType(c);        String cname = null;        if (type == CLASS) {            if (dim == 0)                cname = typeDesc.substring(1, typeDesc.length() - 1);            else                cname = typeDesc.substring(dim + 1, typeDesc.length() - 1);        }        Declarator decl            = new Declarator(type, cname, dim, varNo, new Symbol(varName));        tbl.append(varName, decl);    }    /* compileParameterList() returns the stack size used     * by the produced code.     *     * This method correctly computes the max_stack value.     *     * @param regno     the index of the local variable in which     *                  the first argument is received.     *                  (0: static method, 1: regular method.)     */    public static int compileParameterList(Bytecode code,                                CtClass[] params, int regno) {        if (params == null) {            code.addIconst(0);                          // iconst_0            code.addAnewarray(javaLangObject);          // anewarray Object            return 1;        }        else {            CtClass[] args = new CtClass[1];            int n = params.length;            code.addIconst(n);                          // iconst_<n>            code.addAnewarray(javaLangObject);          // anewarray Object            for (int i = 0; i < n; ++i) {                code.addOpcode(Bytecode.DUP);           // dup                code.addIconst(i);                      // iconst_<i>                if (params[i].isPrimitive()) {                    CtPrimitiveType pt = (CtPrimitiveType)params[i];                    String wrapper = pt.getWrapperName();                    code.addNew(wrapper);               // new <wrapper>                    code.addOpcode(Bytecode.DUP);       // dup                    int s = code.addLoad(regno, pt);    // ?load <regno>                    regno += s;                    args[0] = pt;                    code.addInvokespecial(wrapper, "<init>",                                Descriptor.ofMethod(CtClass.voidType, args));                                                        // invokespecial                }                else {                    code.addAload(regno);               // aload <regno>                    ++regno;                }                code.addOpcode(Bytecode.AASTORE);       // aastore            }            return 8;        }    }    protected void compileUnwrapValue(CtClass type, Bytecode code)        throws CompileError    {        if (type == CtClass.voidType) {            addNullIfVoid();            return;        }        if (exprType == VOID)            throw new CompileError("invalid type for " + returnCastName);        if (type instanceof CtPrimitiveType) {            CtPrimitiveType pt = (CtPrimitiveType)type;            // pt is not voidType.            String wrapper = pt.getWrapperName();            code.addCheckcast(wrapper);            code.addInvokevirtual(wrapper, pt.getGetMethodName(),                                  pt.getGetMethodDescriptor());            setType(type);        }        else {            code.addCheckcast(type);            setType(type);        }    }    /* Sets exprType, arrayDim, and className;     * If type is void, then this method does nothing.     */    public void setType(CtClass type) throws CompileError {        setType(type, 0);    }    private void setType(CtClass type, int dim) throws CompileError {        if (type.isPrimitive()) {            CtPrimitiveType pt = (CtPrimitiveType)type;            exprType = MemberResolver.descToType(pt.getDescriptor());            arrayDim = dim;            className = null;        }        else if (type.isArray())            try {                setType(type.getComponentType(), dim + 1);            }            catch (NotFoundException e) {                throw new CompileError("undefined type: " + type.getName());            }        else {            exprType = CLASS;            arrayDim = dim;            className = MemberResolver.javaToJvmName(type.getName());        }    }    /* Performs implicit coercion from exprType to type.     */    public void doNumCast(CtClass type) throws CompileError {        if (arrayDim == 0 && !isRefType(exprType))            if (type instanceof CtPrimitiveType) {                CtPrimitiveType pt = (CtPrimitiveType)type;                atNumCastExpr(exprType,                              MemberResolver.descToType(pt.getDescriptor()));            }            else                throw new CompileError("type mismatch");    }}

⌨️ 快捷键说明

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