split_verify.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,985 行 · 第 1/5 页
C
1,985 行
/* * @(#)split_verify.c 1.7 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. * *//* * CVM's split verifier implementation. Derived from KVM's verifierUtil.h... */#include "javavm/include/clib.h"#include "javavm/include/porting/ansi/setjmp.h"#include "javavm/include/porting/ansi/limits.h"#include "javavm/include/defs.h"#include "javavm/include/classes.h"#include "javavm/include/typeid.h"#include "javavm/include/globals.h"#include "javavm/include/preloader.h"#include "javavm/include/split_verify.h"#include "javavm/include/opcodes.h"#include "javavm/include/constantpool.h"#include "javavm/include/basictypes.h"#include "javavm/include/bcattr.h"#include <stddef.h>#include "javavm/include/common_exceptions.h"#include "javavm/include/interpreter.h" /* for CVMexceptionOccurred */#include "javavm/include/directmem.h" /* for CVMD_gcUnsafeExec *//* * This file is the concatenation of 3 files from KVM. * This was done to allow for better coupling between functions * by the compiler (e.g. inlining) for better speed. * Within the context of CVM, it is entirely shared. *//* See opcode mappings at the end of this section *//* * ------------------------------------------------------------------------ * * General types * * ------------------------------------------------------------------------ * *//* * In order to split the verifier into a VM-specific part and a VM * independent part the verifier uses a variable typing * system that is slightly different from the surrounding VM. * * The following types are use and have the same meaning as they do in KVM * * CLASS A reference to a class data structure * METHOD A reference to a method data structure */typedef CVMClassBlock* CLASS;typedef CVMMethodBlock* METHOD;typedef CVMFieldBlock* FIELD;typedef CVMTypeID NameTypeKey;/* * The following are type definitions that are only used by the * verifier core. * * In KVM a VERIFIERTYPE and a CVMClassTypeID are fairly similar. * The difference lies in the encoding of primitive data types. * For example, a CVMClassTypeID for an Integer is an ASCII 'I', while * a VERIFIERTYPE for an Integer is ITEM_Integer. In both * cases values less than 256 are primitive data types and * those above 256 are reference types and array types. * In KVM the encoding above 256 are the same for CVMClassTypeID * and VERIFIERTYPE. The are two conversion functions * Vfy_toVerifierType() and Vfy_toClassKey() that will * convert between these types. Currently verifierCore * never needs to convert primitive data types this way, * so these functions simply pass the input to the output * * Another small complexity exists with VERIFIERTYPE. * This is that the value pushed by the NEW bytecode * is an encoding of the IP address of the NEW instruction * that will create the object when executed (this encoding * is the same as that done in the stack maps). This is done in * order to distinguish initialized from uninitialized * references of the same type. For instance: * * new Foo * new Foo * invokespecial <init> * * This results in the stack containing one initialized Foo * and one uninitialized Foo. The verifier needs to keep track * of these so after the invokespecial <init> the verifier * changes all occurences of the second Foo from being type * "New from bytecode-n" to being type "Foo". *//* * This represents a class type in the verifier. Again it could * the same as a CLASS and/or CVMClassTypeID, but in KVM it is another * 16 bit data structure that matches the format the loader produces * for the stack map tables. * In CVM, we use a 32-bit data structure, so we can encode larger * PC values as well as our different encoding of class types. */#define VERIFIERTYPE CVMsplitVerifyMapElement/* * Index in to a bytecode array */#define IPINDEX CVMUint32/* * Index into the local variable array maintained by the verifier */#define SLOTINDEX int/* * Index into the constant pool */#define POOLINDEX int/* * Tag from the constant pool */#define POOLTAG CVMConstantPoolEntryTypetypedef struct VfyContext{ CVMExecEnv* ee; /* * This is always the method being verified. */ METHOD methodBeingVerified; CLASS classBeingVerified; /* * Pointer to the bytecodes for the above method */ unsigned char *bytecodesBeingVerified; /* * Private to the implementation */ VERIFIERTYPE* vStack; VERIFIERTYPE* vLocals; unsigned short vMaxStack; unsigned short vFrameSize; unsigned short vSP; unsigned short vSP_bak; VERIFIERTYPE vStack0_bak; /* * Holds the return signature */ VERIFIERTYPE returnSig; /* * Signature & return type of an invocation we're processing. */ CVMMethodTypeID calleeContext; VERIFIERTYPE sigResult; unsigned long * NEWInstructions; /* must call a this.<init> or super.<init> */ CVMBool vNeedInitialization; /* is the current method a constructor? */ CVMBool vIsConstructor; /* does the current method contain a tableswitch or lookupswitch? */ CVMBool vContainsSwitch; /* * Error Handling jump buffer */ jmp_buf vJumpBuffer;#ifdef CVM_DEBUG /* * For printing debug messages */ int vErrorIp;#endif int constantpoolLength; CVMsplitVerifyStackMaps* maps; int noGcPoints; /* * Stack map cache. Set in Mth_getStackMapEntryIP, read in getStackMap */ CVMsplitVerifyMap* cachedMap; IPINDEX cachedMapIP;} VfyContext;/* * All these functions produce a VERIFIERTYPE corresponding to an array type. *//* The "extra info" associated with well-known system classes */#define Vfy_getSystemClassName(x) CVMcbClassName(CVMsystemClass(x))/* These two are private helpers for contructing the others */#define Vfy_getPrimArrayVfyType(x) MAKE_FULLINFO(ITEM_##x, 1, 0)#define Vfy_getSystemVfyType(x) MAKE_FULLINFO(ITEM_Object, 0, \ Vfy_getSystemClassName(x))#define Vfy_getBooleanArrayVerifierType() Vfy_getPrimArrayVfyType(Byte)#define Vfy_getByteArrayVerifierType() Vfy_getPrimArrayVfyType(Byte)#define Vfy_getCharArrayVerifierType() Vfy_getPrimArrayVfyType(Char)#define Vfy_getShortArrayVerifierType() Vfy_getPrimArrayVfyType(Short)#define Vfy_getIntArrayVerifierType() Vfy_getPrimArrayVfyType(Integer)#define Vfy_getLongArrayVerifierType() Vfy_getPrimArrayVfyType(Long)#define Vfy_getFloatArrayVerifierType() Vfy_getPrimArrayVfyType(Float)#define Vfy_getDoubleArrayVerifierType() Vfy_getPrimArrayVfyType(Double)#define Vfy_getObjectArrayVerifierType() MAKE_FULLINFO(ITEM_Object, 1, \ Vfy_getSystemClassName(java_lang_Object))#define Vfy_getObjectVerifierType() Vfy_getSystemVfyType(java_lang_Object)#define Vfy_getStringVerifierType() Vfy_getSystemVfyType(java_lang_String)#define Vfy_getThrowableVerifierType() Vfy_getSystemVfyType(java_lang_Throwable)/* * Even though in CVM the verifier type is based on TypeID, * and even though the latter are reference counted, we will do no reference * counting here. * We get the TypeIds from class blocks only, and we use our own system * to count array depths, so there should be no danger of either having * them disappear out from under us, or of leaving unused entries behind. *//* * Get a class array from a CVMClassTypeID data type that some kind of object * reference. It is used for ANEWARRAY */#define Vfy_getClassArrayVerifierType(typeKey) \ (CVMassert(CVMtypeidFieldIsRef(typeKey)), \ (Vfy_toVerifierType(typeKey) + MAKE_FULLINFO(0, 1, 0)))/* * Gets the VERIFIERTYPE that represents the element type of an array */#define Vfy_getArrayElementType(typeKey) \ (CVMassert(GET_INDIRECTION(typeKey) != 0), \ ((typeKey) - MAKE_FULLINFO(0, 1, 0)))/* * Gets the VERIFIERTYPE that represents the element type of an array * ... which must itself be a reference type -- either another array * or any object type. */#define Vfy_getReferenceArrayElementType(typeKey) \ (((typeKey) == ITEM_Null) ? ITEM_Null : \ (CVMassert((GET_INDIRECTION(typeKey) > 0 && \ GET_ITEM_TYPE(typeKey) == ITEM_Object) || \ GET_INDIRECTION(typeKey) > 1), \ ((typeKey) - MAKE_FULLINFO(0, 1, 0)))\ )/* * Discover if the given classkey is an array of the given dimensions. */#define Vfy_isArrayClassKey(typeKey, dim) \ (CVMtypeidGetArrayDepth(typeKey) >= (dim))/* * This will encode an IP address into a special kind of VERIFIERTYPE such * that it will not be confused with other types. */#define Vfy_createVerifierTypeForNewAt(ip) VERIFY_MAKE_UNINIT(ip)/* * Tests a VERIFIERTYPE to see if it was created using * Vfy_createVerifierTypeForNewAt() */#define Vfy_isVerifierTypeForNew(verifierType) \ (GET_ITEM_TYPE(verifierType) == ITEM_NewObject)/* * Translates a VERIFIERTYPE encoded using Vfy_createVerifierTypeForNewAt() * back into the IP address that was used to create it. */#define Vfy_retrieveIpForNew(verifierType) \ (CVMassert(Vfy_isVerifierTypeForNew(verifierType)), \ GET_EXTRA_INFO(verifierType))/* * ------------------------------------------------------------------------ * Error codes * ------------------------------------------------------------------------ */#define VE_STACK_OVERFLOW 1#define VE_STACK_UNDERFLOW 2#define VE_STACK_EXPECT_CAT1 3#define VE_STACK_BAD_TYPE 4#define VE_LOCALS_OVERFLOW 5#define VE_LOCALS_BAD_TYPE 6#define VE_LOCALS_UNDERFLOW 7#define VE_TARGET_BAD_TYPE 8#define VE_BACK_BRANCH_UNINIT 9#define VE_SEQ_BAD_TYPE 10#define VE_EXPECT_CLASS 11#define VE_EXPECT_THROWABLE 12#define VE_BAD_LOOKUPSWITCH 13#define VE_BAD_LDC 14#define VE_BALOAD_BAD_TYPE 15#define VE_AALOAD_BAD_TYPE 16#define VE_BASTORE_BAD_TYPE 17#define VE_AASTORE_BAD_TYPE 18#define VE_FIELD_BAD_TYPE 19#define VE_EXPECT_METHODREF 20#define VE_ARGS_NOT_ENOUGH 21#define VE_ARGS_BAD_TYPE 22#define VE_EXPECT_INVOKESPECIAL 23#define VE_EXPECT_NEW 24#define VE_EXPECT_UNINIT 25#define VE_BAD_INSTR 26#define VE_EXPECT_ARRAY 27#define VE_MULTIANEWARRAY 28#define VE_EXPECT_NO_RETVAL 29#define VE_RETVAL_BAD_TYPE 30#define VE_EXPECT_RETVAL 31#define VE_RETURN_UNINIT_THIS 32#define VE_BAD_STACKMAP 33#define VE_FALL_THROUGH 34#define VE_EXPECT_ZERO 35#define VE_NARGS_MISMATCH 36#define VE_INVOKESPECIAL 37#define VE_BAD_INIT_CALL 38#define VE_EXPECT_FIELDREF 39#define VE_FINAL_METHOD_OVERRIDE 40#define VE_MIDDLE_OF_BYTE_CODE 41#define VE_BAD_NEW_OFFSET 42#define VE_BAD_EXCEPTION_HANDLER_RANGE 43#define VE_EXPECTING_OBJ_OR_ARR_ON_STK 44#define VE_CONSTPOOL_OVERINDEX 45#define VE_CALLS_CLINIT 46#define VE_OUT_OF_MEMORY 47/* * Error messages. Keyed by VE_* error codes */static const char *verifierStatusInfo[] = { "<no error>", "push would overflow stack", "pop would underflow stack", "expected 1-word stack entity", "unexpected entity type on stack", "local overindexing", "unexpected entity type in locals", "local underindexing (2nd word of long/double at local[0])", "bad typematch at branch/handler target", "back branch with uninit object", "bad typematch at flow join", "class type constantpool entry expected", "catching non-throwable", "unsorted lookupswitch entries", "ldc references unexpected constant pool entry type", "baload indexes unexpected type", "aaload indexes unexpected type", "bastore indexes unexpected type", "aastore indexes unexpected type", "FIELD_BAD_TYPE", "method constantpool entry type expected", "not enough args on stack", "bad args to called method", "invokespecial must be used to invoke <init>", "'new' instruction expected", "uninit object expected in call to <init>", "bad opcode found", "arraylength expects array", "multianewarray dimension or base type wrong", "void method returns value", "method returns wrong type", "<init> doesn't initialize", "non-void method fails to return value", "stackmap format error",
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?