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