bcutils.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 431 行

C
431
字号
/* * @(#)bcutils.c	1.23 06/10/25 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program 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.    *    * This program 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 at /legal/license.txt).    *    * 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 or visit www.sun.com if you need additional   * information or have any questions.  * */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/interpreter.h"#include "javavm/include/stacks.h"#include "javavm/include/bcattr.h"#include "javavm/include/utils.h"#include "javavm/include/typeid.h"#include "javavm/include/opcodes.h"#include "javavm/include/globals.h"#include "javavm/include/porting/int.h"#include "javavm/include/bcutils.h"#ifdef CVM_JVMTI#ifdef CVM_HW#include "include/hw.h"#endif#endif#ifdef CVM_DEBUG/* * A few debugging routines to help out with byte-codes *//* * CVMbcList(mb): Print out the byte-codes of a given method, with * associated PC. */static void printInst(CVMMethodBlock* mb, CVMUint8* pc, CVMUint32 level, CVMBool doRecurse);static voidprintExceptionTable(CVMJavaMethodDescriptor* jmd, CVMUint32 level);static voiddisassembleRangeWithIndentation(CVMMethodBlock* mb,		      				CVMUint8* codeStart, 				CVMUint8* codeEnd,				CVMUint32 level,				CVMBool   doRecurse);static voidindent(CVMUint32 level);#ifdef CVM_JVMTIstatic CVMUint32getOpcodeLength(CVMExecEnv* ee, CVMUint8* pc){    CVMUint32 opLen;    /* Make sure we get the underlying instruction length, and not that       of opc_breakpoint */    if (*pc == opc_breakpoint) {	/* Find the length of the original opcode, so we can	   skip over it by the appropriate amount */	CVMOpcode instr = CVMjvmtiGetBreakpointOpcode(ee, pc, CVM_FALSE);	*pc = instr;	opLen = CVMopcodeGetLength(pc);	*pc = opc_breakpoint;#ifdef CVM_HW	CVMhwFlushCache(pc, pc + 1);#endif    } else {	opLen = CVMopcodeGetLength(pc);    }    return opLen;}#else#define getOpcodeLength(ee, pc) (CVMopcodeGetLength(pc))#endif/* * The most general disassembler. * Keeps track of call level 'level' and indents accordingly. * Controls recursion based on 'doRecurse'. */voidCVMbcListWithIndentation(CVMMethodBlock* mb, CVMUint32 level, CVMBool doRecurse){    CVMJavaMethodDescriptor *jmd;    CVMUint8* codeStart;    CVMUint8* codeEnd;    if (!CVMmbIsJava(mb)) {	/* Not a Java method. Give up */	CVMconsolePrintf("CVMbcList(%M): not a Java method\n", mb);	return;    }    indent(level);    CVMconsolePrintf("Method %C.%M\n", CVMmbClassBlock(mb), mb);    jmd = CVMmbJmd(mb);    indent(level);    CVMconsolePrintf("Max_stack=%d, max_locals=%d\n",		     CVMjmdMaxStack(jmd), CVMjmdMaxLocals(jmd));    codeStart = CVMjmdCode(jmd);    codeEnd   = &codeStart[CVMjmdCodeLength(jmd)];    /*     * Print out the whole range     */    disassembleRangeWithIndentation(mb, codeStart, codeEnd, level, doRecurse);    /*      * Also print out exception table     */    if (CVMjmdExceptionTableLength(jmd) > 0) {	printExceptionTable(jmd, level);    }}voidCVMbcList(CVMMethodBlock* mb){    CVMbcListWithIndentation(mb, 0, CVM_FALSE);}static voidindent(CVMUint32 level){    while (level-- > 0) {	CVMconsolePrintf("    ");    }}static voiddisassembleRangeWithIndentation(CVMMethodBlock* mb,		      				CVMUint8* codeStart, 				CVMUint8* codeEnd,				CVMUint32 level,				CVMBool doRecurse){    CVMUint8* mbcodeStart = CVMmbJavaCode(mb);    CVMUint8* pc;    /* C stack redzone check */    if (!CVMCstackCheckSize(CVMgetEE(), CVM_REDZONE_disassembleRangeWithIndentation,        "disassembleRangeWithIndentation", CVM_FALSE)) {        return;    }    for (pc = codeStart; pc < codeEnd;	 pc += getOpcodeLength(CVMgetEE(), pc)) {	indent(level);	CVMconsolePrintf("<%d>  (0x%x):    ", pc - mbcodeStart, pc);	printInst(mb, pc, level, doRecurse);    }}voidCVMbcDisassembleRange(CVMMethodBlock* mb,		      		      CVMUint8* codeStart, 		      CVMUint8* codeEnd){    disassembleRangeWithIndentation(mb, codeStart, codeEnd, 0, CVM_FALSE);}static voidprintExceptionTable(CVMJavaMethodDescriptor* jmd, CVMUint32 level){    CVMExceptionHandler *eh = CVMjmdExceptionTable(jmd);    CVMExceptionHandler *ehEnd = eh + CVMjmdExceptionTableLength(jmd);	    indent(level);    CVMconsolePrintf("Exception table:\n");    /* Check each exception handler to see if the pc is in its range */    for (; eh < ehEnd; eh++) { 	indent(level);	CVMconsolePrintf("    start=%d\tend=%d\thandler=%d\n",			 eh->startpc, eh->endpc, eh->handlerpc);    }}static const char * const basicTypeNames[] = {    0,    0,    "Object",    0,    "boolean",    "char",    "float",    "double",    "byte",    "short",    "int",    "long",    0, /* unused */    0, /* unused */    0, /* unused */    0, /* unused */    0, /* unused */    "void"};static void printInst(CVMMethodBlock* mb, 	  CVMUint8* pc, 	  CVMUint32 level, 	  CVMBool doRecurse){    CVMClassBlock*   cb = CVMmbClassBlock(mb);    CVMConstantPool* cp = CVMcbConstantPool(cb);    CVMUint8*        codeStart = CVMmbJavaCode(mb);    CVMOpcode        opcode = (CVMOpcode)*pc;        CVMconsolePrintf("%s ", CVMopnames[opcode]);    switch(opcode) {    case opc_aload: case opc_astore:    case opc_fload: case opc_fstore:    case opc_iload: case opc_istore:    case opc_lload: case opc_lstore:    case opc_dload: case opc_dstore:    case opc_ret: {	CVMconsolePrintf("%d", pc[1]);	break;    }    case opc_iinc: {	CVMconsolePrintf("%d %d", pc[1], pc[2]);	break;    }    case opc_newarray: {	CVMBasicType t = (CVMBasicType)pc[1];	CVMconsolePrintf("%s", basicTypeNames[t]);	break;    }    case opc_anewarray: case opc_anewarray_quick: {	CVMUint32 idx = CVMgetInt16(pc+1);	CVMconsolePrintf("class #%d", idx);	break;    }    case opc_sipush: {	CVMInt32 number = CVMgetInt16(pc+1);	CVMconsolePrintf("%d", number);	break;    }    case opc_bipush: {	CVMInt32 number = pc[1];	CVMconsolePrintf("%d", number);	break;    }    case opc_ldc_quick: case opc_aldc_quick:    case opc_aldc_ind_quick: case opc_ldc: {	CVMUint32 index = pc[1];	CVMconsolePrintf("#%d", index);	break;    }    case opc_invokevirtual_quick_w:    case opc_invokenonvirtual_quick:    case opc_invokestatic_quick:    case opc_invokestatic_checkinit_quick:     case opc_invokeinterface_quick:    case opc_invokestatic: {	CVMUint32 index = CVMgetInt16(pc+1);	CVMconsolePrintf("#%d", index);	if (CVMcpIsResolved(cp, index)) {	    CVMMethodBlock* targetMb = CVMcpGetMb(cp, index);	    CVMconsolePrintf(" <%C.%M>", CVMmbClassBlock(targetMb), targetMb);	    if (doRecurse && CVMmbIsJava(targetMb) &&		(CVMmbCodeLength(targetMb) < 20)) {		CVMconsolePrintf("\n");		if (level > 10) {		    CVMconsolePrintf("NO RECURSION -- GETTING TOO DEEP\n");		} else {		    CVMbcListWithIndentation(targetMb, level+1, CVM_TRUE);		}	    }	}	break;    }    case opc_invokesuper_quick: {	CVMUint32 index = CVMgetInt16(pc+1);	CVMconsolePrintf("#%d", index);	if (CVMcpIsResolved(cp, index)) {	    CVMMethodBlock* targetMb = CVMcpGetMb(cp, index);	    CVMClassBlock* supercb = CVMcbSuperclass(CVMmbClassBlock(targetMb));	    /* Get superclass method */	    targetMb = CVMcbMethodTableSlot(supercb, index);	    CVMconsolePrintf(" <%C.%M>", CVMmbClassBlock(targetMb), targetMb);	    if (doRecurse && CVMmbIsJava(targetMb) &&		(CVMmbCodeLength(targetMb) < 20)) {		CVMconsolePrintf("\n");		if (level > 10) {		    CVMconsolePrintf("NO RECURSION -- GETTING TOO DEEP\n");		} else {		    CVMbcListWithIndentation(targetMb, level+1, CVM_TRUE);		}	    }	}	break;    }    /*     * I don't know the targets precisely here, and I don't want to waste     * any time finding out.      */    case opc_invokespecial:    case opc_invokevirtual:    case opc_invokeinterface: {	CVMUint32 index = CVMgetInt16(pc+1);	CVMconsolePrintf("#%d", index);	if (CVMcpIsResolved(cp, index)) {	    CVMMethodBlock* targetMb = CVMcpGetMb(cp, index);	    CVMconsolePrintf(" <%C.%M>", CVMmbClassBlock(targetMb), targetMb);	}	break;    }    case opc_ldc_w:     case opc_ldc2_w:    case opc_ldc_w_quick:    case opc_aldc_w_quick:    case opc_aldc_ind_w_quick:    case opc_ldc2_w_quick: {	CVMUint32 index = CVMgetInt16(pc+1);	CVMconsolePrintf("#%d", index);	break;    }    case opc_instanceof: case opc_checkcast:    case opc_new:    case opc_new_quick:    case opc_new_checkinit_quick:     case opc_checkcast_quick:    case opc_instanceof_quick: {	CVMUint32 index = CVMgetInt16(pc+1);	CVMconsolePrintf("#%d", index);	if (CVMcpIsResolved(cp, index)) {	    CVMClassBlock* targetCb = CVMcpGetCb(cp, index);	    CVMconsolePrintf(" <%C>", targetCb);	}	break;    }    case opc_multianewarray_quick: {	CVMUint32 index = CVMgetInt16(pc+1);	CVMconsolePrintf("#%d ndim=%d", index, pc[3]);	break;    }    case opc_getstatic:    case opc_putstatic:    case opc_getstatic_quick:    case opc_putstatic_quick:    case opc_agetstatic_quick:    case opc_aputstatic_quick:     case opc_getstatic2_quick:    case opc_putstatic2_quick:    case opc_agetstatic_checkinit_quick:    case opc_aputstatic_checkinit_quick:    case opc_getstatic_checkinit_quick:     case opc_getstatic2_checkinit_quick:     case opc_putstatic_checkinit_quick:     case opc_putstatic2_checkinit_quick:      case opc_getfield_quick_w:    case opc_putfield_quick_w:    case opc_putfield:    case opc_getfield: {	CVMUint32 index = CVMgetInt16(pc+1);	CVMconsolePrintf("#%d", index);	if (CVMcpIsResolved(cp, index)) {	    CVMFieldBlock* targetFb = CVMcpGetFb(cp, index);	    CVMconsolePrintf(" <%C.%F>", CVMfbClassBlock(targetFb), targetFb);	}	break;    }    case opc_jsr: case opc_goto:    case opc_ifeq: case opc_ifge: case opc_ifgt:    case opc_ifle: case opc_iflt: case opc_ifne:    case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpge:    case opc_if_icmpgt: case opc_if_icmple: case opc_if_icmplt:    case opc_if_acmpeq: case opc_if_acmpne:    case opc_ifnull: case opc_ifnonnull: {	CVMUint32 target = (CVMUint32)(pc - codeStart + CVMgetInt16(pc+1));	CVMconsolePrintf("<%d>", target);	break;    }    case opc_getfield_quick:    case opc_putfield_quick:    case opc_getfield2_quick:    case opc_putfield2_quick:    case opc_agetfield_quick:    case opc_aputfield_quick: {	CVMUint32 index = pc[1];	CVMconsolePrintf("#%d", index);	break;    }    case opc_invokevirtualobject_quick:    case opc_invokevirtual_quick:    case opc_ainvokevirtual_quick:    case opc_dinvokevirtual_quick:    case opc_vinvokevirtual_quick: {	CVMconsolePrintf("#%d args=%d", pc[1], pc[2]);	break;    }    default: break; /* print nothing */    }    CVMconsolePrintf("\n");}#endif /* CVM_DEBUG */

⌨️ 快捷键说明

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