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

📄 gen.java

📁 GJC(Generic Java Compiler)编译器
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/** * @(#)Gen.java	1.97 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.comp;import java.io.IOException;import com.sun.tools.javac.v8.util.*;import com.sun.tools.javac.v8.code.*;import com.sun.tools.javac.v8.tree.*;import com.sun.tools.javac.v8.code.Symbol.*;import com.sun.tools.javac.v8.code.Type.*;import com.sun.tools.javac.v8.code.Code.*;import com.sun.tools.javac.v8.tree.Tree.*;import com.sun.tools.javac.v8.comp.Items.*;/** * This pass maps flat Java (i.e. without inner classes) to bytecodes. */public class Gen extends Tree.Visitor implements Flags, Kinds, TypeTags,ByteCodes, CRTFlags {    private static final Context.Key genKey = new Context.Key();    private final Log log;    private final Symtab syms;    private final Check chk;    private final Resolve rs;    private final TreeMaker make;    private final ClassWriter writer;    private final Name.Table names;    private final Target target;    private final boolean generateIproxies;    /**     * A type that serves as the expected type for all method expressions.     */    private final Type methodType;    public static Gen instance(Context context) {        Gen instance = (Gen) context.get(genKey);        if (instance == null)            instance = new Gen(context);        return instance;    }    private Gen(Context context) {        super();        context.put(genKey, this);        names = Name.Table.instance(context);        log = Log.instance(context);        syms = Symtab.instance(context);        chk = Check.instance(context);        rs = Resolve.instance(context);        make = TreeMaker.instance(context);        writer = ClassWriter.instance(context);        target = Target.instance(context);        methodType = new MethodType(null, null, null, syms.methodClass);        Options options = Options.instance(context);        lineDebugInfo = options.get("-g:") == null || options.get("-g:lines") != null;        varDebugInfo = options.get("-g:") == null ? options.get("-g") != null :                options.get("-g:vars") != null;        genCrt = options.get("-Xjcov") != null;        generateIproxies = target.requiresIproxy() || options.get("miranda") != null;        int setjsrlimit = 10;        String jsrlimitString = (String) options.get("jsrlimit");        if (jsrlimitString != null) {            try {                setjsrlimit = Integer.parseInt(jsrlimitString);            } catch (NumberFormatException ex) {            }        }        this.jsrlimit = setjsrlimit;    }    /**      * Switches      */    private final boolean lineDebugInfo;    private final boolean varDebugInfo;    private final boolean genCrt;    /**     * Default limit of (approximate) size of finalizer to inline.     *  Zero means always use jsr.  100 or greater means never use     *  jsr.     */    private final int jsrlimit;    private Pool pool = new Pool();    /**     * Code buffer, set by genMethod.     */    private Code code;    /**     * Items structure, set by genMethod.     */    private Items items;    /**     * Environment for symbol lookup, set by genClass     */    private Env attrEnv;    /**     * The top level tree.     */    private TopLevel toplevel;    /**     * The number of code-gen errors in this class.     */    private int nerrs = 0;    /**     * A hash table mapping syntax trees to their ending source positions.     */    private Hashtable endPositions;    /**     * Generate code to load an integer constant.     *  @param n     The integer to be loaded.     */    void loadIntConst(int n) {        items.makeImmediateItem(syms.intType, new Integer(n)).load();    }    /**      * The opcode that loads a zero constant of a given type code.      *  @param tc   The given type code (@see ByteCode).      */    public static int zero(int tc) {        switch (tc) {        case INTcode:        case BYTEcode:        case SHORTcode:        case CHARcode:            return iconst_0;        case LONGcode:            return lconst_0;        case FLOATcode:            return fconst_0;        case DOUBLEcode:            return dconst_0;        default:            throw new AssertionError("zero");        }    }    /**      * The opcode that loads a one constant of a given type code.      *  @param tc   The given type code (@see ByteCode).      */    public static int one(int tc) {        return zero(tc) + 1;    }    /**      * Generate code to load -1 of the given type code (either int or long).      *  @param tc   The given type code (@see ByteCode).      */    void emitMinusOne(int tc) {        if (tc == LONGcode) {            items.makeImmediateItem(syms.longType, new Long(-1)).load();        } else {            code.emitop(iconst_m1);        }    }    /**      * Construct a symbol to reflect the qualifying type that should      *  appear in the byte code as per JLS 13.1.      *      *  For target >= 1.2: Clone a method with the qualifier as owner (except      *  for those cases where we need to work around VM bugs).      *      *  For target <= 1.1: If qualified variable or method is defined in a      *  non-accessible class, clone it with the qualifier class as owner.      *      *  @param sym    The accessed symbol      *  @param site   The qualifier's type.      */    Symbol binaryQualifier(Symbol sym, Type site) {        if (site.tag == ARRAY) {            if (sym == syms.lengthVar || sym.owner != syms.arrayClass)                return sym;            Symbol qualifier = target.arrayBinaryCompatibility() ?                    new ClassSymbol(Flags.PUBLIC, site.tsym.name, site,                    syms.noSymbol) : syms.objectType.tsym;            return sym.clone(qualifier);        }        if (sym.owner == site.tsym ||                (sym.flags() & (STATIC | SYNTHETIC)) == (STATIC | SYNTHETIC)) {            return sym;        }        if (!target.obeyBinaryCompatibility())            return rs.isAccessible(attrEnv, (TypeSymbol) sym.owner) ? sym :                    sym.clone(site.tsym);        if (!target.interfaceFieldsBinaryCompatibility()) {            if ((sym.owner.flags() & INTERFACE) != 0 && sym.kind == VAR)                return sym;        }        if (sym.owner == syms.objectType.tsym)            return sym;        if (!target.interfaceObjectOverridesBinaryCompatibility()) {            if ((sym.owner.flags() & INTERFACE) != 0 &&                    syms.objectType.tsym.members().lookup(sym.name).scope != null)                return sym;        }        return sym.clone(site.tsym);    }    /**      * Insert a reference to given type in the constant pool,      *  checking for an array with too many dimensions;      *  return the reference's index.      *  @param type   The type for which a reference is inserted.      */    int makeRef(int pos, Type type) {        checkDimension(pos, type);        return pool.put(type.tag == CLASS ? (Object) type.tsym : (Object) type);    }    /**      * Check if the given type is an array with too many dimensions.      */    private void checkDimension(int pos, Type t) {        switch (t.tag) {        case METHOD:            checkDimension(pos, t.restype());            for (List args = t.argtypes(); args.nonEmpty(); args = args.tail)                checkDimension(pos, (Type) args.head);            break;        case ARRAY:            if (t.dimensions() > ClassFile.MAX_DIMENSIONS) {                log.error(pos, "limit.dimensions");                nerrs++;            }            break;        default:            break;        }    }    /**      * Create a tempory variable.      *  @param type   The variable's type.      */    LocalItem makeTemp(Type type) {        return (LocalItem) items.makeLocalItem(type, code.newLocal(type));    }    /**      * Generate code to call a non-private method or constructor.      *  @param pos         Position to be used for error reporting.      *  @param site        The type of which the method is a member.      *  @param name        The method's name.      *  @param argtypes    The method's argument types.      *  @param isStatic    A flag that indicates whether we call a      *                     static or instance method.      */    void callMethod(int pos, Type site, Name name, List argtypes, boolean isStatic) {        Symbol msym = rs.resolveInternalMethod(pos, attrEnv, site, name, argtypes);        if (isStatic)            items.makeStaticItem(msym).invoke();        else            items.makeMemberItem(msym, name == names.init).invoke();    }    /**      * Is the given method definition an access method      *  resulting from a qualified super? This is signified by an odd      *  access code.      */    private boolean isAccessSuper(MethodDef enclMethod) {        return (enclMethod.flags & SYNTHETIC) != 0 &&                isOddAccessName(enclMethod.name);    }    /**      * Does given name start with "access$" and end in an odd digit?      */    private boolean isOddAccessName(Name name) {        return name.startsWith(names.accessDollar) &&                (name.byteAt(name.len - 1) & 1) == 1;    }    /**      * Generate code to invoke the finalizer associated with given      *  environment.      *  Any calls to finalizers are appended to the environments `cont' chain.      *  Mark beginning of gap in catch all range for finalizer.      */    void genFinalizer(Env env) {        if (code.isAlive() && ((Gen.GenContext) env.info).finalize != null)            ((Gen.GenContext) env.info).finalize.gen();    }    /**      * Generate code to call all finalizers of structures aborted by      *  a non-local      *  exit.  Return target environment of the non-local exit.      *  @param target      The tree representing the structure that's aborted      *  @param env         The environment current at the non-local exit.      */    Env unwind(Tree target, Env env) {        Env env1 = env;        while (true) {            genFinalizer(env1);            if (env1.tree == target)                break;            env1 = env1.next;        }        return env1;    }    /**      * Mark end of gap in catch-all range for finalizer.      *  @param env   the environment which might contain the finalizer      *               (if it does, env.info.gaps != null).      */    void endFinalizerGap(Env env) {        if (((Gen.GenContext) env.info).gaps != null &&                ((Gen.GenContext) env.info).gaps.length() % 2 == 1)            ((Gen.GenContext) env.info).gaps.append(new Integer(code.curPc()));    }    /**      * Mark end of all gaps in catch-all ranges for finalizers of environments      *  lying between, and including to two environments.      *  @param from    the most deeply nested environment to mark      *  @param to      the least deeply nested environment to mark      */    void endFinalizerGaps(Env from, Env to) {        Env last = null;        while (last != to) {            endFinalizerGap(from);            last = from;            from = from.next;        }    }

⌨️ 快捷键说明

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