189 unsigned short *table; 190 int entries_used; 191 } hash_table_type; 192 193 #define GET_BUCKET(class_hash, ID)\ 194 (class_hash->buckets[ID / HASH_ROW_SIZE] + ID % HASH_ROW_SIZE) 195 196 /* 197 * There are currently two types of resources that we need to keep 198 * track of (in addition to the CCalloc pool). 199 */ 200 enum { 201 VM_STRING_UTF, /* VM-allocated UTF strings */ 202 VM_MALLOC_BLK /* malloc'ed blocks */ 203 }; 204 205 #define LDC_CLASS_MAJOR_VERSION 49 206 207 #define LDC_METHOD_HANDLE_MAJOR_VERSION 51 208 209 #define ALLOC_STACK_SIZE 16 /* big enough */ 210 211 typedef struct alloc_stack_type { 212 void *ptr; 213 int kind; 214 struct alloc_stack_type *next; 215 } alloc_stack_type; 216 217 /* The context type encapsulates the current invocation of the byte 218 * code verifier. 219 */ 220 struct context_type { 221 222 JNIEnv *env; /* current JNIEnv */ 223 224 /* buffers etc. */ 225 char *message; 226 jint message_buf_len; 227 jboolean err_code; 228 1229 /* Make sure the constant pool item is the right type. */ 1230 int key = (code[offset + 1] << 8) + code[offset + 2]; 1231 this_idata->operand.i = key; 1232 verify_constant_pool_type(context, key, 1 << JVM_CONSTANT_Fieldref); 1233 if (opcode == JVM_OPC_getfield || opcode == JVM_OPC_putfield) 1234 set_protected(context, inumber, key, opcode); 1235 break; 1236 } 1237 1238 case JVM_OPC_invokevirtual: 1239 case JVM_OPC_invokespecial: 1240 case JVM_OPC_invokestatic: 1241 case JVM_OPC_invokedynamic: 1242 case JVM_OPC_invokeinterface: { 1243 /* Make sure the constant pool item is the right type. */ 1244 int key = (code[offset + 1] << 8) + code[offset + 2]; 1245 const char *methodname; 1246 jclass cb = context->class; 1247 fullinfo_type clazz_info; 1248 int is_constructor, is_internal, is_invokedynamic; 1249 int kind = (opcode == JVM_OPC_invokeinterface 1250 ? 1 << JVM_CONSTANT_InterfaceMethodref 1251 : opcode == JVM_OPC_invokedynamic 1252 ? 1 << JVM_CONSTANT_NameAndType 1253 : 1 << JVM_CONSTANT_Methodref); 1254 is_invokedynamic = opcode == JVM_OPC_invokedynamic; 1255 /* Make sure the constant pool item is the right type. */ 1256 verify_constant_pool_type(context, key, kind); 1257 methodname = JVM_GetCPMethodNameUTF(env, cb, key); 1258 check_and_push(context, methodname, VM_STRING_UTF); 1259 is_constructor = !strcmp(methodname, "<init>"); 1260 is_internal = methodname[0] == '<'; 1261 pop_and_free(context); 1262 1263 if (is_invokedynamic) 1264 clazz_info = context->object_info; // anything will do 1265 else 1266 clazz_info = cp_index_to_class_fullinfo(context, key, 1267 JVM_CONSTANT_Methodref); 1268 this_idata->operand.i = key; 1269 this_idata->operand2.fi = clazz_info; 1270 if (is_constructor) { 1271 if (opcode != JVM_OPC_invokespecial) { 1272 CCerror(context, 1273 "Must call initializers using invokespecial"); | 189 unsigned short *table; 190 int entries_used; 191 } hash_table_type; 192 193 #define GET_BUCKET(class_hash, ID)\ 194 (class_hash->buckets[ID / HASH_ROW_SIZE] + ID % HASH_ROW_SIZE) 195 196 /* 197 * There are currently two types of resources that we need to keep 198 * track of (in addition to the CCalloc pool). 199 */ 200 enum { 201 VM_STRING_UTF, /* VM-allocated UTF strings */ 202 VM_MALLOC_BLK /* malloc'ed blocks */ 203 }; 204 205 #define LDC_CLASS_MAJOR_VERSION 49 206 207 #define LDC_METHOD_HANDLE_MAJOR_VERSION 51 208 209 #define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52 210 211 #define ALLOC_STACK_SIZE 16 /* big enough */ 212 213 typedef struct alloc_stack_type { 214 void *ptr; 215 int kind; 216 struct alloc_stack_type *next; 217 } alloc_stack_type; 218 219 /* The context type encapsulates the current invocation of the byte 220 * code verifier. 221 */ 222 struct context_type { 223 224 JNIEnv *env; /* current JNIEnv */ 225 226 /* buffers etc. */ 227 char *message; 228 jint message_buf_len; 229 jboolean err_code; 230 1231 /* Make sure the constant pool item is the right type. */ 1232 int key = (code[offset + 1] << 8) + code[offset + 2]; 1233 this_idata->operand.i = key; 1234 verify_constant_pool_type(context, key, 1 << JVM_CONSTANT_Fieldref); 1235 if (opcode == JVM_OPC_getfield || opcode == JVM_OPC_putfield) 1236 set_protected(context, inumber, key, opcode); 1237 break; 1238 } 1239 1240 case JVM_OPC_invokevirtual: 1241 case JVM_OPC_invokespecial: 1242 case JVM_OPC_invokestatic: 1243 case JVM_OPC_invokedynamic: 1244 case JVM_OPC_invokeinterface: { 1245 /* Make sure the constant pool item is the right type. */ 1246 int key = (code[offset + 1] << 8) + code[offset + 2]; 1247 const char *methodname; 1248 jclass cb = context->class; 1249 fullinfo_type clazz_info; 1250 int is_constructor, is_internal, is_invokedynamic; 1251 int kind; 1252 1253 switch (opcode ) { 1254 case JVM_OPC_invokestatic: 1255 kind = ((context->major_version < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) 1256 ? (1 << JVM_CONSTANT_Methodref) 1257 : ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref))); 1258 break; 1259 case JVM_OPC_invokedynamic: 1260 kind = 1 << JVM_CONSTANT_NameAndType; 1261 break; 1262 case JVM_OPC_invokeinterface: 1263 kind = 1 << JVM_CONSTANT_InterfaceMethodref; 1264 break; 1265 default: 1266 kind = 1 << JVM_CONSTANT_Methodref; 1267 } 1268 1269 is_invokedynamic = opcode == JVM_OPC_invokedynamic; 1270 /* Make sure the constant pool item is the right type. */ 1271 verify_constant_pool_type(context, key, kind); 1272 methodname = JVM_GetCPMethodNameUTF(env, cb, key); 1273 check_and_push(context, methodname, VM_STRING_UTF); 1274 is_constructor = !strcmp(methodname, "<init>"); 1275 is_internal = methodname[0] == '<'; 1276 pop_and_free(context); 1277 1278 if (is_invokedynamic) 1279 clazz_info = context->object_info; // anything will do 1280 else 1281 clazz_info = cp_index_to_class_fullinfo(context, key, 1282 JVM_CONSTANT_Methodref); 1283 this_idata->operand.i = key; 1284 this_idata->operand2.fi = clazz_info; 1285 if (is_constructor) { 1286 if (opcode != JVM_OPC_invokespecial) { 1287 CCerror(context, 1288 "Must call initializers using invokespecial"); |