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

📄 classwriter.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.jvm;import java.io.*;import java.util.*;import java.util.Set;import java.util.HashSet;import javax.tools.JavaFileManager;import javax.tools.FileObject;import javax.tools.JavaFileObject;import com.sun.tools.javac.code.*;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.code.Type.*;import com.sun.tools.javac.util.*;import com.sun.tools.javac.util.List;import static com.sun.tools.javac.code.BoundKind.*;import static com.sun.tools.javac.code.Flags.*;import static com.sun.tools.javac.code.Kinds.*;import static com.sun.tools.javac.code.TypeTags.*;import static com.sun.tools.javac.jvm.UninitializedType.*;import static javax.tools.StandardLocation.CLASS_OUTPUT;/** This class provides operations to map an internal symbol table graph *  rooted in a ClassSymbol into a classfile. * *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If *  you write code that depends on this, you do so at your own risk. *  This code and its internal interfaces are subject to change or *  deletion without notice.</b> */public class ClassWriter extends ClassFile {    protected static final Context.Key<ClassWriter> classWriterKey =        new Context.Key<ClassWriter>();    private final Symtab syms;    private final Options options;    /** 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;    /** Switch: describe the generated stackmap     */    boolean debugstackmap;    /**     * Target class version.     */    private Target target;    /**     * Source language version.     */    private Source source;    /** Type utilities. */    private Types types;    /** The initial sizes of the data and constant pool buffers.     *  sizes are increased when buffers get full.     */    static final int DATA_BUF_SIZE = 0x0fff0;    static final int POOL_BUF_SIZE = 0x1fff0;    /** 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<ClassSymbol> innerClasses;    /** The inner classes to be written, as a queue where     *  enclosing classes come first.     */    ListBuffer<ClassSymbol> innerClassesQueue;    /** The log to use for verbose output.     */    private final Log log;    /** The name table. */    private final Name.Table names;    /** Access to files. */    private final JavaFileManager fileManager;        /** The tags and constants used in compressed stackmap. */    static final int SAME_FRAME_SIZE = 64;    static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247;    static final int SAME_FRAME_EXTENDED = 251;    static final int FULL_FRAME = 255;    static final int MAX_LOCAL_LENGTH_DIFF = 4;    /** Get the ClassWriter instance for this context. */    public static ClassWriter instance(Context context) {        ClassWriter instance = context.get(classWriterKey);        if (instance == null)            instance = new ClassWriter(context);        return instance;    }    /** Construct a class writer, given an options table.     */    private ClassWriter(Context context) {        context.put(classWriterKey, this);        log = Log.instance(context);        names = Name.Table.instance(context);        syms = Symtab.instance(context);        options = Options.instance(context);        target = Target.instance(context);        source = Source.instance(context);        types = Types.instance(context);        fileManager = context.get(JavaFileManager.class);        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;        debugstackmap  = options.get("debugstackmap") != null;        emitSourceFile = options.get("-g:")==null || options.get("-g:source")!=null;        String dumpModFlags = 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);    }/****************************************************************** * Diagnostics: dump generated class names and modifiers ******************************************************************/    /** 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; // -XDdumpmodifiers=c    private final boolean dumpFieldModifiers; // -XDdumpmodifiers=f    private final boolean dumpInnerClassModifiers; // -XDdumpmodifiers=i    private final boolean dumpMethodModifiers; // -XDdumpmodifiers=m    /** 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();    }    //where        private final static String[] flagName = {            "PUBLIC", "PRIVATE", "PROTECTED", "STATIC", "FINAL",            "SUPER", "VOLATILE", "TRANSIENT", "NATIVE", "INTERFACE",            "ABSTRACT", "STRICTFP"};/****************************************************************** * Output routines ******************************************************************/    /** 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) & 0xFF);        buf.elems[op+1] = (byte)((x      ) & 0xFF);    }    /** 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) & 0xFF);        buf.elems[adr+1] = (byte)((x >> 16) & 0xFF);        buf.elems[adr+2] = (byte)((x >>  8) & 0xFF);        buf.elems[adr+3] = (byte)((x      ) & 0xFF);    }/****************************************************************** * Signature Generation ******************************************************************/    /** 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:            sigbuf.appendByte('L');            assembleClassSig(type);            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);            if (hasTypeVar(mt.thrown)) {                for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {                    sigbuf.appendByte('^');                    assembleSig(l.head);                }            }            break;        case WILDCARD: {            WildcardType ta = (WildcardType) type;            switch (ta.kind) {            case SUPER:                sigbuf.appendByte('-');                assembleSig(ta.type);                break;            case EXTENDS:                sigbuf.appendByte('+');                assembleSig(ta.type);                break;            case UNBOUND:                sigbuf.appendByte('*');                break;            default:                throw new AssertionError(ta.kind);            }            break;        }        case TYPEVAR:            sigbuf.appendByte('T');            sigbuf.appendName(type.tsym.name);            sigbuf.appendByte(';');            break;        case FORALL:            ForAll ft = (ForAll)type;            assembleParamsSig(ft.tvars);            assembleSig(ft.qtype);            break;        case UNINITIALIZED_THIS:        case UNINITIALIZED_OBJECT:            // we don't yet have a spec for uninitialized types in the            // local variable table            assembleSig(types.erasure(((UninitializedType)type).qtype));            break;        default:            throw new AssertionError("typeSig " + type.tag);        }    }    boolean hasTypeVar(List<Type> l) {        while (l.nonEmpty()) {            if (l.head.tag == TypeTags.TYPEVAR) return true;            l = l.tail;        }        return false;    }    void assembleClassSig(Type type) {        ClassType ct = (ClassType)type;        ClassSymbol c = (ClassSymbol)ct.tsym;        enterInner(c);        Type outer = ct.getEnclosingType();        if (outer.allparams().nonEmpty()) {            boolean rawOuter =                c.owner.kind == MTH || // either a local class                c.name == names.empty; // or anonymous            assembleClassSig(rawOuter                             ? types.erasure(outer)                             : outer);            sigbuf.appendByte('.');            assert c.flatname.startsWith(c.owner.enclClass().flatname);            sigbuf.appendName(rawOuter                              ? c.flatname.subName(c.owner.enclClass()                                                   .flatname.len+1,                                                   c.flatname.len)                              : c.name);        } else {            sigbuf.appendBytes(externalize(c.flatname));        }        if (ct.getTypeArguments().nonEmpty()) {            sigbuf.appendByte('<');            assembleSig(ct.getTypeArguments());            sigbuf.appendByte('>');        }    }    void assembleSig(List<Type> types) {        for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail)            assembleSig(ts.head);    }    void assembleParamsSig(List<Type> typarams) {        sigbuf.appendByte('<');        for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) {            TypeVar tvar = (TypeVar)ts.head;            sigbuf.appendName(tvar.tsym.name);            List<Type> bounds = types.getBounds(tvar);            if ((bounds.head.tsym.flags() & INTERFACE) != 0) {                sigbuf.appendByte(':');            }

⌨️ 快捷键说明

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