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

📄 code.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
    /** Return two code bytes at position pc as an unsigned int.     */    private 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) {        // pre: pc + 4 <= cp        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() {	int pc = curPc();	alive = true;	pendingStackMap = needStackMap;	return pc;    }    /** Declare an entry point with initial state;     *  return current code pointer     */    public int entryPoint(State state) {	int pc = curPc();	alive = true;	this.state = state.dup();	assert state.stacksize <= max_stack;	if (debugCode) System.err.println("entry point " + state);	pendingStackMap = needStackMap;	return pc;    }    /** Declare an entry point with initial state plus a pushed value;     *  return current code pointer     */    public int entryPoint(State state, Type pushed) {	int pc = curPc();	alive = true;	this.state = state.dup();	assert state.stacksize <= max_stack;	this.state.push(pushed);	if (debugCode) System.err.println("entry point " + state);	pendingStackMap = needStackMap;	return pc;    }/************************************************************************** * Stack map generation *************************************************************************/    /** An entry in the stack map. */    static class StackMapFrame {	int pc;	Type[] locals;	Type[] stack;    }    /** A buffer of cldc stack map entries. */    StackMapFrame[] stackMapBuffer = null;        /** A buffer of compressed StackMapTable entries. */    StackMapTableFrame[] stackMapTableBuffer = null;    int stackMapBufferSize = 0;    /** The last PC at which we generated a stack map. */    int lastStackMapPC = -1;        /** The last stack map frame in StackMapTable. */    StackMapFrame lastFrame = null;        /** The stack map frame before the last one. */    StackMapFrame frameBeforeLast = null;    /** Emit a stack map entry.  */    public void emitStackMap() {	int pc = curPc();	if (!needStackMap) return;                 switch (stackMap) {            case CLDC:                emitCLDCStackMap(pc, getLocalsSize());                break;            case JSR202:                emitStackMapFrame(pc, getLocalsSize());                break;            default:                throw new AssertionError("Should have chosen a stackmap format");	}	// DEBUG code follows	if (debugCode) state.dump(pc);    }        private int getLocalsSize() {        int nextLocal = 0;	for (int i=max_locals-1; i>=0; i--) {	    if (state.defined.isMember(i) && lvar[i] != null) {		nextLocal = i + width(lvar[i].sym.erasure(types));		break;	    }	}        return nextLocal;    }        /** Emit a CLDC stack map frame. */    void emitCLDCStackMap(int pc, int localsSize) {	if (lastStackMapPC == pc) {	    // drop existing stackmap at this offset	    stackMapBuffer[--stackMapBufferSize] = null;	}	lastStackMapPC = pc;	if (stackMapBuffer == null) {	    stackMapBuffer = new StackMapFrame[20];	} else if (stackMapBuffer.length == stackMapBufferSize) {	    StackMapFrame[] newStackMapBuffer =		new StackMapFrame[stackMapBufferSize << 1];	    System.arraycopy(stackMapBuffer, 0, newStackMapBuffer,			     0, stackMapBufferSize);	    stackMapBuffer = newStackMapBuffer;	}	StackMapFrame frame =	    stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();	frame.pc = pc;        	frame.locals = new Type[localsSize];	for (int i=0; i<localsSize; i++) {            if (state.defined.isMember(i) && lvar[i] != null) {                Type vtype = lvar[i].sym.type;		if (!(vtype instanceof UninitializedType))                    vtype = types.erasure(vtype);		frame.locals[i] = vtype;	    }	}	frame.stack = new Type[state.stacksize];	for (int i=0; i<state.stacksize; i++)	    frame.stack[i] = state.stack[i];    }        void emitStackMapFrame(int pc, int localsSize) {        if (lastFrame == null) {            // first frame            lastFrame = getInitialFrame();        } else if (lastFrame.pc == pc) {	    // drop existing stackmap at this offset	    stackMapTableBuffer[--stackMapBufferSize] = null;            lastFrame = frameBeforeLast;            frameBeforeLast = null;	}                StackMapFrame frame = new StackMapFrame();        frame.pc = pc;  	int localCount = 0;	Type[] locals = new Type[localsSize];        for (int i=0; i<localsSize; i++, localCount++) {            if (state.defined.isMember(i) && lvar[i] != null) {                Type vtype = lvar[i].sym.type;		if (!(vtype instanceof UninitializedType))                    vtype = types.erasure(vtype);		locals[i] = vtype;		if (width(vtype) > 1) i++;            }	}	frame.locals = new Type[localCount];	for (int i=0, j=0; i<localsSize; i++, j++) {            assert(j < localCount);	    frame.locals[j] = locals[i];            if (width(locals[i]) > 1) i++;	}	int stackCount = 0;	for (int i=0; i<state.stacksize; i++) {            if (state.stack[i] != null) {                stackCount++;	    }	}	frame.stack = new Type[stackCount];	stackCount = 0;	for (int i=0; i<state.stacksize; i++) {            if (state.stack[i] != null) {                frame.stack[stackCount++] = state.stack[i];	    }	}	                    if (stackMapTableBuffer == null) {	    stackMapTableBuffer = new StackMapTableFrame[20];	} else if (stackMapTableBuffer.length == stackMapBufferSize) {	    StackMapTableFrame[] newStackMapTableBuffer =		new StackMapTableFrame[stackMapBufferSize << 1];	    System.arraycopy(stackMapTableBuffer, 0, newStackMapTableBuffer,			     0, stackMapBufferSize);	    stackMapTableBuffer = newStackMapTableBuffer;	}	stackMapTableBuffer[stackMapBufferSize++] =                 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);                       frameBeforeLast = lastFrame;        lastFrame = frame;    }        StackMapFrame getInitialFrame() {        StackMapFrame frame = new StackMapFrame();        List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;        int len = arg_types.length();        int count = 0;        if (!meth.isStatic()) {            Type thisType = meth.owner.type;            frame.locals = new Type[len+1];            if (meth.isConstructor() && thisType != syms.objectType) {                frame.locals[count++] = UninitializedType.uninitializedThis(thisType);            } else {                frame.locals[count++] = types.erasure(thisType);            }        } else {            frame.locals = new Type[len];        }        for (Type arg_type : arg_types) {            frame.locals[count++] = types.erasure(arg_type);        }        frame.pc = -1;        frame.stack = null;        return frame;    }        /************************************************************************** * Operations having to do with jumps *************************************************************************/    /** 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 machine state after the jump instruction.	 *  Invariant: all elements of a chain list have the same stacksize	 *  and compatible stack and register contents.	 */	Code.State state;	/** The next jump in the list.	 */	public final Chain next;	/** Construct a chain from its jump position, stacksize, previous	 *  chain, and machine state.	 */	public Chain(int pc, Chain next, Code.State state) {	    this.pc = pc;	    this.next = next;	    this.state = state;	}    }    /** 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);		alive = true;		pendingStackMap = needStackMap;	    }	    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),			       result,			       state.dup());	    fixedPc = fatcode;	    if (opcode == goto_) alive = false;	}	return result;    }    /** Resolve chain to point to given target.     */    public void resolve(Chain chain, int target) {	boolean changed = false;	State newState = state;	for (; chain != null; chain = chain.next) {	    assert state != chain.state;            assert target > chain.pc || state.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) {                // If goto the next instruction, the jump is not needed:                 // compact the code.                cp = cp - 3;                target = target - 3;                if (chain.next == null) {                    // This is the only jump to the target. Exit the loop                     // without setting new state. The code is reachable                     // from the instruction before goto_.                    alive = true;                    break;                }            } 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.state.stacksize == newState.stacksize &&		    chain.state.nlocks == newState.nlocks;            }            fixedPc = true;            if (cp == target) {		changed = true;		if (debugCode)		    System.err.println("resolving chain state=" + chain.state);		if (alive) {		    newState = chain.state.join(newState);		} else {		    newState = chain.state;		    alive = true;		}            }	}	assert !changed || state != newState;	if (state != newState) {	    setDefined(newState.defined);	    state = newState;	    pendingStackMap = needStackMap;	}    }    /** Resolve chain to point to current code pointer.     */    public void resolve(Chain chain) {	assert	    !alive ||	    chain==null ||	    state.stacksize == chain.state.stacksize &&	    state.nlocks == chain.state.nlocks;	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) {	// recursive merge sort        if (chain2 == null) return chain1;        if (chain1 == null) return chain2;	assert	    chain1.state.stacksize == chain2.state.stacksize &&	    chain1.state.nlocks == chain2.state.nlocks;        if (chain1.pc < chain2.pc)	    return new Chain(		chain2.pc,		mergeChains(chain1, chain2.next),		chain2.state);	return new Chain(		chain1.pc,		mergeChains(chain1.next, chain2),		chain1.state);    }/* ************************************************************************** * Catch clauses ****************************************************************************/    /** 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});    }/* ************************************************************************** * Line numbers ****************************************************************************/    /** Add a line number entry.     */    public void addLineNumber(char startPc, char lineNumber) {	if (lineDebugInfo) {	    if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)		lineInfo = lineInfo.tail;	    if (lineInfo.isEmpty() || 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() {	if (alive && lineDebugInfo) {	    int line = lineMap.getLineNumber(pendingStatPos);	    char cp1 = (char)cp;	    char line1 = (char)line;	    if (cp1 == cp && line1 == line)		addLineNumber(cp1, line1);	}	pendingStatPos = Position.NOPOS;    }/* ************************************************************************** * Simulated VM machine state ****************************************************************************/    class State implements Cloneable {	/** The set of registers containing values. */	Bits defined;	/** The (types of the) contents of the machine stack. */	Type[] stack;	/** The first stack position currently unused. */	int stacksize;	/** The numbers of registers containing locked monitors. */	int[] locks;	int nlocks;	State() {	    defined = new Bits();	    stack = new Type[16];	}	State dup() {	    try {		State state = (State)super.clone();		state.defined = defined.dup();		state.stack = stack.clone();		if (locks != null) state.locks = locks.clone();		if (debugCode) {		    System.err.println("duping state " + this);		    dump();		}		return state;	    } catch (CloneNotSupportedException ex) {		throw new AssertionError(ex);	    }	}	void lock(int register) {	    if (locks == null) {		locks = new int[20];	    } else if (locks.length == nlocks) {		int[] newLocks = new int[locks.length << 1];		System.arraycopy(locks, 0, newLocks, 0, locks.length);		locks = newLocks;	    }	    locks[nlocks] = register;	    nlocks++;	}	void unlock(int register) {	    nlocks--;	    assert locks[nlocks] == register;	    locks[nlocks] = -1;	}	void push(Type t) {	    if (debugCode) System.err.println("   pushing " + t);	    switch (t.tag) {	    case TypeTags.VOID:		return;	    case TypeTags.BYTE:	    case TypeTags.CHAR:	    case TypeTags.SHORT:	    case TypeTags.BOOLEAN:		t = syms.intType;		break;

⌨️ 快捷键说明

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