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

📄 classwriter.java

📁 这是实现Javac功能的GJC的最新源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/** * @(#)ClassWriter.java	1.48 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.tools.javac.v8.code;import com.sun.tools.javac.v8.util.*;import java.io.*;import com.sun.tools.javac.v8.code.Symbol.*;import com.sun.tools.javac.v8.code.Type.*;/** * This class provides operations to map an internal symbol table graph *  rooted in a ClassSymbol into a classfile. */public class ClassWriter extends ClassFile implements Flags, Kinds, TypeTags {    private static final Context.Key classWriterKey = new Context.Key();    private final Symtab syms;    /**     * Can be reassigned from outside: the output directory.     *  If outDir = null, files are written into same directory as the sources     *  the were generated from.     */    public File outDir = null;    /**     * Switch: verbose output.     */    private boolean verbose;    /**     * Switch: scrable private names.     */    private boolean scramble;    /**     * Switch: scrable private names.     */    private boolean scrambleAll;    /**     * Switch: retrofit mode.     */    private boolean retrofit;    /**     * Switch: emit source file attribute.     */    private boolean emitSourceFile;    /**     * Switch: generate CharacterRangeTable attribute.     */    private boolean genCrt;    /**     * Target class version.     */    private Target target;    /**     * The initial sizes of the data and constant pool buffers.     *  sizes are increased when buffers get full.     */    static final int DATA_BUF_SIZE = 65520;    static final int POOL_BUF_SIZE = 131056;    /**     * An output buffer for member info.     */    ByteBuffer databuf = new ByteBuffer(DATA_BUF_SIZE);    /**     * An output buffer for the constant pool.     */    ByteBuffer poolbuf = new ByteBuffer(POOL_BUF_SIZE);    /**     * An output buffer for type signatures.     */    ByteBuffer sigbuf = new ByteBuffer();    /**     * The constant pool.     */    Pool pool;    /**     * The inner classes to be written, as a set.     */    Set innerClasses;    /**     * The inner classes to be written, as a queue where     *  enclosing classes come first.     */    ListBuffer innerClassesQueue;    /**     * The log to use for verbose output.     */    private final Log log;    /**     * The name table.     */    private final Name.Table names;    /**     * Get the ClassWriter instance for this context.     */    public static ClassWriter instance(Context context) {        ClassWriter instance = (ClassWriter) context.get(classWriterKey);        if (instance == null)            instance = new ClassWriter(context);        return instance;    }    /**      * Construct a class writer, given an options table.      */    private ClassWriter(Context context) {        super();        context.put(classWriterKey, this);        log = Log.instance(context);        names = Name.Table.instance(context);        syms = Symtab.instance(context);        Options options = Options.instance(context);        target = Target.instance(context);        verbose = options.get("-verbose") != null;        scramble = options.get("-scramble") != null;        scrambleAll = options.get("-scrambleAll") != null;        retrofit = options.get("-retrofit") != null;        genCrt = options.get("-Xjcov") != null;        emitSourceFile =                options.get("-g:") == null || options.get("-g:source") != null;        String od = (String) options.get("-d");        if (od != null)            outDir = new File(od);        String dumpModFlags = (String) options.get("dumpmodifiers");        dumpClassModifiers =                (dumpModFlags != null && dumpModFlags.indexOf('c') != -1);        dumpFieldModifiers =                (dumpModFlags != null && dumpModFlags.indexOf('f') != -1);        dumpInnerClassModifiers =                (dumpModFlags != null && dumpModFlags.indexOf('i') != -1);        dumpMethodModifiers =                (dumpModFlags != null && dumpModFlags.indexOf('m') != -1);    }    /**      * Value of option 'dumpmodifiers' is a string      *  indicating which modifiers should be dumped for debugging:      *    'c' -- classes      *    'f' -- fields      *    'i' -- innerclass attributes      *    'm' -- methods      *  For example, to dump everything:      *    javac -XDdumpmodifiers=cifm MyProg.java      */    private final boolean dumpClassModifiers;    private final boolean dumpFieldModifiers;    private final boolean dumpInnerClassModifiers;    private final boolean dumpMethodModifiers;    /**     * Return flags as a string, separated by " ".     */    public static String flagNames(long flags) {        StringBuffer sbuf = new StringBuffer();        int i = 0;        long f = flags & StandardFlags;        while (f != 0) {            if ((f & 1) != 0)                sbuf.append(" " + flagName[i]);            f = f >> 1;            i++;        }        return sbuf.toString();    }    private static final String[] flagName = {"PUBLIC", "PRIVATE", "PROTECTED", "STATIC",    "FINAL", "SUPER", "VOLATILE", "TRANSIENT", "NATIVE", "INTERFACE", "ABSTRACT",    "STRICTFP"};    /**     * Write a character into given byte buffer;     *  byte buffer will not be grown.     */    void putChar(ByteBuffer buf, int op, int x) {        buf.elems[op] = (byte)((x >> 8) & 255);        buf.elems[op + 1] = (byte)((x) & 255);    }    /**      * Write an integer into given byte buffer;      *  byte buffer will not be grown.      */    void putInt(ByteBuffer buf, int adr, int x) {        buf.elems[adr] = (byte)((x >> 24) & 255);        buf.elems[adr + 1] = (byte)((x >> 16) & 255);        buf.elems[adr + 2] = (byte)((x >> 8) & 255);        buf.elems[adr + 3] = (byte)((x) & 255);    }    /**      * Assemble signature of given type in string buffer.      */    void assembleSig(Type type) {        switch (type.tag) {        case BYTE:            sigbuf.appendByte('B');            break;        case SHORT:            sigbuf.appendByte('S');            break;        case CHAR:            sigbuf.appendByte('C');            break;        case INT:            sigbuf.appendByte('I');            break;        case LONG:            sigbuf.appendByte('J');            break;        case FLOAT:            sigbuf.appendByte('F');            break;        case DOUBLE:            sigbuf.appendByte('D');            break;        case BOOLEAN:            sigbuf.appendByte('Z');            break;        case VOID:            sigbuf.appendByte('V');            break;        case CLASS:            ClassType ct = (ClassType) type;            ClassSymbol c = (ClassSymbol) ct.tsym;            enterInner(c);            if (ct.outer().allparams().nonEmpty()) {                assembleSig(ct.outer());                sigbuf.appendByte('.');            }            sigbuf.appendByte('L');            sigbuf.appendBytes(externalize(c.flatname));            sigbuf.appendByte(';');            break;        case ARRAY:            ArrayType at = (ArrayType) type;            sigbuf.appendByte('[');            assembleSig(at.elemtype);            break;        case METHOD:            MethodType mt = (MethodType) type;            sigbuf.appendByte('(');            assembleSig(mt.argtypes);            sigbuf.appendByte(')');            assembleSig(mt.restype);            break;        default:            assert false :            "typeSig" + type.tag;        }    }    void assembleSig(List types) {        for (List ts = types; ts.nonEmpty(); ts = ts.tail)            assembleSig((Type) ts.head);    }    /**      * Return signature of given type      */    Name typeSig(Type type) {        assert sigbuf.length == 0;        assembleSig(type);        Name n = sigbuf.toName(names);        sigbuf.reset();        return n;    }    /**      * Given a type t, return the extended class name of its erasure in      *  external representation.      */    public Name xClassName(Type t) {        if (t.tag == CLASS) {            return names.fromUtf(externalize(t.tsym.flatName()));        } else if (t.tag == ARRAY) {            return typeSig(t.erasure());        } else {            throw new AssertionError("xClassName");        }    }    /**      * Thrown when the constant pool is over full.      */    public static class PoolOverflow extends Exception {        public PoolOverflow() {            super();        }    }    public static class StringOverflow extends Exception {        public final String value;        public StringOverflow(String s) {            super();            value = s;        }    }    /**      * Write constant pool to pool buffer.      *  Note: during writing, constant pool      *  might grow since some parts of constants still need to be entered.      */    void writePool(Pool pool) throws PoolOverflow, StringOverflow {        int poolCountIdx = poolbuf.length;        poolbuf.appendChar(0);        int i = 1;        while (i < pool.pp) {            Object value = pool.pool[i];            assert value != null;            if (value instanceof Pool.Method)                value = ((Pool.Method) value).m;            else if (value instanceof Pool.Variable)                value = ((Pool.Variable) value).v;            if (value instanceof MethodSymbol) {                MethodSymbol m = (MethodSymbol) value;                poolbuf.appendByte((m.owner.flags() & INTERFACE) != 0 ?                        CONSTANT_InterfaceMethodref : CONSTANT_Methodref);                poolbuf.appendChar(pool.put(m.owner));                poolbuf.appendChar(pool.put(nameType(m)));            } else if (value instanceof VarSymbol) {                VarSymbol v = (VarSymbol) value;                poolbuf.appendByte(CONSTANT_Fieldref);                poolbuf.appendChar(pool.put(v.owner));                poolbuf.appendChar(pool.put(nameType(v)));            } else if (value instanceof Name) {                poolbuf.appendByte(CONSTANT_Utf8);                byte[] bs = ((Name) value).toUtf();                poolbuf.appendChar(bs.length);                poolbuf.appendBytes(bs, 0, bs.length);                if (bs.length > Pool.MAX_STRING_LENGTH)                    throw new StringOverflow(value.toString());            } else if (value instanceof ClassSymbol) {                ClassSymbol c = (ClassSymbol) value;                if (c.owner.kind == TYP)                    pool.put(c.owner);                poolbuf.appendByte(CONSTANT_Class);                if (c.type.tag == ARRAY) {                    poolbuf.appendChar(pool.put(typeSig(c.type)));                } else {                    poolbuf.appendChar(                            pool.put(names.fromUtf(externalize(c.flatname))));                    enterInner(c);                }            } else if (value instanceof NameAndType) {                NameAndType nt = (NameAndType) value;                poolbuf.appendByte(CONSTANT_NameandType);                poolbuf.appendChar(pool.put(nt.name));                poolbuf.appendChar(pool.put(typeSig(nt.type)));            } else if (value instanceof Integer) {                poolbuf.appendByte(CONSTANT_Integer);                poolbuf.appendInt(((Integer) value).intValue());            } else if (value instanceof Long) {                poolbuf.appendByte(CONSTANT_Long);                poolbuf.appendLong(((Long) value).longValue());                i++;            } else if (value instanceof Float) {                poolbuf.appendByte(CONSTANT_Float);                poolbuf.appendFloat(((Float) value).floatValue());            } else if (value instanceof Double) {                poolbuf.appendByte(CONSTANT_Double);                poolbuf.appendDouble(((Double) value).doubleValue());                i++;            } else if (value instanceof String) {                poolbuf.appendByte(CONSTANT_String);                poolbuf.appendChar(pool.put(names.fromString((String) value)));            } else if (value instanceof Type) {                poolbuf.appendByte(CONSTANT_Class);                poolbuf.appendChar(pool.put(xClassName((Type) value)));            } else {                assert false :                "writePool " + value;            }            i++;        }        if (pool.pp > Pool.MAX_ENTRIES)            throw new PoolOverflow();        putChar(poolbuf, poolCountIdx, pool.pp);    }    /**      * Given a field, return its name.      */    Name fieldName(Symbol sym) {        if (scramble && (sym.flags() & PRIVATE) != 0 || scrambleAll &&                (sym.flags() & (PROTECTED | PUBLIC)) == 0)            return names.fromString("_$" + sym.name.index);        else

⌨️ 快捷键说明

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