00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "system.h"
00028 #include "tree.h"
00029 #include "java-tree.h"
00030 #include "javaop.h"
00031 #include "java-opcodes.h"
00032 #include "jcf.h"
00033 #include "java-except.h"
00034 #include "toplev.h"
00035
00036 static void push_pending_label PARAMS ((tree));
00037 static tree merge_types PARAMS ((tree, tree));
00038 static const char *check_pending_block PARAMS ((tree));
00039 static void type_stack_dup PARAMS ((int, int));
00040 static int start_pc_cmp PARAMS ((const PTR, const PTR));
00041 static char *pop_argument_types PARAMS ((tree));
00042
00043 extern int stack_pointer;
00044
00045
00046 tree current_subr;
00047
00048
00049
00050
00051 tree pending_blocks;
00052
00053
00054
00055 static void
00056 push_pending_label (target_label)
00057 tree target_label;
00058 {
00059 if (! LABEL_CHANGED (target_label))
00060 {
00061 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
00062 pending_blocks = target_label;
00063 LABEL_CHANGED (target_label) = 1;
00064 }
00065 }
00066
00067
00068
00069
00070
00071 static const char *
00072 check_pending_block (target_label)
00073 tree target_label;
00074 {
00075 int changed = merge_type_state (target_label);
00076
00077 if (changed)
00078 {
00079 if (changed < 0)
00080 return "types could not be merged";
00081 push_pending_label (target_label);
00082 }
00083
00084 if (current_subr == NULL)
00085 {
00086 if (LABEL_IN_SUBR (target_label))
00087 return "might transfer control into subroutine";
00088 }
00089 else
00090 {
00091 if (LABEL_IN_SUBR (target_label))
00092 {
00093 if (LABEL_SUBR_START (target_label) != current_subr)
00094 return "transfer out of subroutine";
00095 }
00096 else if (! LABEL_VERIFIED (target_label))
00097 {
00098 LABEL_IN_SUBR (target_label) = 1;
00099 LABEL_SUBR_START (target_label) = current_subr;
00100 }
00101 else
00102 return "transfer out of subroutine";
00103 }
00104 return NULL;
00105 }
00106
00107
00108
00109 static int
00110 subroutine_nesting (tree label)
00111 {
00112 int nesting = 0;
00113 while (label != NULL_TREE && LABEL_IN_SUBR (label))
00114 {
00115 if (! LABEL_IS_SUBR_START(label))
00116 label = LABEL_SUBR_START (label);
00117 label = LABEL_SUBR_CONTEXT (label);
00118 nesting++;
00119 }
00120 return nesting;
00121 }
00122
00123
00124
00125
00126
00127
00128 static tree
00129 merge_types (type1, type2)
00130 tree type1, type2;
00131 {
00132 if (type1 == type2)
00133 return type1;
00134 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
00135 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
00136 return TYPE_UNKNOWN;
00137 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
00138 {
00139 int depth1, depth2;
00140 tree tt1, tt2;
00141
00142
00143 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
00144 return type2;
00145 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
00146 return type1;
00147
00148 tt1 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type1));
00149 tt2 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type2));
00150
00151
00152
00153 if (!TYPE_SIZE (tt1))
00154 {
00155 load_class (tt1, 1);
00156 safe_layout_class (tt1);
00157 }
00158
00159 if (!TYPE_SIZE (tt2))
00160 {
00161 load_class (tt2, 1);
00162 safe_layout_class (tt2);
00163 }
00164
00165 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
00166 {
00167 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
00168 {
00169 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
00170 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
00171 tree el_type = NULL_TREE;
00172 if (el_type1 == el_type2)
00173 el_type = el_type1;
00174 else if (TREE_CODE (el_type1) == POINTER_TYPE
00175 && TREE_CODE (el_type2) == POINTER_TYPE)
00176 el_type = merge_types (el_type1, el_type2);
00177 if (el_type != NULL_TREE)
00178 {
00179 HOST_WIDE_INT len1 = java_array_type_length (tt1);
00180 HOST_WIDE_INT len2 = java_array_type_length (tt2);
00181 if (len1 != len2)
00182 len1 = -1;
00183 else if (el_type1 == el_type2)
00184 return type1;
00185 return promote_type (build_java_array_type (el_type, len1));
00186 }
00187 }
00188 return object_ptr_type_node;
00189 }
00190
00191 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
00192 {
00193
00194
00195 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
00196 {
00197
00198
00199
00200 return object_ptr_type_node;
00201 }
00202 else
00203 {
00204 if (can_widen_reference_to (tt2, tt1))
00205 return type1;
00206 else
00207 return object_ptr_type_node;
00208 }
00209 }
00210 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
00211 {
00212 if (can_widen_reference_to (tt1, tt2))
00213 return type2;
00214 else
00215 return object_ptr_type_node;
00216 }
00217
00218 type1 = tt1;
00219 type2 = tt2;
00220
00221 depth1 = class_depth (type1);
00222 depth2 = class_depth (type2);
00223 for ( ; depth1 > depth2; depth1--)
00224 type1 = TYPE_BINFO_BASETYPE (type1, 0);
00225 for ( ; depth2 > depth1; depth2--)
00226 type2 = TYPE_BINFO_BASETYPE (type2, 0);
00227 while (type1 != type2)
00228 {
00229 type1 = TYPE_BINFO_BASETYPE (type1, 0);
00230 type2 = TYPE_BINFO_BASETYPE (type2, 0);
00231 }
00232 return promote_type (type1);
00233 }
00234 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
00235 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
00236 return int_type_node;
00237 return TYPE_UNKNOWN;
00238 }
00239
00240
00241
00242
00243
00244 int
00245 merge_type_state (label)
00246 tree label;
00247 {
00248 int nlocals = DECL_MAX_LOCALS (current_function_decl);
00249 int cur_length = stack_pointer + nlocals;
00250 tree vec = LABEL_TYPE_STATE (label);
00251 tree return_map;
00252 if (vec == NULL_TREE)
00253 {
00254 if (!vec)
00255 {
00256 vec = make_tree_vec (cur_length);
00257 LABEL_TYPE_STATE (label) = vec;
00258 }
00259 while (--cur_length >= 0)
00260 TREE_VEC_ELT (vec, cur_length) = type_map [cur_length];
00261 return 1;
00262 }
00263 else
00264 {
00265 int i;
00266 int changed = 0;
00267 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
00268 && current_subr != label)
00269 return_map = LABEL_RETURN_TYPE_STATE (label);
00270 else
00271 return_map = NULL_TREE;
00272 if (TREE_VEC_LENGTH (vec) != cur_length)
00273 {
00274 return -1;
00275 }
00276 for (i = 0; i < cur_length; i++)
00277 {
00278 tree old_type = TREE_VEC_ELT (vec, i);
00279 tree new_type = merge_types (old_type, type_map [i]);
00280 if (TREE_VEC_ELT (vec, i) != new_type)
00281 {
00282
00283
00284
00285
00286 if (return_map == NULL_TREE || i >= nlocals
00287 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
00288 || (TYPE_IS_WIDE (new_type)
00289 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
00290 changed = 1;
00291 }
00292 TREE_VEC_ELT (vec, i) = new_type;
00293 if (new_type == TYPE_UNKNOWN)
00294 {
00295 if (i >= nlocals)
00296 return -1;
00297 }
00298 else if (TYPE_IS_WIDE (new_type))
00299 i++;
00300 }
00301 return changed;
00302 }
00303 }
00304
00305
00306
00307 static void
00308 type_stack_dup (size, offset)
00309 int size, offset;
00310 {
00311 tree type[4];
00312 int index;
00313 for (index = 0; index < size + offset; index++)
00314 {
00315 type[index] = stack_type_map[stack_pointer - 1];
00316 if (type[index] == void_type_node)
00317 {
00318 index++;
00319 type[index] = stack_type_map[stack_pointer - 2];
00320 if (! TYPE_IS_WIDE (type[index]))
00321 abort ();
00322 if (index == size || index == size + offset)
00323
00324 abort ();
00325 }
00326 pop_type (type[index]);
00327 }
00328 for (index = size; --index >= 0; )
00329 {
00330 if (type[index] != void_type_node)
00331 push_type (type[index]);
00332 }
00333
00334 for (index = size + offset; --index >= 0; )
00335 {
00336 if (type[index] != void_type_node)
00337 push_type (type[index]);
00338 }
00339 }
00340
00341
00342 struct pc_index
00343 {
00344 int start_pc;
00345 int index;
00346 };
00347
00348
00349 static int
00350 start_pc_cmp (xp, yp)
00351 const PTR xp;
00352 const PTR yp;
00353 {
00354 const struct pc_index *x = (const struct pc_index *) xp;
00355 const struct pc_index *y = (const struct pc_index *) yp;
00356 return x->start_pc - y->start_pc;
00357 }
00358
00359
00360
00361 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
00362 #define INVALID_PC (-1)
00363
00364 #define VERIFICATION_ERROR(MESSAGE) \
00365 do { message = MESSAGE; goto verify_error; } while (0)
00366
00367 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
00368 do { message = MESSAGE; goto error_with_index; } while (0)
00369
00370
00371
00372
00373
00374 static char *
00375 pop_argument_types (arg_types)
00376 tree arg_types;
00377 {
00378 if (arg_types == end_params_node)
00379 return NULL;
00380 if (TREE_CODE (arg_types) == TREE_LIST)
00381 {
00382 char *message = pop_argument_types (TREE_CHAIN (arg_types));
00383 if (message == NULL)
00384 pop_type_0 (TREE_VALUE (arg_types), &message);
00385 return message;
00386 }
00387 abort ();
00388 }
00389
00390 #define POP_TYPE(TYPE, MESSAGE) \
00391 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
00392 if (pmessage != NULL) goto pop_type_error; \
00393 } while (0)
00394
00395 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
00396 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
00397 if (pmessage != NULL) goto pop_type_error; \
00398 } while (0)
00399
00400 #define PUSH_TYPE(TYPE) \
00401 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
00402
00403 #define PUSH_PENDING(LABEL) \
00404 do { tree tmplab = LABEL; \
00405 if ((message = check_pending_block (tmplab)) != NULL) \
00406 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
00407
00408 #ifdef __GNUC__
00409 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
00410 #else
00411 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
00412 #endif
00413
00414 #define BCODE byte_ops
00415
00416
00417
00418 int
00419 verify_jvm_instructions (jcf, byte_ops, length)
00420 JCF* jcf;
00421 const unsigned char *byte_ops;
00422 long length;
00423 {
00424 tree label;
00425 int wide = 0;
00426 int op_code;
00427 int PC;
00428 int oldpc = 0;
00429 int prevpc = 0;
00430 const char *message = 0;
00431 char *pmessage;
00432 int i;
00433 int index;
00434 register unsigned char *p;
00435 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
00436 struct eh_range *eh_ranges;
00437 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
00438 struct pc_index *starts;
00439 int eh_count;
00440
00441 jint int_value = -1;
00442
00443 pending_blocks = NULL_TREE;
00444
00445
00446 method_init_exceptions ();
00447 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
00448 eh_count = JCF_readu2 (jcf);
00449
00450
00451
00452 starts = (struct pc_index *) xmalloc (eh_count * sizeof (struct pc_index));
00453 for (i = 0; i < eh_count; ++i)
00454 {
00455 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
00456 starts[i].index = i;
00457 }
00458 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
00459
00460 for (i = 0; i < eh_count; ++i)
00461 {
00462 int start_pc, end_pc, handler_pc, catch_type;
00463
00464 p = jcf->read_ptr + 8 * starts[i].index;
00465
00466 start_pc = GET_u2 (p);
00467 end_pc = GET_u2 (p+2);
00468 handler_pc = GET_u2 (p+4);
00469 catch_type = GET_u2 (p+6);
00470
00471 if (start_pc < 0 || start_pc >= length
00472 || end_pc < 0 || end_pc > length || start_pc >= end_pc
00473 || handler_pc < 0 || handler_pc >= length
00474 || (handler_pc >= start_pc && handler_pc < end_pc)
00475 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
00476 || (end_pc < length &&
00477 ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START))
00478 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
00479 {
00480 error ("bad pc in exception_table");
00481 free (starts);
00482 return 0;
00483 }
00484
00485 add_handler (start_pc, end_pc,
00486 lookup_label (handler_pc),
00487 catch_type == 0 ? NULL_TREE
00488 : get_class_constant (jcf, catch_type));
00489
00490 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
00491 }
00492
00493 free (starts);
00494 handle_nested_ranges ();
00495
00496 for (PC = 0;;)
00497 {
00498 tree type, tmp;
00499 if (((PC != INVALID_PC
00500 && instruction_bits [PC] & BCODE_TARGET) != 0)
00501 || PC == 0)
00502 {
00503 PUSH_PENDING (lookup_label (PC));
00504 INVALIDATE_PC;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513 if (current_subr
00514 && PC == INVALID_PC)
00515 {
00516 if (pending_blocks == NULL_TREE
00517 || (subroutine_nesting (pending_blocks)
00518 < subroutine_nesting (current_subr)))
00519 {
00520 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
00521 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
00522 tmp = LABEL_RETURN_LABELS (current_subr);
00523
00524
00525
00526
00527
00528 current_subr = LABEL_SUBR_CONTEXT (current_subr);
00529
00530 if (RETURN_MAP_ADJUSTED (ret_map))
00531 {
00532
00533
00534
00535 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
00536 {
00537 tree return_label = TREE_VALUE (tmp);
00538 tree return_state = LABEL_TYPE_STATE (return_label);
00539 if (return_state == NULL_TREE)
00540 {
00541
00542
00543
00544
00545
00546 }
00547 else
00548 {
00549
00550
00551
00552 for (index = size; --index >= 0; )
00553 {
00554 type_map[index] = TREE_VEC_ELT (ret_map, index);
00555 if (type_map[index] == TYPE_UNUSED)
00556 type_map[index]
00557 = TREE_VEC_ELT (return_state, index);
00558 }
00559 }
00560 PUSH_PENDING (return_label);
00561 }
00562 }
00563 }
00564 }
00565 if (PC == INVALID_PC)
00566 {
00567 label = pending_blocks;
00568 if (label == NULL_TREE)
00569 break;
00570 pending_blocks = LABEL_PENDING_CHAIN (label);
00571 LABEL_CHANGED (label) = 0;
00572
00573 if (LABEL_IN_SUBR (label))
00574 current_subr = LABEL_SUBR_START (label);
00575 else
00576 current_subr = NULL_TREE;
00577
00578
00579
00580
00581 load_type_state (label);
00582 PC = LABEL_PC (label);
00583 }
00584 else if (PC >= length)
00585 VERIFICATION_ERROR ("falling through end of method");
00586
00587
00588
00589 oldpc = PC;
00590
00591 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
00592 VERIFICATION_ERROR ("PC not at instruction start");
00593
00594 instruction_bits[PC] |= BCODE_VERIFIED;
00595
00596 eh_ranges = find_handler (oldpc);
00597
00598 op_code = byte_ops[PC++];
00599 switch (op_code)
00600 {
00601 int is_static, is_putting;
00602 case OPCODE_nop:
00603 break;
00604 case OPCODE_iconst_m1:
00605 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
00606 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
00607 i = op_code - OPCODE_iconst_0;
00608 goto push_int;
00609 push_int:
00610 if (byte_ops[PC] == OPCODE_newarray
00611 || byte_ops[PC] == OPCODE_anewarray)
00612 int_value = i;
00613 PUSH_TYPE (int_type_node); break;
00614 case OPCODE_lconst_0: case OPCODE_lconst_1:
00615 PUSH_TYPE (long_type_node); break;
00616 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
00617 PUSH_TYPE (float_type_node); break;
00618 case OPCODE_dconst_0: case OPCODE_dconst_1:
00619 PUSH_TYPE (double_type_node); break;
00620 case OPCODE_bipush:
00621 i = IMMEDIATE_s1;
00622 goto push_int;
00623 case OPCODE_sipush:
00624 i = IMMEDIATE_s2;
00625 goto push_int;
00626 case OPCODE_iload: type = int_type_node; goto general_load;
00627 case OPCODE_lload: type = long_type_node; goto general_load;
00628 case OPCODE_fload: type = float_type_node; goto general_load;
00629 case OPCODE_dload: type = double_type_node; goto general_load;
00630 case OPCODE_aload: type = ptr_type_node; goto general_load;
00631 general_load:
00632 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
00633 wide = 0;
00634 goto load;
00635 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
00636 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
00637 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
00638 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
00639 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
00640 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
00641 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
00642 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
00643 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
00644 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
00645 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
00646 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
00647 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
00648 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
00649 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
00650 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
00651 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
00652 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
00653 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
00654 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
00655 load:
00656 if (index < 0
00657 || (index + TYPE_IS_WIDE (type)
00658 >= DECL_MAX_LOCALS (current_function_decl)))
00659 VERIFICATION_ERROR_WITH_INDEX
00660 ("invalid local variable index %d in load");
00661 tmp = type_map[index];
00662 if (tmp == TYPE_UNKNOWN)
00663 VERIFICATION_ERROR_WITH_INDEX
00664 ("loading local variable %d which has unknown type");
00665 else if (tmp == TYPE_SECOND
00666 || (TYPE_IS_WIDE (type)
00667 && type_map[index+1] != void_type_node)
00668 || (type == ptr_type_node
00669 ? TREE_CODE (tmp) != POINTER_TYPE
00670 : type == int_type_node
00671 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
00672 : type != tmp))
00673 VERIFICATION_ERROR_WITH_INDEX
00674 ("loading local variable %d which has invalid type");
00675 PUSH_TYPE (tmp);
00676 goto note_used;
00677 case OPCODE_istore: type = int_type_node; goto general_store;
00678 case OPCODE_lstore: type = long_type_node; goto general_store;
00679 case OPCODE_fstore: type = float_type_node; goto general_store;
00680 case OPCODE_dstore: type = double_type_node; goto general_store;
00681 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
00682 general_store:
00683 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
00684 wide = 0;
00685 goto store;
00686 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
00687 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
00688 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
00689 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
00690 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
00691 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
00692 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
00693 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
00694 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
00695 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
00696 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
00697 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
00698 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
00699 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
00700 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
00701 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
00702 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
00703 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
00704 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
00705 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
00706 store:
00707 if (index < 0
00708 || (index + TYPE_IS_WIDE (type)
00709 >= DECL_MAX_LOCALS (current_function_decl)))
00710 {
00711 VERIFICATION_ERROR_WITH_INDEX
00712 ("invalid local variable index %d in store");
00713 return 0;
00714 }
00715 POP_TYPE_CONV (type, type, NULL);
00716 type_map[index] = type;
00717
00718
00719 prev_eh_ranges = NULL_EH_RANGE;
00720
00721
00722
00723 find_local_variable (index, type, oldpc);
00724
00725 if (TYPE_IS_WIDE (type))
00726 type_map[index+1] = TYPE_SECOND;
00727
00728 note_used:
00729
00730
00731 if (current_subr)
00732 {
00733 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
00734 tree subr_vec = LABEL_TYPE_STATE (current_subr);
00735 int len = 1 + TYPE_IS_WIDE (type);
00736 while (--len >= 0)
00737 {
00738 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
00739 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
00740 }
00741 }
00742 break;
00743 case OPCODE_iadd:
00744 case OPCODE_iand:
00745 case OPCODE_idiv:
00746 case OPCODE_imul:
00747 case OPCODE_ior:
00748 case OPCODE_irem:
00749 case OPCODE_ishl:
00750 case OPCODE_ishr:
00751 case OPCODE_isub:
00752 case OPCODE_iushr:
00753 case OPCODE_ixor:
00754 type = int_type_node; goto binop;
00755 case OPCODE_ineg:
00756 case OPCODE_i2c:
00757 case OPCODE_i2b:
00758 case OPCODE_i2s:
00759 type = int_type_node; goto unop;
00760 case OPCODE_ladd:
00761 case OPCODE_land:
00762 case OPCODE_ldiv:
00763 case OPCODE_lsub:
00764 case OPCODE_lmul:
00765 case OPCODE_lrem:
00766 case OPCODE_lor:
00767 case OPCODE_lxor:
00768 type = long_type_node; goto binop;
00769 case OPCODE_lneg:
00770 type = long_type_node; goto unop;
00771 case OPCODE_fadd: case OPCODE_fsub:
00772 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
00773 type = float_type_node; goto binop;
00774 case OPCODE_fneg:
00775 type = float_type_node; goto unop;
00776 case OPCODE_dadd: case OPCODE_dsub:
00777 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
00778 type = double_type_node; goto binop;
00779 case OPCODE_dneg:
00780 type = double_type_node; goto unop;
00781 unop:
00782 pop_type (type);
00783 PUSH_TYPE (type);
00784 break;
00785 binop:
00786 pop_type (type);
00787 pop_type (type);
00788 PUSH_TYPE (type);
00789 break;
00790 case OPCODE_lshl:
00791 case OPCODE_lshr:
00792 case OPCODE_lushr:
00793 pop_type (int_type_node);
00794 pop_type (long_type_node);
00795 PUSH_TYPE (long_type_node);
00796 break;
00797 case OPCODE_iinc:
00798 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
00799 PC += wide + 1;
00800 wide = 0;
00801 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
00802 VERIFICATION_ERROR ("invalid local variable index in iinc");
00803 tmp = type_map[index];
00804 if (tmp == NULL_TREE
00805 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
00806 VERIFICATION_ERROR ("invalid local variable type in iinc");
00807 break;
00808 case OPCODE_i2l:
00809 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
00810 case OPCODE_i2f:
00811 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
00812 case OPCODE_i2d:
00813 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
00814 case OPCODE_l2i:
00815 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
00816 case OPCODE_l2f:
00817 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
00818 case OPCODE_l2d:
00819 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
00820 case OPCODE_f2i:
00821 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
00822 case OPCODE_f2l:
00823 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
00824 case OPCODE_f2d:
00825 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
00826 case OPCODE_d2i:
00827 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
00828 case OPCODE_d2l:
00829 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
00830 case OPCODE_d2f:
00831 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
00832 case OPCODE_lcmp:
00833 type = long_type_node; goto compare;
00834 case OPCODE_fcmpl:
00835 case OPCODE_fcmpg:
00836 type = float_type_node; goto compare;
00837 case OPCODE_dcmpl:
00838 case OPCODE_dcmpg:
00839 type = double_type_node; goto compare;
00840 compare:
00841 pop_type (type); pop_type (type);
00842 PUSH_TYPE (int_type_node); break;
00843 case OPCODE_ifeq:
00844 case OPCODE_ifne:
00845 case OPCODE_iflt:
00846 case OPCODE_ifge:
00847 case OPCODE_ifgt:
00848 case OPCODE_ifle:
00849 pop_type (int_type_node); goto cond;
00850 case OPCODE_ifnull:
00851 case OPCODE_ifnonnull:
00852 pop_type (ptr_type_node ); goto cond;
00853 case OPCODE_if_icmpeq:
00854 case OPCODE_if_icmpne:
00855 case OPCODE_if_icmplt:
00856 case OPCODE_if_icmpge:
00857 case OPCODE_if_icmpgt:
00858 case OPCODE_if_icmple:
00859 pop_type (int_type_node); pop_type (int_type_node); goto cond;
00860 case OPCODE_if_acmpeq:
00861 case OPCODE_if_acmpne:
00862 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
00863 goto cond;
00864 cond:
00865 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
00866 break;
00867 case OPCODE_goto:
00868 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
00869 INVALIDATE_PC;
00870 break;
00871 case OPCODE_wide:
00872 switch (byte_ops[PC])
00873 {
00874 case OPCODE_iload: case OPCODE_lload:
00875 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
00876 case OPCODE_istore: case OPCODE_lstore:
00877 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
00878 case OPCODE_iinc:
00879 case OPCODE_ret:
00880 wide = 1;
00881 break;
00882 default:
00883 VERIFICATION_ERROR ("invalid use of wide instruction");
00884 }
00885 break;
00886 case OPCODE_return: type = void_type_node; goto ret;
00887 case OPCODE_ireturn:
00888 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
00889 || TREE_CODE (return_type) == CHAR_TYPE
00890 || TREE_CODE (return_type) == INTEGER_TYPE)
00891 && TYPE_PRECISION (return_type) <= 32)
00892 type = return_type;
00893 else
00894 type = NULL_TREE;
00895 goto ret;
00896 case OPCODE_lreturn: type = long_type_node; goto ret;
00897 case OPCODE_freturn: type = float_type_node; goto ret;
00898 case OPCODE_dreturn: type = double_type_node; goto ret;
00899 case OPCODE_areturn:
00900 if (TREE_CODE (return_type) == POINTER_TYPE)
00901 type = return_type;
00902 else
00903 type = NULL_TREE;
00904 goto ret;
00905 ret:
00906 if (type != return_type)
00907 VERIFICATION_ERROR ("incorrect ?return opcode");
00908 if (type != void_type_node)
00909 POP_TYPE(type, "return value has wrong type");
00910 INVALIDATE_PC;
00911 break;
00912 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
00913 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
00914 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
00915 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
00916 field:
00917 {
00918 tree field_signature, field_type;
00919 index = IMMEDIATE_u2;
00920 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
00921 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
00922 if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref)
00923 VERIFICATION_ERROR
00924 ("field instruction does not reference a Fieldref");
00925 field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index);
00926 field_type = get_type_from_signature (field_signature);
00927 if (is_putting)
00928 POP_TYPE (field_type, "incorrect type for field");
00929 if (! is_static)
00930 {
00931 int clindex = COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
00932 index);
00933 tree self_type = get_class_constant (current_jcf, clindex);
00934
00935 POP_TYPE(self_type, "incorrect type for field reference");
00936 }
00937 if (! is_putting)
00938 PUSH_TYPE (field_type);
00939 break;
00940 }
00941 case OPCODE_new:
00942 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
00943 break;
00944 case OPCODE_dup: wide = 1; index = 0; goto dup;
00945 case OPCODE_dup_x1: wide = 1; index = 1; goto dup;
00946 case OPCODE_dup_x2: wide = 1; index = 2; goto dup;
00947 case OPCODE_dup2: wide = 2; index = 0; goto dup;
00948 case OPCODE_dup2_x1: wide = 2; index = 1; goto dup;
00949 case OPCODE_dup2_x2: wide = 2; index = 2; goto dup;
00950 dup:
00951 if (wide + index > stack_pointer)
00952 VERIFICATION_ERROR ("stack underflow - dup* operation");
00953 type_stack_dup (wide, index);
00954 wide = 0;
00955 break;
00956 case OPCODE_pop: index = 1; goto pop;
00957 case OPCODE_pop2: index = 2; goto pop;
00958 pop:
00959 if (stack_pointer < index)
00960 VERIFICATION_ERROR ("stack underflow");
00961 stack_pointer -= index;
00962 break;
00963 case OPCODE_swap:
00964 if (stack_pointer < 2)
00965 VERIFICATION_ERROR ("stack underflow (in swap)");
00966 else
00967 {
00968 tree type1 = stack_type_map[stack_pointer - 1];
00969 tree type2 = stack_type_map[stack_pointer - 2];
00970 if (type1 == void_type_node || type2 == void_type_node)
00971 VERIFICATION_ERROR ("verifier (swap): double or long value");
00972 stack_type_map[stack_pointer - 2] = type1;
00973 stack_type_map[stack_pointer - 1] = type2;
00974 }
00975 break;
00976 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
00977 case OPCODE_ldc2_w:
00978 case OPCODE_ldc_w:
00979 index = IMMEDIATE_u2; goto ldc;
00980 ldc:
00981 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
00982 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
00983 int_value = -1;
00984 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
00985 {
00986 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
00987 case CONSTANT_Float: type = float_type_node; goto check_ldc;
00988 case CONSTANT_String: type = string_type_node; goto check_ldc;
00989 case CONSTANT_Long: type = long_type_node; goto check_ldc;
00990 case CONSTANT_Double: type = double_type_node; goto check_ldc;
00991 check_ldc:
00992 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
00993 break;
00994
00995 default:
00996 VERIFICATION_ERROR ("bad constant pool tag in ldc");
00997 }
00998 if (type == int_type_node)
00999 {
01000 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
01001 goto push_int;
01002 }
01003 PUSH_TYPE (type);
01004 break;
01005
01006 case OPCODE_invokevirtual:
01007 case OPCODE_invokespecial:
01008 case OPCODE_invokestatic:
01009 case OPCODE_invokeinterface:
01010 {
01011 tree sig, method_name, method_type, self_type;
01012 int self_is_interface, tag;
01013 index = IMMEDIATE_u2;
01014 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
01015 VERIFICATION_ERROR_WITH_INDEX
01016 ("bad constant pool index %d for invoke");
01017 tag = JPOOL_TAG (current_jcf, index);
01018 if (op_code == OPCODE_invokeinterface)
01019 {
01020 if (tag != CONSTANT_InterfaceMethodref)
01021 VERIFICATION_ERROR
01022 ("invokeinterface does not reference an InterfaceMethodref");
01023 }
01024 else
01025 {
01026 if (tag != CONSTANT_Methodref)
01027 VERIFICATION_ERROR ("invoke does not reference a Methodref");
01028 }
01029 sig = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index);
01030 self_type = get_class_constant
01031 (current_jcf, COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
01032 index));
01033 if (! CLASS_LOADED_P (self_type))
01034 load_class (self_type, 1);
01035 self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
01036 method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, index);
01037 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
01038 IDENTIFIER_LENGTH (sig));
01039 if (TREE_CODE (method_type) != FUNCTION_TYPE)
01040 VERIFICATION_ERROR ("bad method signature");
01041 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
01042 if (pmessage != NULL)
01043 {
01044 message = "invalid argument type";
01045 goto pop_type_error;
01046 }
01047
01048
01049 if (ID_CLINIT_P (method_name))
01050 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
01051
01052 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
01053 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
01054
01055 if (op_code != OPCODE_invokestatic)
01056 POP_TYPE (self_type,
01057 "stack type not subclass of invoked method's class");
01058
01059 switch (op_code)
01060 {
01061 case OPCODE_invokeinterface:
01062 {
01063 int nargs = IMMEDIATE_u1;
01064 int notZero = IMMEDIATE_u1;
01065
01066 if (!nargs || notZero)
01067 VERIFICATION_ERROR
01068 ("invalid argument number in invokeinterface");
01069
01070
01071 if (! self_is_interface)
01072 VERIFICATION_ERROR ("invokeinterface calls method not in interface");
01073 break;
01074 default:
01075 if (self_is_interface)
01076 VERIFICATION_ERROR ("method in interface called");
01077 }
01078 }
01079
01080 if (TREE_TYPE (method_type) != void_type_node)
01081 PUSH_TYPE (TREE_TYPE (method_type));
01082 break;
01083 }
01084
01085 case OPCODE_arraylength:
01086
01087 pop_type( ptr_type_node );
01088 PUSH_TYPE( int_type_node );
01089 break;
01090
01091
01092
01093
01094 case OPCODE_iastore: type = int_type_node; goto astore;
01095 case OPCODE_lastore: type = long_type_node; goto astore;
01096 case OPCODE_fastore: type = float_type_node; goto astore;
01097 case OPCODE_dastore: type = double_type_node; goto astore;
01098 case OPCODE_aastore: type = ptr_type_node; goto astore;
01099 case OPCODE_bastore: type = int_type_node; goto astore;
01100 case OPCODE_castore: type = int_type_node; goto astore;
01101 case OPCODE_sastore: type = int_type_node; goto astore;
01102 astore:
01103
01104 pop_type (type);
01105 pop_type (int_type_node);
01106 pop_type (ptr_type_node);
01107 break;
01108
01109
01110
01111 case OPCODE_iaload: type = int_type_node; goto aload;
01112 case OPCODE_laload: type = long_type_node; goto aload;
01113 case OPCODE_faload: type = float_type_node; goto aload;
01114 case OPCODE_daload: type = double_type_node; goto aload;
01115 case OPCODE_aaload: type = ptr_type_node; goto aload;
01116 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
01117 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
01118 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
01119 aload:
01120 pop_type (int_type_node);
01121 tmp = pop_type (ptr_type_node);
01122 if (is_array_type_p (tmp))
01123 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
01124 else if (tmp != TYPE_NULL)
01125 VERIFICATION_ERROR ("array load from non-array type");
01126 PUSH_TYPE (type);
01127 break;
01128
01129 case OPCODE_anewarray:
01130 type = get_class_constant (current_jcf, IMMEDIATE_u2);
01131 type = promote_type (type);
01132 goto newarray;
01133
01134 case OPCODE_newarray:
01135 index = IMMEDIATE_u1;
01136 type = decode_newarray_type (index);
01137 if (type == NULL_TREE)
01138 VERIFICATION_ERROR ("invalid type code in newarray opcode");
01139 goto newarray;
01140
01141 newarray:
01142 if (int_value >= 0 && prevpc >= 0)
01143 {
01144
01145
01146 switch (byte_ops[prevpc])
01147 {
01148 case OPCODE_iconst_0: case OPCODE_iconst_1:
01149 case OPCODE_iconst_2: case OPCODE_iconst_3:
01150 case OPCODE_iconst_4: case OPCODE_iconst_5:
01151 case OPCODE_bipush: case OPCODE_sipush:
01152 case OPCODE_ldc: case OPCODE_ldc_w:
01153 break;
01154 default:
01155 int_value = -1;
01156 }
01157 }
01158 else
01159 int_value = -1;
01160 type = build_java_array_type (type, int_value);
01161 pop_type (int_type_node);
01162 PUSH_TYPE (type);
01163 break;
01164
01165 case OPCODE_multianewarray:
01166 {
01167 int ndim, i;
01168 index = IMMEDIATE_u2;
01169 ndim = IMMEDIATE_u1;
01170
01171 if( ndim < 1 )
01172 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
01173
01174 for( i = 0; i < ndim; i++ )
01175 pop_type (int_type_node);
01176 PUSH_TYPE (get_class_constant (current_jcf, index));
01177 break;
01178 }
01179
01180 case OPCODE_aconst_null:
01181 PUSH_TYPE (ptr_type_node);
01182 break;
01183
01184 case OPCODE_athrow:
01185
01186 POP_TYPE (throwable_type_node, "missing throwable at athrow" );
01187 INVALIDATE_PC;
01188 break;
01189
01190 case OPCODE_checkcast:
01191 POP_TYPE (object_ptr_type_node,
01192 "checkcast operand is not a pointer");
01193 type = get_class_constant (current_jcf, IMMEDIATE_u2);
01194 PUSH_TYPE (type);
01195 break;
01196 case OPCODE_instanceof:
01197 POP_TYPE (object_ptr_type_node,
01198 "instanceof operand is not a pointer");
01199 get_class_constant (current_jcf, IMMEDIATE_u2);
01200 PUSH_TYPE (int_type_node);
01201 break;
01202
01203 case OPCODE_tableswitch:
01204 {
01205 jint low, high;
01206
01207 POP_TYPE (int_type_node, "missing int for tableswitch");
01208 while (PC%4)
01209 {
01210 if (byte_ops[PC++])
01211 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
01212 }
01213 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
01214 low = IMMEDIATE_s4;
01215 high = IMMEDIATE_s4;
01216
01217 if (low > high)
01218 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
01219
01220 while (low++ <= high)
01221 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
01222 INVALIDATE_PC;
01223 break;
01224 }
01225
01226 case OPCODE_lookupswitch:
01227 {
01228 jint npairs, last = 0, not_registered = 1;
01229
01230 POP_TYPE (int_type_node, "missing int for lookupswitch");
01231 while (PC%4)
01232 {
01233 if (byte_ops[PC++])
01234 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
01235 }
01236
01237 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
01238 npairs = IMMEDIATE_s4;
01239
01240 if (npairs < 0)
01241 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
01242
01243 while (npairs--)
01244 {
01245 int match = IMMEDIATE_s4;
01246 if (not_registered)
01247 not_registered = 0;
01248 else if (last >= match)
01249 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
01250
01251 last = match;
01252 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
01253 }
01254 INVALIDATE_PC;
01255 break;
01256 }
01257
01258 case OPCODE_monitorenter:
01259
01260 case OPCODE_monitorexit:
01261 pop_type (ptr_type_node);
01262 break;
01263
01264 case OPCODE_goto_w:
01265 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
01266 INVALIDATE_PC;
01267 break;
01268
01269 case OPCODE_jsr:
01270 {
01271 tree target = lookup_label (oldpc + IMMEDIATE_s2);
01272 tree return_label = lookup_label (PC);
01273 PUSH_TYPE (return_address_type_node);
01274
01275
01276 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
01277 {
01278 tree return_type_map;
01279 int nlocals = DECL_MAX_LOCALS (current_function_decl);
01280 index = nlocals + DECL_MAX_STACK (current_function_decl);
01281 return_type_map = make_tree_vec (index);
01282 while (index > nlocals)
01283 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
01284 while (index > 0)
01285 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
01286 LABEL_RETURN_LABEL (target)
01287 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
01288 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
01289 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
01290 LABEL_IS_SUBR_START (target) = 1;
01291 LABEL_IN_SUBR (target) = 1;
01292 LABEL_SUBR_START (target) = target;
01293 LABEL_SUBR_CONTEXT (target) = current_subr;
01294 }
01295 else if (! LABEL_IS_SUBR_START (target)
01296 || LABEL_SUBR_CONTEXT (target) != current_subr)
01297 VERIFICATION_ERROR ("label part of different subroutines");
01298
01299 i = merge_type_state (target);
01300 if (i != 0)
01301 {
01302 if (i < 0)
01303 VERIFICATION_ERROR ("types could not be merged at jsr");
01304 push_pending_label (target);
01305 }
01306 current_subr = target;
01307
01308
01309 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
01310 {
01311 LABEL_RETURN_LABELS (target)
01312 = tree_cons (NULL_TREE, return_label,
01313 LABEL_RETURN_LABELS (target));
01314 }
01315
01316 if (LABEL_VERIFIED (target))
01317 {
01318 tree return_map = LABEL_RETURN_TYPE_STATE (target);
01319 int len = TREE_VEC_LENGTH (return_map);
01320 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
01321 while (--len >= 0)
01322 {
01323 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
01324 type_map[len] = TREE_VEC_ELT (return_map, len);
01325 }
01326 current_subr = LABEL_SUBR_CONTEXT (target);
01327 PUSH_PENDING (return_label);
01328 }
01329
01330 INVALIDATE_PC;
01331 }
01332 break;
01333 case OPCODE_ret:
01334 if (current_subr == NULL)
01335 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
01336 else
01337 {
01338 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
01339 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
01340 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
01341 wide = 0;
01342 INVALIDATE_PC;
01343 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
01344 || type_map[index] != TYPE_RETURN_ADDR)
01345 VERIFICATION_ERROR ("invalid ret index");
01346
01347
01348
01349
01350
01351
01352
01353 if (! RETURN_MAP_ADJUSTED (ret_map))
01354 {
01355 TREE_VEC_LENGTH (ret_map) = size;
01356 for (index = size; --index >= 0; )
01357 {
01358 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
01359 TREE_VEC_ELT (ret_map, index) = type_map[index];
01360 }
01361 RETURN_MAP_ADJUSTED (ret_map) = 1;
01362 }
01363 else
01364 {
01365 if (TREE_VEC_LENGTH (ret_map) != size)
01366 VERIFICATION_ERROR ("inconsistent stack size on ret");
01367 for (index = 0; index < size; index++)
01368 {
01369 tree type = TREE_VEC_ELT (ret_map, index);
01370 if (type != TYPE_UNUSED)
01371 {
01372 type = merge_types (type, type_map [index]);
01373 TREE_VEC_ELT (ret_map, index) = type;
01374 if (type == TYPE_UNKNOWN)
01375 {
01376 if (index >= size - stack_pointer)
01377 VERIFICATION_ERROR
01378 ("inconsistent types on ret from jsr");
01379 }
01380 else if (TYPE_IS_WIDE (type))
01381 index++;
01382 }
01383 }
01384 }
01385
01386
01387 }
01388 break;
01389 case OPCODE_jsr_w:
01390 case OPCODE_ret_w:
01391 default:
01392 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
01393 return 0;
01394 }
01395
01396 prevpc = oldpc;
01397
01398
01399
01400
01401
01402
01403 if (eh_ranges != prev_eh_ranges)
01404 {
01405 int save_stack_pointer = stack_pointer;
01406 int index = DECL_MAX_LOCALS (current_function_decl);
01407 tree save_type = type_map[index];
01408 tree save_current_subr = current_subr;
01409 struct eh_range *ranges = find_handler (oldpc);
01410 stack_pointer = 1;
01411 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
01412 {
01413 tree chain = ranges->handlers;
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 current_subr = save_current_subr;
01431 for ( ; current_subr != NULL_TREE;
01432 current_subr = LABEL_SUBR_CONTEXT (current_subr))
01433 {
01434 tree return_labels = LABEL_RETURN_LABELS (current_subr);
01435
01436
01437 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
01438 if (return_pc <= ranges->start_pc
01439 || return_pc > ranges->end_pc)
01440 break;
01441 }
01442
01443 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
01444 {
01445 tree handler = TREE_VALUE (chain);
01446 tree type = TREE_PURPOSE (chain);
01447 if (type == NULL_TREE)
01448 type = throwable_type_node;
01449 type_map[index] = promote_type (type);
01450
01451 PUSH_PENDING (handler);
01452 }
01453 }
01454 stack_pointer = save_stack_pointer;
01455 current_subr = save_current_subr;
01456 type_map[index] = save_type;
01457 prev_eh_ranges = eh_ranges;
01458 }
01459 }
01460 return 1;
01461 pop_type_error:
01462 error ("verification error at PC=%d", oldpc);
01463 if (message != NULL)
01464 error ("%s", message);
01465 error ("%s", pmessage);
01466 free (pmessage);
01467 return 0;
01468 stack_overflow:
01469 message = "stack overflow";
01470 goto verify_error;
01471 bad_pc:
01472 message = "program counter out of range";
01473 goto verify_error;
01474 error_with_index:
01475 error ("verification error at PC=%d", oldpc);
01476 error (message, index);
01477 return 0;
01478 verify_error:
01479 error ("verification error at PC=%d", oldpc);
01480 error ("%s", message);
01481 return 0;
01482 }