re PR target/8343 ([m68k] [3.2 regression] m68k-elf/rtems ICE at instantiate_virtual_...
[official-gcc.git] / gcc / java / verify.c
blob585cd171dd7d613f7d746fd5218b8e66cef2d533
1 /* Handle verification of bytecoded methods for the GNU compiler for
2 the Java(TM) language.
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc. */
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "tree.h"
32 #include "java-tree.h"
33 #include "javaop.h"
34 #include "java-opcodes.h"
35 #include "jcf.h"
36 #include "java-except.h"
37 #include "toplev.h"
39 static void push_pending_label PARAMS ((tree));
40 static tree merge_types PARAMS ((tree, tree));
41 static const char *check_pending_block PARAMS ((tree));
42 static void type_stack_dup PARAMS ((int, int));
43 static int start_pc_cmp PARAMS ((const PTR, const PTR));
44 static char *pop_argument_types PARAMS ((tree));
46 extern int stack_pointer;
48 /* During verification, start of the current subroutine (jsr target). */
49 tree current_subr;
51 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
52 A pending block is one that has LABEL_CHANGED set, which means
53 it requires (re-) verification. */
54 tree pending_blocks;
56 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
58 static void
59 push_pending_label (target_label)
60 tree target_label;
62 if (! LABEL_CHANGED (target_label))
64 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
65 pending_blocks = target_label;
66 LABEL_CHANGED (target_label) = 1;
70 /* Note that TARGET_LABEL is a possible successor instruction.
71 Merge the type state etc.
72 Return NULL on success, or an error message on failure. */
74 static const char *
75 check_pending_block (target_label)
76 tree target_label;
78 int changed = merge_type_state (target_label);
80 if (changed)
82 if (changed < 0)
83 return "types could not be merged";
84 push_pending_label (target_label);
87 if (current_subr == NULL)
89 if (LABEL_IN_SUBR (target_label))
90 return "might transfer control into subroutine";
92 else
94 if (LABEL_IN_SUBR (target_label))
96 if (LABEL_SUBR_START (target_label) != current_subr)
97 return "transfer out of subroutine";
99 else if (! LABEL_VERIFIED (target_label))
101 LABEL_IN_SUBR (target_label) = 1;
102 LABEL_SUBR_START (target_label) = current_subr;
104 else
105 return "transfer out of subroutine";
107 return NULL;
110 /* Count the number of nested jsr calls needed to reach LABEL. */
112 static int
113 subroutine_nesting (tree label)
115 int nesting = 0;
116 while (label != NULL_TREE && LABEL_IN_SUBR (label))
118 if (! LABEL_IS_SUBR_START(label))
119 label = LABEL_SUBR_START (label);
120 label = LABEL_SUBR_CONTEXT (label);
121 nesting++;
123 return nesting;
126 /* Return the "merged" types of TYPE1 and TYPE2.
127 If either is primitive, the other must match (after promotion to int).
128 For reference types, return the common super-class.
129 Return TYPE_UNKNOWN if the types cannot be merged. */
131 static tree
132 merge_types (type1, type2)
133 tree type1, type2;
135 if (type1 == type2)
136 return type1;
137 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
138 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
139 return TYPE_UNKNOWN;
140 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
142 int depth1, depth2;
143 tree tt1, tt2;
144 /* ptr_type_node is only used for a null reference,
145 which is compatible with any reference type. */
146 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
147 return type2;
148 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
149 return type1;
151 tt1 = TREE_TYPE (type1);
152 tt2 = TREE_TYPE (type2);
154 /* If tt{1,2} haven't been properly loaded, now is a good time
155 to do it. */
156 if (!TYPE_SIZE (tt1))
158 load_class (tt1, 1);
159 safe_layout_class (tt1);
162 if (!TYPE_SIZE (tt2))
164 load_class (tt2, 1);
165 safe_layout_class (tt2);
168 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
170 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
172 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
173 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
174 tree el_type = NULL_TREE;
175 if (el_type1 == el_type2)
176 el_type = el_type1;
177 else if (TREE_CODE (el_type1) == POINTER_TYPE
178 && TREE_CODE (el_type2) == POINTER_TYPE)
179 el_type = merge_types (el_type1, el_type2);
180 if (el_type != NULL_TREE)
182 HOST_WIDE_INT len1 = java_array_type_length (tt1);
183 HOST_WIDE_INT len2 = java_array_type_length (tt2);
184 if (len1 != len2)
185 len1 = -1;
186 else if (el_type1 == el_type2)
187 return type1;
188 return promote_type (build_java_array_type (el_type, len1));
191 return object_ptr_type_node;
194 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
196 /* FIXME: should see if two interfaces have a common
197 superinterface. */
198 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
200 /* This is a kludge, but matches what Sun's verifier does.
201 It can be tricked, but is safe as long as type errors
202 (i.e. interface method calls) are caught at run-time. */
203 return object_ptr_type_node;
205 else
207 if (can_widen_reference_to (tt2, tt1))
208 return type1;
209 else
210 return object_ptr_type_node;
213 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
215 if (can_widen_reference_to (tt1, tt2))
216 return type2;
217 else
218 return object_ptr_type_node;
221 type1 = tt1;
222 type2 = tt2;
224 depth1 = class_depth (type1);
225 depth2 = class_depth (type2);
226 for ( ; depth1 > depth2; depth1--)
227 type1 = TYPE_BINFO_BASETYPE (type1, 0);
228 for ( ; depth2 > depth1; depth2--)
229 type2 = TYPE_BINFO_BASETYPE (type2, 0);
230 while (type1 != type2)
232 type1 = TYPE_BINFO_BASETYPE (type1, 0);
233 type2 = TYPE_BINFO_BASETYPE (type2, 0);
235 return promote_type (type1);
237 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
238 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
239 return int_type_node;
240 return TYPE_UNKNOWN;
243 /* Merge the current type state with that at LABEL.
244 Return -1 the the states are incompatible (i.e. on error),
245 0 if there was no change, and 1 if there was a change. */
248 merge_type_state (label)
249 tree label;
251 int nlocals = DECL_MAX_LOCALS (current_function_decl);
252 int cur_length = stack_pointer + nlocals;
253 tree vec = LABEL_TYPE_STATE (label);
254 tree return_map;
255 if (vec == NULL_TREE)
257 if (!vec)
259 vec = make_tree_vec (cur_length);
260 LABEL_TYPE_STATE (label) = vec;
262 while (--cur_length >= 0)
263 TREE_VEC_ELT (vec, cur_length) = type_map [cur_length];
264 return 1;
266 else
268 int i;
269 int changed = 0;
270 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
271 && current_subr != label)
272 return_map = LABEL_RETURN_TYPE_STATE (label);
273 else
274 return_map = NULL_TREE;
275 if (TREE_VEC_LENGTH (vec) != cur_length)
277 return -1;
279 for (i = 0; i < cur_length; i++)
281 tree old_type = TREE_VEC_ELT (vec, i);
282 tree new_type = merge_types (old_type, type_map [i]);
283 if (TREE_VEC_ELT (vec, i) != new_type)
285 /* If there has been a change, note that since we must re-verify.
286 However, if the label is the start of a subroutine,
287 we don't care about local variables that are neither
288 set nor used in the sub-routine. */
289 if (return_map == NULL_TREE || i >= nlocals
290 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
291 || (TYPE_IS_WIDE (new_type)
292 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
293 changed = 1;
295 TREE_VEC_ELT (vec, i) = new_type;
296 if (new_type == TYPE_UNKNOWN)
298 if (i >= nlocals)
299 return -1;
301 else if (TYPE_IS_WIDE (new_type))
302 i++;
304 return changed;
308 /* Handle dup-like operations. */
310 static void
311 type_stack_dup (size, offset)
312 int size, offset;
314 tree type[4];
315 int index;
316 for (index = 0; index < size + offset; index++)
318 type[index] = stack_type_map[stack_pointer - 1];
319 if (type[index] == void_type_node)
321 index++;
322 type[index] = stack_type_map[stack_pointer - 2];
323 if (! TYPE_IS_WIDE (type[index]))
324 abort ();
325 if (index == size || index == size + offset)
326 /* Dup operation splits 64-bit number. */
327 abort ();
329 pop_type (type[index]);
331 for (index = size; --index >= 0; )
333 if (type[index] != void_type_node)
334 push_type (type[index]);
337 for (index = size + offset; --index >= 0; )
339 if (type[index] != void_type_node)
340 push_type (type[index]);
344 /* This keeps track of a start PC and corresponding initial index. */
345 struct pc_index
347 int start_pc;
348 int index;
351 /* A helper that is used when sorting exception ranges. */
352 static int
353 start_pc_cmp (xp, yp)
354 const PTR xp;
355 const PTR yp;
357 const struct pc_index *x = (const struct pc_index *) xp;
358 const struct pc_index *y = (const struct pc_index *) yp;
359 return x->start_pc - y->start_pc;
362 /* This causes the next iteration to ignore the next instruction
363 and look for some other unhandled instruction. */
364 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
365 #define INVALID_PC (-1)
367 #define VERIFICATION_ERROR(MESSAGE) \
368 do { message = MESSAGE; goto verify_error; } while (0)
370 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
371 do { message = MESSAGE; goto error_with_index; } while (0)
373 /* Recursive helper function to pop argument types during verifiation.
374 ARG_TYPES is the list of formal parameter types.
375 Return NULL on success and a freshly malloc'd error message on failure. */
377 static char *
378 pop_argument_types (arg_types)
379 tree arg_types;
381 if (arg_types == end_params_node)
382 return NULL;
383 if (TREE_CODE (arg_types) == TREE_LIST)
385 char *message = pop_argument_types (TREE_CHAIN (arg_types));
386 if (message == NULL)
387 pop_type_0 (TREE_VALUE (arg_types), &message);
388 return message;
390 abort ();
393 #define POP_TYPE(TYPE, MESSAGE) \
394 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
395 if (pmessage != NULL) goto pop_type_error; \
396 } while (0)
398 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
399 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
400 if (pmessage != NULL) goto pop_type_error; \
401 } while (0)
403 #define PUSH_TYPE(TYPE) \
404 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
406 #define PUSH_PENDING(LABEL) \
407 do { tree tmplab = LABEL; \
408 if ((message = check_pending_block (tmplab)) != NULL) \
409 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
411 #ifdef __GNUC__
412 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
413 #else
414 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
415 #endif
417 #define BCODE byte_ops
419 /* Verify the bytecodes of the current method.
420 Return 1 on success, 0 on failure. */
422 verify_jvm_instructions (jcf, byte_ops, length)
423 JCF* jcf;
424 const unsigned char *byte_ops;
425 long length;
427 tree label;
428 int wide = 0;
429 int op_code;
430 int PC;
431 int oldpc = 0; /* PC of start of instruction. */
432 int prevpc = 0; /* If >= 0, PC of previous instruction. */
433 const char *message = 0;
434 char *pmessage;
435 int i;
436 int index;
437 register unsigned char *p;
438 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
439 struct eh_range *eh_ranges;
440 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
441 struct pc_index *starts;
442 int eh_count;
444 jint int_value = -1;
446 pending_blocks = NULL_TREE;
448 /* Handle the exception table. */
449 method_init_exceptions ();
450 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
451 eh_count = JCF_readu2 (jcf);
453 /* We read the exception handlers in order of increasing start PC.
454 To do this we first read and sort the start PCs. */
455 starts = xmalloc (eh_count * sizeof (struct pc_index));
456 for (i = 0; i < eh_count; ++i)
458 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
459 starts[i].index = i;
461 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
463 for (i = 0; i < eh_count; ++i)
465 int start_pc, end_pc, handler_pc, catch_type;
467 p = jcf->read_ptr + 8 * starts[i].index;
469 start_pc = GET_u2 (p);
470 end_pc = GET_u2 (p+2);
471 handler_pc = GET_u2 (p+4);
472 catch_type = GET_u2 (p+6);
474 if (start_pc < 0 || start_pc >= length
475 || end_pc < 0 || end_pc > length || start_pc >= end_pc
476 || handler_pc < 0 || handler_pc >= length
477 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
478 || (end_pc < length &&
479 ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START))
480 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
482 error ("bad pc in exception_table");
483 free (starts);
484 return 0;
487 if (handler_pc >= start_pc && handler_pc < end_pc)
488 warning ("exception handler inside code that is being protected");
490 add_handler (start_pc, end_pc,
491 lookup_label (handler_pc),
492 catch_type == 0 ? NULL_TREE
493 : get_class_constant (jcf, catch_type));
495 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
498 free (starts);
499 handle_nested_ranges ();
501 for (PC = 0;;)
503 tree type, tmp;
504 if (((PC != INVALID_PC
505 && instruction_bits [PC] & BCODE_TARGET) != 0)
506 || PC == 0)
508 PUSH_PENDING (lookup_label (PC));
509 INVALIDATE_PC;
511 /* Check if there are any more pending blocks in the current
512 subroutine. Because we push pending blocks in a
513 last-in-first-out order, and because we don't push anything
514 from our caller until we are done with this subroutine or
515 anything nested in it, then we are done if the top of the
516 pending_blocks stack is not in a subroutine, or it is in our
517 caller. */
518 if (current_subr
519 && PC == INVALID_PC)
521 if (pending_blocks == NULL_TREE
522 || (subroutine_nesting (pending_blocks)
523 < subroutine_nesting (current_subr)))
525 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
526 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
527 tmp = LABEL_RETURN_LABELS (current_subr);
529 /* FIXME: If we exit a subroutine via a throw, we might
530 have returned to an earlier caller. Obviously a
531 "ret" can only return one level, but a throw may
532 return many levels.*/
533 current_subr = LABEL_SUBR_CONTEXT (current_subr);
535 if (RETURN_MAP_ADJUSTED (ret_map))
537 /* Since we are done with this subroutine , set up
538 the (so far known) return address as pending -
539 with the merged type state. */
540 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
542 tree return_label = TREE_VALUE (tmp);
543 tree return_state = LABEL_TYPE_STATE (return_label);
544 if (return_state == NULL_TREE)
546 /* This means means we had not verified the
547 subroutine earlier, so this is the first jsr to
548 call it. In this case, the type_map of the return
549 address is just the current type_map - and that
550 is handled by the following PUSH_PENDING. */
552 else
554 /* In this case we have to do a merge. But first
555 restore the type_map for unused slots to those
556 that were in effect at the jsr. */
557 for (index = size; --index >= 0; )
559 type_map[index] = TREE_VEC_ELT (ret_map, index);
560 if (type_map[index] == TYPE_UNUSED)
561 type_map[index]
562 = TREE_VEC_ELT (return_state, index);
565 PUSH_PENDING (return_label);
570 if (PC == INVALID_PC)
572 label = pending_blocks;
573 if (label == NULL_TREE)
574 break; /* We're done! */
575 pending_blocks = LABEL_PENDING_CHAIN (label);
576 LABEL_CHANGED (label) = 0;
578 if (LABEL_IN_SUBR (label))
579 current_subr = LABEL_SUBR_START (label);
580 else
581 current_subr = NULL_TREE;
583 /* Restore type_map and stack_pointer from
584 LABEL_TYPE_STATE (label), and continue
585 compiling from there. */
586 load_type_state (label);
587 PC = LABEL_PC (label);
589 else if (PC >= length)
590 VERIFICATION_ERROR ("falling through end of method");
592 /* fprintf (stderr, "** %d\n", PC); */
594 oldpc = PC;
596 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
597 VERIFICATION_ERROR ("PC not at instruction start");
599 instruction_bits[PC] |= BCODE_VERIFIED;
601 eh_ranges = find_handler (oldpc);
603 op_code = byte_ops[PC++];
604 switch (op_code)
606 int is_static, is_putting;
607 case OPCODE_nop:
608 break;
609 case OPCODE_iconst_m1:
610 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
611 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
612 i = op_code - OPCODE_iconst_0;
613 goto push_int;
614 push_int:
615 if (byte_ops[PC] == OPCODE_newarray
616 || byte_ops[PC] == OPCODE_anewarray)
617 int_value = i;
618 PUSH_TYPE (int_type_node); break;
619 case OPCODE_lconst_0: case OPCODE_lconst_1:
620 PUSH_TYPE (long_type_node); break;
621 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
622 PUSH_TYPE (float_type_node); break;
623 case OPCODE_dconst_0: case OPCODE_dconst_1:
624 PUSH_TYPE (double_type_node); break;
625 case OPCODE_bipush:
626 i = IMMEDIATE_s1;
627 goto push_int;
628 case OPCODE_sipush:
629 i = IMMEDIATE_s2;
630 goto push_int;
631 case OPCODE_iload: type = int_type_node; goto general_load;
632 case OPCODE_lload: type = long_type_node; goto general_load;
633 case OPCODE_fload: type = float_type_node; goto general_load;
634 case OPCODE_dload: type = double_type_node; goto general_load;
635 case OPCODE_aload: type = ptr_type_node; goto general_load;
636 general_load:
637 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
638 wide = 0;
639 goto load;
640 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
641 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
642 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
643 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
644 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
645 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
646 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
647 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
648 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
649 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
650 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
651 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
652 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
653 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
654 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
655 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
656 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
657 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
658 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
659 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
660 load:
661 if (index < 0
662 || (index + TYPE_IS_WIDE (type)
663 >= DECL_MAX_LOCALS (current_function_decl)))
664 VERIFICATION_ERROR_WITH_INDEX
665 ("invalid local variable index %d in load");
666 tmp = type_map[index];
667 if (tmp == TYPE_UNKNOWN)
668 VERIFICATION_ERROR_WITH_INDEX
669 ("loading local variable %d which has unknown type");
670 else if (tmp == TYPE_SECOND
671 || (TYPE_IS_WIDE (type)
672 && type_map[index+1] != void_type_node)
673 || (type == ptr_type_node
674 ? TREE_CODE (tmp) != POINTER_TYPE
675 : type == int_type_node
676 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
677 : type != tmp))
678 VERIFICATION_ERROR_WITH_INDEX
679 ("loading local variable %d which has invalid type");
680 PUSH_TYPE (tmp);
681 goto note_used;
682 case OPCODE_istore: type = int_type_node; goto general_store;
683 case OPCODE_lstore: type = long_type_node; goto general_store;
684 case OPCODE_fstore: type = float_type_node; goto general_store;
685 case OPCODE_dstore: type = double_type_node; goto general_store;
686 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
687 general_store:
688 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
689 wide = 0;
690 goto store;
691 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
692 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
693 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
694 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
695 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
696 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
697 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
698 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
699 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
700 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
701 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
702 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
703 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
704 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
705 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
706 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
707 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
708 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
709 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
710 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
711 store:
712 if (index < 0
713 || (index + TYPE_IS_WIDE (type)
714 >= DECL_MAX_LOCALS (current_function_decl)))
716 VERIFICATION_ERROR_WITH_INDEX
717 ("invalid local variable index %d in store");
718 return 0;
720 POP_TYPE_CONV (type, type, NULL);
721 type_map[index] = type;
723 /* If local variable changed, we need to reconsider eh handlers. */
724 prev_eh_ranges = NULL_EH_RANGE;
726 /* Allocate decl and rtx for this variable now, so if we're not
727 optmizing, we get a temporary that survives the whole method. */
728 find_local_variable (index, type, oldpc);
730 if (TYPE_IS_WIDE (type))
731 type_map[index+1] = TYPE_SECOND;
732 /* ... fall through to note_used ... */
733 note_used:
734 /* For store or load, note that local variable INDEX is used.
735 This is needed to verify try-finally sub-routines. */
736 if (current_subr)
738 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
739 tree subr_vec = LABEL_TYPE_STATE (current_subr);
740 int len = 1 + TYPE_IS_WIDE (type);
741 while (--len >= 0)
743 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
744 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
747 break;
748 case OPCODE_iadd:
749 case OPCODE_iand:
750 case OPCODE_idiv:
751 case OPCODE_imul:
752 case OPCODE_ior:
753 case OPCODE_irem:
754 case OPCODE_ishl:
755 case OPCODE_ishr:
756 case OPCODE_isub:
757 case OPCODE_iushr:
758 case OPCODE_ixor:
759 type = int_type_node; goto binop;
760 case OPCODE_ineg:
761 case OPCODE_i2c:
762 case OPCODE_i2b:
763 case OPCODE_i2s:
764 type = int_type_node; goto unop;
765 case OPCODE_ladd:
766 case OPCODE_land:
767 case OPCODE_ldiv:
768 case OPCODE_lsub:
769 case OPCODE_lmul:
770 case OPCODE_lrem:
771 case OPCODE_lor:
772 case OPCODE_lxor:
773 type = long_type_node; goto binop;
774 case OPCODE_lneg:
775 type = long_type_node; goto unop;
776 case OPCODE_fadd: case OPCODE_fsub:
777 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
778 type = float_type_node; goto binop;
779 case OPCODE_fneg:
780 type = float_type_node; goto unop;
781 case OPCODE_dadd: case OPCODE_dsub:
782 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
783 type = double_type_node; goto binop;
784 case OPCODE_dneg:
785 type = double_type_node; goto unop;
786 unop:
787 pop_type (type);
788 PUSH_TYPE (type);
789 break;
790 binop:
791 pop_type (type);
792 pop_type (type);
793 PUSH_TYPE (type);
794 break;
795 case OPCODE_lshl:
796 case OPCODE_lshr:
797 case OPCODE_lushr:
798 pop_type (int_type_node);
799 pop_type (long_type_node);
800 PUSH_TYPE (long_type_node);
801 break;
802 case OPCODE_iinc:
803 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
804 PC += wide + 1;
805 wide = 0;
806 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
807 VERIFICATION_ERROR ("invalid local variable index in iinc");
808 tmp = type_map[index];
809 if (tmp == NULL_TREE
810 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
811 VERIFICATION_ERROR ("invalid local variable type in iinc");
812 break;
813 case OPCODE_i2l:
814 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
815 case OPCODE_i2f:
816 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
817 case OPCODE_i2d:
818 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
819 case OPCODE_l2i:
820 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
821 case OPCODE_l2f:
822 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
823 case OPCODE_l2d:
824 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
825 case OPCODE_f2i:
826 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
827 case OPCODE_f2l:
828 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
829 case OPCODE_f2d:
830 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
831 case OPCODE_d2i:
832 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
833 case OPCODE_d2l:
834 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
835 case OPCODE_d2f:
836 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
837 case OPCODE_lcmp:
838 type = long_type_node; goto compare;
839 case OPCODE_fcmpl:
840 case OPCODE_fcmpg:
841 type = float_type_node; goto compare;
842 case OPCODE_dcmpl:
843 case OPCODE_dcmpg:
844 type = double_type_node; goto compare;
845 compare:
846 pop_type (type); pop_type (type);
847 PUSH_TYPE (int_type_node); break;
848 case OPCODE_ifeq:
849 case OPCODE_ifne:
850 case OPCODE_iflt:
851 case OPCODE_ifge:
852 case OPCODE_ifgt:
853 case OPCODE_ifle:
854 pop_type (int_type_node); goto cond;
855 case OPCODE_ifnull:
856 case OPCODE_ifnonnull:
857 pop_type (ptr_type_node ); goto cond;
858 case OPCODE_if_icmpeq:
859 case OPCODE_if_icmpne:
860 case OPCODE_if_icmplt:
861 case OPCODE_if_icmpge:
862 case OPCODE_if_icmpgt:
863 case OPCODE_if_icmple:
864 pop_type (int_type_node); pop_type (int_type_node); goto cond;
865 case OPCODE_if_acmpeq:
866 case OPCODE_if_acmpne:
867 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
868 goto cond;
869 cond:
870 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
871 break;
872 case OPCODE_goto:
873 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
874 INVALIDATE_PC;
875 break;
876 case OPCODE_wide:
877 switch (byte_ops[PC])
879 case OPCODE_iload: case OPCODE_lload:
880 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
881 case OPCODE_istore: case OPCODE_lstore:
882 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
883 case OPCODE_iinc:
884 case OPCODE_ret:
885 wide = 1;
886 break;
887 default:
888 VERIFICATION_ERROR ("invalid use of wide instruction");
890 break;
891 case OPCODE_return: type = void_type_node; goto ret;
892 case OPCODE_ireturn:
893 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
894 || TREE_CODE (return_type) == CHAR_TYPE
895 || TREE_CODE (return_type) == INTEGER_TYPE)
896 && TYPE_PRECISION (return_type) <= 32)
897 type = return_type;
898 else
899 type = NULL_TREE;
900 goto ret;
901 case OPCODE_lreturn: type = long_type_node; goto ret;
902 case OPCODE_freturn: type = float_type_node; goto ret;
903 case OPCODE_dreturn: type = double_type_node; goto ret;
904 case OPCODE_areturn:
905 if (TREE_CODE (return_type) == POINTER_TYPE)
906 type = return_type;
907 else
908 type = NULL_TREE;
909 goto ret;
910 ret:
911 if (type != return_type)
912 VERIFICATION_ERROR ("incorrect ?return opcode");
913 if (type != void_type_node)
914 POP_TYPE(type, "return value has wrong type");
915 INVALIDATE_PC;
916 break;
917 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
918 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
919 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
920 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
921 field:
923 tree field_signature, field_type;
924 index = IMMEDIATE_u2;
925 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
926 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
927 if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref)
928 VERIFICATION_ERROR
929 ("field instruction does not reference a Fieldref");
930 field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
931 field_type = get_type_from_signature (field_signature);
932 if (is_putting)
933 POP_TYPE (field_type, "incorrect type for field");
934 if (! is_static)
936 int clindex = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
937 index);
938 tree self_type = get_class_constant (current_jcf, clindex);
939 /* Defer actual checking until next pass. */
940 POP_TYPE(self_type, "incorrect type for field reference");
942 if (! is_putting)
943 PUSH_TYPE (field_type);
944 break;
946 case OPCODE_new:
947 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
948 break;
949 case OPCODE_dup: wide = 1; index = 0; goto dup;
950 case OPCODE_dup_x1: wide = 1; index = 1; goto dup;
951 case OPCODE_dup_x2: wide = 1; index = 2; goto dup;
952 case OPCODE_dup2: wide = 2; index = 0; goto dup;
953 case OPCODE_dup2_x1: wide = 2; index = 1; goto dup;
954 case OPCODE_dup2_x2: wide = 2; index = 2; goto dup;
955 dup:
956 if (wide + index > stack_pointer)
957 VERIFICATION_ERROR ("stack underflow - dup* operation");
958 type_stack_dup (wide, index);
959 wide = 0;
960 break;
961 case OPCODE_pop: index = 1; goto pop;
962 case OPCODE_pop2: index = 2; goto pop;
963 pop:
964 if (stack_pointer < index)
965 VERIFICATION_ERROR ("stack underflow");
966 stack_pointer -= index;
967 break;
968 case OPCODE_swap:
969 if (stack_pointer < 2)
970 VERIFICATION_ERROR ("stack underflow (in swap)");
971 else
973 tree type1 = stack_type_map[stack_pointer - 1];
974 tree type2 = stack_type_map[stack_pointer - 2];
975 if (type1 == void_type_node || type2 == void_type_node)
976 VERIFICATION_ERROR ("verifier (swap): double or long value");
977 stack_type_map[stack_pointer - 2] = type1;
978 stack_type_map[stack_pointer - 1] = type2;
980 break;
981 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
982 case OPCODE_ldc2_w:
983 case OPCODE_ldc_w:
984 index = IMMEDIATE_u2; goto ldc;
985 ldc:
986 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
987 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
988 int_value = -1;
989 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
991 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
992 case CONSTANT_Float: type = float_type_node; goto check_ldc;
993 case CONSTANT_String: type = string_type_node; goto check_ldc;
994 case CONSTANT_Long: type = long_type_node; goto check_ldc;
995 case CONSTANT_Double: type = double_type_node; goto check_ldc;
996 check_ldc:
997 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
998 break;
999 /* ... else fall through ... */
1000 default:
1001 VERIFICATION_ERROR ("bad constant pool tag in ldc");
1003 if (type == int_type_node)
1005 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
1006 goto push_int;
1008 PUSH_TYPE (type);
1009 break;
1011 case OPCODE_invokevirtual:
1012 case OPCODE_invokespecial:
1013 case OPCODE_invokestatic:
1014 case OPCODE_invokeinterface:
1016 tree sig, method_name, method_type, self_type;
1017 int self_is_interface, tag;
1018 index = IMMEDIATE_u2;
1019 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
1020 VERIFICATION_ERROR_WITH_INDEX
1021 ("bad constant pool index %d for invoke");
1022 tag = JPOOL_TAG (current_jcf, index);
1023 if (op_code == OPCODE_invokeinterface)
1025 if (tag != CONSTANT_InterfaceMethodref)
1026 VERIFICATION_ERROR
1027 ("invokeinterface does not reference an InterfaceMethodref");
1029 else
1031 if (tag != CONSTANT_Methodref)
1032 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1034 sig = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
1035 self_type = get_class_constant
1036 (current_jcf, COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
1037 index));
1038 if (! CLASS_LOADED_P (self_type))
1039 load_class (self_type, 1);
1040 self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
1041 method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
1042 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
1043 IDENTIFIER_LENGTH (sig));
1044 if (TREE_CODE (method_type) != FUNCTION_TYPE)
1045 VERIFICATION_ERROR ("bad method signature");
1046 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
1047 if (pmessage != NULL)
1049 message = "invalid argument type";
1050 goto pop_type_error;
1053 /* Can't invoke <clinit> */
1054 if (ID_CLINIT_P (method_name))
1055 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1056 /* Apart invokespecial, can't invoke <init> */
1057 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
1058 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1060 if (op_code != OPCODE_invokestatic)
1061 POP_TYPE (self_type,
1062 "stack type not subclass of invoked method's class");
1064 switch (op_code)
1066 case OPCODE_invokeinterface:
1068 int nargs = IMMEDIATE_u1;
1069 int notZero = IMMEDIATE_u1;
1071 if (!nargs || notZero)
1072 VERIFICATION_ERROR
1073 ("invalid argument number in invokeinterface");
1074 /* If we verify/resolve the constant pool, as we should,
1075 this test (and the one just following) are redundant. */
1076 if (! self_is_interface)
1077 VERIFICATION_ERROR ("invokeinterface calls method not in interface");
1078 break;
1079 default:
1080 if (self_is_interface)
1081 VERIFICATION_ERROR ("method in interface called");
1085 if (TREE_TYPE (method_type) != void_type_node)
1086 PUSH_TYPE (TREE_TYPE (method_type));
1087 break;
1090 case OPCODE_arraylength:
1091 /* Type checking actually made during code generation */
1092 pop_type( ptr_type_node );
1093 PUSH_TYPE( int_type_node );
1094 break;
1096 /* Q&D verification *or* more checking done during code generation
1097 for byte/boolean/char/short, the value popped is a int coerced
1098 into the right type before being stored. */
1099 case OPCODE_iastore: type = int_type_node; goto astore;
1100 case OPCODE_lastore: type = long_type_node; goto astore;
1101 case OPCODE_fastore: type = float_type_node; goto astore;
1102 case OPCODE_dastore: type = double_type_node; goto astore;
1103 case OPCODE_aastore: type = ptr_type_node; goto astore;
1104 case OPCODE_bastore: type = int_type_node; goto astore;
1105 case OPCODE_castore: type = int_type_node; goto astore;
1106 case OPCODE_sastore: type = int_type_node; goto astore;
1107 astore:
1108 /* FIXME - need better verification here */
1109 pop_type (type); /* new value */
1110 pop_type (int_type_node); /* index */
1111 pop_type (ptr_type_node); /* array */
1112 break;
1114 /* Q&D verification *or* more checking done during code generation
1115 for byte/boolean/char/short, the value pushed is a int. */
1116 case OPCODE_iaload: type = int_type_node; goto aload;
1117 case OPCODE_laload: type = long_type_node; goto aload;
1118 case OPCODE_faload: type = float_type_node; goto aload;
1119 case OPCODE_daload: type = double_type_node; goto aload;
1120 case OPCODE_aaload: type = ptr_type_node; goto aload;
1121 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1122 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1123 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1124 aload:
1125 pop_type (int_type_node);
1126 tmp = pop_type (ptr_type_node);
1127 if (is_array_type_p (tmp))
1128 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1129 else if (tmp != TYPE_NULL)
1130 VERIFICATION_ERROR ("array load from non-array type");
1131 PUSH_TYPE (type);
1132 break;
1134 case OPCODE_anewarray:
1135 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1136 type = promote_type (type);
1137 goto newarray;
1139 case OPCODE_newarray:
1140 index = IMMEDIATE_u1;
1141 type = decode_newarray_type (index);
1142 if (type == NULL_TREE)
1143 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1144 goto newarray;
1146 newarray:
1147 if (int_value >= 0 && prevpc >= 0)
1149 /* If previous instruction pushed int constant,
1150 we want to use it. */
1151 switch (byte_ops[prevpc])
1153 case OPCODE_iconst_0: case OPCODE_iconst_1:
1154 case OPCODE_iconst_2: case OPCODE_iconst_3:
1155 case OPCODE_iconst_4: case OPCODE_iconst_5:
1156 case OPCODE_bipush: case OPCODE_sipush:
1157 case OPCODE_ldc: case OPCODE_ldc_w:
1158 break;
1159 default:
1160 int_value = -1;
1163 else
1164 int_value = -1;
1165 type = build_java_array_type (type, int_value);
1166 pop_type (int_type_node);
1167 PUSH_TYPE (type);
1168 break;
1170 case OPCODE_multianewarray:
1172 int ndim, i;
1173 index = IMMEDIATE_u2;
1174 ndim = IMMEDIATE_u1;
1176 if( ndim < 1 )
1177 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
1179 for( i = 0; i < ndim; i++ )
1180 pop_type (int_type_node);
1181 PUSH_TYPE (get_class_constant (current_jcf, index));
1182 break;
1185 case OPCODE_aconst_null:
1186 PUSH_TYPE (ptr_type_node);
1187 break;
1189 case OPCODE_athrow:
1190 /* FIXME: athrow also empties the stack. */
1191 POP_TYPE (throwable_type_node, "missing throwable at athrow" );
1192 INVALIDATE_PC;
1193 break;
1195 case OPCODE_checkcast:
1196 POP_TYPE (object_ptr_type_node,
1197 "checkcast operand is not a pointer");
1198 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1199 PUSH_TYPE (type);
1200 break;
1201 case OPCODE_instanceof:
1202 POP_TYPE (object_ptr_type_node,
1203 "instanceof operand is not a pointer");
1204 get_class_constant (current_jcf, IMMEDIATE_u2);
1205 PUSH_TYPE (int_type_node);
1206 break;
1208 case OPCODE_tableswitch:
1210 jint low, high;
1212 POP_TYPE (int_type_node, "missing int for tableswitch");
1213 while (PC%4)
1215 if (byte_ops[PC++])
1216 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1218 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1219 low = IMMEDIATE_s4;
1220 high = IMMEDIATE_s4;
1222 if (low > high)
1223 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1225 while (low++ <= high)
1226 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1227 INVALIDATE_PC;
1228 break;
1231 case OPCODE_lookupswitch:
1233 jint npairs, last = 0, not_registered = 1;
1235 POP_TYPE (int_type_node, "missing int for lookupswitch");
1236 while (PC%4)
1238 if (byte_ops[PC++])
1239 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1242 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1243 npairs = IMMEDIATE_s4;
1245 if (npairs < 0)
1246 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1248 while (npairs--)
1250 int match = IMMEDIATE_s4;
1251 if (not_registered)
1252 not_registered = 0;
1253 else if (last >= match)
1254 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1256 last = match;
1257 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1259 INVALIDATE_PC;
1260 break;
1263 case OPCODE_monitorenter:
1264 /* fall thru */
1265 case OPCODE_monitorexit:
1266 pop_type (ptr_type_node);
1267 break;
1269 case OPCODE_goto_w:
1270 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1271 INVALIDATE_PC;
1272 break;
1274 case OPCODE_jsr:
1276 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1277 tree return_label = lookup_label (PC);
1278 PUSH_TYPE (return_address_type_node);
1279 /* The return label chain will be null if this is the first
1280 time we've seen this jsr target. */
1281 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1283 tree return_type_map;
1284 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1285 index = nlocals + DECL_MAX_STACK (current_function_decl);
1286 return_type_map = make_tree_vec (index);
1287 while (index > nlocals)
1288 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1289 while (index > 0)
1290 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1291 LABEL_RETURN_LABEL (target)
1292 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1293 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
1294 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1295 LABEL_IS_SUBR_START (target) = 1;
1296 LABEL_IN_SUBR (target) = 1;
1297 LABEL_SUBR_START (target) = target;
1298 LABEL_SUBR_CONTEXT (target) = current_subr;
1300 else if (! LABEL_IS_SUBR_START (target)
1301 || LABEL_SUBR_CONTEXT (target) != current_subr)
1302 VERIFICATION_ERROR ("label part of different subroutines");
1304 i = merge_type_state (target);
1305 if (i != 0)
1307 if (i < 0)
1308 VERIFICATION_ERROR ("types could not be merged at jsr");
1309 push_pending_label (target);
1311 current_subr = target;
1313 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1314 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1316 LABEL_RETURN_LABELS (target)
1317 = tree_cons (NULL_TREE, return_label,
1318 LABEL_RETURN_LABELS (target));
1321 if (LABEL_VERIFIED (target))
1323 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1324 int len = TREE_VEC_LENGTH (return_map);
1325 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1326 while (--len >= 0)
1328 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1329 type_map[len] = TREE_VEC_ELT (return_map, len);
1331 current_subr = LABEL_SUBR_CONTEXT (target);
1332 if (RETURN_MAP_ADJUSTED (return_map))
1333 PUSH_PENDING (return_label);
1336 INVALIDATE_PC;
1338 break;
1339 case OPCODE_ret:
1340 if (current_subr == NULL)
1341 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1342 else
1344 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1345 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
1346 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1347 wide = 0;
1348 INVALIDATE_PC;
1349 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1350 || type_map[index] != TYPE_RETURN_ADDR)
1351 VERIFICATION_ERROR ("invalid ret index");
1353 /* The next chunk of code is similar to an inlined version of
1354 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1355 * The main differences are that LABEL_RETURN_LABEL is
1356 * pre-allocated by the jsr (but we don't know the size then);
1357 * and that we have to handle TYPE_UNUSED. */
1359 if (! RETURN_MAP_ADJUSTED (ret_map))
1360 { /* First return from this subroutine - fix stack pointer. */
1361 TREE_VEC_LENGTH (ret_map) = size;
1362 for (index = size; --index >= 0; )
1364 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1365 TREE_VEC_ELT (ret_map, index) = type_map[index];
1367 RETURN_MAP_ADJUSTED (ret_map) = 1;
1369 else
1371 if (TREE_VEC_LENGTH (ret_map) != size)
1372 VERIFICATION_ERROR ("inconsistent stack size on ret");
1373 for (index = 0; index < size; index++)
1375 tree type = TREE_VEC_ELT (ret_map, index);
1376 if (type != TYPE_UNUSED)
1378 type = merge_types (type, type_map [index]);
1379 TREE_VEC_ELT (ret_map, index) = type;
1380 if (type == TYPE_UNKNOWN)
1382 if (index >= size - stack_pointer)
1383 VERIFICATION_ERROR
1384 ("inconsistent types on ret from jsr");
1386 else if (TYPE_IS_WIDE (type))
1387 index++;
1394 break;
1395 case OPCODE_jsr_w:
1396 case OPCODE_ret_w:
1397 default:
1398 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1399 return 0;
1402 prevpc = oldpc;
1404 /* The following test is true if we have entered or exited an exception
1405 handler range *or* we have done a store to a local variable.
1406 In either case we need to consider any exception handlers that
1407 might "follow" this instruction. */
1409 if (eh_ranges != prev_eh_ranges)
1411 int save_stack_pointer = stack_pointer;
1412 int index = DECL_MAX_LOCALS (current_function_decl);
1413 tree save_type = type_map[index];
1414 tree save_current_subr = current_subr;
1415 struct eh_range *ranges = find_handler (oldpc);
1416 stack_pointer = 1;
1417 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1419 tree chain = ranges->handlers;
1421 /* We need to determine if the handler is part of current_subr.
1422 The are two cases: (1) The exception catch range
1423 is entirely within current_subr. In that case the handler
1424 is also part of current_subr.
1425 (2) Some of the catch range is not in current_subr.
1426 In that case, the handler is *not* part of current_subr.
1428 Figuring out which is the case is not necessarily obvious,
1429 in the presence of clever code generators (and obfuscators).
1430 We make a simplifying assumption that in case (2) we
1431 have that the current_subr is entirely within the catch range.
1432 In that case we can assume if that if a caller (the jsr) of
1433 a subroutine is within the catch range, then the handler is
1434 *not* part of the subroutine, and vice versa. */
1436 current_subr = save_current_subr;
1437 for ( ; current_subr != NULL_TREE;
1438 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1440 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1441 /* There could be multiple return_labels, but
1442 we only need to check one. */
1443 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1444 if (return_pc <= ranges->start_pc
1445 || return_pc > ranges->end_pc)
1446 break;
1449 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1451 tree handler = TREE_VALUE (chain);
1452 tree type = TREE_PURPOSE (chain);
1453 if (type == NULL_TREE) /* a finally handler */
1454 type = throwable_type_node;
1455 type_map[index] = promote_type (type);
1457 PUSH_PENDING (handler);
1460 stack_pointer = save_stack_pointer;
1461 current_subr = save_current_subr;
1462 type_map[index] = save_type;
1463 prev_eh_ranges = eh_ranges;
1466 return 1;
1467 pop_type_error:
1468 error ("verification error at PC=%d", oldpc);
1469 if (message != NULL)
1470 error ("%s", message);
1471 error ("%s", pmessage);
1472 free (pmessage);
1473 return 0;
1474 stack_overflow:
1475 message = "stack overflow";
1476 goto verify_error;
1477 bad_pc:
1478 message = "program counter out of range";
1479 goto verify_error;
1480 error_with_index:
1481 error ("verification error at PC=%d", oldpc);
1482 error (message, index);
1483 return 0;
1484 verify_error:
1485 error ("verification error at PC=%d", oldpc);
1486 error ("%s", message);
1487 return 0;