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

📄 code.java

📁 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 + -