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

📄 code.java

📁 这是实现Javac功能的GJC的最新源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    public void put4(int pc, int od) {        put1(pc, od >> 24);        put1(pc + 1, od >> 16);        put1(pc + 2, od >> 8);        put1(pc + 3, od);    }    /**      * Return code byte at position pc as an unsigned int.      */    public int get1(int pc) {        return code[pc] & 255;    }    /**      * Return two code bytes at position pc as an unsigned int.      */    public int get2(int pc) {        return (get1(pc)<< 8) | get1(pc + 1);    }    /**      * Return four code bytes at position pc as an int.      */    public int get4(int pc) {        return (get1(pc)<< 24) | (get1(pc + 1)<< 16) | (get1(pc + 2)<< 8) |                (get1(pc + 3));    }    /**      * Is code generation currently enabled?      */    public boolean isAlive() {        return alive || pendingJumps != null;    }    /**      * Switch code generation on/off.      */    public void markDead() {        alive = false;    }    /**      * Declare an entry point; return current code pointer      */    public int entryPoint() {        alive = true;        return curPc();    }    /**      * Declare an entry point with initial stack size;      *  return current code pointer      */    public int entryPoint(int size) {        alive = true;        stacksize = size;        if (stacksize > max_stack)            max_stack = stacksize;        return curPc();    }    /**      * A chain represents a list of unresolved jumps. Jump locations      *  are sorted in decreasing order.      */    public static class Chain {        /**         * The position of the jump instruction.         */        public final int pc;        /**         * The stacksize after the jump instruction.         *  Invariant: all elements of a chain list have the same stacksize.         */        public final int stacksize;        /**         * The next jump in the list.         */        public final Chain next;        /**         * The set of variables alive at the jump.         */        public final Bits defined;        /**         * Construct a chain from its jump position, stacksize, previous         *  chain, and set of defined variables.         */        public Chain(int pc, int stacksize, Chain next, Bits defined) {            super();            this.pc = pc;            this.stacksize = stacksize;            this.next = next;            this.defined = defined;        }    }    /**      * Negate a branch opcode.      */    public static int negate(int opcode) {        if (opcode == if_acmp_null)            return if_acmp_nonnull;        else if (opcode == if_acmp_nonnull)            return if_acmp_null;        else return ((opcode + 1) ^ 1)                    - 1;    }    /**      * Emit a jump instruction.      *  Return code pointer of instruction to be patched.      */    public int emitJump(int opcode) {        if (fatcode) {            if (opcode == goto_ || opcode == jsr) {                emitop4(opcode + goto_w - goto_, 0);            } else {                emitop2(negate(opcode), 8);                emitop4(goto_w, 0);            }            return cp - 5;        } else {            emitop2(opcode, 0);            return cp - 3;        }    }    /**      * Emit a branch with given opcode; return its chain.      *  branch differs from jump in that jsr is treated as no-op.      */    public Chain branch(int opcode) {        Chain result = null;        if (opcode == goto_) {            result = pendingJumps;            pendingJumps = null;        }        if (opcode != dontgoto && isAlive()) {            result = new Chain(emitJump(opcode), stacksize, result,                    varDebugInfo ? defined.dup() : null);            fixedPc = fatcode;            if (opcode == goto_)                alive = false;        }        return result;    }    /**      * Resolve chain l to point to given target.      */    public void resolve(Chain chain, int target) {        Bits newDefined = defined;        for (; chain != null; chain = chain.next) {            assert target > chain.pc || stacksize == 0;            if (target >= cp) {                target = cp;            } else if (get1(target) == goto_) {                if (fatcode)                    target = target + get4(target + 1);                else                    target = target + get2(target + 1);            }            if (get1(chain.pc) == goto_ && chain.pc + 3 == target &&                    target == cp && !fixedPc) {                cp = cp - 3;                target = target - 3;            } else {                if (fatcode)                    put4(chain.pc + 1, target - chain.pc);                else if (target - chain.pc < Short.MIN_VALUE ||                        target - chain.pc > Short.MAX_VALUE)                    fatcode = true;                else                    put2(chain.pc + 1, target - chain.pc);                assert ! alive || chain.stacksize == stacksize;            }            fixedPc = true;            if (cp == target) {                if (alive) {                    assert stacksize == chain.stacksize;                    if (varDebugInfo)                        newDefined = chain.defined.andSet(defined);                } else {                    stacksize = chain.stacksize;                    if (varDebugInfo)                        newDefined = chain.defined;                    alive = true;                }            }        }        setDefined(newDefined);    }    /**      * Set the current variable defined state.      */    public void setDefined(Bits newDefined) {        if (alive && varDebugInfo && newDefined != defined) {            Bits diff = defined.dup().xorSet(newDefined);            for (int adr = diff.nextBit(0); adr >= 0; adr = diff.nextBit(adr + 1)) {                if (adr >= nextreg)                    defined.excl(adr);                else if (defined.isMember(adr))                    setUndefined(adr);                else                    setDefined(adr);            }        }    }    /**      * Resolve chain l to point to current code pointer.      */    public void resolve(Chain chain) {        pendingJumps = mergeChains(chain, pendingJumps);    }    /**      * Resolve any pending jumps.      */    public void resolvePending() {        Chain x = pendingJumps;        pendingJumps = null;        resolve(x, cp);    }    /**      * Merge the jumps in of two chains into one.      */    public static Chain mergeChains(Chain chain1, Chain chain2) {        if (chain2 == null)            return chain1;        if (chain1 == null)            return chain2;        if (chain1.pc < chain2.pc)            return new Chain(chain2.pc, chain2.stacksize,                    mergeChains(chain1, chain2.next), chain2.defined);        return new Chain(chain1.pc, chain1.stacksize,                mergeChains(chain1.next, chain2), chain1.defined);    }    /**      * Add a catch clause to code.      */    public void addCatch(char startPc, char endPc, char handlerPc, char catchType) {        catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});    }    /**      * Add a line number entry.      */    public void addLineNumber(char startPc, char lineNumber) {        if (lineDebugInfo) {            if (lineInfo.nonEmpty() && ((char[]) lineInfo.head)[0] == startPc)                lineInfo = lineInfo.tail;            if (lineInfo.isEmpty() || ((char[]) lineInfo.head)[1] != lineNumber)                lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});        }    }    /**      * Mark beginning of statement.      */    public void statBegin(int pos) {        if (pos != Position.NOPOS) {            pendingStatPos = pos;        }    }    /**      * Force stat begin eagerly      */    public void markStatBegin() {        int line = Position.line(pendingStatPos);        pendingStatPos = Position.NOPOS;        if (alive && lineDebugInfo) {            char cp1 = (char) cp;            char line1 = (char) line;            if (cp1 == cp && line1 == line)                addLineNumber(cp1, line1);        }    }    /**      * A live range of a local variable.      */    static class LocalVar {        final VarSymbol var;        final char reg;        char start_pc = Character.MAX_VALUE;        char length = Character.MAX_VALUE;        LocalVar(VarSymbol v) {            super();            this.var = v;            this.reg = (char) v.adr;        }        public LocalVar dup() {            return new LocalVar(var);        }    }    {    }    /**      * Local variables, indexed by register.      */    LocalVar[] lvar;    public Bits defined;    /**     * Add a new local variable.     */    private void addLocalVar(VarSymbol v) {        int adr = v.adr;        if (adr >= lvar.length) {            int newlength = lvar.length * 2;            if (newlength <= adr)                newlength = adr + 10;            LocalVar[] new_lvar = new LocalVar[newlength];            System.arraycopy(lvar, 0, new_lvar, 0, lvar.length);            lvar = new_lvar;        }        assert lvar[adr] == null;        lvar[adr] = new LocalVar(v);        defined.excl(adr);    }    /**      * Mark a register as being defined.      */    public void setDefined(int adr) {        if (!varDebugInfo)            return;        defined.incl(adr);        if (cp < Character.MAX_VALUE && adr < lvar.length) {            LocalVar v = lvar[adr];            if (v != null && v.start_pc == Character.MAX_VALUE)                v.start_pc = (char) cp;        }    }    /**      * Mark a register as being undefined.      */    public void setUndefined(int adr) {        defined.excl(adr);        if (adr < lvar.length && lvar[adr] != null &&                lvar[adr].start_pc != Character.MAX_VALUE) {            LocalVar v = lvar[adr];            char length = (char)(curPc() - v.start_pc);            if (length < Character.MAX_VALUE) {                lvar[adr] = v.dup();                v.length = length;                putVar(v);            } else {                v.start_pc = Character.MAX_VALUE;            }        }    }    /**      * End the scope of a variable.      */    private void endScope(int adr) {        defined.excl(adr);        if (adr < lvar.length && lvar[adr] != null) {            LocalVar v = lvar[adr];            lvar[adr] = null;            if (v.start_pc != Character.MAX_VALUE) {                char length = (char)(curPc() - v.start_pc);                if (length < Character.MAX_VALUE) {                    v.length = length;                    putVar(v);                }            }        }    }    /**      * Put a live variable range into the buffer to be output to the      *  class file.      */    void putVar(LocalVar var) {        if (varBuffer == null)            varBuffer = new LocalVar[20];        if (varBufferSize >= varBuffer.length) {            LocalVar[] newVarBuffer = new LocalVar[varBufferSize * 2];            System.arraycopy(varBuffer, 0, newVarBuffer, 0, varBuffer.length);            varBuffer = newVarBuffer;        }        varBuffer[varBufferSize++] = var;    }    /**      * Previously live local variables, to be put into the variable table.      */    LocalVar[] varBuffer;    int varBufferSize;    /**     * Create a new local variable address and return it.     */    public int newLocal(int typecode) {        int reg = nextreg;        int w = width(typecode);        nextreg = reg + w;        if (nextreg > max_locals)            max_locals = nextreg;        return reg;    }    public int newLocal(Type type) {        return newLocal(typecode(type));    }    public int newLocal(VarSymbol v) {        int reg = v.adr = newLocal(v.erasure());        if (varDebugInfo)            addLocalVar(v);        return reg;    }    /**      * Start a set of fresh registers.      */    public void newRegSegment() {        nextreg = max_locals;    }    /**      * End scopes of all variables with registers >= first.

⌨️ 快捷键说明

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