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

📄 method.java

📁 java 到c的转换程序的原代码.对喜欢C程序而不懂JAVA程序的人很有帮助
💻 JAVA
字号:
//  Method.java -- analysis of one Java methodpackage toba.classfile;import java.io.*;import java.util.*;public class Method {			// information about one Java method    // instance variables    public ClassData cl;		// containing class    public Field fl;			// method field    public ClassRef exthrown[];		// list of exceptions thrown    public int max_stack;		// maximum stack used    public int max_locals;		// maximum locals used    public byte code[];			// raw bytecode    public Instr instrs[];		// instruction list    public short pcmap[];		// pc to instruction mapping    int numLabels;                     // Number of instructions that have labels    public short lblmap[];              // label to instruction mapping    public Handler handlers[];		// exception table    public MethodCode mtcode;           // Information on code for this method    public String astack;		// argument stack on entry    public String rstack;		// stack state at time of return    public int oflags;			// OR of flags of reachable opcodes    //  Bit vectors record exactly which local variables are used, by JVM type.    //  Only stores are recorded; if it's not stored, it can't be loaded.    //  Don't forget the implicit stores of method parameters, though.    public static BitSet[] varused;	// local variables used, by type    public static int[] maxvar;		// highest number used, by type    //  JVM types that appear on the stack.    public static BitSet stktypes;	// types used on stack    public static boolean useUnextendedBasicBlocks = false; // Change basic block def// manifest constantspublic static final int CHAR_INDX_SIZE = 128;  // size of array indexed by                                                // (C) charspublic static final String JVM_TYPES="ailfd";  // Java Virtual Machine types/** Assign code-generator specific information about method code.  * E.g., the interpreter needs only a function pointer; the JIT requires  * machine code, backpatch information, etc.  * @param mc an instance of (a subtype of) MethodCode, specific to this method  * @returns the parameter mc  */public MethodCodesetMethodCode (MethodCode mc)   // Code object instance{    if (null != mtcode) {        /* Can't assign multiple code instances to one method. */        throw new InternalError ("Multiple method code instances assigned");    }    mtcode = mc;    return mc;}//  new Method(cl, fl) -- build method struct from classdata and field////  for abstract or native methods, many fields are left uninitialized.// This is invoked by whoever generates code; translator/CFile, or// runtime/CodeGen on behalf of the interpreter or JIT.  CodeGen invokes// this through defineClass at load time.  The created object may need// to be revisited at link time, which is when Resolve.resolveClass is// invoked.  So we save a pointer to it in the Field parameter.public Method(ClassData cl, Field fl)    throws ClassFormatError{    int c, i, n;    Instr ins;    Handler h;    this.cl = cl;			// record containing class    this.fl = fl;			// record corresponding Field struct    /* Keep a backpointer from the field structure to the Method instance,     * so we can find it again */    if (null != this.fl.tableObj) {        throw new InternalError ("Method fields used multiply");    }    this.fl.tableObj = this;    sigscan();				// always scan signature info    // record exceptions thrown by this method (possibly none)    byte[] xattr = Attribute.find(fl.attributes, "Exceptions");    if (xattr == null) {	exthrown = new ClassRef[0];    } else try {	ByteArrayInputStream b = new ByteArrayInputStream(xattr);	DataInputStream d = new DataInputStream(b);	exthrown = new ClassRef[d.readUnsignedShort()];	for (i = 0; i < exthrown.length; i++) {	    exthrown[i] = (ClassRef)cl.constants[d.readUnsignedShort()].value;	}    } catch (IOException e) {	throw new ClassFormatError(	    "Exceptions attribute of " + cl.name + "." + fl.name);    }    // check for abstract or native method, and bail out if no code    if ((fl.access & (ClassData.ACC_ABSTRACT | ClassData.ACC_NATIVE)) != 0)    	return;				// nothing more to do    // initialize    stktypes = new BitSet();    maxvar = new int[CHAR_INDX_SIZE];    varused = new BitSet[CHAR_INDX_SIZE];    for (i = 0; i < JVM_TYPES.length(); i++) {	c = (int)JVM_TYPES.charAt(i);	maxvar[c] = -1;	varused[c] = new BitSet();    }    // mark variables that are passed as arguments    for (i = 0; i < astack.length(); i++)  {        c = astack.charAt(i);	if (c == 'x') {	    markvar((char)astack.charAt(i+1), i);	    i++;	} else	    markvar((char)c, i);    }    // find and unpack the "Code" attribute    byte[] cattr = Attribute.find(fl.attributes, "Code");    if (cattr == null)	throw new ClassFormatError(	    "no Code attribute for " + cl.name + "." + fl.name);    ByteArrayInputStream b = new ByteArrayInputStream(cattr);    DataInputStream d = new DataInputStream(b);    try {	max_stack = d.readUnsignedShort();	max_locals = d.readUnsignedShort();	code = new byte[d.readInt()];	d.readFully(code);	// exception table	handlers = new Handler[d.readUnsignedShort()];	for (i = 0; i < handlers.length; i++) {	    int start = d.readUnsignedShort(),		end = d.readUnsignedShort(),	        target = d.readUnsignedShort();	    int type = d.readUnsignedShort(); 	    ClassRef cr = null;	    if (type > 0)	        cr = (ClassRef)cl.constants[type].value;	    handlers[i] = new Handler(start, end, target, cr);	}    } catch (IOException e) {	throw new ClassFormatError(	    "Code attribute of " + cl.name + "." + fl.name);    }    // construct instruction list    Vector insvec = new Vector();    pcmap = new short[code.length];    for (int pc = 0; pc < code.length; pc += ins.length) {	pcmap[pc] = (short)insvec.size();	ins = new Instr(code, pc, cl.constants);	insvec.addElement(ins);    }    instrs = new Instr[insvec.size()];    insvec.copyInto(instrs);    // set boundary bits for instructions at ends of exception ranges    for (i = 0; i < handlers.length; i++) {	h = handlers[i];	instrs[pcmap[h.start]].isBoundary = true;	// mark first instr	if (h.end < code.length)	    instrs[pcmap[h.end]].isBoundary = true;	// mark last instr    }     // number exception range segments, marking each instr by segment number    if (handlers.length > 0) {	for (i = n = 0; i < instrs.length; i++) {	    ins = instrs[i];	    if (ins.isBoundary)		n++;	    ins.xseg = n;	}    }    // mark directly reachable code, noting jump targets and stack depths    numLabels = 0;    mark(0, "", 0);			// begin at entry, with empty stack    // mark exception handling code    for (i = 0; i < handlers.length; i++)	mark(handlers[i].jump, "a", -1);    if (useUnextendedBasicBlocks) {        // mark successor instructions (fall-thrus) from conditional jumps        // as targets; we want real basic blocks, not just extended BBs.        for (i = 1; i < instrs.length; i++) {            ins = instrs [i-1];            // If not already a target, and predecessor is conditional CFTI,            // mark as target.            if (( ! instrs [i].isTarget) &&                ((Opcode.IFZRO == ins.opcode.kind) ||                 (Opcode.IFCMP == ins.opcode.kind))) {                ++numLabels;                instrs [i].isTarget = true;            }        }    }        // assign labels to jump targets    n = 0;    lblmap = new short [numLabels];    for (i = 0; i < instrs.length; i++) {	ins = instrs[i];	if (ins.isTarget) {	    ins.label = n;            lblmap [n] = (short) i;            ++n;        }    }}//  sigscan() -- scan method signature to set astack and rstackprivate void sigscan(){    String s = fl.signature;			// signature being scanned    StringBuffer a = new StringBuffer();	// arg stack being built    int i = 1;					// current position (skip "(")    if ((fl.access & ClassData.ACC_STATIC) == 0) // instance function?	a.append('a');				// "self" parameterloop:    for (i = 1; ; i++) {	switch (s.charAt(i)) {	    case Field.FT_object:				// object		i = s.indexOf(';', i);		a.append('a');		break;	    case Field.FT_array:				// array		while (s.charAt(i) == Field.FT_array)		    i++;		if (s.charAt(i) == Field.FT_object)		    i = s.indexOf(';', i);		a.append('a');		break;	    // primitive types	    case Field.FT_byte:    a.append('i');   break;	    case Field.FT_char:    a.append('i');   break;	    case Field.FT_double:  a.append("xd");  break;	    case Field.FT_float:   a.append('f');   break;	    case Field.FT_int:     a.append('i');   break;	    case Field.FT_long:    a.append("xl");  break;	    case Field.FT_short:   a.append('i');   break;	    case Field.FT_boolean: a.append('i');   break;	    case ')':  break loop;		// end of parameters	}    }    astack = a.toString();    switch (s.charAt(++i)) {	case Field.FT_void:     rstack = "";    break;	// void	case Field.FT_byte:     rstack = "i";   break;	case Field.FT_char:     rstack = "i";   break;	case Field.FT_double:   rstack = "xd";  break;	case Field.FT_float:    rstack = "f";   break;	case Field.FT_int:      rstack = "i";   break;	case Field.FT_long:     rstack = "xl";  break;	case Field.FT_short:    rstack = "i";   break;	case Field.FT_boolean:  rstack = "i";   break;	default:          rstack = "a";   break;    }}//  mark(pc, stack, segnum) -- mark reachable code, maintaining stack state////  If segnum differs from segment number of instruction at pc, the first//  instruction (at pc) is also marked as a boundary instruction.////  Also marks local variables referenced by STORE-class instructionsprivate void mark(int pc, String stack, int segnum){    int i = pcmap[pc];    Instr ins = instrs[i];    if (! ins.isTarget) {        ++numLabels;        ins.isTarget = true;    }    if (ins.xseg != segnum)	ins.isBoundary = true;    while (true) {	ins = instrs[i++];	if (ins.isReached) {			// if already processed	    if (!ins.before.equals(stack))	// sanity check		throw new VerifyError( "stack mismatch: pc=" + pc +		   " stack1=" + ins.before + " stack2=" + stack);	    return;	}	ins.isReached = true;			// mark instruction as processed	oflags |= ins.opcode.flags;		// accumulate flag bits	ins.before = stack;	if (stack.length() > 0) {	    char c = stack.charAt(stack.length() - 1);	    stktypes.set((int)c);	    if (ins.opcode.kind == Opcode.STORE)		markvar(c, ins.opcode.var + ins.val);	}	stack = ins.after = ins.nextStack();	if ((ins.opcode.flags & Opcode.JSRI) != 0) {	// if JSR instruction	    mark(ins.val, stack + "a", ins.xseg);	    					// mark JSR routine with arg	    mark(ins.pc + ins.length, stack, -1);	    					// mark successor as jump tgt	} else if ((ins.opcode.flags & Opcode.PC) != 0) // if other jump	    mark(ins.val, stack, ins.xseg); 	// mark target instrs	if ((ins.opcode.flags & Opcode.SWCH) != 0) {	// if switch instruction	    mark(ins.more[0], stack, ins.xseg);		// mark default	    for (int j = 3; j < ins.more.length; j++) {		mark(ins.more[j], stack, ins.xseg);	// mark other labels		if (ins.opcode.kind == Opcode.LKPSW)		    j++;			// skip tag if lookupswitch	    }	}	if ((ins.opcode.flags & Opcode.NFT) != 0)	    break;				// opcode never falls through	else	    ins.succ = instrs[i];		// note sequential successor    }}//  markvar(jtype, n) -- mark a local variable as being used.private void markvar(char jtype, int n){    int i = (int)jtype;    if (maxvar[i] < n)	maxvar[i] = n;    varused[i].set(n);}//  target(pc) -- return label corresponding to jump target given in pc termsprivate int target(int pc){    return instrs[pcmap[pc]].label;}public StringtoString (){    return (cl.name + "." + fl.name);}} // class Method

⌨️ 快捷键说明

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