2001-02-14 Tom Tromey <tromey@redhat.com>
[official-gcc.git] / gcc / java / verify.c
blob5ac1d057e5c4281ffb05313805427bd25fbfd1eb
1 /* Handle verification of bytecoded methods for the GNU compiler for
2 the Java(TM) language.
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 #include "config.h"
27 #include "system.h"
28 #include "tree.h"
29 #include "java-tree.h"
30 #include "javaop.h"
31 #include "java-opcodes.h"
32 #include "jcf.h"
33 #include "java-except.h"
34 #include "toplev.h"
36 static void push_pending_label PARAMS ((tree));
37 static tree merge_types PARAMS ((tree, tree));
38 static const char *check_pending_block PARAMS ((tree));
39 static void type_stack_dup PARAMS ((int, int));
40 static int start_pc_cmp PARAMS ((const PTR, const PTR));
41 static char *pop_argument_types PARAMS ((tree));
43 extern int stack_pointer;
45 /* During verification, start of the current subroutine (jsr target). */
46 tree current_subr;
48 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
49 A pending block is one that has LABEL_CHANGED set, which means
50 it requires (re-) verification. */
51 tree pending_blocks;
53 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
55 static void
56 push_pending_label (target_label)
57 tree target_label;
59 if (! LABEL_CHANGED (target_label))
61 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
62 pending_blocks = target_label;
63 LABEL_CHANGED (target_label) = 1;
67 /* Note that TARGET_LABEL is a possible successor instruction.
68 Merge the type state etc.
69 Return NULL on sucess, or an error message on failure. */
71 static const char *
72 check_pending_block (target_label)
73 tree target_label;
75 int changed = merge_type_state (target_label);
77 if (changed)
79 if (changed < 0)
80 return "types could not be merged";
81 push_pending_label (target_label);
84 if (current_subr == NULL)
86 if (LABEL_IN_SUBR (target_label))
87 return "might transfer control into subroutine";
89 else
91 if (LABEL_IN_SUBR (target_label))
93 if (LABEL_SUBR_START (target_label) != current_subr)
94 return "transfer out of subroutine";
96 else if (! LABEL_VERIFIED (target_label))
98 LABEL_IN_SUBR (target_label) = 1;
99 LABEL_SUBR_START (target_label) = current_subr;
101 else
102 return "transfer out of subroutine";
104 return NULL;
107 /* Return the "merged" types of TYPE1 and TYPE2.
108 If either is primitive, the other must match (after promotion to int).
109 For reference types, return the common super-class.
110 Return TYPE_UNKNOWN if the types cannot be merged. */
112 static tree
113 merge_types (type1, type2)
114 tree type1, type2;
116 if (type1 == type2)
117 return type1;
118 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
119 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
120 return TYPE_UNKNOWN;
121 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
123 int depth1, depth2;
124 tree tt1, tt2;
125 /* ptr_type_node is only used for a null reference,
126 which is compatible with any reference type. */
127 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
128 return type2;
129 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
130 return type1;
132 tt1 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type1));
133 tt2 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type2));
135 /* If tt{1,2} haven't been properly loaded, now is a good time
136 to do it. */
137 if (!TYPE_SIZE (tt1))
139 load_class (tt1, 1);
140 safe_layout_class (tt1);
143 if (!TYPE_SIZE (tt2))
145 load_class (tt2, 1);
146 safe_layout_class (tt2);
149 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
151 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
153 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
154 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
155 tree el_type = NULL_TREE;
156 if (el_type1 == el_type2)
157 el_type = el_type1;
158 else if (TREE_CODE (el_type1) == POINTER_TYPE
159 && TREE_CODE (el_type2) == POINTER_TYPE)
160 el_type = merge_types (el_type1, el_type2);
161 if (el_type != NULL_TREE)
163 HOST_WIDE_INT len1 = java_array_type_length (tt1);
164 HOST_WIDE_INT len2 = java_array_type_length (tt2);
165 if (len1 != len2)
166 len1 = -1;
167 else if (el_type1 == el_type2)
168 return type1;
169 return promote_type (build_java_array_type (el_type, len1));
172 return object_ptr_type_node;
175 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
177 /* FIXME: should see if two interfaces have a common
178 superinterface. */
179 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
181 /* This is a kludge, but matches what Sun's verifier does.
182 It can be tricked, but is safe as long as type errors
183 (i.e. interface method calls) are caught at run-time. */
184 return object_ptr_type_node;
186 else
188 if (can_widen_reference_to (tt2, tt1))
189 return type1;
190 else
191 return object_ptr_type_node;
194 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
196 if (can_widen_reference_to (tt1, tt2))
197 return type2;
198 else
199 return object_ptr_type_node;
202 type1 = tt1;
203 type2 = tt2;
205 depth1 = class_depth (type1);
206 depth2 = class_depth (type2);
207 for ( ; depth1 > depth2; depth1--)
208 type1 = TYPE_BINFO_BASETYPE (type1, 0);
209 for ( ; depth2 > depth1; depth2--)
210 type2 = TYPE_BINFO_BASETYPE (type2, 0);
211 while (type1 != type2)
213 type1 = TYPE_BINFO_BASETYPE (type1, 0);
214 type2 = TYPE_BINFO_BASETYPE (type2, 0);
216 return promote_type (type1);
218 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
219 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
220 return int_type_node;
221 return TYPE_UNKNOWN;
224 /* Merge the current type state with that at LABEL.
225 Return -1 the the states are incompatible (i.e. on error),
226 0 if there was no change, and 1 if there was a change. */
229 merge_type_state (label)
230 tree label;
232 int nlocals = DECL_MAX_LOCALS (current_function_decl);
233 int cur_length = stack_pointer + nlocals;
234 tree vec = LABEL_TYPE_STATE (label);
235 tree return_map;
236 if (vec == NULL_TREE)
238 if (!vec)
240 vec = make_tree_vec (cur_length);
241 LABEL_TYPE_STATE (label) = vec;
243 while (--cur_length >= 0)
244 TREE_VEC_ELT (vec, cur_length) = type_map [cur_length];
245 return 1;
247 else
249 int i;
250 int changed = 0;
251 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
252 && current_subr != label)
253 return_map = LABEL_RETURN_TYPE_STATE (label);
254 else
255 return_map = NULL_TREE;
256 if (TREE_VEC_LENGTH (vec) != cur_length)
258 return -1;
260 for (i = 0; i < cur_length; i++)
262 tree old_type = TREE_VEC_ELT (vec, i);
263 tree new_type = merge_types (old_type, type_map [i]);
264 if (TREE_VEC_ELT (vec, i) != new_type)
266 /* If there has been a change, note that since we must re-verify.
267 However, if the label is the start of a subroutine,
268 we don't care about local variables that are neither
269 set nor used in the sub-routine. */
270 if (return_map == NULL_TREE || i >= nlocals
271 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
272 || (TYPE_IS_WIDE (new_type)
273 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
274 changed = 1;
276 TREE_VEC_ELT (vec, i) = new_type;
277 if (new_type == TYPE_UNKNOWN)
279 if (i >= nlocals)
280 return -1;
282 else if (TYPE_IS_WIDE (new_type))
283 i++;
285 return changed;
289 /* Handle dup-like operations. */
291 static void
292 type_stack_dup (size, offset)
293 int size, offset;
295 tree type[4];
296 int index;
297 if (size + offset > stack_pointer)
298 error ("stack underflow - dup* operation");
299 for (index = 0; index < size + offset; index++)
301 type[index] = stack_type_map[stack_pointer - 1];
302 if (type[index] == void_type_node)
304 index++;
305 type[index] = stack_type_map[stack_pointer - 2];
306 if (! TYPE_IS_WIDE (type[index]))
307 abort ();
308 if (index == size || index == size + offset)
309 /* Dup operation splits 64-bit number. */
310 abort ();
312 pop_type (type[index]);
314 for (index = size; --index >= 0; )
316 if (type[index] != void_type_node)
317 push_type (type[index]);
320 for (index = size + offset; --index >= 0; )
322 if (type[index] != void_type_node)
323 push_type (type[index]);
327 /* This keeps track of a start PC and corresponding initial index. */
328 struct pc_index
330 int start_pc;
331 int index;
334 /* A helper that is used when sorting exception ranges. */
335 static int
336 start_pc_cmp (xp, yp)
337 const PTR xp;
338 const PTR yp;
340 const struct pc_index *x = (const struct pc_index *) xp;
341 const struct pc_index *y = (const struct pc_index *) yp;
342 return x->start_pc - y->start_pc;
345 /* This causes the next iteration to ignore the next instruction
346 and look for some other unhandled instruction. */
347 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
348 #define INVALID_PC (-1)
350 #define VERIFICATION_ERROR(MESSAGE) \
351 do { message = MESSAGE; goto verify_error; } while (0)
353 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
354 do { message = MESSAGE; goto error_with_index; } while (0)
356 /* Recursive helper function to pop argument types during verifiation.
357 ARG_TYPES is the list of formal parameter types.
358 Return NULL on success and a freshly malloc'd error message on failure. */
360 static char *
361 pop_argument_types (arg_types)
362 tree arg_types;
364 if (arg_types == end_params_node)
365 return NULL;
366 if (TREE_CODE (arg_types) == TREE_LIST)
368 char *message = pop_argument_types (TREE_CHAIN (arg_types));
369 if (message == NULL)
370 pop_type_0 (TREE_VALUE (arg_types), &message);
371 return message;
373 abort ();
376 #define POP_TYPE(TYPE, MESSAGE) \
377 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
378 if (pmessage != NULL) goto pop_type_error; \
379 } while (0)
381 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
382 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
383 if (pmessage != NULL) goto pop_type_error; \
384 } while (0)
386 #define PUSH_TYPE(TYPE) \
387 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
389 #define PUSH_PENDING(LABEL) \
390 do { tree tmplab = LABEL; \
391 if ((message = check_pending_block (tmplab)) != NULL) \
392 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
394 #ifdef __GNUC__
395 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
396 #else
397 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
398 #endif
400 #define BCODE byte_ops
402 /* Verify the bytecodes of the current method.
403 Return 1 on sucess, 0 on failure. */
405 verify_jvm_instructions (jcf, byte_ops, length)
406 JCF* jcf;
407 const unsigned char *byte_ops;
408 long length;
410 tree label;
411 int wide = 0;
412 int op_code;
413 int PC;
414 int oldpc = 0; /* PC of start of instruction. */
415 int prevpc = 0; /* If >= 0, PC of previous instruction. */
416 const char *message;
417 char *pmessage;
418 int i;
419 int index;
420 register unsigned char *p;
421 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
422 struct eh_range *eh_ranges;
423 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
424 struct pc_index *starts;
425 int eh_count;
427 jint int_value = -1;
429 pending_blocks = NULL_TREE;
431 /* Handle the exception table. */
432 method_init_exceptions ();
433 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
434 eh_count = JCF_readu2 (jcf);
436 /* We read the exception handlers in order of increasing start PC.
437 To do this we first read and sort the start PCs. */
438 starts = (struct pc_index *) xmalloc (eh_count * sizeof (struct pc_index));
439 for (i = 0; i < eh_count; ++i)
441 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
442 starts[i].index = i;
444 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
446 for (i = 0; i < eh_count; ++i)
448 int start_pc, end_pc, handler_pc, catch_type;
450 p = jcf->read_ptr + 8 * starts[i].index;
452 start_pc = GET_u2 (p);
453 end_pc = GET_u2 (p+2);
454 handler_pc = GET_u2 (p+4);
455 catch_type = GET_u2 (p+6);
457 if (start_pc < 0 || start_pc >= length
458 || end_pc < 0 || end_pc > length || start_pc >= end_pc
459 || handler_pc < 0 || handler_pc >= length
460 || (handler_pc >= start_pc && handler_pc < end_pc)
461 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
462 || (end_pc < length &&
463 ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START))
464 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
466 error ("bad pc in exception_table");
467 free (starts);
468 return 0;
471 add_handler (start_pc, end_pc,
472 lookup_label (handler_pc),
473 catch_type == 0 ? NULL_TREE
474 : get_class_constant (jcf, catch_type));
476 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
479 free (starts);
480 handle_nested_ranges ();
482 for (PC = 0;;)
484 tree type, tmp;
485 if (((PC != INVALID_PC
486 && instruction_bits [PC] & BCODE_TARGET) != 0)
487 || PC == 0)
489 PUSH_PENDING (lookup_label (PC));
490 INVALIDATE_PC;
492 /* Check if there are any more pending blocks in the current
493 subroutine. Because we push pending blocks in a
494 last-in-first-out order, and because we don't push anything
495 from our caller until we are done with this subroutine or
496 anything nested in it, then we are done if the top of the
497 pending_blocks stack is not in a subroutine, or it is in our
498 caller. */
499 if (current_subr
500 && PC == INVALID_PC)
502 tree caller = LABEL_SUBR_CONTEXT (current_subr);
504 if (pending_blocks == NULL_TREE
505 || ! LABEL_IN_SUBR (pending_blocks)
506 || LABEL_SUBR_START (pending_blocks) == caller)
508 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
509 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
510 tmp = LABEL_RETURN_LABELS (current_subr);
512 /* FIXME: If we exit a subroutine via a throw, we might
513 have returned to an earlier caller. Obviously a
514 "ret" can only return one level, but a throw may
515 return many levels.*/
516 current_subr = caller;
518 if (RETURN_MAP_ADJUSTED (ret_map))
520 /* Since we are done with this subroutine , set up
521 the (so far known) return address as pending -
522 with the merged type state. */
523 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
525 tree return_label = TREE_VALUE (tmp);
526 tree return_state = LABEL_TYPE_STATE (return_label);
527 if (return_state == NULL_TREE)
529 /* This means means we had not verified the
530 subroutine earlier, so this is the first jsr to
531 call it. In this case, the type_map of the return
532 address is just the current type_map - and that
533 is handled by the following PUSH_PENDING. */
535 else
537 /* In this case we have to do a merge. But first
538 restore the type_map for unused slots to those
539 that were in effect at the jsr. */
540 for (index = size; --index >= 0; )
542 type_map[index] = TREE_VEC_ELT (ret_map, index);
543 if (type_map[index] == TYPE_UNUSED)
544 type_map[index]
545 = TREE_VEC_ELT (return_state, index);
548 PUSH_PENDING (return_label);
553 if (PC == INVALID_PC)
555 label = pending_blocks;
556 if (label == NULL_TREE)
557 break; /* We're done! */
558 pending_blocks = LABEL_PENDING_CHAIN (label);
559 LABEL_CHANGED (label) = 0;
561 if (LABEL_IN_SUBR (label))
562 current_subr = LABEL_SUBR_START (label);
563 else
564 current_subr = NULL_TREE;
566 /* Restore type_map and stack_pointer from
567 LABEL_TYPE_STATE (label), and continue
568 compiling from there. */
569 load_type_state (label);
570 PC = LABEL_PC (label);
572 else if (PC >= length)
573 VERIFICATION_ERROR ("falling through end of method");
575 /* fprintf (stderr, "** %d\n", PC); */
577 oldpc = PC;
579 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
580 VERIFICATION_ERROR ("PC not at instruction start");
582 instruction_bits[PC] |= BCODE_VERIFIED;
584 eh_ranges = find_handler (oldpc);
586 op_code = byte_ops[PC++];
587 switch (op_code)
589 int is_static, is_putting;
590 case OPCODE_nop:
591 break;
592 case OPCODE_iconst_m1:
593 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
594 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
595 i = op_code - OPCODE_iconst_0;
596 goto push_int;
597 push_int:
598 if (byte_ops[PC] == OPCODE_newarray
599 || byte_ops[PC] == OPCODE_newarray)
600 int_value = i;
601 PUSH_TYPE (int_type_node); break;
602 case OPCODE_lconst_0: case OPCODE_lconst_1:
603 PUSH_TYPE (long_type_node); break;
604 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
605 PUSH_TYPE (float_type_node); break;
606 case OPCODE_dconst_0: case OPCODE_dconst_1:
607 PUSH_TYPE (double_type_node); break;
608 case OPCODE_bipush:
609 i = IMMEDIATE_s1;
610 goto push_int;
611 case OPCODE_sipush:
612 i = IMMEDIATE_s2;
613 goto push_int;
614 case OPCODE_iload: type = int_type_node; goto general_load;
615 case OPCODE_lload: type = long_type_node; goto general_load;
616 case OPCODE_fload: type = float_type_node; goto general_load;
617 case OPCODE_dload: type = double_type_node; goto general_load;
618 case OPCODE_aload: type = ptr_type_node; goto general_load;
619 general_load:
620 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
621 wide = 0;
622 goto load;
623 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
624 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
625 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
626 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
627 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
628 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
629 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
630 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
631 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
632 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
633 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
634 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
635 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
636 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
637 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
638 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
639 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
640 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
641 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
642 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
643 load:
644 if (index < 0
645 || (index + TYPE_IS_WIDE (type)
646 >= DECL_MAX_LOCALS (current_function_decl)))
647 VERIFICATION_ERROR_WITH_INDEX
648 ("invalid local variable index %d in load");
649 tmp = type_map[index];
650 if (tmp == TYPE_UNKNOWN)
651 VERIFICATION_ERROR_WITH_INDEX
652 ("loading local variable %d which has unknown type");
653 else if (tmp == TYPE_SECOND
654 || (TYPE_IS_WIDE (type)
655 && type_map[index+1] != void_type_node)
656 || (type == ptr_type_node
657 ? TREE_CODE (tmp) != POINTER_TYPE
658 : type == int_type_node
659 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
660 : type != tmp))
661 VERIFICATION_ERROR_WITH_INDEX
662 ("loading local variable %d which has invalid type");
663 PUSH_TYPE (tmp);
664 goto note_used;
665 case OPCODE_istore: type = int_type_node; goto general_store;
666 case OPCODE_lstore: type = long_type_node; goto general_store;
667 case OPCODE_fstore: type = float_type_node; goto general_store;
668 case OPCODE_dstore: type = double_type_node; goto general_store;
669 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
670 general_store:
671 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
672 wide = 0;
673 goto store;
674 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
675 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
676 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
677 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
678 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
679 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
680 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
681 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
682 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
683 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
684 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
685 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
686 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
687 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
688 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
689 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
690 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
691 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
692 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
693 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
694 store:
695 if (index < 0
696 || (index + TYPE_IS_WIDE (type)
697 >= DECL_MAX_LOCALS (current_function_decl)))
699 VERIFICATION_ERROR_WITH_INDEX
700 ("invalid local variable index %d in store");
701 return 0;
703 POP_TYPE_CONV (type, type, NULL);
704 type_map[index] = type;
706 /* If local variable changed, we need to reconsider eh handlers. */
707 prev_eh_ranges = NULL_EH_RANGE;
709 /* Allocate decl and rtx for this variable now, so if we're not
710 optmizing, we get a temporary that survives the whole method. */
711 find_local_variable (index, type, oldpc);
713 if (TYPE_IS_WIDE (type))
714 type_map[index+1] = TYPE_SECOND;
715 /* ... fall through to note_used ... */
716 note_used:
717 /* For store or load, note that local variable INDEX is used.
718 This is needed to verify try-finally sub-routines. */
719 if (current_subr)
721 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
722 tree subr_vec = LABEL_TYPE_STATE (current_subr);
723 int len = 1 + TYPE_IS_WIDE (type);
724 while (--len >= 0)
726 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
727 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
730 break;
731 case OPCODE_iadd:
732 case OPCODE_iand:
733 case OPCODE_idiv:
734 case OPCODE_imul:
735 case OPCODE_ior:
736 case OPCODE_irem:
737 case OPCODE_ishl:
738 case OPCODE_ishr:
739 case OPCODE_isub:
740 case OPCODE_iushr:
741 case OPCODE_ixor:
742 type = int_type_node; goto binop;
743 case OPCODE_ineg:
744 case OPCODE_i2c:
745 case OPCODE_i2b:
746 case OPCODE_i2s:
747 type = int_type_node; goto unop;
748 case OPCODE_ladd:
749 case OPCODE_land:
750 case OPCODE_ldiv:
751 case OPCODE_lsub:
752 case OPCODE_lmul:
753 case OPCODE_lrem:
754 case OPCODE_lor:
755 case OPCODE_lxor:
756 type = long_type_node; goto binop;
757 case OPCODE_lneg:
758 type = long_type_node; goto unop;
759 case OPCODE_fadd: case OPCODE_fsub:
760 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
761 type = float_type_node; goto binop;
762 case OPCODE_fneg:
763 type = float_type_node; goto unop;
764 case OPCODE_dadd: case OPCODE_dsub:
765 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
766 type = double_type_node; goto binop;
767 case OPCODE_dneg:
768 type = double_type_node; goto unop;
769 unop:
770 pop_type (type);
771 PUSH_TYPE (type);
772 break;
773 binop:
774 pop_type (type);
775 pop_type (type);
776 PUSH_TYPE (type);
777 break;
778 case OPCODE_lshl:
779 case OPCODE_lshr:
780 case OPCODE_lushr:
781 pop_type (int_type_node);
782 pop_type (long_type_node);
783 PUSH_TYPE (long_type_node);
784 break;
785 case OPCODE_iinc:
786 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
787 PC += wide + 1;
788 wide = 0;
789 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
790 VERIFICATION_ERROR ("invalid local variable index in iinc");
791 tmp = type_map[index];
792 if (tmp == NULL_TREE
793 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
794 VERIFICATION_ERROR ("invalid local variable type in iinc");
795 break;
796 case OPCODE_i2l:
797 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
798 case OPCODE_i2f:
799 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
800 case OPCODE_i2d:
801 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
802 case OPCODE_l2i:
803 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
804 case OPCODE_l2f:
805 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
806 case OPCODE_l2d:
807 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
808 case OPCODE_f2i:
809 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
810 case OPCODE_f2l:
811 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
812 case OPCODE_f2d:
813 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
814 case OPCODE_d2i:
815 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
816 case OPCODE_d2l:
817 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
818 case OPCODE_d2f:
819 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
820 case OPCODE_lcmp:
821 type = long_type_node; goto compare;
822 case OPCODE_fcmpl:
823 case OPCODE_fcmpg:
824 type = float_type_node; goto compare;
825 case OPCODE_dcmpl:
826 case OPCODE_dcmpg:
827 type = double_type_node; goto compare;
828 compare:
829 pop_type (type); pop_type (type);
830 PUSH_TYPE (int_type_node); break;
831 case OPCODE_ifeq:
832 case OPCODE_ifne:
833 case OPCODE_iflt:
834 case OPCODE_ifge:
835 case OPCODE_ifgt:
836 case OPCODE_ifle:
837 pop_type (int_type_node); goto cond;
838 case OPCODE_ifnull:
839 case OPCODE_ifnonnull:
840 pop_type (ptr_type_node ); goto cond;
841 case OPCODE_if_icmpeq:
842 case OPCODE_if_icmpne:
843 case OPCODE_if_icmplt:
844 case OPCODE_if_icmpge:
845 case OPCODE_if_icmpgt:
846 case OPCODE_if_icmple:
847 pop_type (int_type_node); pop_type (int_type_node); goto cond;
848 case OPCODE_if_acmpeq:
849 case OPCODE_if_acmpne:
850 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
851 goto cond;
852 cond:
853 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
854 break;
855 case OPCODE_goto:
856 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
857 INVALIDATE_PC;
858 break;
859 case OPCODE_wide:
860 switch (byte_ops[PC])
862 case OPCODE_iload: case OPCODE_lload:
863 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
864 case OPCODE_istore: case OPCODE_lstore:
865 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
866 case OPCODE_iinc:
867 case OPCODE_ret:
868 wide = 1;
869 break;
870 default:
871 VERIFICATION_ERROR ("invalid use of wide instruction");
873 break;
874 case OPCODE_return: type = void_type_node; goto ret;
875 case OPCODE_ireturn:
876 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
877 || TREE_CODE (return_type) == CHAR_TYPE
878 || TREE_CODE (return_type) == INTEGER_TYPE)
879 && TYPE_PRECISION (return_type) <= 32)
880 type = return_type;
881 else
882 type = NULL_TREE;
883 goto ret;
884 case OPCODE_lreturn: type = long_type_node; goto ret;
885 case OPCODE_freturn: type = float_type_node; goto ret;
886 case OPCODE_dreturn: type = double_type_node; goto ret;
887 case OPCODE_areturn:
888 if (TREE_CODE (return_type) == POINTER_TYPE)
889 type = return_type;
890 else
891 type = NULL_TREE;
892 goto ret;
893 ret:
894 if (type != return_type)
895 VERIFICATION_ERROR ("incorrect ?return opcode");
896 if (type != void_type_node)
897 POP_TYPE(type, "return value has wrong type");
898 INVALIDATE_PC;
899 break;
900 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
901 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
902 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
903 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
904 field:
906 int index = IMMEDIATE_u2;
907 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
908 tree field_type = get_type_from_signature (field_signature);
909 if (is_putting)
910 POP_TYPE (field_type, "incorrect type for field");
911 if (! is_static)
913 int clindex = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
914 index);
915 tree self_type = get_class_constant (current_jcf, clindex);
916 /* Defer actual checking until next pass. */
917 POP_TYPE(self_type, "incorrect type for field reference");
919 if (! is_putting)
920 PUSH_TYPE (field_type);
921 break;
923 case OPCODE_new:
924 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
925 break;
926 case OPCODE_dup: type_stack_dup (1, 0); break;
927 case OPCODE_dup_x1: type_stack_dup (1, 1); break;
928 case OPCODE_dup_x2: type_stack_dup (1, 2); break;
929 case OPCODE_dup2: type_stack_dup (2, 0); break;
930 case OPCODE_dup2_x1: type_stack_dup (2, 1); break;
931 case OPCODE_dup2_x2: type_stack_dup (2, 2); break;
932 case OPCODE_pop: index = 1; goto pop;
933 case OPCODE_pop2: index = 2; goto pop;
934 pop:
935 if (stack_pointer < index)
936 VERIFICATION_ERROR ("stack underflow");
937 stack_pointer -= index;
938 break;
939 case OPCODE_swap:
940 if (stack_pointer < 2)
941 VERIFICATION_ERROR ("stack underflow (in swap)");
942 else
944 tree type1 = stack_type_map[stack_pointer - 1];
945 tree type2 = stack_type_map[stack_pointer - 2];
946 if (type1 == void_type_node || type2 == void_type_node)
947 VERIFICATION_ERROR ("verifier (swap): double or long value");
948 stack_type_map[stack_pointer - 2] = type1;
949 stack_type_map[stack_pointer - 1] = type2;
951 break;
952 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
953 case OPCODE_ldc2_w:
954 case OPCODE_ldc_w:
955 index = IMMEDIATE_u2; goto ldc;
956 ldc:
957 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
958 VERIFICATION_ERROR ("bad constant pool index in ldc");
959 int_value = -1;
960 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
962 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
963 case CONSTANT_Float: type = float_type_node; goto check_ldc;
964 case CONSTANT_String: type = string_type_node; goto check_ldc;
965 case CONSTANT_Long: type = long_type_node; goto check_ldc;
966 case CONSTANT_Double: type = double_type_node; goto check_ldc;
967 check_ldc:
968 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
969 break;
970 /* ... else fall through ... */
971 default:
972 VERIFICATION_ERROR ("bad constant pool tag in ldc");
974 if (type == int_type_node)
976 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
977 goto push_int;
979 PUSH_TYPE (type);
980 break;
982 case OPCODE_invokevirtual:
983 case OPCODE_invokespecial:
984 case OPCODE_invokestatic:
985 case OPCODE_invokeinterface:
987 int index = IMMEDIATE_u2;
988 tree sig = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
989 tree self_type = get_class_constant
990 (current_jcf, COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
991 index));
992 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
993 tree method_type;
994 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
995 IDENTIFIER_LENGTH (sig));
996 if (TREE_CODE (method_type) != FUNCTION_TYPE)
997 VERIFICATION_ERROR ("bad method signature");
998 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
999 if (pmessage != NULL)
1001 message = "invalid argument type";
1002 goto pop_type_error;
1005 /* Can't invoke <clinit> */
1006 if (ID_CLINIT_P (method_name))
1007 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1008 /* Apart invokespecial, can't invoke <init> */
1009 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
1010 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1012 if (op_code != OPCODE_invokestatic)
1013 POP_TYPE (self_type,
1014 "stack type not subclass of invoked method's class");
1016 switch (op_code)
1018 case OPCODE_invokeinterface:
1020 int nargs = IMMEDIATE_u1;
1021 int notZero = IMMEDIATE_u1;
1023 if (!nargs || notZero)
1024 VERIFICATION_ERROR
1025 ("invalid argument number in invokeinterface");
1026 break;
1030 if (TREE_TYPE (method_type) != void_type_node)
1031 PUSH_TYPE (TREE_TYPE (method_type));
1032 break;
1035 case OPCODE_arraylength:
1036 /* Type checking actually made during code generation */
1037 pop_type( ptr_type_node );
1038 PUSH_TYPE( int_type_node );
1039 break;
1041 /* Q&D verification *or* more checking done during code generation
1042 for byte/boolean/char/short, the value popped is a int coerced
1043 into the right type before being stored. */
1044 case OPCODE_iastore: type = int_type_node; goto astore;
1045 case OPCODE_lastore: type = long_type_node; goto astore;
1046 case OPCODE_fastore: type = float_type_node; goto astore;
1047 case OPCODE_dastore: type = double_type_node; goto astore;
1048 case OPCODE_aastore: type = ptr_type_node; goto astore;
1049 case OPCODE_bastore: type = int_type_node; goto astore;
1050 case OPCODE_castore: type = int_type_node; goto astore;
1051 case OPCODE_sastore: type = int_type_node; goto astore;
1052 astore:
1053 /* FIXME - need better verification here */
1054 pop_type (type); /* new value */
1055 pop_type (int_type_node); /* index */
1056 pop_type (ptr_type_node); /* array */
1057 break;
1059 /* Q&D verification *or* more checking done during code generation
1060 for byte/boolean/char/short, the value pushed is a int. */
1061 case OPCODE_iaload: type = int_type_node; goto aload;
1062 case OPCODE_laload: type = long_type_node; goto aload;
1063 case OPCODE_faload: type = float_type_node; goto aload;
1064 case OPCODE_daload: type = double_type_node; goto aload;
1065 case OPCODE_aaload: type = ptr_type_node; goto aload;
1066 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1067 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1068 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1069 aload:
1070 pop_type (int_type_node);
1071 tmp = pop_type (ptr_type_node);
1072 if (is_array_type_p (tmp))
1073 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1074 else if (tmp != TYPE_NULL)
1075 VERIFICATION_ERROR ("array load from non-array type");
1076 PUSH_TYPE (type);
1077 break;
1079 case OPCODE_anewarray:
1080 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1081 type = promote_type (type);
1082 goto newarray;
1084 case OPCODE_newarray:
1085 index = IMMEDIATE_u1;
1086 type = decode_newarray_type (index);
1087 if (type == NULL_TREE)
1088 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1089 goto newarray;
1091 newarray:
1092 if (int_value >= 0 && prevpc >= 0)
1094 /* If previous instruction pushed int constant,
1095 we want to use it. */
1096 switch (byte_ops[prevpc])
1098 case OPCODE_iconst_0: case OPCODE_iconst_1:
1099 case OPCODE_iconst_2: case OPCODE_iconst_3:
1100 case OPCODE_iconst_4: case OPCODE_iconst_5:
1101 case OPCODE_bipush: case OPCODE_sipush:
1102 case OPCODE_ldc: case OPCODE_ldc_w:
1103 break;
1104 default:
1105 int_value = -1;
1108 else
1109 int_value = -1;
1110 type = build_java_array_type (type, int_value);
1111 pop_type (int_type_node);
1112 PUSH_TYPE (type);
1113 break;
1115 case OPCODE_multianewarray:
1117 int ndim, i;
1118 index = IMMEDIATE_u2;
1119 ndim = IMMEDIATE_u1;
1121 if( ndim < 1 )
1122 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
1124 for( i = 0; i < ndim; i++ )
1125 pop_type (int_type_node);
1126 PUSH_TYPE (get_class_constant (current_jcf, index));
1127 break;
1130 case OPCODE_aconst_null:
1131 PUSH_TYPE (ptr_type_node);
1132 break;
1134 case OPCODE_athrow:
1135 /* FIXME: athrow also empties the stack. */
1136 pop_type (throwable_type_node);
1137 INVALIDATE_PC;
1138 break;
1140 case OPCODE_checkcast:
1141 pop_type (ptr_type_node);
1142 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1143 PUSH_TYPE (type);
1144 break;
1145 case OPCODE_instanceof:
1146 pop_type (ptr_type_node);
1147 get_class_constant (current_jcf, IMMEDIATE_u2);
1148 PUSH_TYPE (int_type_node);
1149 break;
1151 case OPCODE_tableswitch:
1153 jint low, high;
1155 pop_type (int_type_node);
1156 while (PC%4)
1158 if (byte_ops[PC++])
1159 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1161 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1162 low = IMMEDIATE_s4;
1163 high = IMMEDIATE_s4;
1165 if (low > high)
1166 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1168 while (low++ <= high)
1169 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1170 INVALIDATE_PC;
1171 break;
1174 case OPCODE_lookupswitch:
1176 jint npairs, last = 0, not_registered = 1;
1178 pop_type (int_type_node);
1179 while (PC%4)
1181 if (byte_ops[PC++])
1182 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1185 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1186 npairs = IMMEDIATE_s4;
1188 if (npairs < 0)
1189 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1191 while (npairs--)
1193 int match = IMMEDIATE_s4;
1194 if (not_registered)
1195 not_registered = 0;
1196 else if (last >= match)
1197 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1199 last = match;
1200 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1202 INVALIDATE_PC;
1203 break;
1206 case OPCODE_monitorenter:
1207 /* fall thru */
1208 case OPCODE_monitorexit:
1209 pop_type (ptr_type_node);
1210 break;
1212 case OPCODE_goto_w:
1213 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1214 INVALIDATE_PC;
1215 break;
1217 case OPCODE_jsr:
1219 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1220 tree return_label = lookup_label (PC);
1221 PUSH_TYPE (return_address_type_node);
1222 /* The return label chain will be null if this is the first
1223 time we've seen this jsr target. */
1224 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1226 tree return_type_map;
1227 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1228 index = nlocals + DECL_MAX_STACK (current_function_decl);
1229 return_type_map = make_tree_vec (index);
1230 while (index > nlocals)
1231 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1232 while (index > 0)
1233 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1234 LABEL_RETURN_LABEL (target)
1235 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1236 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
1237 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1238 LABEL_IS_SUBR_START (target) = 1;
1239 LABEL_IN_SUBR (target) = 1;
1240 LABEL_SUBR_START (target) = target;
1241 LABEL_SUBR_CONTEXT (target) = current_subr;
1243 else if (! LABEL_IS_SUBR_START (target)
1244 || LABEL_SUBR_CONTEXT (target) != current_subr)
1245 VERIFICATION_ERROR ("label part of different subroutines");
1247 i = merge_type_state (target);
1248 if (i != 0)
1250 if (i < 0)
1251 VERIFICATION_ERROR ("types could not be merged at jsr");
1252 push_pending_label (target);
1254 current_subr = target;
1256 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1257 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1259 LABEL_RETURN_LABELS (target)
1260 = tree_cons (NULL_TREE, return_label,
1261 LABEL_RETURN_LABELS (target));
1264 if (LABEL_VERIFIED (target))
1266 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1267 int len = TREE_VEC_LENGTH (return_map);
1268 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1269 while (--len >= 0)
1271 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1272 type_map[len] = TREE_VEC_ELT (return_map, len);
1274 current_subr = LABEL_SUBR_CONTEXT (target);
1275 PUSH_PENDING (return_label);
1278 INVALIDATE_PC;
1280 break;
1281 case OPCODE_ret:
1282 if (current_subr == NULL)
1283 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1284 else
1286 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1287 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
1288 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1289 wide = 0;
1290 INVALIDATE_PC;
1291 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1292 || type_map[index] != TYPE_RETURN_ADDR)
1293 VERIFICATION_ERROR ("invalid ret index");
1295 /* The next chunk of code is similar to an inlined version of
1296 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1297 * The main differences are that LABEL_RETURN_LABEL is
1298 * pre-allocated by the jsr (but we don't know the size then);
1299 * and that we have to handle TYPE_UNUSED. */
1301 if (! RETURN_MAP_ADJUSTED (ret_map))
1302 { /* First return from this subroutine - fix stack pointer. */
1303 TREE_VEC_LENGTH (ret_map) = size;
1304 for (index = size; --index >= 0; )
1306 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1307 TREE_VEC_ELT (ret_map, index) = type_map[index];
1309 RETURN_MAP_ADJUSTED (ret_map) = 1;
1311 else
1313 if (TREE_VEC_LENGTH (ret_map) != size)
1314 VERIFICATION_ERROR ("inconsistent stack size on ret");
1315 for (index = 0; index < size; index++)
1317 tree type = TREE_VEC_ELT (ret_map, index);
1318 if (type != TYPE_UNUSED)
1320 type = merge_types (type, type_map [index]);
1321 TREE_VEC_ELT (ret_map, index) = type;
1322 if (type == TYPE_UNKNOWN)
1324 if (index >= size - stack_pointer)
1325 VERIFICATION_ERROR
1326 ("inconsistent types on ret from jsr");
1328 else if (TYPE_IS_WIDE (type))
1329 index++;
1336 break;
1337 case OPCODE_jsr_w:
1338 case OPCODE_ret_w:
1339 default:
1340 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1341 return 0;
1344 prevpc = oldpc;
1346 /* The following test is true if we have entered or exited an exception
1347 handler range *or* we have done a store to a local variable.
1348 In either case we need to consider any exception handlers that
1349 might "follow" this instruction. */
1351 if (eh_ranges != prev_eh_ranges)
1353 int save_stack_pointer = stack_pointer;
1354 int index = DECL_MAX_LOCALS (current_function_decl);
1355 tree save_type = type_map[index];
1356 tree save_current_subr = current_subr;
1357 struct eh_range *ranges = find_handler (oldpc);
1358 stack_pointer = 1;
1359 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1361 tree chain = ranges->handlers;
1363 /* We need to determine if the handler is part of current_subr.
1364 The are two cases: (1) The exception catch range
1365 is entirely within current_subr. In that case the handler
1366 is also part of current_subr.
1367 (2) Some of the catch range is not in current_subr.
1368 In that case, the handler is *not* part of current_subr.
1370 Figuring out which is the case is not necessarily obvious,
1371 in the presence of clever code generators (and obfuscators).
1372 We make a simplifying assumption that in case (2) we
1373 have that the current_subr is entirely within the catch range.
1374 In that case we can assume if that if a caller (the jsr) of
1375 a subroutine is within the catch range, then the handler is
1376 *not* part of the subroutine, and vice versa. */
1378 current_subr = save_current_subr;
1379 for ( ; current_subr != NULL_TREE;
1380 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1382 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1383 /* There could be multiple return_labels, but
1384 we only need to check one. */
1385 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1386 if (return_pc <= ranges->start_pc
1387 || return_pc > ranges->end_pc)
1388 break;
1391 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1393 tree handler = TREE_VALUE (chain);
1394 tree type = TREE_PURPOSE (chain);
1395 if (type == NULL_TREE) /* a finally handler */
1396 type = throwable_type_node;
1397 type_map[index] = promote_type (type);
1399 PUSH_PENDING (handler);
1402 stack_pointer = save_stack_pointer;
1403 current_subr = save_current_subr;
1404 type_map[index] = save_type;
1405 prev_eh_ranges = eh_ranges;
1408 return 1;
1409 pop_type_error:
1410 error ("verification error at PC=%d", oldpc);
1411 if (message != NULL)
1412 error ("%s", message);
1413 error ("%s", pmessage);
1414 free (pmessage);
1415 return 0;
1416 stack_overflow:
1417 message = "stack overflow";
1418 goto verify_error;
1419 bad_pc:
1420 message = "program counter out of range";
1421 goto verify_error;
1422 error_with_index:
1423 error ("verification error at PC=%d", oldpc);
1424 error (message, index);
1425 return 0;
1426 verify_error:
1427 error ("verification error at PC=%d", oldpc);
1428 error ("%s", message);
1429 return 0;