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