Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / java / verify.c
blobf81936d7b6e4baf2c58e0878e2a48cdfc55894be
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, 2004, 2005
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 /* This bytecode verifier is an implementation of the bytecode
28 verification process described in section 4.9 of "The Java(TM) Virtual
29 Machine Specification", Second Edition, by Tim Lindholm and Frank Yellin,
30 published by Addison-Wesley in 1999. */
32 #include "config.h"
33 #include "system.h"
34 #include "coretypes.h"
35 #include "tm.h"
36 #include "tree.h"
37 #include "java-tree.h"
38 #include "javaop.h"
39 #include "java-opcodes.h"
40 #include "jcf.h"
41 #include "java-except.h"
42 #include "toplev.h"
44 static void push_pending_label (tree);
45 static tree merge_types (tree, tree);
46 static const char *check_pending_block (tree);
47 static void type_stack_dup (int, int);
48 static int start_pc_cmp (const void *, const void *);
49 static char *pop_argument_types (tree);
51 extern int stack_pointer;
53 /* During verification, start of the current subroutine (jsr target). */
54 tree current_subr;
56 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
57 A pending block is one that has LABEL_CHANGED set, which means
58 it requires (re-) verification. */
59 tree pending_blocks;
61 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
63 static void
64 push_pending_label (tree target_label)
66 if (! LABEL_CHANGED (target_label))
68 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
69 pending_blocks = target_label;
70 LABEL_CHANGED (target_label) = 1;
74 /* Note that TARGET_LABEL is a possible successor instruction.
75 Merge the type state etc.
76 Return NULL on success, or an error message on failure. */
78 static const char *
79 check_pending_block (tree target_label)
81 int changed = merge_type_state (target_label);
83 if (changed)
85 if (changed < 0)
86 return "types could not be merged";
87 push_pending_label (target_label);
90 if (current_subr == NULL_TREE)
92 if (LABEL_IN_SUBR (target_label))
93 return "might transfer control into subroutine";
95 else
97 if (LABEL_IN_SUBR (target_label))
99 if (LABEL_SUBR_START (target_label) != current_subr)
100 return "transfer out of subroutine";
102 else if (! LABEL_VERIFIED (target_label))
104 LABEL_IN_SUBR (target_label) = 1;
105 LABEL_SUBR_START (target_label) = current_subr;
107 else
108 return "transfer out of subroutine";
110 return NULL;
113 /* Count the number of nested jsr calls needed to reach LABEL. */
115 static int
116 subroutine_nesting (tree label)
118 int nesting = 0;
119 while (label != NULL_TREE && LABEL_IN_SUBR (label))
121 if (! LABEL_IS_SUBR_START (label))
122 label = LABEL_SUBR_START (label);
123 label = LABEL_SUBR_CONTEXT (label);
124 nesting++;
126 return nesting;
129 /* Return the "merged" types of TYPE1 and TYPE2.
130 If either is primitive, the other must match (after promotion to int).
131 For reference types, return the common super-class.
132 Return TYPE_UNKNOWN if the types cannot be merged. */
134 static tree
135 merge_types (tree type1, tree type2)
137 if (type1 == type2)
138 return type1;
139 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
140 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
141 return TYPE_UNKNOWN;
142 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
144 int depth1, depth2;
145 tree tt1, tt2;
146 /* ptr_type_node is only used for a null reference,
147 which is compatible with any reference type. */
148 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
149 return type2;
150 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
151 return type1;
153 tt1 = TREE_TYPE (type1);
154 tt2 = TREE_TYPE (type2);
156 /* If tt{1,2} haven't been properly loaded, now is a good time
157 to do it. */
158 if (!TYPE_SIZE (tt1))
160 load_class (tt1, 1);
161 safe_layout_class (tt1);
164 if (!TYPE_SIZE (tt2))
166 load_class (tt2, 1);
167 safe_layout_class (tt2);
170 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
172 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
174 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
175 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
176 tree el_type = NULL_TREE;
177 if (el_type1 == el_type2)
178 el_type = el_type1;
179 else if (TREE_CODE (el_type1) == POINTER_TYPE
180 && TREE_CODE (el_type2) == POINTER_TYPE)
181 el_type = merge_types (el_type1, el_type2);
182 if (el_type != NULL_TREE)
184 HOST_WIDE_INT len1 = java_array_type_length (tt1);
185 HOST_WIDE_INT len2 = java_array_type_length (tt2);
186 if (len1 != len2)
187 len1 = -1;
188 else if (el_type1 == el_type2)
189 return type1;
190 return promote_type (build_java_array_type (el_type, len1));
193 return object_ptr_type_node;
196 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
198 /* FIXME: should see if two interfaces have a common
199 superinterface. */
200 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
202 /* This is a kludge, but matches what Sun's verifier does.
203 It can be tricked, but is safe as long as type errors
204 (i.e. interface method calls) are caught at run-time. */
205 return object_ptr_type_node;
207 else
209 if (can_widen_reference_to (tt2, tt1))
210 return type1;
211 else
212 return object_ptr_type_node;
215 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
217 if (can_widen_reference_to (tt1, tt2))
218 return type2;
219 else
220 return object_ptr_type_node;
223 type1 = tt1;
224 type2 = tt2;
226 depth1 = class_depth (type1);
227 depth2 = class_depth (type2);
228 for ( ; depth1 > depth2; depth1--)
229 type1 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type1), 0));
230 for ( ; depth2 > depth1; depth2--)
231 type2 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type2), 0));
232 while (type1 != type2)
234 type1 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type1), 0));
235 type2 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type2), 0));
237 return promote_type (type1);
239 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
240 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
241 return int_type_node;
242 return TYPE_UNKNOWN;
245 /* Merge the current type state with that at LABEL.
246 Return -1 if the states are incompatible (i.e. on error),
247 0 if there was no change, and 1 if there was a change. */
250 merge_type_state (tree label)
252 int nlocals = DECL_MAX_LOCALS (current_function_decl);
253 int cur_length = stack_pointer + nlocals;
254 tree vec = LABEL_TYPE_STATE (label);
255 tree return_map;
256 if (vec == NULL_TREE)
258 vec = make_tree_vec (cur_length);
259 LABEL_TYPE_STATE (label) = vec;
261 while (--cur_length >= 0)
262 TREE_VEC_ELT (vec, cur_length) = type_map[cur_length];
263 return 1;
265 else
267 int i;
268 int changed = 0;
269 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
270 && current_subr != label)
271 return_map = LABEL_RETURN_TYPE_STATE (label);
272 else
273 return_map = NULL_TREE;
274 if (TREE_VEC_LENGTH (vec) != cur_length)
276 return -1;
278 for (i = 0; i < cur_length; i++)
280 tree old_type = TREE_VEC_ELT (vec, i);
281 tree new_type = merge_types (old_type, type_map[i]);
282 if (TREE_VEC_ELT (vec, i) != new_type)
284 /* If there has been a change, note that since we must re-verify.
285 However, if the label is the start of a subroutine,
286 we don't care about local variables that are neither
287 set nor used in the subroutine. */
288 if (return_map == NULL_TREE || i >= nlocals
289 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
290 || (TYPE_IS_WIDE (new_type)
291 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
292 changed = 1;
294 TREE_VEC_ELT (vec, i) = new_type;
295 if (new_type == TYPE_UNKNOWN)
297 if (i >= nlocals)
298 return -1;
300 else if (TYPE_IS_WIDE (new_type))
301 i++;
303 return changed;
307 /* Handle dup-like operations. */
309 static void
310 type_stack_dup (int size, int offset)
312 tree type[4];
313 int index;
314 for (index = 0; index < size + offset; index++)
316 type[index] = stack_type_map[stack_pointer - 1];
317 if (type[index] == void_type_node)
319 index++;
320 type[index] = stack_type_map[stack_pointer - 2];
321 if (! TYPE_IS_WIDE (type[index]))
322 abort ();
323 if (index == size || index == size + offset)
324 /* Dup operation splits 64-bit number. */
325 abort ();
327 pop_type (type[index]);
329 for (index = size; --index >= 0; )
331 if (type[index] != void_type_node)
332 push_type (type[index]);
335 for (index = size + offset; --index >= 0; )
337 if (type[index] != void_type_node)
338 push_type (type[index]);
342 /* This keeps track of a start PC and corresponding initial index. */
343 struct pc_index
345 int start_pc;
346 int index;
349 /* A helper that is used when sorting exception ranges. */
350 static int
351 start_pc_cmp (const void *xp, const void *yp)
353 const struct pc_index *x = (const struct pc_index *) xp;
354 const struct pc_index *y = (const struct pc_index *) yp;
355 return x->start_pc - y->start_pc;
358 /* This causes the next iteration to ignore the next instruction
359 and look for some other unhandled instruction. */
360 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
361 #define INVALID_PC (-1)
363 #define VERIFICATION_ERROR(MESSAGE) \
364 do { message = MESSAGE; goto verify_error; } while (0)
366 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
367 do { message = MESSAGE; goto error_with_index; } while (0)
369 /* Recursive helper function to pop argument types during verification.
370 ARG_TYPES is the list of formal parameter types.
371 Return NULL on success and a freshly malloc'd error message on failure. */
373 static char *
374 pop_argument_types (tree arg_types)
376 if (arg_types == end_params_node)
377 return NULL;
378 if (TREE_CODE (arg_types) == TREE_LIST)
380 char *message = pop_argument_types (TREE_CHAIN (arg_types));
381 if (message == NULL)
382 pop_type_0 (TREE_VALUE (arg_types), &message);
383 return message;
385 abort ();
388 #define POP_TYPE(TYPE, MESSAGE) \
389 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
390 if (pmessage != NULL) goto pop_type_error; \
391 } while (0)
393 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
394 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
395 if (pmessage != NULL) goto pop_type_error; \
396 } while (0)
398 #define PUSH_TYPE(TYPE) \
399 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
401 #define PUSH_PENDING(LABEL) \
402 do { tree tmplab = LABEL; \
403 if ((message = check_pending_block (tmplab)) != NULL) \
404 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
406 #ifdef __GNUC__
407 #define CHECK_PC_IN_RANGE(PC) __extension__ \
408 ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
409 #else
410 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
411 #endif
413 #define BCODE byte_ops
416 /* Verify the bytecodes of the current method, with the instructions
417 starting at BYTE_OPS and LENGTH in number, from the class file pointed to
418 by JCF.
419 Return 1 on success, 0 on failure. */
421 verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
423 tree label;
424 int wide = 0;
425 int op_code;
426 int PC;
427 int oldpc = 0; /* PC of start of instruction. */
428 int prevpc = 0; /* If >= 0, PC of previous instruction. */
429 const char *message = 0;
430 char *pmessage;
431 int i;
432 int index;
433 unsigned char *p;
434 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
435 struct eh_range *eh_ranges;
436 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
437 struct pc_index *starts;
438 int eh_count;
440 jint int_value = -1;
442 pending_blocks = NULL_TREE;
444 current_subr = NULL_TREE;
446 /* Handle the exception table. */
447 method_init_exceptions ();
448 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
449 eh_count = JCF_readu2 (jcf);
451 /* We read the exception handlers in order of increasing start PC.
452 To do this we first read and sort the start PCs. */
453 starts = xmalloc (eh_count * sizeof (struct pc_index));
454 for (i = 0; i < eh_count; ++i)
456 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
457 starts[i].index = i;
459 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
461 for (i = 0; i < eh_count; ++i)
463 int start_pc, end_pc, handler_pc, catch_type;
465 p = jcf->read_ptr + 8 * starts[i].index;
467 start_pc = GET_u2 (p);
468 end_pc = GET_u2 (p+2);
469 handler_pc = GET_u2 (p+4);
470 catch_type = GET_u2 (p+6);
472 if (start_pc < 0 || start_pc >= length
473 || end_pc < 0 || end_pc > length || start_pc >= end_pc
474 || handler_pc < 0 || handler_pc >= length
475 || ! (instruction_bits[start_pc] & BCODE_INSTRUCTION_START)
476 || (end_pc < length &&
477 ! (instruction_bits[end_pc] & BCODE_INSTRUCTION_START))
478 || ! (instruction_bits[handler_pc] & BCODE_INSTRUCTION_START))
480 error ("bad pc in exception_table");
481 free (starts);
482 return 0;
485 add_handler (start_pc, end_pc,
486 lookup_label (handler_pc),
487 catch_type == 0 ? NULL_TREE
488 : get_class_constant (jcf, catch_type));
490 instruction_bits[handler_pc] |= BCODE_EXCEPTION_TARGET;
493 free (starts);
494 handle_nested_ranges ();
496 for (PC = 0;;)
498 tree type, tmp;
500 if (((PC != INVALID_PC
501 && instruction_bits[PC] & BCODE_TARGET) != 0)
502 || PC == 0)
504 PUSH_PENDING (lookup_label (PC));
505 INVALIDATE_PC;
508 /* Check if there are any more pending blocks in the current
509 subroutine. Because we push pending blocks in a
510 last-in-first-out order, and because we don't push anything
511 from our caller until we are done with this subroutine or
512 anything nested in it, we are done if the top of the
513 pending_blocks stack is not in a subroutine, or it is in our
514 caller. */
515 if (current_subr && PC == INVALID_PC)
517 if (pending_blocks == NULL_TREE
518 || (subroutine_nesting (pending_blocks)
519 < subroutine_nesting (current_subr)))
521 int size
522 = DECL_MAX_LOCALS (current_function_decl) + stack_pointer;
524 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
525 tmp = LABEL_RETURN_LABELS (current_subr);
527 /* FIXME: If we exit a subroutine via a throw, we might
528 have returned to an earlier caller. Obviously a
529 "ret" can only return one level, but a throw may
530 return many levels. */
531 current_subr = LABEL_SUBR_CONTEXT (current_subr);
533 if (RETURN_MAP_ADJUSTED (ret_map))
535 /* Since we are done with this subroutine, set up
536 the (so far known) return address as pending -
537 with the merged type state. */
538 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
540 tree return_label = TREE_VALUE (tmp);
541 tree return_state = LABEL_TYPE_STATE (return_label);
542 if (return_state == NULL_TREE)
544 /* This means we had not verified the subroutine
545 earlier, so this is the first jsr to call it.
546 In this case, the type_map of the return
547 address is just the current type_map - and that
548 is handled by the following PUSH_PENDING. */
550 else
552 /* In this case we have to do a merge. But first
553 restore the type_map for unused slots to those
554 that were in effect at the jsr. */
555 for (index = size; --index >= 0; )
557 type_map[index]
558 = 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);
571 if (PC == INVALID_PC)
573 label = pending_blocks;
575 if (label == NULL_TREE)
576 break; /* We're done! */
578 pending_blocks = LABEL_PENDING_CHAIN (label);
579 LABEL_CHANGED (label) = 0;
581 if (LABEL_IN_SUBR (label))
582 current_subr = LABEL_SUBR_START (label);
583 else
584 current_subr = NULL_TREE;
586 /* Restore type_map and stack_pointer from
587 LABEL_TYPE_STATE (label), and continue
588 compiling from there. */
589 load_type_state (label);
591 PC = LABEL_PC (label);
593 else if (PC >= length)
594 VERIFICATION_ERROR ("falling through the end of the method");
597 oldpc = PC;
599 if (! (instruction_bits[PC] & BCODE_INSTRUCTION_START) && ! wide)
600 VERIFICATION_ERROR ("PC not at instruction start");
602 instruction_bits[PC] |= BCODE_VERIFIED;
604 eh_ranges = find_handler (oldpc);
606 op_code = byte_ops[PC++];
607 switch (op_code)
609 int is_static, is_putting;
611 case OPCODE_nop:
612 break;
614 case OPCODE_iconst_m1:
615 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
616 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
617 i = op_code - OPCODE_iconst_0;
618 goto push_int;
619 push_int:
620 if (byte_ops[PC] == OPCODE_newarray
621 || byte_ops[PC] == OPCODE_anewarray)
622 int_value = i;
623 PUSH_TYPE (int_type_node); break;
625 case OPCODE_lconst_0: case OPCODE_lconst_1:
626 PUSH_TYPE (long_type_node); break;
628 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
629 PUSH_TYPE (float_type_node); break;
631 case OPCODE_dconst_0: case OPCODE_dconst_1:
632 PUSH_TYPE (double_type_node); break;
634 case OPCODE_bipush:
635 i = IMMEDIATE_s1;
636 goto push_int;
638 case OPCODE_sipush:
639 i = IMMEDIATE_s2;
640 goto push_int;
642 case OPCODE_iload: type = int_type_node; goto general_load;
643 case OPCODE_lload: type = long_type_node; goto general_load;
644 case OPCODE_fload: type = float_type_node; goto general_load;
645 case OPCODE_dload: type = double_type_node; goto general_load;
646 case OPCODE_aload: type = ptr_type_node; goto general_load;
647 general_load:
648 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
649 wide = 0;
650 goto load;
651 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
652 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
653 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
654 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
655 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
656 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
657 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
658 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
659 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
660 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
661 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
662 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
663 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
664 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
665 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
666 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
667 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
668 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
669 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
670 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
671 load:
672 if (index < 0
673 || (index + TYPE_IS_WIDE (type)
674 >= DECL_MAX_LOCALS (current_function_decl)))
675 VERIFICATION_ERROR_WITH_INDEX
676 ("invalid local variable index %d in load");
677 tmp = type_map[index];
678 if (tmp == TYPE_UNKNOWN)
679 VERIFICATION_ERROR_WITH_INDEX
680 ("loading local variable %d which has unknown type");
681 else if (tmp == TYPE_SECOND
682 || (TYPE_IS_WIDE (type)
683 && type_map[index+1] != void_type_node)
684 || (type == ptr_type_node
685 ? TREE_CODE (tmp) != POINTER_TYPE
686 : type == int_type_node
687 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
688 : type != tmp))
689 VERIFICATION_ERROR_WITH_INDEX
690 ("loading local variable %d which has invalid type");
691 PUSH_TYPE (tmp);
692 goto note_used;
693 case OPCODE_istore: type = int_type_node; goto general_store;
694 case OPCODE_lstore: type = long_type_node; goto general_store;
695 case OPCODE_fstore: type = float_type_node; goto general_store;
696 case OPCODE_dstore: type = double_type_node; goto general_store;
697 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
698 general_store:
699 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
700 wide = 0;
701 goto store;
702 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
703 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
704 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
705 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
706 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
707 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
708 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
709 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
710 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
711 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
712 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
713 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
714 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
715 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
716 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
717 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
718 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
719 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
720 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
721 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
722 store:
723 if (index < 0
724 || (index + TYPE_IS_WIDE (type)
725 >= DECL_MAX_LOCALS (current_function_decl)))
727 VERIFICATION_ERROR_WITH_INDEX
728 ("invalid local variable index %d in store");
729 return 0;
731 POP_TYPE_CONV (type, type, NULL);
732 type_map[index] = type;
734 /* If a local variable has changed, we need to reconsider exception
735 handlers. */
736 prev_eh_ranges = NULL_EH_RANGE;
738 /* Allocate decl for this variable now, so we get a temporary
739 ! that survives the whole method. */
740 find_local_variable (index, type, oldpc);
742 if (TYPE_IS_WIDE (type))
743 type_map[index+1] = TYPE_SECOND;
745 /* ... fall through to note_used ... */
746 note_used:
747 /* For store or load, note that local variable INDEX is used.
748 This is needed to verify try-finally subroutines. */
749 if (current_subr)
751 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
752 tree subr_vec = LABEL_TYPE_STATE (current_subr);
753 int len = 1 + TYPE_IS_WIDE (type);
754 while (--len >= 0)
756 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
757 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
760 break;
761 case OPCODE_iadd:
762 case OPCODE_iand:
763 case OPCODE_idiv:
764 case OPCODE_imul:
765 case OPCODE_ior:
766 case OPCODE_irem:
767 case OPCODE_ishl:
768 case OPCODE_ishr:
769 case OPCODE_isub:
770 case OPCODE_iushr:
771 case OPCODE_ixor:
772 type = int_type_node; goto binop;
773 case OPCODE_ineg:
774 case OPCODE_i2c:
775 case OPCODE_i2b:
776 case OPCODE_i2s:
777 type = int_type_node; goto unop;
778 case OPCODE_ladd:
779 case OPCODE_land:
780 case OPCODE_ldiv:
781 case OPCODE_lsub:
782 case OPCODE_lmul:
783 case OPCODE_lrem:
784 case OPCODE_lor:
785 case OPCODE_lxor:
786 type = long_type_node; goto binop;
787 case OPCODE_lneg:
788 type = long_type_node; goto unop;
789 case OPCODE_fadd: case OPCODE_fsub:
790 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
791 type = float_type_node; goto binop;
792 case OPCODE_fneg:
793 type = float_type_node; goto unop;
794 case OPCODE_dadd: case OPCODE_dsub:
795 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
796 type = double_type_node; goto binop;
797 case OPCODE_dneg:
798 type = double_type_node; goto unop;
800 unop:
801 pop_type (type);
802 PUSH_TYPE (type);
803 break;
805 binop:
806 pop_type (type);
807 pop_type (type);
808 PUSH_TYPE (type);
809 break;
811 case OPCODE_lshl:
812 case OPCODE_lshr:
813 case OPCODE_lushr:
814 pop_type (int_type_node);
815 pop_type (long_type_node);
816 PUSH_TYPE (long_type_node);
817 break;
819 case OPCODE_iinc:
820 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
821 PC += wide + 1;
822 wide = 0;
823 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
824 VERIFICATION_ERROR ("invalid local variable index in iinc");
825 tmp = type_map[index];
826 if (tmp == NULL_TREE
827 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
828 VERIFICATION_ERROR ("invalid local variable type in iinc");
829 break;
831 case OPCODE_i2l:
832 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
833 case OPCODE_i2f:
834 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
835 case OPCODE_i2d:
836 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
837 case OPCODE_l2i:
838 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
839 case OPCODE_l2f:
840 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
841 case OPCODE_l2d:
842 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
843 case OPCODE_f2i:
844 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
845 case OPCODE_f2l:
846 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
847 case OPCODE_f2d:
848 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
849 case OPCODE_d2i:
850 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
851 case OPCODE_d2l:
852 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
853 case OPCODE_d2f:
854 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
856 case OPCODE_lcmp:
857 type = long_type_node; goto compare;
858 case OPCODE_fcmpl:
859 case OPCODE_fcmpg:
860 type = float_type_node; goto compare;
861 case OPCODE_dcmpl:
862 case OPCODE_dcmpg:
863 type = double_type_node; goto compare;
864 compare:
865 pop_type (type); pop_type (type);
866 PUSH_TYPE (int_type_node); break;
868 case OPCODE_ifeq:
869 case OPCODE_ifne:
870 case OPCODE_iflt:
871 case OPCODE_ifge:
872 case OPCODE_ifgt:
873 case OPCODE_ifle:
874 pop_type (int_type_node); goto cond;
875 case OPCODE_ifnull:
876 case OPCODE_ifnonnull:
877 pop_type (ptr_type_node ); goto cond;
878 case OPCODE_if_icmpeq:
879 case OPCODE_if_icmpne:
880 case OPCODE_if_icmplt:
881 case OPCODE_if_icmpge:
882 case OPCODE_if_icmpgt:
883 case OPCODE_if_icmple:
884 pop_type (int_type_node); pop_type (int_type_node); goto cond;
885 case OPCODE_if_acmpeq:
886 case OPCODE_if_acmpne:
887 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
888 goto cond;
890 cond:
891 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
892 break;
894 case OPCODE_goto:
895 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
896 INVALIDATE_PC;
897 break;
899 case OPCODE_wide:
900 switch (byte_ops[PC])
902 case OPCODE_iload: case OPCODE_lload:
903 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
904 case OPCODE_istore: case OPCODE_lstore:
905 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
906 case OPCODE_iinc:
907 case OPCODE_ret:
908 wide = 1;
909 break;
910 default:
911 VERIFICATION_ERROR ("invalid use of wide instruction");
913 break;
915 case OPCODE_return: type = void_type_node; goto ret;
916 case OPCODE_ireturn:
917 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
918 || TREE_CODE (return_type) == CHAR_TYPE
919 || TREE_CODE (return_type) == INTEGER_TYPE)
920 && TYPE_PRECISION (return_type) <= 32)
921 type = return_type;
922 else
923 type = NULL_TREE;
924 goto ret;
925 case OPCODE_lreturn: type = long_type_node; goto ret;
926 case OPCODE_freturn: type = float_type_node; goto ret;
927 case OPCODE_dreturn: type = double_type_node; goto ret;
928 case OPCODE_areturn:
929 if (TREE_CODE (return_type) == POINTER_TYPE)
930 type = return_type;
931 else
932 type = NULL_TREE;
933 goto ret;
935 ret:
936 if (type != return_type)
937 VERIFICATION_ERROR ("incorrect ?return opcode");
938 if (type != void_type_node)
939 POP_TYPE (type, "return value has wrong type");
940 INVALIDATE_PC;
941 break;
943 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
944 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
945 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
946 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
947 field:
949 tree field_signature, field_type;
950 index = IMMEDIATE_u2;
952 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
953 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
955 if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref)
956 VERIFICATION_ERROR
957 ("field instruction does not reference a Fieldref");
959 field_signature
960 = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
962 field_type = get_type_from_signature (field_signature);
964 if (is_putting)
965 POP_TYPE (field_type, "incorrect type for field");
967 if (! is_static)
969 int clindex
970 = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, index);
972 tree self_type = get_class_constant (current_jcf, clindex);
974 /* Defer actual checking until next pass. */
975 POP_TYPE (self_type, "incorrect type for field reference");
978 if (! is_putting)
979 PUSH_TYPE (field_type);
980 break;
983 case OPCODE_new:
984 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
985 break;
987 case OPCODE_dup: wide = 1; index = 0; goto dup;
988 case OPCODE_dup_x1: wide = 1; index = 1; goto dup;
989 case OPCODE_dup_x2: wide = 1; index = 2; goto dup;
990 case OPCODE_dup2: wide = 2; index = 0; goto dup;
991 case OPCODE_dup2_x1: wide = 2; index = 1; goto dup;
992 case OPCODE_dup2_x2: wide = 2; index = 2; goto dup;
994 dup:
995 if (wide + index > stack_pointer)
996 VERIFICATION_ERROR ("stack underflow - dup* operation");
997 type_stack_dup (wide, index);
998 wide = 0;
999 break;
1001 case OPCODE_pop: index = 1; goto pop;
1002 case OPCODE_pop2: index = 2; goto pop;
1004 pop:
1005 if (stack_pointer < index)
1006 VERIFICATION_ERROR ("stack underflow");
1007 stack_pointer -= index;
1008 break;
1010 case OPCODE_swap:
1011 if (stack_pointer < 2)
1012 VERIFICATION_ERROR ("stack underflow (in swap)");
1013 else
1015 tree type1 = stack_type_map[stack_pointer - 1];
1016 tree type2 = stack_type_map[stack_pointer - 2];
1018 if (type1 == void_type_node || type2 == void_type_node)
1019 VERIFICATION_ERROR ("verifier (swap): double or long value");
1021 stack_type_map[stack_pointer - 2] = type1;
1022 stack_type_map[stack_pointer - 1] = type2;
1024 break;
1026 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
1027 case OPCODE_ldc2_w:
1028 case OPCODE_ldc_w:
1029 index = IMMEDIATE_u2; goto ldc;
1031 ldc:
1032 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
1033 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
1035 int_value = -1;
1036 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
1038 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
1039 case CONSTANT_Float: type = float_type_node; goto check_ldc;
1040 case CONSTANT_String: type = string_type_node; goto check_ldc;
1041 case CONSTANT_Long: type = long_type_node; goto check_ldc;
1042 case CONSTANT_Double: type = double_type_node; goto check_ldc;
1043 check_ldc:
1044 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
1045 break;
1046 /* ... else fall through ... */
1047 default:
1048 VERIFICATION_ERROR ("bad constant pool tag in ldc");
1050 if (type == int_type_node)
1052 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
1053 goto push_int;
1055 PUSH_TYPE (type);
1056 break;
1058 case OPCODE_invokevirtual:
1059 case OPCODE_invokespecial:
1060 case OPCODE_invokestatic:
1061 case OPCODE_invokeinterface:
1063 tree sig, method_name, method_type, self_type;
1064 int self_is_interface, tag;
1065 index = IMMEDIATE_u2;
1067 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
1068 VERIFICATION_ERROR_WITH_INDEX
1069 ("bad constant pool index %d for invoke");
1071 tag = JPOOL_TAG (current_jcf, index);
1073 if (op_code == OPCODE_invokeinterface)
1075 if (tag != CONSTANT_InterfaceMethodref)
1076 VERIFICATION_ERROR
1077 ("invokeinterface does not reference an InterfaceMethodref");
1079 else
1081 if (tag != CONSTANT_Methodref)
1082 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1085 sig = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
1087 self_type
1088 = get_class_constant (current_jcf,
1089 COMPONENT_REF_CLASS_INDEX
1090 (&current_jcf->cpool, index));
1092 if (! CLASS_LOADED_P (self_type))
1093 load_class (self_type, 1);
1095 self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
1096 method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
1097 method_type = parse_signature_string ((const unsigned char *) IDENTIFIER_POINTER (sig),
1098 IDENTIFIER_LENGTH (sig));
1100 if (TREE_CODE (method_type) != FUNCTION_TYPE)
1101 VERIFICATION_ERROR ("bad method signature");
1103 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
1104 if (pmessage != NULL)
1106 message = "invalid argument type";
1107 goto pop_type_error;
1110 /* Can't invoke <clinit>. */
1111 if (ID_CLINIT_P (method_name))
1112 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1114 /* Apart from invokespecial, can't invoke <init>. */
1115 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
1116 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1118 if (op_code != OPCODE_invokestatic)
1119 POP_TYPE (self_type,
1120 "stack type not subclass of invoked method's class");
1122 switch (op_code)
1124 case OPCODE_invokeinterface:
1126 int nargs = IMMEDIATE_u1;
1127 int notZero = IMMEDIATE_u1;
1129 if (!nargs || notZero)
1130 VERIFICATION_ERROR
1131 ("invalid argument number in invokeinterface");
1133 /* If we verify/resolve the constant pool, as we should,
1134 this test (and the one just following) are redundant. */
1135 if (! self_is_interface)
1136 VERIFICATION_ERROR
1137 ("invokeinterface calls method not in interface");
1138 break;
1140 default:
1141 if (self_is_interface)
1142 VERIFICATION_ERROR ("method in interface called");
1146 if (TREE_TYPE (method_type) != void_type_node)
1147 PUSH_TYPE (TREE_TYPE (method_type));
1148 break;
1151 case OPCODE_arraylength:
1152 /* Type checking actually made during code generation. */
1153 pop_type (ptr_type_node);
1154 PUSH_TYPE (int_type_node);
1155 break;
1157 /* Q&D verification *or* more checking done during code generation
1158 for byte/boolean/char/short, the value popped is a int coerced
1159 into the right type before being stored. */
1160 case OPCODE_iastore: type = int_type_node; goto astore;
1161 case OPCODE_lastore: type = long_type_node; goto astore;
1162 case OPCODE_fastore: type = float_type_node; goto astore;
1163 case OPCODE_dastore: type = double_type_node; goto astore;
1164 case OPCODE_aastore: type = ptr_type_node; goto astore;
1165 case OPCODE_bastore: type = int_type_node; goto astore;
1166 case OPCODE_castore: type = int_type_node; goto astore;
1167 case OPCODE_sastore: type = int_type_node; goto astore;
1169 astore:
1170 /* FIXME - need better verification here. */
1171 pop_type (type); /* new value */
1172 pop_type (int_type_node); /* index */
1173 pop_type (ptr_type_node); /* array */
1174 break;
1176 /* Q&D verification *or* more checking done during code generation
1177 for byte/boolean/char/short, the value pushed is a int. */
1178 case OPCODE_iaload: type = int_type_node; goto aload;
1179 case OPCODE_laload: type = long_type_node; goto aload;
1180 case OPCODE_faload: type = float_type_node; goto aload;
1181 case OPCODE_daload: type = double_type_node; goto aload;
1182 case OPCODE_aaload: type = ptr_type_node; goto aload;
1183 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1184 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1185 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1187 aload:
1188 pop_type (int_type_node);
1189 tmp = pop_type (ptr_type_node);
1190 if (is_array_type_p (tmp))
1191 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1192 else if (tmp != TYPE_NULL)
1193 VERIFICATION_ERROR ("array load from non-array type");
1194 PUSH_TYPE (type);
1195 break;
1197 case OPCODE_anewarray:
1198 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1199 type = promote_type (type);
1200 goto newarray;
1202 case OPCODE_newarray:
1203 index = IMMEDIATE_u1;
1204 type = decode_newarray_type (index);
1205 if (type == NULL_TREE)
1206 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1207 goto newarray;
1209 newarray:
1210 if (int_value >= 0 && prevpc >= 0)
1212 /* If the previous instruction pushed an int constant,
1213 we want to use it. */
1214 switch (byte_ops[prevpc])
1216 case OPCODE_iconst_0: case OPCODE_iconst_1:
1217 case OPCODE_iconst_2: case OPCODE_iconst_3:
1218 case OPCODE_iconst_4: case OPCODE_iconst_5:
1219 case OPCODE_bipush: case OPCODE_sipush:
1220 case OPCODE_ldc: case OPCODE_ldc_w:
1221 break;
1222 default:
1223 int_value = -1;
1226 else
1227 int_value = -1;
1229 type = build_java_array_type (type, int_value);
1230 pop_type (int_type_node);
1231 PUSH_TYPE (type);
1232 break;
1234 case OPCODE_multianewarray:
1236 int ndim, i;
1237 index = IMMEDIATE_u2;
1238 ndim = IMMEDIATE_u1;
1240 if (ndim < 1)
1241 VERIFICATION_ERROR
1242 ("number of dimension lower that 1 in multianewarray" );
1244 for (i = 0; i < ndim; i++)
1245 pop_type (int_type_node);
1247 PUSH_TYPE (get_class_constant (current_jcf, index));
1248 break;
1251 case OPCODE_aconst_null:
1252 PUSH_TYPE (ptr_type_node);
1253 break;
1255 case OPCODE_athrow:
1256 /* FIXME: athrow also empties the stack. */
1257 POP_TYPE (throwable_type_node, "missing throwable at athrow" );
1258 INVALIDATE_PC;
1259 break;
1261 case OPCODE_checkcast:
1262 POP_TYPE (object_ptr_type_node,
1263 "checkcast operand is not a pointer");
1264 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1265 PUSH_TYPE (type);
1266 break;
1268 case OPCODE_instanceof:
1269 POP_TYPE (object_ptr_type_node,
1270 "instanceof operand is not a pointer");
1271 get_class_constant (current_jcf, IMMEDIATE_u2);
1272 PUSH_TYPE (int_type_node);
1273 break;
1275 case OPCODE_tableswitch:
1277 jint low, high;
1279 POP_TYPE (int_type_node, "missing int for tableswitch");
1281 while (PC%4)
1283 if (byte_ops[PC++])
1284 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1287 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1288 low = IMMEDIATE_s4;
1289 high = IMMEDIATE_s4;
1291 if (low > high)
1292 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1294 while (low++ <= high)
1295 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1297 INVALIDATE_PC;
1298 break;
1301 case OPCODE_lookupswitch:
1303 jint npairs, last = 0, not_registered = 1;
1305 POP_TYPE (int_type_node, "missing int for lookupswitch");
1307 while (PC%4)
1309 if (byte_ops[PC++])
1310 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1313 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1314 npairs = IMMEDIATE_s4;
1316 if (npairs < 0)
1317 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1319 while (npairs--)
1321 int match = IMMEDIATE_s4;
1323 if (not_registered)
1324 not_registered = 0;
1325 else if (last >= match)
1326 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1328 last = match;
1329 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1331 INVALIDATE_PC;
1332 break;
1335 case OPCODE_monitorenter:
1336 /* fall thru */
1337 case OPCODE_monitorexit:
1338 pop_type (ptr_type_node);
1339 break;
1341 case OPCODE_goto_w:
1342 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1343 INVALIDATE_PC;
1344 break;
1346 case OPCODE_jsr:
1348 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1349 tree return_label = lookup_label (PC);
1350 PUSH_TYPE (return_address_type_node);
1351 /* The return label chain will be null if this is the first
1352 time we've seen this jsr target. */
1353 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1355 tree return_type_map;
1356 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1357 index = nlocals + DECL_MAX_STACK (current_function_decl);
1358 return_type_map = make_tree_vec (index);
1360 while (index > nlocals)
1361 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1363 while (index > 0)
1364 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1366 LABEL_RETURN_LABEL (target)
1367 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1368 LABEL_PC (LABEL_RETURN_LABEL (target)) = INVALID_PC;
1369 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1370 LABEL_IS_SUBR_START (target) = 1;
1371 LABEL_IN_SUBR (target) = 1;
1372 LABEL_SUBR_START (target) = target;
1373 LABEL_SUBR_CONTEXT (target) = current_subr;
1375 else if (! LABEL_IS_SUBR_START (target)
1376 || LABEL_SUBR_CONTEXT (target) != current_subr)
1377 VERIFICATION_ERROR ("label part of different subroutines");
1379 i = merge_type_state (target);
1380 if (i != 0)
1382 if (i < 0)
1383 VERIFICATION_ERROR ("types could not be merged at jsr");
1384 push_pending_label (target);
1386 current_subr = target;
1388 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1389 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1391 LABEL_RETURN_LABELS (target)
1392 = tree_cons (NULL_TREE, return_label,
1393 LABEL_RETURN_LABELS (target));
1396 if (LABEL_VERIFIED (target))
1398 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1399 int len = TREE_VEC_LENGTH (return_map);
1400 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1401 while (--len >= 0)
1403 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1404 type_map[len] = TREE_VEC_ELT (return_map, len);
1406 current_subr = LABEL_SUBR_CONTEXT (target);
1407 if (RETURN_MAP_ADJUSTED (return_map))
1408 PUSH_PENDING (return_label);
1411 INVALIDATE_PC;
1413 break;
1415 case OPCODE_ret:
1416 if (current_subr == NULL_TREE)
1417 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1418 else
1420 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1421 int size
1422 = DECL_MAX_LOCALS (current_function_decl) + stack_pointer;
1423 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1424 wide = 0;
1425 INVALIDATE_PC;
1426 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1427 || type_map[index] != TYPE_RETURN_ADDR)
1428 VERIFICATION_ERROR ("invalid ret index");
1430 /* The next chunk of code is similar to an inlined version of
1431 merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1432 The main differences are that LABEL_RETURN_LABEL is
1433 pre-allocated by the jsr (but we don't know the size then);
1434 and that we have to handle TYPE_UNUSED. */
1436 if (! RETURN_MAP_ADJUSTED (ret_map))
1438 /* First return from this subroutine - fix stack
1439 pointer. */
1440 TREE_VEC_LENGTH (ret_map) = size;
1441 for (index = size; --index >= 0; )
1443 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1444 TREE_VEC_ELT (ret_map, index) = type_map[index];
1446 RETURN_MAP_ADJUSTED (ret_map) = 1;
1448 else
1450 if (TREE_VEC_LENGTH (ret_map) != size)
1451 VERIFICATION_ERROR ("inconsistent stack size on ret");
1452 for (index = 0; index < size; index++)
1454 tree type = TREE_VEC_ELT (ret_map, index);
1455 if (type != TYPE_UNUSED)
1457 type = merge_types (type, type_map[index]);
1458 TREE_VEC_ELT (ret_map, index) = type;
1459 if (type == TYPE_UNKNOWN)
1461 if (index >= size - stack_pointer)
1462 VERIFICATION_ERROR
1463 ("inconsistent types on ret from jsr");
1465 else if (TYPE_IS_WIDE (type))
1466 index++;
1471 break;
1473 case OPCODE_jsr_w:
1474 case OPCODE_ret_w:
1475 default:
1476 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1477 return 0;
1480 prevpc = oldpc;
1482 /* The following test is true if we have entered or exited an exception
1483 handler range *or* we have done a store to a local variable.
1484 In either case we need to consider any exception handlers that
1485 might "follow" this instruction. */
1487 if (eh_ranges != prev_eh_ranges)
1489 int save_stack_pointer = stack_pointer;
1490 int index = DECL_MAX_LOCALS (current_function_decl);
1491 tree save_type = type_map[index];
1492 tree save_current_subr = current_subr;
1493 struct eh_range *ranges = find_handler (oldpc);
1494 stack_pointer = 1;
1496 for ( ; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1498 tree chain = ranges->handlers;
1500 /* We need to determine if the handler is part of current_subr.
1501 The are two cases: (1) The exception catch range
1502 is entirely within current_subr. In that case the handler
1503 is also part of current_subr.
1504 (2) Some of the catch range is not in current_subr.
1505 In that case, the handler is *not* part of current_subr.
1507 Figuring out which is the case is not necessarily obvious,
1508 in the presence of clever code generators (and obfuscators).
1509 We make a simplifying assumption that in case (2) we
1510 have that the current_subr is entirely within the catch range.
1511 In that case we can assume if that if a caller (the jsr) of
1512 a subroutine is within the catch range, then the handler is
1513 *not* part of the subroutine, and vice versa. */
1515 current_subr = save_current_subr;
1516 for ( ; current_subr != NULL_TREE;
1517 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1519 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1520 /* There could be multiple return_labels, but
1521 we only need to check one. */
1522 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1523 if (return_pc <= ranges->start_pc
1524 || return_pc > ranges->end_pc)
1525 break;
1528 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1530 tree handler = TREE_VALUE (chain);
1531 tree type = TREE_PURPOSE (chain);
1533 if (type == NULL_TREE) /* a finally handler */
1534 type = throwable_type_node;
1536 type_map[index] = promote_type (type);
1538 PUSH_PENDING (handler);
1541 stack_pointer = save_stack_pointer;
1542 current_subr = save_current_subr;
1543 type_map[index] = save_type;
1544 prev_eh_ranges = eh_ranges;
1548 return 1;
1550 pop_type_error:
1551 error ("verification error at PC=%d", oldpc);
1552 if (message != NULL)
1553 error ("%s", message);
1554 error ("%s", pmessage);
1555 free (pmessage);
1556 return 0;
1558 stack_overflow:
1559 message = "stack overflow";
1560 goto verify_error;
1562 bad_pc:
1563 message = "program counter out of range";
1564 goto verify_error;
1566 error_with_index:
1567 error ("verification error at PC=%d", oldpc);
1568 error (message, index);
1569 return 0;
1571 verify_error:
1572 error ("verification error at PC=%d", oldpc);
1573 error ("%s", message);
1574 return 0;