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

📄 code.java

📁 这是实现Javac功能的GJC的最新源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/** * @(#)Code.java	1.23 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 com.sun.tools.javac.v8.code.Symbol.*;/** * An internal structure that corresponds to the code attribute of *  methods in a classfile. The class also provides some utility operations to *  generate bytecode instructions. */public class Code implements ByteCodes, TypeTags {    public static final boolean debugCode = false;    /**     * The maximum stack size.     */    public int max_stack = 0;    /**     * The maximum number of local variable slots.     */    public int max_locals = 0;    /**     * The code buffer.     */    public byte[] code = new byte[64];    /**     * the current code pointer.     */    public int cp = 0;    /**     * Check the code against VM spec limits; if     *  problems report them and return true.     */    public boolean checkLimits(int pos, Log log) {        if (cp > ClassFile.MAX_CODE) {            log.error(pos, "limit.code");            return true;        }        if (max_locals > ClassFile.MAX_LOCALS) {            log.error(pos, "limit.locals");            return true;        }        if (max_stack > ClassFile.MAX_STACK) {            log.error(pos, "limit.stack");            return true;        }        return false;    }    /**      * A buffer for expression catch data. Each enter is a vector      *  of four unsigned shorts.      */    ListBuffer catchInfo = new ListBuffer();    /**     * A buffer for line number information. Each entry is a vector     *  of two unsigned shorts.     */    List lineInfo = new List();    /**     * The CharacterRangeTable     */    public CRTable crt;    /**     * Are we generating code with jumps >= 32K?     */    public boolean fatcode;    /**     * Code generation enabled?     */    private boolean alive = true;    /**     * The current stacksize.     */    public int stacksize = 0;    /**     * Is it forbidden to compactify code, because something is     *  pointing to current location?     */    private boolean fixedPc = false;    /**     * The next available register.     */    public int nextreg = 0;    /**     * A chain for jumps to be resolved before the next opcode is emitted.     *  We do this lazily to avoid jumps to jumps.     */    Chain pendingJumps = null;    /**     * The position of the currently statement, if we are at the     *  start of this statement, NOPOS otherwise.     *  We need this to emit line numbers lazily, which we need to do     *  because of jump-to-jump optimization.     */    int pendingStatPos = 0;    /**     * Switch: emit variable debug info.     */    boolean varDebugInfo;    /**     * Switch: emit line number info.     */    boolean lineDebugInfo;    /**     * Construct a code object, given the settings of the fatcode,     *  debugging info switches and the CharacterRangeTable.     */    public Code(boolean fatcode, boolean lineDebugInfo, boolean varDebugInfo,            CRTable crt) {        super();        this.fatcode = fatcode;        this.lineDebugInfo = lineDebugInfo;        this.varDebugInfo = varDebugInfo;        this.crt = crt;        if (varDebugInfo) {            defined = new Bits();            lvar = new LocalVar[20];        }    }    /**      * Given a type, return its type code (used implicitly in the      *  JVM architecture).      */    public static int typecode(Type type) {        switch (type.tag) {        case BYTE:            return BYTEcode;        case SHORT:            return SHORTcode;        case CHAR:            return CHARcode;        case INT:            return INTcode;        case LONG:            return LONGcode;        case FLOAT:            return FLOATcode;        case DOUBLE:            return DOUBLEcode;        case BOOLEAN:            return BYTEcode;        case VOID:            return VOIDcode;        case CLASS:        case ARRAY:        case METHOD:        case BOT:            return OBJECTcode;        default:            throw new AssertionError("typecode " + type.tag);        }    }    /**      * Collapse type code for subtypes of int to INTcode.      */    public static int truncate(int tc) {        switch (tc) {        case BYTEcode:        case SHORTcode:        case CHARcode:            return INTcode;        default:            return tc;        }    }    /**      * The width in bytes of objects of the type.      */    public static int width(int typecode) {        switch (typecode) {        case LONGcode:        case DOUBLEcode:            return 2;        case VOIDcode:            return 0;        default:            return 1;        }    }    public static int width(Type type) {        return width(typecode(type));    }    /**      * The total width taken up by a vector of objects.      */    public static int width(List types) {        int w = 0;        for (List l = types; l.nonEmpty(); l = l.tail)            w = w + width((Type) l.head);        return w;    }    /**      * Given a type, return its code for allocating arrays of that type.      */    public static int arraycode(Type type) {        switch (type.tag) {        case BYTE:            return 8;        case BOOLEAN:            return 4;        case SHORT:            return 9;        case CHAR:            return 5;        case INT:            return 10;        case LONG:            return 11;        case FLOAT:            return 6;        case DOUBLE:            return 7;        case CLASS:            return 0;        case ARRAY:            return 1;        default:            throw new AssertionError("arraycode " + type);        }    }    /**      * The current output code pointer.      */    public int curPc() {        if (pendingJumps != null)            resolvePending();        if (pendingStatPos != Position.NOPOS)            markStatBegin();        fixedPc = true;        return cp;    }    /**      * Emit a byte of code.      */    public void emit1(int od) {        if (alive) {            if (cp == code.length) {                byte[] newcode = new byte[cp * 2];                System.arraycopy(code, 0, newcode, 0, cp);                code = newcode;            }            code[cp++] = (byte) od;        }    }    /**      * Emit two bytes of code.      */    public void emit2(int od) {        if (alive) {            if (cp + 2 > code.length) {                emit1(od >> 8);                emit1(od);            } else {                code[cp++] = (byte)(od >> 8);                code[cp++] = (byte) od;            }        }    }    /**      * Emit four bytes of code.      */    public void emit4(int od) {        if (alive) {            if (cp + 4 > code.length) {                emit1(od >> 24);                emit1(od >> 16);                emit1(od >> 8);                emit1(od);            } else {                code[cp++] = (byte)(od >> 24);                code[cp++] = (byte)(od >> 16);                code[cp++] = (byte)(od >> 8);                code[cp++] = (byte) od;            }        }    }    /**      * Emit an opcode, adjust stacksize by sdiff.      */    public void emitop(int op, int sdiff) {        if (pendingJumps != null)            resolvePending();        if (alive) {            if (pendingStatPos != Position.NOPOS)                markStatBegin();            if (debugCode)                System.err.println(cp + ":" + stacksize + ": " + mnem(op));            emit1(op);            if (sdiff <= -1000) {                stacksize = stacksize + sdiff + 1000;                alive = false;                assert stacksize == 0;            } else {                stacksize = stacksize + sdiff;                assert stacksize >= 0;                if (stacksize > max_stack)                    max_stack = stacksize;            }        }    }    /**      * Emit an opcode, adjust stacksize by stackdiff[op].      */    public void emitop(int op) {        emitop(op, stackdiff[op]);    }    /**      * Emit an opcode with a one-byte operand field.      */    public void emitop1(int op, int od) {        emitop(op);        emit1(od);    }    /**      * Emit an opcode with a one-byte operand field;      *  widen if field does not fit in a byte.      */    public void emitop1w(int op, int od) {        if (od > 255) {            emitop(wide);            emitop2(op, od);        } else {            emitop1(op, od);        }    }    /**      * Emit an opcode with a two-byte operand field.      */    public void emitop2(int op, int od) {        emitop(op);        emit2(od);    }    /**      * Emit an opcode with a four-byte operand field.      */    public void emitop4(int op, int od) {        emitop(op);        emit4(od);    }    /**      * Align code pointer to next `incr' boundary.      */    public void align(int incr) {        if (alive)            while (cp % incr != 0)                emit1(0);    }    /**      * Place a byte into code at address pc. Pre: pc + 1 <= cp.      */    public void put1(int pc, int op) {        code[pc] = (byte) op;    }    /**      * Place two bytes into code at address pc. Pre: pc + 2 <= cp.      */    public void put2(int pc, int od) {        put1(pc, od >> 8);        put1(pc + 1, od);    }    /**      * Place four  bytes into code at address pc. Pre: pc + 4 <= cp.      */

⌨️ 快捷键说明

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