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

📄 code.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.jvm;import com.sun.tools.javac.code.*;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.util.*;import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;import static com.sun.tools.javac.code.TypeTags.*;import static com.sun.tools.javac.jvm.ByteCodes.*;import static com.sun.tools.javac.jvm.UninitializedType.*;import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;/** 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. * *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If *  you write code that depends on this, you do so at your own risk. *  This code and its internal interfaces are subject to change or *  deletion without notice.</b> */public class Code {    public final boolean debugCode;    public final boolean needStackMap;        public enum StackMapFormat {	NONE,	CLDC {	    Name getAttributeName(Name.Table names) {		return names.StackMap;            }   	}, 	JSR202 {            Name getAttributeName(Name.Table names) {		return names.StackMapTable;            }   	};	Name getAttributeName(Name.Table names) {            return names.empty;	}            }        final Types types;    final Symtab syms;/*---------- classfile fields: --------------- */    /** 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(DiagnosticPosition 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<char[]> catchInfo = new ListBuffer<char[]>();    /** A buffer for line number information. Each entry is a vector     *  of two unsigned shorts.     */    List<char[]> lineInfo = List.nil(); // handled in stack fashion    /** The CharacterRangeTable     */    public CRTable crt;/*---------- internal fields: --------------- */    /** Are we generating code with jumps >= 32K?     */    public boolean fatcode;    /** Code generation enabled?     */    private boolean alive = true;    /** The current machine state (registers and stack).     */    State state;    /** 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 = Position.NOPOS;    /** Set true when a stackMap is needed at the current PC. */    boolean pendingStackMap = false;        /** The stack map format to be generated. */    StackMapFormat stackMap;        /** Switch: emit variable debug info.     */    boolean varDebugInfo;    /** Switch: emit line number info.     */    boolean lineDebugInfo;        /** Emit line number info if map supplied     */    Position.LineMap lineMap;    /** The constant pool of the current class.     */    final Pool pool;    final MethodSymbol meth;    /** Construct a code object, given the settings of the fatcode,     *  debugging info switches and the CharacterRangeTable.     */    public Code(MethodSymbol meth,		boolean fatcode,		Position.LineMap lineMap,		boolean varDebugInfo,		StackMapFormat stackMap,		boolean debugCode,		CRTable crt,		Symtab syms,		Types types,		Pool pool) {	this.meth = meth;	this.fatcode = fatcode;	this.lineMap = lineMap;	this.lineDebugInfo = lineMap != null;	this.varDebugInfo = varDebugInfo;	this.crt = crt;	this.syms = syms;	this.types = types;	this.debugCode = debugCode;	this.stackMap = stackMap;	switch (stackMap) {	case CLDC:	case JSR202:	    this.needStackMap = true;	    break;	default:	    this.needStackMap = false;	}	state = new State();	lvar = new LocalVar[20];	this.pool = pool;    }/* ************************************************************************** * Typecodes & related stuff ****************************************************************************/    /** 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:	case TYPEVAR:	case UNINITIALIZED_THIS:	case UNINITIALIZED_OBJECT:	    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 type == null ? 1 : width(typecode(type));    }    /** The total width taken up by a vector of objects.     */    public static int width(List<Type> types) {        int w = 0;        for (List<Type> l = types; l.nonEmpty(); l = l.tail)	    w = w + width(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);        }    }/* ************************************************************************** * Emit code ****************************************************************************/    /** 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.     */    private  void emit1(int od) {        if (!alive) return;	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.     */    private void emit2(int od) {        if (!alive) return;	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) return;	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.     */    private void emitop(int op) {	if (pendingJumps != null) resolvePending();        if (alive) {	    if (pendingStatPos != Position.NOPOS)		markStatBegin();	    if (pendingStackMap) {		pendingStackMap = false;		emitStackMap(); 	    }	    if (debugCode)		System.err.println("emit@" + cp + " stack=" +				   state.stacksize + ": " +				   mnem(op));            emit1(op);        }    }    void postop() {	assert alive || state.stacksize == 0;    }    /** Emit a multinewarray instruction.     */    public void emitMultianewarray(int ndims, int type, Type arrayType) {	emitop(multianewarray);        if (!alive) return;	emit2(type);	emit1(ndims);	state.pop(ndims);	state.push(arrayType);    }    /** Emit newarray.     */    public void emitNewarray(int elemcode, Type arrayType) {	emitop(newarray);	if (!alive) return;	emit1(elemcode);	state.pop(1); // count	state.push(arrayType);    }    /** Emit anewarray.     */    public void emitAnewarray(int od, Type arrayType) {        emitop(anewarray);	if (!alive) return;	emit2(od);	state.pop(1);	state.push(arrayType);    }    /** Emit an invokeinterface instruction.     */    public void emitInvokeinterface(int meth, Type mtype) {	int argsize = width(mtype.getParameterTypes());	emitop(invokeinterface);        if (!alive) return;	emit2(meth);	emit1(argsize + 1);	emit1(0);	state.pop(argsize + 1);	state.push(mtype.getReturnType());    }    /** Emit an invokespecial instruction.     */    public void emitInvokespecial(int meth, Type mtype) {	int argsize = width(mtype.getParameterTypes());	emitop(invokespecial);        if (!alive) return;	emit2(meth);	Symbol sym = (Symbol)pool.pool[meth];	state.pop(argsize);	if (sym.isConstructor())	    state.markInitialized((UninitializedType)state.peek());	state.pop(1);	state.push(mtype.getReturnType());    }    /** Emit an invokestatic instruction.     */    public void emitInvokestatic(int meth, Type mtype) {	int argsize = width(mtype.getParameterTypes());	emitop(invokestatic);        if (!alive) return;	emit2(meth);	state.pop(argsize);	state.push(mtype.getReturnType());    }    /** Emit an invokevirtual instruction.     */    public void emitInvokevirtual(int meth, Type mtype) {	int argsize = width(mtype.getParameterTypes());	emitop(invokevirtual);        if (!alive) return;	emit2(meth);	state.pop(argsize + 1);	state.push(mtype.getReturnType());    }    /** Emit an opcode with no operand field.     */    public void emitop0(int op) {	emitop(op);	if (!alive) return;	switch (op) {	case aaload: {	    state.pop(1);// index	    Type a = state.stack[state.stacksize-1];	    state.pop(1);	    state.push(types.erasure(types.elemtype(a))); }	    break;	case goto_:	    markDead();	    break;	case nop:	case ineg:	case lneg:	case fneg:	case dneg:	    break;	case aconst_null:	    state.push(syms.botType);	    break;	case iconst_m1:	case iconst_0:	case iconst_1:	case iconst_2:	case iconst_3:	case iconst_4:	case iconst_5:	case iload_0:	case iload_1:	case iload_2:	case iload_3:	    state.push(syms.intType);	    break;	case lconst_0:	case lconst_1:	case lload_0:	case lload_1:	case lload_2:	case lload_3:	    state.push(syms.longType);	    break;	case fconst_0:	case fconst_1:	case fconst_2:	case fload_0:	case fload_1:	case fload_2:	case fload_3:	    state.push(syms.floatType);	    break;	case dconst_0:	case dconst_1:	case dload_0:	case dload_1:	case dload_2:	case dload_3:	    state.push(syms.doubleType);	    break;	case aload_0: 	    state.push(lvar[0].sym.type);	    break;	case aload_1:	    state.push(lvar[1].sym.type);	    break;	case aload_2:	    state.push(lvar[2].sym.type);	    break;	case aload_3:	    state.push(lvar[3].sym.type);	    break;	case iaload:	case baload:	case caload:	case saload:	    state.pop(2);	    state.push(syms.intType);	    break;	case laload:	    state.pop(2);	    state.push(syms.longType);	    break;	case faload:	    state.pop(2);

⌨️ 快捷键说明

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