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

📄 javac.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License.  Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist.compiler;import javassist.CtClass;import javassist.CtPrimitiveType;import javassist.CtMember;import javassist.CtField;import javassist.CtBehavior;import javassist.CtMethod;import javassist.CtConstructor;import javassist.CannotCompileException;import javassist.Modifier;import javassist.bytecode.Bytecode;import javassist.bytecode.CodeAttribute;import javassist.bytecode.LocalVariableAttribute;import javassist.bytecode.Opcode;import javassist.NotFoundException;import javassist.compiler.ast.*;public class Javac {    JvstCodeGen gen;    SymbolTable stable;    private Bytecode bytecode;    public static final String param0Name = "$0";    public static final String resultVarName = "$_";    public static final String proceedName = "$proceed";    /**     * Constructs a compiler.     *     * @param thisClass         the class that a compiled method/field     *                          belongs to.     */    public Javac(CtClass thisClass) {        this(new Bytecode(thisClass.getClassFile2().getConstPool(), 0, 0),             thisClass);    }    /**     * Constructs a compiler.     * The produced bytecode is stored in the <code>Bytecode</code> object     * specified by <code>b</code>.     *     * @param thisClass         the class that a compiled method/field     *                          belongs to.     */    public Javac(Bytecode b, CtClass thisClass) {        gen = new JvstCodeGen(b, thisClass, thisClass.getClassPool());        stable = new SymbolTable();        bytecode = b;    }    /**     * Returns the produced bytecode.     */    public Bytecode getBytecode() { return bytecode; }    /**     * Compiles a method, constructor, or field declaration     * to a class.     * A field declaration can declare only one field.     *     * <p>In a method or constructor body, $0, $1, ... and $_     * are not available.     *     * @return          a <code>CtMethod</code>, <code>CtConstructor</code>,     *                  or <code>CtField</code> object.     * @see #recordProceed(String,String)     */    public CtMember compile(String src) throws CompileError {        Parser p = new Parser(new Lex(src));        ASTList mem = p.parseMember1(stable);        try {            if (mem instanceof FieldDecl)                return compileField((FieldDecl)mem);            else                return compileMethod(p, (MethodDecl)mem);        }        catch (CannotCompileException e) {            throw new CompileError(e.getMessage());        }    }    public static class CtFieldWithInit extends CtField {        private ASTree init;        CtFieldWithInit(CtClass type, String name, CtClass declaring)            throws CannotCompileException        {            super(type, name, declaring);            init = null;        }        protected void setInit(ASTree i) { init = i; }        protected ASTree getInitAST() {            return init;        }    }    private CtField compileField(FieldDecl fd)        throws CompileError, CannotCompileException    {        CtFieldWithInit f;        Declarator d = fd.getDeclarator();        f = new CtFieldWithInit(gen.resolver.lookupClass(d),                                d.getVariable().get(), gen.getThisClass());        f.setModifiers(MemberResolver.getModifiers(fd.getModifiers()));        if (fd.getInit() != null)            f.setInit(fd.getInit());        return f;    }    private CtMember compileMethod(Parser p, MethodDecl md)        throws CompileError    {        int mod = MemberResolver.getModifiers(md.getModifiers());        CtClass[] plist = gen.makeParamList(md);        CtClass[] tlist = gen.makeThrowsList(md);        recordParams(plist, Modifier.isStatic(mod));        md = p.parseMethod2(stable, md);        try {            if (md.isConstructor()) {                CtConstructor cons = new CtConstructor(plist,                                                   gen.getThisClass());                cons.setModifiers(mod);                md.accept(gen);                cons.getMethodInfo().setCodeAttribute(                                        bytecode.toCodeAttribute());                cons.setExceptionTypes(tlist);                return cons;            }            else {                Declarator r = md.getReturn();                CtClass rtype = gen.resolver.lookupClass(r);                recordReturnType(rtype, false);                CtMethod method = new CtMethod(rtype, r.getVariable().get(),                                           plist, gen.getThisClass());                method.setModifiers(mod);                gen.setThisMethod(method);                md.accept(gen);                if (md.getBody() != null)                    method.getMethodInfo().setCodeAttribute(                                        bytecode.toCodeAttribute());                else                    method.setModifiers(mod | Modifier.ABSTRACT);                method.setExceptionTypes(tlist);                return method;            }        }        catch (NotFoundException e) {            throw new CompileError(e.toString());        }    }    /**     * Compiles a method (or constructor) body.     *     * @src	a single statement or a block.     *          If null, this method produces a body returning zero or null.     */    public Bytecode compileBody(CtBehavior method, String src)        throws CompileError    {        try {            int mod = method.getModifiers();            recordParams(method.getParameterTypes(), Modifier.isStatic(mod));            CtClass rtype;            if (method instanceof CtMethod) {                gen.setThisMethod((CtMethod)method);                rtype = ((CtMethod)method).getReturnType();            }            else                rtype = CtClass.voidType;            recordReturnType(rtype, false);            boolean isVoid = rtype == CtClass.voidType;            if (src == null)                makeDefaultBody(bytecode, rtype);            else {                Parser p = new Parser(new Lex(src));                SymbolTable stb = new SymbolTable(stable);                Stmnt s = p.parseStatement(stb);                if (p.hasMore())                    throw new CompileError(                        "the method/constructor body must be surrounded by {}");                boolean callSuper = false;                if (method instanceof CtConstructor)                    callSuper = !((CtConstructor)method).isClassInitializer();                gen.atMethodBody(s, callSuper, isVoid);            }            return bytecode;        }        catch (NotFoundException e) {            throw new CompileError(e.toString());        }    }    private static void makeDefaultBody(Bytecode b, CtClass type) {        int op;        int value;        if (type instanceof CtPrimitiveType) {            CtPrimitiveType pt = (CtPrimitiveType)type;            op = pt.getReturnOp();            if (op == Opcode.DRETURN)                value = Opcode.DCONST_0;            else if (op == Opcode.FRETURN)                value = Opcode.FCONST_0;            else if (op == Opcode.LRETURN)                value = Opcode.LCONST_0;            else if (op == Opcode.RETURN)                value = Opcode.NOP;            else                value = Opcode.ICONST_0;        }        else {            op = Opcode.ARETURN;            value = Opcode.ACONST_NULL;        }        if (value != Opcode.NOP)            b.addOpcode(value);        b.addOpcode(op);    }    /**     * Records local variables available at the specified program counter.     * If the LocalVariableAttribute is not available, this method does not     * record any local variable.  It only returns false.     *     * @param pc    program counter (&gt;= 0)     * @return false if the CodeAttribute does not include a     *              LocalVariableAttribute.     */    public boolean recordLocalVariables(CodeAttribute ca, int pc)        throws CompileError    {        LocalVariableAttribute va            = (LocalVariableAttribute)              ca.getAttribute(LocalVariableAttribute.tag);        if (va == null)            return false;        int n = va.tableLength();        for (int i = 0; i < n; ++i) {            int start = va.startPc(i);            int len = va.codeLength(i);            if (start <= pc && pc < start + len)                gen.recordVariable(va.descriptor(i), va.variableName(i),                                   va.index(i), stable);        }        return true;    }    /**     * Records parameter names if the LocalVariableAttribute is available.     * It returns false unless the LocalVariableAttribute is available.     *     * @param numOfLocalVars    the number of local variables used     *                          for storing the parameters.     * @return false if the CodeAttribute does not include a     *              LocalVariableAttribute.     */    public boolean recordParamNames(CodeAttribute ca, int numOfLocalVars)        throws CompileError    {        LocalVariableAttribute va            = (LocalVariableAttribute)              ca.getAttribute(LocalVariableAttribute.tag);        if (va == null)            return false;        int n = va.tableLength();        for (int i = 0; i < n; ++i) {            int index = va.index(i);

⌨️ 快捷键说明

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