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