FSF GCC merge 02/23/03
[official-gcc.git] / gcc / java / verify.c
bloba5375bf135701c5589edf63c3009dde932c7138e
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 (tree);
40 static tree merge_types (tree, tree);
41 static const char *check_pending_block (tree);
42 static void type_stack_dup (int, int);
43 static int start_pc_cmp (const void *, const void *);
44 static char *pop_argument_types (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 (tree target_label)
61 if (! LABEL_CHANGED (target_label))
63 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
64 pending_blocks = target_label;
65 LABEL_CHANGED (target_label) = 1;
69 /* Note that TARGET_LABEL is a possible successor instruction.
70 Merge the type state etc.
71 Return NULL on success, or an error message on failure. */
73 static const char *
74 check_pending_block (tree target_label)
76 int changed = merge_type_state (target_label);
78 if (changed)
80 if (changed < 0)
81 return "types could not be merged";
82 push_pending_label (target_label);
85 if (current_subr == NULL)
87 if (LABEL_IN_SUBR (target_label))
88 return "might transfer control into subroutine";
90 else
92 if (LABEL_IN_SUBR (target_label))
94 if (LABEL_SUBR_START (target_label) != current_subr)
95 return "transfer out of subroutine";
97 else if (! LABEL_VERIFIED (target_label))
99 LABEL_IN_SUBR (target_label) = 1;
100 LABEL_SUBR_START (target_label) = current_subr;
102 else
103 return "transfer out of subroutine";
105 return NULL;
108 /* Count the number of nested jsr calls needed to reach LABEL. */
110 static int
111 subroutine_nesting (tree label)
113 int nesting = 0;
114 while (label != NULL_TREE && LABEL_IN_SUBR (label))
116 if (! LABEL_IS_SUBR_START(label))
117 label = LABEL_SUBR_START (label);
118 label = LABEL_SUBR_CONTEXT (label);
119 nesting++;
121 return nesting;
124 /* Return the "merged" types of TYPE1 and TYPE2.
125 If either is primitive, the other must match (after promotion to int).
126 For reference types, return the common super-class.
127 Return TYPE_UNKNOWN if the types cannot be merged. */
129 static tree
130 merge_types (tree type1, tree type2)
132 if (type1 == type2)
133 return type1;
134 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
135 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
136 return TYPE_UNKNOWN;
137 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
139 int depth1, depth2;
140 tree tt1, tt2;
141 /* ptr_type_node is only used for a null reference,
142 which is compatible with any reference type. */
143 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
144 return type2;
145 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
146 return type1;
148 tt1 = TREE_TYPE (type1);
149 tt2 = TREE_TYPE (type2);
151 /* If tt{1,2} haven't been properly loaded, now is a good time
152 to do it. */
153 if (!TYPE_SIZE (tt1))
155 load_class (tt1, 1);
156 safe_layout_class (tt1);
159 if (!TYPE_SIZE (tt2))
161 load_class (tt2, 1);
162 safe_layout_class (tt2);
165 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
167 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
169 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
170 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
171 tree el_type = NULL_TREE;
172 if (el_type1 == el_type2)
173 el_type = el_type1;
174 else if (TREE_CODE (el_type1) == POINTER_TYPE
175 && TREE_CODE (el_type2) == POINTER_TYPE)
176 el_type = merge_types (el_type1, el_type2);
177 if (el_type != NULL_TREE)
179 HOST_WIDE_INT len1 = java_array_type_length (tt1);
180 HOST_WIDE_INT len2 = java_array_type_length (tt2);
181 if (len1 != len2)
182 len1 = -1;
183 else if (el_type1 == el_type2)
184 return type1;
185 return promote_type (build_java_array_type (el_type, len1));
188 return object_ptr_type_node;
191 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
193 /* FIXME: should see if two interfaces have a common
194 superinterface. */
195 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
197 /* This is a kludge, but matches what Sun's verifier does.
198 It can be tricked, but is safe as long as type errors
199 (i.e. interface method calls) are caught at run-time. */
200 return object_ptr_type_node;
202 else
204 if (can_widen_reference_to (tt2, tt1))
205 return type1;
206 else
207 return object_ptr_type_node;
210 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
212 if (can_widen_reference_to (tt1, tt2))
213 return type2;
214 else
215 return object_ptr_type_node;
218 type1 = tt1;
219 type2 = tt2;
221 depth1 = class_depth (type1);
222 depth2 = class_depth (type2);
223 for ( ; depth1 > depth2; depth1--)
224 type1 = TYPE_BINFO_BASETYPE (type1, 0);
225 for ( ; depth2 > depth1; depth2--)
226 type2 = TYPE_BINFO_BASETYPE (type2, 0);
227 while (type1 != type2)
229 type1 = TYPE_BINFO_BASETYPE (type1, 0);
230 type2 = TYPE_BINFO_BASETYPE (type2, 0);
232 return promote_type (type1);
234 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
235 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
236 return int_type_node;
237 return TYPE_UNKNOWN;
240 /* Merge the current type state with that at LABEL.
241 Return -1 the the states are incompatible (i.e. on error),
242 0 if there was no change, and 1 if there was a change. */
245 merge_type_state (tree label)
247 int nlocals = DECL_MAX_LOCALS (current_function_decl);
248 int cur_length = stack_pointer + nlocals;
249 tree vec = LABEL_TYPE_STATE (label);
250 tree return_map;
251 if (vec == NULL_TREE)
253 if (!vec)
255 vec = make_tree_vec (cur_length);
256 LABEL_TYPE_STATE (label) = vec;
258 while (--cur_length >= 0)
259 TREE_VEC_ELT (vec, cur_length) = type_map [cur_length];
260 return 1;
262 else
264 int i;
265 int changed = 0;
266 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
267 && current_subr != label)
268 return_map = LABEL_RETURN_TYPE_STATE (label);
269 else
270 return_map = NULL_TREE;
271 if (TREE_VEC_LENGTH (vec) != cur_length)
273 return -1;
275 for (i = 0; i < cur_length; i++)
277 tree old_type = TREE_VEC_ELT (vec, i);
278 tree new_type = merge_types (old_type, type_map [i]);
279 if (TREE_VEC_ELT (vec, i) != new_type)
281 /* If there has been a change, note that since we must re-verify.
282 However, if the label is the start of a subroutine,
283 we don't care about local variables that are neither
284 set nor used in the sub-routine. */
285 if (return_map == NULL_TREE || i >= nlocals
286 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
287 || (TYPE_IS_WIDE (new_type)
288 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
289 changed = 1;
291 TREE_VEC_ELT (vec, i) = new_type;
292 if (new_type == TYPE_UNKNOWN)
294 if (i >= nlocals)
295 return -1;
297 else if (TYPE_IS_WIDE (new_type))
298 i++;
300 return changed;
304 /* Handle dup-like operations. */
306 static void
307 type_stack_dup (int size, int offset)
309 tree type[4];
310 int index;
311 for (index = 0; index < size + offset; index++)
313 type[index] = stack_type_map[stack_pointer - 1];
314 if (type[index] == void_type_node)
316 index++;
317 type[index] = stack_type_map[stack_pointer - 2];
318 if (! TYPE_IS_WIDE (type[index]))
319 abort ();
320 if (index == size || index == size + offset)
321 /* Dup operation splits 64-bit number. */
322 abort ();
324 pop_type (type[index]);
326 for (index = size; --index >= 0; )
328 if (type[index] != void_type_node)
329 push_type (type[index]);
332 for (index = size + offset; --index >= 0; )
334 if (type[index] != void_type_node)
335 push_type (type[index]);
339 /* This keeps track of a start PC and corresponding initial index. */
340 struct pc_index
342 int start_pc;
343 int index;
346 /* A helper that is used when sorting exception ranges. */
347 static int
348 start_pc_cmp (const void *xp, const void *yp)
350 const struct pc_index *x = (const struct pc_index *) xp;
351 const struct pc_index *y = (const struct pc_index *) yp;
352 return x->start_pc - y->start_pc;
355 /* This causes the next iteration to ignore the next instruction
356 and look for some other unhandled instruction. */
357 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
358 #define INVALID_PC (-1)
360 #define VERIFICATION_ERROR(MESSAGE) \
361 do { message = MESSAGE; goto verify_error; } while (0)
363 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
364 do { message = MESSAGE; goto error_with_index; } while (0)
366 /* Recursive helper function to pop argument types during verification.
367 ARG_TYPES is the list of formal parameter types.
368 Return NULL on success and a freshly malloc'd error message on failure. */
370 static char *
371 pop_argument_types (tree arg_types)
373 if (arg_types == end_params_node)
374 return NULL;
375 if (TREE_CODE (arg_types) == TREE_LIST)
377 char *message = pop_argument_types (TREE_CHAIN (arg_types));
378 if (message == NULL)
379 pop_type_0 (TREE_VALUE (arg_types), &message);
380 return message;
382 abort ();
385 #define POP_TYPE(TYPE, MESSAGE) \
386 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
387 if (pmessage != NULL) goto pop_type_error; \
388 } while (0)
390 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
391 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
392 if (pmessage != NULL) goto pop_type_error; \
393 } while (0)
395 #define PUSH_TYPE(TYPE) \
396 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
398 #define PUSH_PENDING(LABEL) \
399 do { tree tmplab = LABEL; \
400 if ((message = check_pending_block (tmplab)) != NULL) \
401 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
403 #ifdef __GNUC__
404 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
405 #else
406 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
407 #endif
409 #define BCODE byte_ops
411 /* Verify the bytecodes of the current method.
412 Return 1 on success, 0 on failure. */
414 verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
416 tree label;
417 int wide = 0;
418 int op_code;
419 int PC;
420 int oldpc = 0; /* PC of start of instruction. */
421 int prevpc = 0; /* If >= 0, PC of previous instruction. */
422 const char *message = 0;
423 char *pmessage;
424 int i;
425 int index;
426 register unsigned char *p;
427 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
428 struct eh_range *eh_ranges;
429 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
430 struct pc_index *starts;
431 int eh_count;
433 jint int_value = -1;
435 pending_blocks = NULL_TREE;
437 /* Handle the exception table. */
438 method_init_exceptions ();
439 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
440 eh_count = JCF_readu2 (jcf);
442 /* We read the exception handlers in order of increasing start PC.
443 To do this we first read and sort the start PCs. */
444 starts = xmalloc (eh_count * sizeof (struct pc_index));
445 for (i = 0; i < eh_count; ++i)
447 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
448 starts[i].index = i;
450 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
452 for (i = 0; i < eh_count; ++i)
454 int start_pc, end_pc, handler_pc, catch_type;
456 p = jcf->read_ptr + 8 * starts[i].index;
458 start_pc = GET_u2 (p);
459 end_pc = GET_u2 (p+2);
460 handler_pc = GET_u2 (p+4);
461 catch_type = GET_u2 (p+6);
463 if (start_pc < 0 || start_pc >= length
464 || end_pc < 0 || end_pc > length || start_pc >= end_pc
465 || handler_pc < 0 || handler_pc >= length
466 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
467 || (end_pc < length &&
468 ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START))
469 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
471 error ("bad pc in exception_table");
472 free (starts);
473 return 0;
476 if (handler_pc >= start_pc && handler_pc < end_pc)
477 warning ("exception handler inside code that is being protected");
479 add_handler (start_pc, end_pc,
480 lookup_label (handler_pc),
481 catch_type == 0 ? NULL_TREE
482 : get_class_constant (jcf, catch_type));
484 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
487 free (starts);
488 handle_nested_ranges ();
490 for (PC = 0;;)
492 tree type, tmp;
493 if (((PC != INVALID_PC
494 && instruction_bits [PC] & BCODE_TARGET) != 0)
495 || PC == 0)
497 PUSH_PENDING (lookup_label (PC));
498 INVALIDATE_PC;
500 /* Check if there are any more pending blocks in the current
501 subroutine. Because we push pending blocks in a
502 last-in-first-out order, and because we don't push anything
503 from our caller until we are done with this subroutine or
504 anything nested in it, then we are done if the top of the
505 pending_blocks stack is not in a subroutine, or it is in our
506 caller. */
507 if (current_subr
508 && PC == INVALID_PC)
510 if (pending_blocks == NULL_TREE
511 || (subroutine_nesting (pending_blocks)
512 < subroutine_nesting (current_subr)))
514 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
515 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
516 tmp = LABEL_RETURN_LABELS (current_subr);
518 /* FIXME: If we exit a subroutine via a throw, we might
519 have returned to an earlier caller. Obviously a
520 "ret" can only return one level, but a throw may
521 return many levels.*/
522 current_subr = LABEL_SUBR_CONTEXT (current_subr);
524 if (RETURN_MAP_ADJUSTED (ret_map))
526 /* Since we are done with this subroutine , set up
527 the (so far known) return address as pending -
528 with the merged type state. */
529 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
531 tree return_label = TREE_VALUE (tmp);
532 tree return_state = LABEL_TYPE_STATE (return_label);
533 if (return_state == NULL_TREE)
535 /* This means means we had not verified the
536 subroutine earlier, so this is the first jsr to
537 call it. In this case, the type_map of the return
538 address is just the current type_map - and that
539 is handled by the following PUSH_PENDING. */
541 else
543 /* In this case we have to do a merge. But first
544 restore the type_map for unused slots to those
545 that were in effect at the jsr. */
546 for (index = size; --index >= 0; )
548 type_map[index] = TREE_VEC_ELT (ret_map, index);
549 if (type_map[index] == TYPE_UNUSED)
550 type_map[index]
551 = TREE_VEC_ELT (return_state, index);
554 PUSH_PENDING (return_label);
559 if (PC == INVALID_PC)
561 label = pending_blocks;
562 if (label == NULL_TREE)
563 break; /* We're done! */
564 pending_blocks = LABEL_PENDING_CHAIN (label);
565 LABEL_CHANGED (label) = 0;
567 if (LABEL_IN_SUBR (label))
568 current_subr = LABEL_SUBR_START (label);
569 else
570 current_subr = NULL_TREE;
572 /* Restore type_map and stack_pointer from
573 LABEL_TYPE_STATE (label), and continue
574 compiling from there. */
575 load_type_state (label);
576 PC = LABEL_PC (label);
578 else if (PC >= length)
579 VERIFICATION_ERROR ("falling through end of method");
581 /* fprintf (stderr, "** %d\n", PC); */
583 oldpc = PC;
585 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
586 VERIFICATION_ERROR ("PC not at instruction start");
588 instruction_bits[PC] |= BCODE_VERIFIED;
590 eh_ranges = find_handler (oldpc);
592 op_code = byte_ops[PC++];
593 switch (op_code)
595 int is_static, is_putting;
596 case OPCODE_nop:
597 break;
598 case OPCODE_iconst_m1:
599 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
600 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
601 i = op_code - OPCODE_iconst_0;
602 goto push_int;
603 push_int:
604 if (byte_ops[PC] == OPCODE_newarray
605 || byte_ops[PC] == OPCODE_anewarray)
606 int_value = i;
607 PUSH_TYPE (int_type_node); break;
608 case OPCODE_lconst_0: case OPCODE_lconst_1:
609 PUSH_TYPE (long_type_node); break;
610 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
611 PUSH_TYPE (float_type_node); break;
612 case OPCODE_dconst_0: case OPCODE_dconst_1:
613 PUSH_TYPE (double_type_node); break;
614 case OPCODE_bipush:
615 i = IMMEDIATE_s1;
616 goto push_int;
617 case OPCODE_sipush:
618 i = IMMEDIATE_s2;
619 goto push_int;
620 case OPCODE_iload: type = int_type_node; goto general_load;
621 case OPCODE_lload: type = long_type_node; goto general_load;
622 case OPCODE_fload: type = float_type_node; goto general_load;
623 case OPCODE_dload: type = double_type_node; goto general_load;
624 case OPCODE_aload: type = ptr_type_node; goto general_load;
625 general_load:
626 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
627 wide = 0;
628 goto load;
629 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
630 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
631 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
632 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
633 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
634 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
635 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
636 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
637 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
638 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
639 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
640 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
641 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
642 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
643 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
644 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
645 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
646 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
647 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
648 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
649 load:
650 if (index < 0
651 || (index + TYPE_IS_WIDE (type)
652 >= DECL_MAX_LOCALS (current_function_decl)))
653 VERIFICATION_ERROR_WITH_INDEX
654 ("invalid local variable index %d in load");
655 tmp = type_map[index];
656 if (tmp == TYPE_UNKNOWN)
657 VERIFICATION_ERROR_WITH_INDEX
658 ("loading local variable %d which has unknown type");
659 else if (tmp == TYPE_SECOND
660 || (TYPE_IS_WIDE (type)
661 && type_map[index+1] != void_type_node)
662 || (type == ptr_type_node
663 ? TREE_CODE (tmp) != POINTER_TYPE
664 : type == int_type_node
665 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
666 : type != tmp))
667 VERIFICATION_ERROR_WITH_INDEX
668 ("loading local variable %d which has invalid type");
669 PUSH_TYPE (tmp);
670 goto note_used;
671 case OPCODE_istore: type = int_type_node; goto general_store;
672 case OPCODE_lstore: type = long_type_node; goto general_store;
673 case OPCODE_fstore: type = float_type_node; goto general_store;
674 case OPCODE_dstore: type = double_type_node; goto general_store;
675 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
676 general_store:
677 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
678 wide = 0;
679 goto store;
680 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
681 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
682 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
683 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
684 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
685 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
686 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
687 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
688 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
689 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
690 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
691 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
692 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
693 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
694 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
695 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
696 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
697 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
698 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
699 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
700 store:
701 if (index < 0
702 || (index + TYPE_IS_WIDE (type)
703 >= DECL_MAX_LOCALS (current_function_decl)))
705 VERIFICATION_ERROR_WITH_INDEX
706 ("invalid local variable index %d in store");
707 return 0;
709 POP_TYPE_CONV (type, type, NULL);
710 type_map[index] = type;
712 /* If local variable changed, we need to reconsider eh handlers. */
713 prev_eh_ranges = NULL_EH_RANGE;
715 /* Allocate decl and rtx for this variable now, so if we're not
716 optimizing, we get a temporary that survives the whole method. */
717 find_local_variable (index, type, oldpc);
719 if (TYPE_IS_WIDE (type))
720 type_map[index+1] = TYPE_SECOND;
721 /* ... fall through to note_used ... */
722 note_used:
723 /* For store or load, note that local variable INDEX is used.
724 This is needed to verify try-finally sub-routines. */
725 if (current_subr)
727 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
728 tree subr_vec = LABEL_TYPE_STATE (current_subr);
729 int len = 1 + TYPE_IS_WIDE (type);
730 while (--len >= 0)
732 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
733 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
736 break;
737 case OPCODE_iadd:
738 case OPCODE_iand:
739 case OPCODE_idiv:
740 case OPCODE_imul:
741 case OPCODE_ior:
742 case OPCODE_irem:
743 case OPCODE_ishl:
744 case OPCODE_ishr:
745 case OPCODE_isub:
746 case OPCODE_iushr:
747 case OPCODE_ixor:
748 type = int_type_node; goto binop;
749 case OPCODE_ineg:
750 case OPCODE_i2c:
751 case OPCODE_i2b:
752 case OPCODE_i2s:
753 type = int_type_node; goto unop;
754 case OPCODE_ladd:
755 case OPCODE_land:
756 case OPCODE_ldiv:
757 case OPCODE_lsub:
758 case OPCODE_lmul:
759 case OPCODE_lrem:
760 case OPCODE_lor:
761 case OPCODE_lxor:
762 type = long_type_node; goto binop;
763 case OPCODE_lneg:
764 type = long_type_node; goto unop;
765 case OPCODE_fadd: case OPCODE_fsub:
766 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
767 type = float_type_node; goto binop;
768 case OPCODE_fneg:
769 type = float_type_node; goto unop;
770 case OPCODE_dadd: case OPCODE_dsub:
771 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
772 type = double_type_node; goto binop;
773 case OPCODE_dneg:
774 type = double_type_node; goto unop;
775 unop:
776 pop_type (type);
777 PUSH_TYPE (type);
778 break;
779 binop:
780 pop_type (type);
781 pop_type (type);
782 PUSH_TYPE (type);
783 break;
784 case OPCODE_lshl:
785 case OPCODE_lshr:
786 case OPCODE_lushr:
787 pop_type (int_type_node);
788 pop_type (long_type_node);
789 PUSH_TYPE (long_type_node);
790 break;
791 case OPCODE_iinc:
792 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
793 PC += wide + 1;
794 wide = 0;
795 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
796 VERIFICATION_ERROR ("invalid local variable index in iinc");
797 tmp = type_map[index];
798 if (tmp == NULL_TREE
799 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
800 VERIFICATION_ERROR ("invalid local variable type in iinc");
801 break;
802 case OPCODE_i2l:
803 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
804 case OPCODE_i2f:
805 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
806 case OPCODE_i2d:
807 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
808 case OPCODE_l2i:
809 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
810 case OPCODE_l2f:
811 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
812 case OPCODE_l2d:
813 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
814 case OPCODE_f2i:
815 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
816 case OPCODE_f2l:
817 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
818 case OPCODE_f2d:
819 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
820 case OPCODE_d2i:
821 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
822 case OPCODE_d2l:
823 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
824 case OPCODE_d2f:
825 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
826 case OPCODE_lcmp:
827 type = long_type_node; goto compare;
828 case OPCODE_fcmpl:
829 case OPCODE_fcmpg:
830 type = float_type_node; goto compare;
831 case OPCODE_dcmpl:
832 case OPCODE_dcmpg:
833 type = double_type_node; goto compare;
834 compare:
835 pop_type (type); pop_type (type);
836 PUSH_TYPE (int_type_node); break;
837 case OPCODE_ifeq:
838 case OPCODE_ifne:
839 case OPCODE_iflt:
840 case OPCODE_ifge:
841 case OPCODE_ifgt:
842 case OPCODE_ifle:
843 pop_type (int_type_node); goto cond;
844 case OPCODE_ifnull:
845 case OPCODE_ifnonnull:
846 pop_type (ptr_type_node ); goto cond;
847 case OPCODE_if_icmpeq:
848 case OPCODE_if_icmpne:
849 case OPCODE_if_icmplt:
850 case OPCODE_if_icmpge:
851 case OPCODE_if_icmpgt:
852 case OPCODE_if_icmple:
853 pop_type (int_type_node); pop_type (int_type_node); goto cond;
854 case OPCODE_if_acmpeq:
855 case OPCODE_if_acmpne:
856 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
857 goto cond;
858 cond:
859 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
860 break;
861 case OPCODE_goto:
862 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
863 INVALIDATE_PC;
864 break;
865 case OPCODE_wide:
866 switch (byte_ops[PC])
868 case OPCODE_iload: case OPCODE_lload:
869 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
870 case OPCODE_istore: case OPCODE_lstore:
871 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
872 case OPCODE_iinc:
873 case OPCODE_ret:
874 wide = 1;
875 break;
876 default:
877 VERIFICATION_ERROR ("invalid use of wide instruction");
879 break;
880 case OPCODE_return: type = void_type_node; goto ret;
881 case OPCODE_ireturn:
882 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
883 || TREE_CODE (return_type) == CHAR_TYPE
884 || TREE_CODE (return_type) == INTEGER_TYPE)
885 && TYPE_PRECISION (return_type) <= 32)
886 type = return_type;
887 else
888 type = NULL_TREE;
889 goto ret;
890 case OPCODE_lreturn: type = long_type_node; goto ret;
891 case OPCODE_freturn: type = float_type_node; goto ret;
892 case OPCODE_dreturn: type = double_type_node; goto ret;
893 case OPCODE_areturn:
894 if (TREE_CODE (return_type) == POINTER_TYPE)
895 type = return_type;
896 else
897 type = NULL_TREE;
898 goto ret;
899 ret:
900 if (type != return_type)
901 VERIFICATION_ERROR ("incorrect ?return opcode");
902 if (type != void_type_node)
903 POP_TYPE(type, "return value has wrong type");
904 INVALIDATE_PC;
905 break;
906 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
907 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
908 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
909 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
910 field:
912 tree field_signature, field_type;
913 index = IMMEDIATE_u2;
914 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
915 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
916 if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref)
917 VERIFICATION_ERROR
918 ("field instruction does not reference a Fieldref");
919 field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
920 field_type = get_type_from_signature (field_signature);
921 if (is_putting)
922 POP_TYPE (field_type, "incorrect type for field");
923 if (! is_static)
925 int clindex = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
926 index);
927 tree self_type = get_class_constant (current_jcf, clindex);
928 /* Defer actual checking until next pass. */
929 POP_TYPE(self_type, "incorrect type for field reference");
931 if (! is_putting)
932 PUSH_TYPE (field_type);
933 break;
935 case OPCODE_new:
936 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
937 break;
938 case OPCODE_dup: wide = 1; index = 0; goto dup;
939 case OPCODE_dup_x1: wide = 1; index = 1; goto dup;
940 case OPCODE_dup_x2: wide = 1; index = 2; goto dup;
941 case OPCODE_dup2: wide = 2; index = 0; goto dup;
942 case OPCODE_dup2_x1: wide = 2; index = 1; goto dup;
943 case OPCODE_dup2_x2: wide = 2; index = 2; goto dup;
944 dup:
945 if (wide + index > stack_pointer)
946 VERIFICATION_ERROR ("stack underflow - dup* operation");
947 type_stack_dup (wide, index);
948 wide = 0;
949 break;
950 case OPCODE_pop: index = 1; goto pop;
951 case OPCODE_pop2: index = 2; goto pop;
952 pop:
953 if (stack_pointer < index)
954 VERIFICATION_ERROR ("stack underflow");
955 stack_pointer -= index;
956 break;
957 case OPCODE_swap:
958 if (stack_pointer < 2)
959 VERIFICATION_ERROR ("stack underflow (in swap)");
960 else
962 tree type1 = stack_type_map[stack_pointer - 1];
963 tree type2 = stack_type_map[stack_pointer - 2];
964 if (type1 == void_type_node || type2 == void_type_node)
965 VERIFICATION_ERROR ("verifier (swap): double or long value");
966 stack_type_map[stack_pointer - 2] = type1;
967 stack_type_map[stack_pointer - 1] = type2;
969 break;
970 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
971 case OPCODE_ldc2_w:
972 case OPCODE_ldc_w:
973 index = IMMEDIATE_u2; goto ldc;
974 ldc:
975 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
976 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
977 int_value = -1;
978 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
980 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
981 case CONSTANT_Float: type = float_type_node; goto check_ldc;
982 case CONSTANT_String: type = string_type_node; goto check_ldc;
983 case CONSTANT_Long: type = long_type_node; goto check_ldc;
984 case CONSTANT_Double: type = double_type_node; goto check_ldc;
985 check_ldc:
986 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
987 break;
988 /* ... else fall through ... */
989 default:
990 VERIFICATION_ERROR ("bad constant pool tag in ldc");
992 if (type == int_type_node)
994 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
995 goto push_int;
997 PUSH_TYPE (type);
998 break;
1000 case OPCODE_invokevirtual:
1001 case OPCODE_invokespecial:
1002 case OPCODE_invokestatic:
1003 case OPCODE_invokeinterface:
1005 tree sig, method_name, method_type, self_type;
1006 int self_is_interface, tag;
1007 index = IMMEDIATE_u2;
1008 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
1009 VERIFICATION_ERROR_WITH_INDEX
1010 ("bad constant pool index %d for invoke");
1011 tag = JPOOL_TAG (current_jcf, index);
1012 if (op_code == OPCODE_invokeinterface)
1014 if (tag != CONSTANT_InterfaceMethodref)
1015 VERIFICATION_ERROR
1016 ("invokeinterface does not reference an InterfaceMethodref");
1018 else
1020 if (tag != CONSTANT_Methodref)
1021 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1023 sig = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
1024 self_type = get_class_constant
1025 (current_jcf, COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
1026 index));
1027 if (! CLASS_LOADED_P (self_type))
1028 load_class (self_type, 1);
1029 self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
1030 method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
1031 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
1032 IDENTIFIER_LENGTH (sig));
1033 if (TREE_CODE (method_type) != FUNCTION_TYPE)
1034 VERIFICATION_ERROR ("bad method signature");
1035 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
1036 if (pmessage != NULL)
1038 message = "invalid argument type";
1039 goto pop_type_error;
1042 /* Can't invoke <clinit> */
1043 if (ID_CLINIT_P (method_name))
1044 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1045 /* Apart invokespecial, can't invoke <init> */
1046 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
1047 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1049 if (op_code != OPCODE_invokestatic)
1050 POP_TYPE (self_type,
1051 "stack type not subclass of invoked method's class");
1053 switch (op_code)
1055 case OPCODE_invokeinterface:
1057 int nargs = IMMEDIATE_u1;
1058 int notZero = IMMEDIATE_u1;
1060 if (!nargs || notZero)
1061 VERIFICATION_ERROR
1062 ("invalid argument number in invokeinterface");
1063 /* If we verify/resolve the constant pool, as we should,
1064 this test (and the one just following) are redundant. */
1065 if (! self_is_interface)
1066 VERIFICATION_ERROR ("invokeinterface calls method not in interface");
1067 break;
1068 default:
1069 if (self_is_interface)
1070 VERIFICATION_ERROR ("method in interface called");
1074 if (TREE_TYPE (method_type) != void_type_node)
1075 PUSH_TYPE (TREE_TYPE (method_type));
1076 break;
1079 case OPCODE_arraylength:
1080 /* Type checking actually made during code generation */
1081 pop_type( ptr_type_node );
1082 PUSH_TYPE( int_type_node );
1083 break;
1085 /* Q&D verification *or* more checking done during code generation
1086 for byte/boolean/char/short, the value popped is a int coerced
1087 into the right type before being stored. */
1088 case OPCODE_iastore: type = int_type_node; goto astore;
1089 case OPCODE_lastore: type = long_type_node; goto astore;
1090 case OPCODE_fastore: type = float_type_node; goto astore;
1091 case OPCODE_dastore: type = double_type_node; goto astore;
1092 case OPCODE_aastore: type = ptr_type_node; goto astore;
1093 case OPCODE_bastore: type = int_type_node; goto astore;
1094 case OPCODE_castore: type = int_type_node; goto astore;
1095 case OPCODE_sastore: type = int_type_node; goto astore;
1096 astore:
1097 /* FIXME - need better verification here */
1098 pop_type (type); /* new value */
1099 pop_type (int_type_node); /* index */
1100 pop_type (ptr_type_node); /* array */
1101 break;
1103 /* Q&D verification *or* more checking done during code generation
1104 for byte/boolean/char/short, the value pushed is a int. */
1105 case OPCODE_iaload: type = int_type_node; goto aload;
1106 case OPCODE_laload: type = long_type_node; goto aload;
1107 case OPCODE_faload: type = float_type_node; goto aload;
1108 case OPCODE_daload: type = double_type_node; goto aload;
1109 case OPCODE_aaload: type = ptr_type_node; goto aload;
1110 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1111 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1112 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1113 aload:
1114 pop_type (int_type_node);
1115 tmp = pop_type (ptr_type_node);
1116 if (is_array_type_p (tmp))
1117 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1118 else if (tmp != TYPE_NULL)
1119 VERIFICATION_ERROR ("array load from non-array type");
1120 PUSH_TYPE (type);
1121 break;
1123 case OPCODE_anewarray:
1124 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1125 type = promote_type (type);
1126 goto newarray;
1128 case OPCODE_newarray:
1129 index = IMMEDIATE_u1;
1130 type = decode_newarray_type (index);
1131 if (type == NULL_TREE)
1132 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1133 goto newarray;
1135 newarray:
1136 if (int_value >= 0 && prevpc >= 0)
1138 /* If previous instruction pushed int constant,
1139 we want to use it. */
1140 switch (byte_ops[prevpc])
1142 case OPCODE_iconst_0: case OPCODE_iconst_1:
1143 case OPCODE_iconst_2: case OPCODE_iconst_3:
1144 case OPCODE_iconst_4: case OPCODE_iconst_5:
1145 case OPCODE_bipush: case OPCODE_sipush:
1146 case OPCODE_ldc: case OPCODE_ldc_w:
1147 break;
1148 default:
1149 int_value = -1;
1152 else
1153 int_value = -1;
1154 type = build_java_array_type (type, int_value);
1155 pop_type (int_type_node);
1156 PUSH_TYPE (type);
1157 break;
1159 case OPCODE_multianewarray:
1161 int ndim, i;
1162 index = IMMEDIATE_u2;
1163 ndim = IMMEDIATE_u1;
1165 if( ndim < 1 )
1166 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
1168 for( i = 0; i < ndim; i++ )
1169 pop_type (int_type_node);
1170 PUSH_TYPE (get_class_constant (current_jcf, index));
1171 break;
1174 case OPCODE_aconst_null:
1175 PUSH_TYPE (ptr_type_node);
1176 break;
1178 case OPCODE_athrow:
1179 /* FIXME: athrow also empties the stack. */
1180 POP_TYPE (throwable_type_node, "missing throwable at athrow" );
1181 INVALIDATE_PC;
1182 break;
1184 case OPCODE_checkcast:
1185 POP_TYPE (object_ptr_type_node,
1186 "checkcast operand is not a pointer");
1187 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1188 PUSH_TYPE (type);
1189 break;
1190 case OPCODE_instanceof:
1191 POP_TYPE (object_ptr_type_node,
1192 "instanceof operand is not a pointer");
1193 get_class_constant (current_jcf, IMMEDIATE_u2);
1194 PUSH_TYPE (int_type_node);
1195 break;
1197 case OPCODE_tableswitch:
1199 jint low, high;
1201 POP_TYPE (int_type_node, "missing int for tableswitch");
1202 while (PC%4)
1204 if (byte_ops[PC++])
1205 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1207 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1208 low = IMMEDIATE_s4;
1209 high = IMMEDIATE_s4;
1211 if (low > high)
1212 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1214 while (low++ <= high)
1215 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1216 INVALIDATE_PC;
1217 break;
1220 case OPCODE_lookupswitch:
1222 jint npairs, last = 0, not_registered = 1;
1224 POP_TYPE (int_type_node, "missing int for lookupswitch");
1225 while (PC%4)
1227 if (byte_ops[PC++])
1228 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1231 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1232 npairs = IMMEDIATE_s4;
1234 if (npairs < 0)
1235 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1237 while (npairs--)
1239 int match = IMMEDIATE_s4;
1240 if (not_registered)
1241 not_registered = 0;
1242 else if (last >= match)
1243 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1245 last = match;
1246 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1248 INVALIDATE_PC;
1249 break;
1252 case OPCODE_monitorenter:
1253 /* fall thru */
1254 case OPCODE_monitorexit:
1255 pop_type (ptr_type_node);
1256 break;
1258 case OPCODE_goto_w:
1259 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1260 INVALIDATE_PC;
1261 break;
1263 case OPCODE_jsr:
1265 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1266 tree return_label = lookup_label (PC);
1267 PUSH_TYPE (return_address_type_node);
1268 /* The return label chain will be null if this is the first
1269 time we've seen this jsr target. */
1270 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1272 tree return_type_map;
1273 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1274 index = nlocals + DECL_MAX_STACK (current_function_decl);
1275 return_type_map = make_tree_vec (index);
1276 while (index > nlocals)
1277 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1278 while (index > 0)
1279 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1280 LABEL_RETURN_LABEL (target)
1281 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1282 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
1283 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1284 LABEL_IS_SUBR_START (target) = 1;
1285 LABEL_IN_SUBR (target) = 1;
1286 LABEL_SUBR_START (target) = target;
1287 LABEL_SUBR_CONTEXT (target) = current_subr;
1289 else if (! LABEL_IS_SUBR_START (target)
1290 || LABEL_SUBR_CONTEXT (target) != current_subr)
1291 VERIFICATION_ERROR ("label part of different subroutines");
1293 i = merge_type_state (target);
1294 if (i != 0)
1296 if (i < 0)
1297 VERIFICATION_ERROR ("types could not be merged at jsr");
1298 push_pending_label (target);
1300 current_subr = target;
1302 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1303 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1305 LABEL_RETURN_LABELS (target)
1306 = tree_cons (NULL_TREE, return_label,
1307 LABEL_RETURN_LABELS (target));
1310 if (LABEL_VERIFIED (target))
1312 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1313 int len = TREE_VEC_LENGTH (return_map);
1314 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1315 while (--len >= 0)
1317 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1318 type_map[len] = TREE_VEC_ELT (return_map, len);
1320 current_subr = LABEL_SUBR_CONTEXT (target);
1321 if (RETURN_MAP_ADJUSTED (return_map))
1322 PUSH_PENDING (return_label);
1325 INVALIDATE_PC;
1327 break;
1328 case OPCODE_ret:
1329 if (current_subr == NULL)
1330 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1331 else
1333 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1334 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
1335 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1336 wide = 0;
1337 INVALIDATE_PC;
1338 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1339 || type_map[index] != TYPE_RETURN_ADDR)
1340 VERIFICATION_ERROR ("invalid ret index");
1342 /* The next chunk of code is similar to an inlined version of
1343 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1344 * The main differences are that LABEL_RETURN_LABEL is
1345 * pre-allocated by the jsr (but we don't know the size then);
1346 * and that we have to handle TYPE_UNUSED. */
1348 if (! RETURN_MAP_ADJUSTED (ret_map))
1349 { /* First return from this subroutine - fix stack pointer. */
1350 TREE_VEC_LENGTH (ret_map) = size;
1351 for (index = size; --index >= 0; )
1353 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1354 TREE_VEC_ELT (ret_map, index) = type_map[index];
1356 RETURN_MAP_ADJUSTED (ret_map) = 1;
1358 else
1360 if (TREE_VEC_LENGTH (ret_map) != size)
1361 VERIFICATION_ERROR ("inconsistent stack size on ret");
1362 for (index = 0; index < size; index++)
1364 tree type = TREE_VEC_ELT (ret_map, index);
1365 if (type != TYPE_UNUSED)
1367 type = merge_types (type, type_map [index]);
1368 TREE_VEC_ELT (ret_map, index) = type;
1369 if (type == TYPE_UNKNOWN)
1371 if (index >= size - stack_pointer)
1372 VERIFICATION_ERROR
1373 ("inconsistent types on ret from jsr");
1375 else if (TYPE_IS_WIDE (type))
1376 index++;
1383 break;
1384 case OPCODE_jsr_w:
1385 case OPCODE_ret_w:
1386 default:
1387 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1388 return 0;
1391 prevpc = oldpc;
1393 /* The following test is true if we have entered or exited an exception
1394 handler range *or* we have done a store to a local variable.
1395 In either case we need to consider any exception handlers that
1396 might "follow" this instruction. */
1398 if (eh_ranges != prev_eh_ranges)
1400 int save_stack_pointer = stack_pointer;
1401 int index = DECL_MAX_LOCALS (current_function_decl);
1402 tree save_type = type_map[index];
1403 tree save_current_subr = current_subr;
1404 struct eh_range *ranges = find_handler (oldpc);
1405 stack_pointer = 1;
1406 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1408 tree chain = ranges->handlers;
1410 /* We need to determine if the handler is part of current_subr.
1411 The are two cases: (1) The exception catch range
1412 is entirely within current_subr. In that case the handler
1413 is also part of current_subr.
1414 (2) Some of the catch range is not in current_subr.
1415 In that case, the handler is *not* part of current_subr.
1417 Figuring out which is the case is not necessarily obvious,
1418 in the presence of clever code generators (and obfuscators).
1419 We make a simplifying assumption that in case (2) we
1420 have that the current_subr is entirely within the catch range.
1421 In that case we can assume if that if a caller (the jsr) of
1422 a subroutine is within the catch range, then the handler is
1423 *not* part of the subroutine, and vice versa. */
1425 current_subr = save_current_subr;
1426 for ( ; current_subr != NULL_TREE;
1427 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1429 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1430 /* There could be multiple return_labels, but
1431 we only need to check one. */
1432 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1433 if (return_pc <= ranges->start_pc
1434 || return_pc > ranges->end_pc)
1435 break;
1438 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1440 tree handler = TREE_VALUE (chain);
1441 tree type = TREE_PURPOSE (chain);
1442 if (type == NULL_TREE) /* a finally handler */
1443 type = throwable_type_node;
1444 type_map[index] = promote_type (type);
1446 PUSH_PENDING (handler);
1449 stack_pointer = save_stack_pointer;
1450 current_subr = save_current_subr;
1451 type_map[index] = save_type;
1452 prev_eh_ranges = eh_ranges;
1455 return 1;
1456 pop_type_error:
1457 error ("verification error at PC=%d", oldpc);
1458 if (message != NULL)
1459 error ("%s", message);
1460 error ("%s", pmessage);
1461 free (pmessage);
1462 return 0;
1463 stack_overflow:
1464 message = "stack overflow";
1465 goto verify_error;
1466 bad_pc:
1467 message = "program counter out of range";
1468 goto verify_error;
1469 error_with_index:
1470 error ("verification error at PC=%d", oldpc);
1471 error (message, index);
1472 return 0;
1473 verify_error:
1474 error ("verification error at PC=%d", oldpc);
1475 error ("%s", message);
1476 return 0;