2005-06-07 Thomas Koenig <Thomas.Koenig@online.de>
[official-gcc.git] / gcc / java / verify.c
blob6f947834189cc0d91a58475345a9456b4bf39b5a
1 /* Handle verification of bytecoded methods for the GNU compiler for
2 the Java(TM) language.
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc. */
27 /* This bytecode verifier is an implementation of the bytecode
28 verification process described in section 4.9 of "The Java(TM) Virtual
29 Machine Specification", Second Edition, by Tim Lindholm and Frank Yellin,
30 published by Addison-Wesley in 1999. */
32 #include "config.h"
33 #include "system.h"
34 #include "coretypes.h"
35 #include "tm.h"
36 #include "tree.h"
37 #include "java-tree.h"
38 #include "javaop.h"
39 #include "java-opcodes.h"
40 #include "jcf.h"
41 #include "java-except.h"
42 #include "toplev.h"
44 static void push_pending_label (tree);
45 static tree merge_types (tree, tree);
46 static const char *check_pending_block (tree);
47 static void type_stack_dup (int, int);
48 static int start_pc_cmp (const void *, const void *);
49 static char *pop_argument_types (tree);
51 extern int stack_pointer;
53 /* During verification, start of the current subroutine (jsr target). */
54 tree current_subr;
56 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
57 A pending block is one that has LABEL_CHANGED set, which means
58 it requires (re-) verification. */
59 tree pending_blocks;
61 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
63 static void
64 push_pending_label (tree target_label)
66 if (! LABEL_CHANGED (target_label))
68 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
69 pending_blocks = target_label;
70 LABEL_CHANGED (target_label) = 1;
74 /* Note that TARGET_LABEL is a possible successor instruction.
75 Merge the type state etc.
76 Return NULL on success, or an error message on failure. */
78 static const char *
79 check_pending_block (tree target_label)
81 int changed = merge_type_state (target_label);
83 if (changed)
85 if (changed < 0)
86 return "types could not be merged";
87 push_pending_label (target_label);
90 if (current_subr == NULL_TREE)
92 if (LABEL_IN_SUBR (target_label))
93 return "might transfer control into subroutine";
95 else
97 if (LABEL_IN_SUBR (target_label))
99 if (LABEL_SUBR_START (target_label) != current_subr)
100 return "transfer out of subroutine";
102 else if (! LABEL_VERIFIED (target_label))
104 LABEL_IN_SUBR (target_label) = 1;
105 LABEL_SUBR_START (target_label) = current_subr;
107 else
108 return "transfer out of subroutine";
110 return NULL;
113 /* Count the number of nested jsr calls needed to reach LABEL. */
115 static int
116 subroutine_nesting (tree label)
118 int nesting = 0;
119 while (label != NULL_TREE && LABEL_IN_SUBR (label))
121 if (! LABEL_IS_SUBR_START (label))
122 label = LABEL_SUBR_START (label);
123 label = LABEL_SUBR_CONTEXT (label);
124 nesting++;
126 return nesting;
129 /* Return the "merged" types of TYPE1 and TYPE2.
130 If either is primitive, the other must match (after promotion to int).
131 For reference types, return the common super-class.
132 Return TYPE_UNKNOWN if the types cannot be merged. */
134 static tree
135 merge_types (tree type1, tree type2)
137 if (type1 == type2)
138 return type1;
139 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
140 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
141 return TYPE_UNKNOWN;
142 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
144 int depth1, depth2;
145 tree tt1, tt2;
146 /* ptr_type_node is only used for a null reference,
147 which is compatible with any reference type. */
148 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
149 return type2;
150 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
151 return type1;
153 tt1 = TREE_TYPE (type1);
154 tt2 = TREE_TYPE (type2);
156 /* If tt{1,2} haven't been properly loaded, now is a good time
157 to do it. */
158 if (!TYPE_SIZE (tt1))
160 load_class (tt1, 1);
161 safe_layout_class (tt1);
164 if (!TYPE_SIZE (tt2))
166 load_class (tt2, 1);
167 safe_layout_class (tt2);
170 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
172 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
174 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
175 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
176 tree el_type = NULL_TREE;
177 if (el_type1 == el_type2)
178 el_type = el_type1;
179 else if (TREE_CODE (el_type1) == POINTER_TYPE
180 && TREE_CODE (el_type2) == POINTER_TYPE)
181 el_type = merge_types (el_type1, el_type2);
182 if (el_type != NULL_TREE)
184 HOST_WIDE_INT len1 = java_array_type_length (tt1);
185 HOST_WIDE_INT len2 = java_array_type_length (tt2);
186 if (len1 != len2)
187 len1 = -1;
188 else if (el_type1 == el_type2)
189 return type1;
190 return promote_type (build_java_array_type (el_type, len1));
193 return object_ptr_type_node;
196 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
198 /* FIXME: should see if two interfaces have a common
199 superinterface. */
200 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
202 /* This is a kludge, but matches what Sun's verifier does.
203 It can be tricked, but is safe as long as type errors
204 (i.e. interface method calls) are caught at run-time. */
205 return object_ptr_type_node;
207 else
209 if (can_widen_reference_to (tt2, tt1))
210 return type1;
211 else
212 return object_ptr_type_node;
215 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
217 if (can_widen_reference_to (tt1, tt2))
218 return type2;
219 else
220 return object_ptr_type_node;
223 type1 = tt1;
224 type2 = tt2;
226 depth1 = class_depth (type1);
227 depth2 = class_depth (type2);
228 for ( ; depth1 > depth2; depth1--)
229 type1 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type1), 0));
230 for ( ; depth2 > depth1; depth2--)
231 type2 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type2), 0));
232 while (type1 != type2)
234 type1 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type1), 0));
235 type2 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type2), 0));
237 return promote_type (type1);
239 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
240 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
241 return int_type_node;
242 return TYPE_UNKNOWN;
245 /* Merge the current type state with that at LABEL.
246 Return -1 if the states are incompatible (i.e. on error),
247 0 if there was no change, and 1 if there was a change. */
250 merge_type_state (tree label)
252 int nlocals = DECL_MAX_LOCALS (current_function_decl);
253 int cur_length = stack_pointer + nlocals;
254 tree vec = LABEL_TYPE_STATE (label);
255 tree return_map;
256 if (vec == NULL_TREE)
258 vec = make_tree_vec (cur_length);
259 LABEL_TYPE_STATE (label) = vec;
261 while (--cur_length >= 0)
262 TREE_VEC_ELT (vec, cur_length) = type_map[cur_length];
263 return 1;
265 else
267 int i;
268 int changed = 0;
269 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
270 && current_subr != label)
271 return_map = LABEL_RETURN_TYPE_STATE (label);
272 else
273 return_map = NULL_TREE;
274 if (TREE_VEC_LENGTH (vec) != cur_length)
276 return -1;
278 for (i = 0; i < cur_length; i++)
280 tree old_type = TREE_VEC_ELT (vec, i);
281 tree new_type = merge_types (old_type, type_map[i]);
282 if (TREE_VEC_ELT (vec, i) != new_type)
284 /* If there has been a change, note that since we must re-verify.
285 However, if the label is the start of a subroutine,
286 we don't care about local variables that are neither
287 set nor used in the subroutine. */
288 if (return_map == NULL_TREE || i >= nlocals
289 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
290 || (TYPE_IS_WIDE (new_type)
291 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
292 changed = 1;
294 TREE_VEC_ELT (vec, i) = new_type;
295 if (new_type == TYPE_UNKNOWN)
297 if (i >= nlocals)
298 return -1;
300 else if (TYPE_IS_WIDE (new_type))
301 i++;
303 return changed;
307 /* Handle dup-like operations. */
309 static void
310 type_stack_dup (int size, int offset)
312 tree type[4];
313 int index;
314 for (index = 0; index < size + offset; index++)
316 type[index] = stack_type_map[stack_pointer - 1];
317 if (type[index] == void_type_node)
319 index++;
320 type[index] = stack_type_map[stack_pointer - 2];
321 if (! TYPE_IS_WIDE (type[index]))
322 abort ();
323 if (index == size || index == size + offset)
324 /* Dup operation splits 64-bit number. */
325 abort ();
327 pop_type (type[index]);
329 for (index = size; --index >= 0; )
331 if (type[index] != void_type_node)
332 push_type (type[index]);
335 for (index = size + offset; --index >= 0; )
337 if (type[index] != void_type_node)
338 push_type (type[index]);
342 /* This keeps track of a start PC and corresponding initial index. */
343 struct pc_index
345 int start_pc;
346 int index;
349 /* A helper that is used when sorting exception ranges. */
350 static int
351 start_pc_cmp (const void *xp, const void *yp)
353 const struct pc_index *x = (const struct pc_index *) xp;
354 const struct pc_index *y = (const struct pc_index *) yp;
355 return x->start_pc - y->start_pc;
358 /* This causes the next iteration to ignore the next instruction
359 and look for some other unhandled instruction. */
360 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
361 #define INVALID_PC (-1)
363 #define VERIFICATION_ERROR(MESSAGE) \
364 do { message = MESSAGE; goto verify_error; } while (0)
366 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
367 do { message = MESSAGE; goto error_with_index; } while (0)
369 /* Recursive helper function to pop argument types during verification.
370 ARG_TYPES is the list of formal parameter types.
371 Return NULL on success and a freshly malloc'd error message on failure. */
373 static char *
374 pop_argument_types (tree arg_types)
376 if (arg_types == end_params_node)
377 return NULL;
378 if (TREE_CODE (arg_types) == TREE_LIST)
380 char *message = pop_argument_types (TREE_CHAIN (arg_types));
381 if (message == NULL)
382 pop_type_0 (TREE_VALUE (arg_types), &message);
383 return message;
385 abort ();
388 #define POP_TYPE(TYPE, MESSAGE) \
389 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
390 if (pmessage != NULL) goto pop_type_error; \
391 } while (0)
393 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
394 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
395 if (pmessage != NULL) goto pop_type_error; \
396 } while (0)
398 #define PUSH_TYPE(TYPE) \
399 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
401 #define PUSH_PENDING(LABEL) \
402 do { tree tmplab = LABEL; \
403 if ((message = check_pending_block (tmplab)) != NULL) \
404 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
406 #ifdef __GNUC__
407 #define CHECK_PC_IN_RANGE(PC) __extension__ \
408 ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
409 #else
410 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
411 #endif
413 #define BCODE byte_ops
416 /* Verify the bytecodes of the current method, with the instructions
417 starting at BYTE_OPS and LENGTH in number, from the class file pointed to
418 by JCF.
419 Return 1 on success, 0 on failure. */
421 verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
423 tree label;
424 int wide = 0;
425 int op_code;
426 int PC;
427 int oldpc = 0; /* PC of start of instruction. */
428 int prevpc = 0; /* If >= 0, PC of previous instruction. */
429 const char *message = 0;
430 char *pmessage;
431 int i;
432 int index;
433 unsigned char *p;
434 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
435 struct eh_range *eh_ranges;
436 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
437 struct pc_index *starts;
438 int eh_count;
440 jint int_value = -1;
442 pending_blocks = NULL_TREE;
444 current_subr = NULL_TREE;
446 /* Handle the exception table. */
447 method_init_exceptions ();
448 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
449 eh_count = JCF_readu2 (jcf);
451 /* We read the exception handlers in order of increasing start PC.
452 To do this we first read and sort the start PCs. */
453 starts = xmalloc (eh_count * sizeof (struct pc_index));
454 for (i = 0; i < eh_count; ++i)
456 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
457 starts[i].index = i;
459 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
461 for (i = 0; i < eh_count; ++i)
463 int start_pc, end_pc, handler_pc, catch_type;
465 p = jcf->read_ptr + 8 * starts[i].index;
467 start_pc = GET_u2 (p);
468 end_pc = GET_u2 (p+2);
469 handler_pc = GET_u2 (p+4);
470 catch_type = GET_u2 (p+6);
472 if (start_pc < 0 || start_pc >= length
473 || end_pc < 0 || end_pc > length || start_pc >= end_pc
474 || handler_pc < 0 || handler_pc >= length
475 || ! (instruction_bits[start_pc] & BCODE_INSTRUCTION_START)
476 || (end_pc < length &&
477 ! (instruction_bits[end_pc] & BCODE_INSTRUCTION_START))
478 || ! (instruction_bits[handler_pc] & BCODE_INSTRUCTION_START))
480 error ("bad pc in exception_table");
481 free (starts);
482 return 0;
485 add_handler (start_pc, end_pc,
486 lookup_label (handler_pc),
487 catch_type == 0 ? NULL_TREE
488 : get_class_constant (jcf, catch_type));
490 instruction_bits[handler_pc] |= BCODE_EXCEPTION_TARGET;
493 free (starts);
495 for (PC = 0;;)
497 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;
507 /* Check if there are any more pending blocks in the current
508 subroutine. Because we push pending blocks in a
509 last-in-first-out order, and because we don't push anything
510 from our caller until we are done with this subroutine or
511 anything nested in it, we are done if the top of the
512 pending_blocks stack is not in a subroutine, or it is in our
513 caller. */
514 if (current_subr && PC == INVALID_PC)
516 if (pending_blocks == NULL_TREE
517 || (subroutine_nesting (pending_blocks)
518 < subroutine_nesting (current_subr)))
520 int size
521 = DECL_MAX_LOCALS (current_function_decl) + stack_pointer;
523 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
524 tmp = LABEL_RETURN_LABELS (current_subr);
526 /* FIXME: If we exit a subroutine via a throw, we might
527 have returned to an earlier caller. Obviously a
528 "ret" can only return one level, but a throw may
529 return many levels. */
530 current_subr = LABEL_SUBR_CONTEXT (current_subr);
532 if (RETURN_MAP_ADJUSTED (ret_map))
534 /* Since we are done with this subroutine, set up
535 the (so far known) return address as pending -
536 with the merged type state. */
537 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
539 tree return_label = TREE_VALUE (tmp);
540 tree return_state = LABEL_TYPE_STATE (return_label);
541 if (return_state == NULL_TREE)
543 /* This means we had not verified the subroutine
544 earlier, so this is the first jsr to call it.
545 In this case, the type_map of the return
546 address is just the current type_map - and that
547 is handled by the following PUSH_PENDING. */
549 else
551 /* In this case we have to do a merge. But first
552 restore the type_map for unused slots to those
553 that were in effect at the jsr. */
554 for (index = size; --index >= 0; )
556 type_map[index]
557 = TREE_VEC_ELT (ret_map, index);
559 if (type_map[index] == TYPE_UNUSED)
560 type_map[index]
561 = TREE_VEC_ELT (return_state, index);
564 PUSH_PENDING (return_label);
570 if (PC == INVALID_PC)
572 label = pending_blocks;
574 if (label == NULL_TREE)
575 break; /* We're done! */
577 pending_blocks = LABEL_PENDING_CHAIN (label);
578 LABEL_CHANGED (label) = 0;
580 if (LABEL_IN_SUBR (label))
581 current_subr = LABEL_SUBR_START (label);
582 else
583 current_subr = NULL_TREE;
585 /* Restore type_map and stack_pointer from
586 LABEL_TYPE_STATE (label), and continue
587 compiling from there. */
588 load_type_state (label);
590 PC = LABEL_PC (label);
592 else if (PC >= length)
593 VERIFICATION_ERROR ("falling through the end of the method");
596 oldpc = PC;
598 if (! (instruction_bits[PC] & BCODE_INSTRUCTION_START) && ! wide)
599 VERIFICATION_ERROR ("PC not at instruction start");
601 instruction_bits[PC] |= BCODE_VERIFIED;
603 eh_ranges = find_handler (oldpc);
605 op_code = byte_ops[PC++];
606 switch (op_code)
608 int is_static, is_putting;
610 case OPCODE_nop:
611 break;
613 case OPCODE_iconst_m1:
614 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
615 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
616 i = op_code - OPCODE_iconst_0;
617 goto push_int;
618 push_int:
619 if (byte_ops[PC] == OPCODE_newarray
620 || byte_ops[PC] == OPCODE_anewarray)
621 int_value = i;
622 PUSH_TYPE (int_type_node); break;
624 case OPCODE_lconst_0: case OPCODE_lconst_1:
625 PUSH_TYPE (long_type_node); break;
627 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
628 PUSH_TYPE (float_type_node); break;
630 case OPCODE_dconst_0: case OPCODE_dconst_1:
631 PUSH_TYPE (double_type_node); break;
633 case OPCODE_bipush:
634 i = IMMEDIATE_s1;
635 goto push_int;
637 case OPCODE_sipush:
638 i = IMMEDIATE_s2;
639 goto push_int;
641 case OPCODE_iload: type = int_type_node; goto general_load;
642 case OPCODE_lload: type = long_type_node; goto general_load;
643 case OPCODE_fload: type = float_type_node; goto general_load;
644 case OPCODE_dload: type = double_type_node; goto general_load;
645 case OPCODE_aload: type = ptr_type_node; goto general_load;
646 general_load:
647 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
648 wide = 0;
649 goto load;
650 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
651 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
652 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
653 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
654 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
655 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
656 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
657 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
658 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
659 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
660 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
661 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
662 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
663 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
664 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
665 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
666 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
667 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
668 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
669 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
670 load:
671 if (index < 0
672 || (index + TYPE_IS_WIDE (type)
673 >= DECL_MAX_LOCALS (current_function_decl)))
674 VERIFICATION_ERROR_WITH_INDEX
675 ("invalid local variable index %d in load");
676 tmp = type_map[index];
677 if (tmp == TYPE_UNKNOWN)
678 VERIFICATION_ERROR_WITH_INDEX
679 ("loading local variable %d which has unknown type");
680 else if (tmp == TYPE_SECOND
681 || (TYPE_IS_WIDE (type)
682 && type_map[index+1] != void_type_node)
683 || (type == ptr_type_node
684 ? TREE_CODE (tmp) != POINTER_TYPE
685 : type == int_type_node
686 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
687 : type != tmp))
688 VERIFICATION_ERROR_WITH_INDEX
689 ("loading local variable %d which has invalid type");
690 PUSH_TYPE (tmp);
691 goto note_used;
692 case OPCODE_istore: type = int_type_node; goto general_store;
693 case OPCODE_lstore: type = long_type_node; goto general_store;
694 case OPCODE_fstore: type = float_type_node; goto general_store;
695 case OPCODE_dstore: type = double_type_node; goto general_store;
696 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
697 general_store:
698 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
699 wide = 0;
700 goto store;
701 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
702 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
703 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
704 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
705 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
706 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
707 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
708 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
709 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
710 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
711 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
712 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
713 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
714 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
715 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
716 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
717 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
718 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
719 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
720 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
721 store:
722 if (index < 0
723 || (index + TYPE_IS_WIDE (type)
724 >= DECL_MAX_LOCALS (current_function_decl)))
726 VERIFICATION_ERROR_WITH_INDEX
727 ("invalid local variable index %d in store");
728 return 0;
730 POP_TYPE_CONV (type, type, NULL);
731 type_map[index] = type;
733 /* If a local variable has changed, we need to reconsider exception
734 handlers. */
735 prev_eh_ranges = NULL_EH_RANGE;
737 /* Allocate decl for this variable now, so we get a temporary
738 ! that survives the whole method. */
739 find_local_variable (index, type, oldpc);
741 if (TYPE_IS_WIDE (type))
742 type_map[index+1] = TYPE_SECOND;
744 /* ... fall through to note_used ... */
745 note_used:
746 /* For store or load, note that local variable INDEX is used.
747 This is needed to verify try-finally subroutines. */
748 if (current_subr)
750 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
751 tree subr_vec = LABEL_TYPE_STATE (current_subr);
752 int len = 1 + TYPE_IS_WIDE (type);
753 while (--len >= 0)
755 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
756 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
759 break;
760 case OPCODE_iadd:
761 case OPCODE_iand:
762 case OPCODE_idiv:
763 case OPCODE_imul:
764 case OPCODE_ior:
765 case OPCODE_irem:
766 case OPCODE_ishl:
767 case OPCODE_ishr:
768 case OPCODE_isub:
769 case OPCODE_iushr:
770 case OPCODE_ixor:
771 type = int_type_node; goto binop;
772 case OPCODE_ineg:
773 case OPCODE_i2c:
774 case OPCODE_i2b:
775 case OPCODE_i2s:
776 type = int_type_node; goto unop;
777 case OPCODE_ladd:
778 case OPCODE_land:
779 case OPCODE_ldiv:
780 case OPCODE_lsub:
781 case OPCODE_lmul:
782 case OPCODE_lrem:
783 case OPCODE_lor:
784 case OPCODE_lxor:
785 type = long_type_node; goto binop;
786 case OPCODE_lneg:
787 type = long_type_node; goto unop;
788 case OPCODE_fadd: case OPCODE_fsub:
789 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
790 type = float_type_node; goto binop;
791 case OPCODE_fneg:
792 type = float_type_node; goto unop;
793 case OPCODE_dadd: case OPCODE_dsub:
794 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
795 type = double_type_node; goto binop;
796 case OPCODE_dneg:
797 type = double_type_node; goto unop;
799 unop:
800 pop_type (type);
801 PUSH_TYPE (type);
802 break;
804 binop:
805 pop_type (type);
806 pop_type (type);
807 PUSH_TYPE (type);
808 break;
810 case OPCODE_lshl:
811 case OPCODE_lshr:
812 case OPCODE_lushr:
813 pop_type (int_type_node);
814 pop_type (long_type_node);
815 PUSH_TYPE (long_type_node);
816 break;
818 case OPCODE_iinc:
819 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
820 PC += wide + 1;
821 wide = 0;
822 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
823 VERIFICATION_ERROR ("invalid local variable index in iinc");
824 tmp = type_map[index];
825 if (tmp == NULL_TREE
826 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
827 VERIFICATION_ERROR ("invalid local variable type in iinc");
828 break;
830 case OPCODE_i2l:
831 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
832 case OPCODE_i2f:
833 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
834 case OPCODE_i2d:
835 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
836 case OPCODE_l2i:
837 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
838 case OPCODE_l2f:
839 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
840 case OPCODE_l2d:
841 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
842 case OPCODE_f2i:
843 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
844 case OPCODE_f2l:
845 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
846 case OPCODE_f2d:
847 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
848 case OPCODE_d2i:
849 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
850 case OPCODE_d2l:
851 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
852 case OPCODE_d2f:
853 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
855 case OPCODE_lcmp:
856 type = long_type_node; goto compare;
857 case OPCODE_fcmpl:
858 case OPCODE_fcmpg:
859 type = float_type_node; goto compare;
860 case OPCODE_dcmpl:
861 case OPCODE_dcmpg:
862 type = double_type_node; goto compare;
863 compare:
864 pop_type (type); pop_type (type);
865 PUSH_TYPE (int_type_node); break;
867 case OPCODE_ifeq:
868 case OPCODE_ifne:
869 case OPCODE_iflt:
870 case OPCODE_ifge:
871 case OPCODE_ifgt:
872 case OPCODE_ifle:
873 pop_type (int_type_node); goto cond;
874 case OPCODE_ifnull:
875 case OPCODE_ifnonnull:
876 pop_type (ptr_type_node ); goto cond;
877 case OPCODE_if_icmpeq:
878 case OPCODE_if_icmpne:
879 case OPCODE_if_icmplt:
880 case OPCODE_if_icmpge:
881 case OPCODE_if_icmpgt:
882 case OPCODE_if_icmple:
883 pop_type (int_type_node); pop_type (int_type_node); goto cond;
884 case OPCODE_if_acmpeq:
885 case OPCODE_if_acmpne:
886 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
887 goto cond;
889 cond:
890 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
891 break;
893 case OPCODE_goto:
894 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
895 INVALIDATE_PC;
896 break;
898 case OPCODE_wide:
899 switch (byte_ops[PC])
901 case OPCODE_iload: case OPCODE_lload:
902 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
903 case OPCODE_istore: case OPCODE_lstore:
904 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
905 case OPCODE_iinc:
906 case OPCODE_ret:
907 wide = 1;
908 break;
909 default:
910 VERIFICATION_ERROR ("invalid use of wide instruction");
912 break;
914 case OPCODE_return: type = void_type_node; goto ret;
915 case OPCODE_ireturn:
916 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
917 || TREE_CODE (return_type) == CHAR_TYPE
918 || TREE_CODE (return_type) == INTEGER_TYPE)
919 && TYPE_PRECISION (return_type) <= 32)
920 type = return_type;
921 else
922 type = NULL_TREE;
923 goto ret;
924 case OPCODE_lreturn: type = long_type_node; goto ret;
925 case OPCODE_freturn: type = float_type_node; goto ret;
926 case OPCODE_dreturn: type = double_type_node; goto ret;
927 case OPCODE_areturn:
928 if (TREE_CODE (return_type) == POINTER_TYPE)
929 type = return_type;
930 else
931 type = NULL_TREE;
932 goto ret;
934 ret:
935 if (type != return_type)
936 VERIFICATION_ERROR ("incorrect ?return opcode");
937 if (type != void_type_node)
938 POP_TYPE (type, "return value has wrong type");
939 INVALIDATE_PC;
940 break;
942 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
943 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
944 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
945 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
946 field:
948 tree field_signature, field_type;
949 index = IMMEDIATE_u2;
951 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
952 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
954 if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref)
955 VERIFICATION_ERROR
956 ("field instruction does not reference a Fieldref");
958 field_signature
959 = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
961 field_type = get_type_from_signature (field_signature);
963 if (is_putting)
964 POP_TYPE (field_type, "incorrect type for field");
966 if (! is_static)
968 int clindex
969 = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, index);
971 tree self_type = get_class_constant (current_jcf, clindex);
973 /* Defer actual checking until next pass. */
974 POP_TYPE (self_type, "incorrect type for field reference");
977 if (! is_putting)
978 PUSH_TYPE (field_type);
979 break;
982 case OPCODE_new:
983 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
984 break;
986 case OPCODE_dup: wide = 1; index = 0; goto dup;
987 case OPCODE_dup_x1: wide = 1; index = 1; goto dup;
988 case OPCODE_dup_x2: wide = 1; index = 2; goto dup;
989 case OPCODE_dup2: wide = 2; index = 0; goto dup;
990 case OPCODE_dup2_x1: wide = 2; index = 1; goto dup;
991 case OPCODE_dup2_x2: wide = 2; index = 2; goto dup;
993 dup:
994 if (wide + index > stack_pointer)
995 VERIFICATION_ERROR ("stack underflow - dup* operation");
996 type_stack_dup (wide, index);
997 wide = 0;
998 break;
1000 case OPCODE_pop: index = 1; goto pop;
1001 case OPCODE_pop2: index = 2; goto pop;
1003 pop:
1004 if (stack_pointer < index)
1005 VERIFICATION_ERROR ("stack underflow");
1006 stack_pointer -= index;
1007 break;
1009 case OPCODE_swap:
1010 if (stack_pointer < 2)
1011 VERIFICATION_ERROR ("stack underflow (in swap)");
1012 else
1014 tree type1 = stack_type_map[stack_pointer - 1];
1015 tree type2 = stack_type_map[stack_pointer - 2];
1017 if (type1 == void_type_node || type2 == void_type_node)
1018 VERIFICATION_ERROR ("verifier (swap): double or long value");
1020 stack_type_map[stack_pointer - 2] = type1;
1021 stack_type_map[stack_pointer - 1] = type2;
1023 break;
1025 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
1026 case OPCODE_ldc2_w:
1027 case OPCODE_ldc_w:
1028 index = IMMEDIATE_u2; goto ldc;
1030 ldc:
1031 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
1032 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
1034 int_value = -1;
1035 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
1037 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
1038 case CONSTANT_Float: type = float_type_node; goto check_ldc;
1039 case CONSTANT_String: type = string_type_node; goto check_ldc;
1040 case CONSTANT_Long: type = long_type_node; goto check_ldc;
1041 case CONSTANT_Double: type = double_type_node; goto check_ldc;
1042 check_ldc:
1043 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
1044 break;
1045 /* ... else fall through ... */
1046 default:
1047 VERIFICATION_ERROR ("bad constant pool tag in ldc");
1049 if (type == int_type_node)
1051 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
1052 goto push_int;
1054 PUSH_TYPE (type);
1055 break;
1057 case OPCODE_invokevirtual:
1058 case OPCODE_invokespecial:
1059 case OPCODE_invokestatic:
1060 case OPCODE_invokeinterface:
1062 tree sig, method_name, method_type, self_type;
1063 int self_is_interface, tag;
1064 index = IMMEDIATE_u2;
1066 if (index <= 0 || index >= JPOOL_SIZE (current_jcf))
1067 VERIFICATION_ERROR_WITH_INDEX
1068 ("bad constant pool index %d for invoke");
1070 tag = JPOOL_TAG (current_jcf, index);
1072 if (op_code == OPCODE_invokeinterface)
1074 if (tag != CONSTANT_InterfaceMethodref)
1075 VERIFICATION_ERROR
1076 ("invokeinterface does not reference an InterfaceMethodref");
1078 else
1080 if (tag != CONSTANT_Methodref)
1081 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1084 sig = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
1086 self_type
1087 = get_class_constant (current_jcf,
1088 COMPONENT_REF_CLASS_INDEX
1089 (&current_jcf->cpool, index));
1091 if (! CLASS_LOADED_P (self_type))
1092 load_class (self_type, 1);
1094 self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
1095 method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
1096 method_type = parse_signature_string ((const unsigned char *) IDENTIFIER_POINTER (sig),
1097 IDENTIFIER_LENGTH (sig));
1099 if (TREE_CODE (method_type) != FUNCTION_TYPE)
1100 VERIFICATION_ERROR ("bad method signature");
1102 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
1103 if (pmessage != NULL)
1105 message = "invalid argument type";
1106 goto pop_type_error;
1109 /* Can't invoke <clinit>. */
1110 if (ID_CLINIT_P (method_name))
1111 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1113 /* Apart from invokespecial, can't invoke <init>. */
1114 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
1115 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1117 if (op_code != OPCODE_invokestatic)
1118 POP_TYPE (self_type,
1119 "stack type not subclass of invoked method's class");
1121 switch (op_code)
1123 case OPCODE_invokeinterface:
1125 int nargs = IMMEDIATE_u1;
1126 int notZero = IMMEDIATE_u1;
1128 if (!nargs || notZero)
1129 VERIFICATION_ERROR
1130 ("invalid argument number in invokeinterface");
1132 /* If we verify/resolve the constant pool, as we should,
1133 this test (and the one just following) are redundant. */
1134 if (! self_is_interface)
1135 VERIFICATION_ERROR
1136 ("invokeinterface calls method not in interface");
1137 break;
1139 default:
1140 if (self_is_interface)
1141 VERIFICATION_ERROR ("method in interface called");
1145 if (TREE_TYPE (method_type) != void_type_node)
1146 PUSH_TYPE (TREE_TYPE (method_type));
1147 break;
1150 case OPCODE_arraylength:
1151 /* Type checking actually made during code generation. */
1152 pop_type (ptr_type_node);
1153 PUSH_TYPE (int_type_node);
1154 break;
1156 /* Q&D verification *or* more checking done during code generation
1157 for byte/boolean/char/short, the value popped is a int coerced
1158 into the right type before being stored. */
1159 case OPCODE_iastore: type = int_type_node; goto astore;
1160 case OPCODE_lastore: type = long_type_node; goto astore;
1161 case OPCODE_fastore: type = float_type_node; goto astore;
1162 case OPCODE_dastore: type = double_type_node; goto astore;
1163 case OPCODE_aastore: type = ptr_type_node; goto astore;
1164 case OPCODE_bastore: type = int_type_node; goto astore;
1165 case OPCODE_castore: type = int_type_node; goto astore;
1166 case OPCODE_sastore: type = int_type_node; goto astore;
1168 astore:
1169 /* FIXME - need better verification here. */
1170 pop_type (type); /* new value */
1171 pop_type (int_type_node); /* index */
1172 pop_type (ptr_type_node); /* array */
1173 break;
1175 /* Q&D verification *or* more checking done during code generation
1176 for byte/boolean/char/short, the value pushed is a int. */
1177 case OPCODE_iaload: type = int_type_node; goto aload;
1178 case OPCODE_laload: type = long_type_node; goto aload;
1179 case OPCODE_faload: type = float_type_node; goto aload;
1180 case OPCODE_daload: type = double_type_node; goto aload;
1181 case OPCODE_aaload: type = ptr_type_node; goto aload;
1182 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1183 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1184 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1186 aload:
1187 pop_type (int_type_node);
1188 tmp = pop_type (ptr_type_node);
1189 if (is_array_type_p (tmp))
1190 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1191 else if (tmp != TYPE_NULL)
1192 VERIFICATION_ERROR ("array load from non-array type");
1193 PUSH_TYPE (type);
1194 break;
1196 case OPCODE_anewarray:
1197 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1198 type = promote_type (type);
1199 goto newarray;
1201 case OPCODE_newarray:
1202 index = IMMEDIATE_u1;
1203 type = decode_newarray_type (index);
1204 if (type == NULL_TREE)
1205 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1206 goto newarray;
1208 newarray:
1209 if (int_value >= 0 && prevpc >= 0)
1211 /* If the previous instruction pushed an int constant,
1212 we want to use it. */
1213 switch (byte_ops[prevpc])
1215 case OPCODE_iconst_0: case OPCODE_iconst_1:
1216 case OPCODE_iconst_2: case OPCODE_iconst_3:
1217 case OPCODE_iconst_4: case OPCODE_iconst_5:
1218 case OPCODE_bipush: case OPCODE_sipush:
1219 case OPCODE_ldc: case OPCODE_ldc_w:
1220 break;
1221 default:
1222 int_value = -1;
1225 else
1226 int_value = -1;
1228 type = build_java_array_type (type, int_value);
1229 pop_type (int_type_node);
1230 PUSH_TYPE (type);
1231 break;
1233 case OPCODE_multianewarray:
1235 int ndim, i;
1236 index = IMMEDIATE_u2;
1237 ndim = IMMEDIATE_u1;
1239 if (ndim < 1)
1240 VERIFICATION_ERROR
1241 ("number of dimension lower that 1 in multianewarray" );
1243 for (i = 0; i < ndim; i++)
1244 pop_type (int_type_node);
1246 PUSH_TYPE (get_class_constant (current_jcf, index));
1247 break;
1250 case OPCODE_aconst_null:
1251 PUSH_TYPE (ptr_type_node);
1252 break;
1254 case OPCODE_athrow:
1255 /* FIXME: athrow also empties the stack. */
1256 POP_TYPE (throwable_type_node, "missing throwable at athrow" );
1257 INVALIDATE_PC;
1258 break;
1260 case OPCODE_checkcast:
1261 POP_TYPE (object_ptr_type_node,
1262 "checkcast operand is not a pointer");
1263 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1264 PUSH_TYPE (type);
1265 break;
1267 case OPCODE_instanceof:
1268 POP_TYPE (object_ptr_type_node,
1269 "instanceof operand is not a pointer");
1270 get_class_constant (current_jcf, IMMEDIATE_u2);
1271 PUSH_TYPE (int_type_node);
1272 break;
1274 case OPCODE_tableswitch:
1276 jint low, high;
1278 POP_TYPE (int_type_node, "missing int for tableswitch");
1280 while (PC%4)
1282 if (byte_ops[PC++])
1283 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1286 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1287 low = IMMEDIATE_s4;
1288 high = IMMEDIATE_s4;
1290 if (low > high)
1291 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1293 while (low++ <= high)
1294 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1296 INVALIDATE_PC;
1297 break;
1300 case OPCODE_lookupswitch:
1302 jint npairs, last = 0, not_registered = 1;
1304 POP_TYPE (int_type_node, "missing int for lookupswitch");
1306 while (PC%4)
1308 if (byte_ops[PC++])
1309 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1312 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1313 npairs = IMMEDIATE_s4;
1315 if (npairs < 0)
1316 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1318 while (npairs--)
1320 int match = IMMEDIATE_s4;
1322 if (not_registered)
1323 not_registered = 0;
1324 else if (last >= match)
1325 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1327 last = match;
1328 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1330 INVALIDATE_PC;
1331 break;
1334 case OPCODE_monitorenter:
1335 /* fall thru */
1336 case OPCODE_monitorexit:
1337 pop_type (ptr_type_node);
1338 break;
1340 case OPCODE_goto_w:
1341 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1342 INVALIDATE_PC;
1343 break;
1345 case OPCODE_jsr:
1347 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1348 tree return_label = lookup_label (PC);
1349 PUSH_TYPE (return_address_type_node);
1350 /* The return label chain will be null if this is the first
1351 time we've seen this jsr target. */
1352 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1354 tree return_type_map;
1355 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1356 index = nlocals + DECL_MAX_STACK (current_function_decl);
1357 return_type_map = make_tree_vec (index);
1359 while (index > nlocals)
1360 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1362 while (index > 0)
1363 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1365 LABEL_RETURN_LABEL (target)
1366 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1367 LABEL_PC (LABEL_RETURN_LABEL (target)) = INVALID_PC;
1368 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1369 LABEL_IS_SUBR_START (target) = 1;
1370 LABEL_IN_SUBR (target) = 1;
1371 LABEL_SUBR_START (target) = target;
1372 LABEL_SUBR_CONTEXT (target) = current_subr;
1374 else if (! LABEL_IS_SUBR_START (target)
1375 || LABEL_SUBR_CONTEXT (target) != current_subr)
1376 VERIFICATION_ERROR ("label part of different subroutines");
1378 i = merge_type_state (target);
1379 if (i != 0)
1381 if (i < 0)
1382 VERIFICATION_ERROR ("types could not be merged at jsr");
1383 push_pending_label (target);
1385 current_subr = target;
1387 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1388 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1390 LABEL_RETURN_LABELS (target)
1391 = tree_cons (NULL_TREE, return_label,
1392 LABEL_RETURN_LABELS (target));
1395 if (LABEL_VERIFIED (target))
1397 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1398 int len = TREE_VEC_LENGTH (return_map);
1399 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1400 while (--len >= 0)
1402 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1403 type_map[len] = TREE_VEC_ELT (return_map, len);
1405 current_subr = LABEL_SUBR_CONTEXT (target);
1406 if (RETURN_MAP_ADJUSTED (return_map))
1407 PUSH_PENDING (return_label);
1410 INVALIDATE_PC;
1412 break;
1414 case OPCODE_ret:
1415 if (current_subr == NULL_TREE)
1416 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1417 else
1419 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1420 int size
1421 = DECL_MAX_LOCALS (current_function_decl) + stack_pointer;
1422 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1423 wide = 0;
1424 INVALIDATE_PC;
1425 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1426 || type_map[index] != TYPE_RETURN_ADDR)
1427 VERIFICATION_ERROR ("invalid ret index");
1429 /* The next chunk of code is similar to an inlined version of
1430 merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1431 The main differences are that LABEL_RETURN_LABEL is
1432 pre-allocated by the jsr (but we don't know the size then);
1433 and that we have to handle TYPE_UNUSED. */
1435 if (! RETURN_MAP_ADJUSTED (ret_map))
1437 /* First return from this subroutine - fix stack
1438 pointer. */
1439 TREE_VEC_LENGTH (ret_map) = size;
1440 for (index = size; --index >= 0; )
1442 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1443 TREE_VEC_ELT (ret_map, index) = type_map[index];
1445 RETURN_MAP_ADJUSTED (ret_map) = 1;
1447 else
1449 if (TREE_VEC_LENGTH (ret_map) != size)
1450 VERIFICATION_ERROR ("inconsistent stack size on ret");
1451 for (index = 0; index < size; index++)
1453 tree type = TREE_VEC_ELT (ret_map, index);
1454 if (type != TYPE_UNUSED)
1456 type = merge_types (type, type_map[index]);
1457 TREE_VEC_ELT (ret_map, index) = type;
1458 if (type == TYPE_UNKNOWN)
1460 if (index >= size - stack_pointer)
1461 VERIFICATION_ERROR
1462 ("inconsistent types on ret from jsr");
1464 else if (TYPE_IS_WIDE (type))
1465 index++;
1470 break;
1472 case OPCODE_jsr_w:
1473 case OPCODE_ret_w:
1474 default:
1475 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1476 return 0;
1479 prevpc = oldpc;
1481 /* The following test is true if we have entered or exited an exception
1482 handler range *or* we have done a store to a local variable.
1483 In either case we need to consider any exception handlers that
1484 might "follow" this instruction. */
1486 if (eh_ranges != prev_eh_ranges)
1488 int save_stack_pointer = stack_pointer;
1489 int index = DECL_MAX_LOCALS (current_function_decl);
1490 tree save_type = type_map[index];
1491 tree save_current_subr = current_subr;
1492 struct eh_range *ranges = find_handler (oldpc);
1493 stack_pointer = 1;
1495 for ( ; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1497 tree chain = ranges->handlers;
1499 /* We need to determine if the handler is part of current_subr.
1500 The are two cases: (1) The exception catch range
1501 is entirely within current_subr. In that case the handler
1502 is also part of current_subr.
1503 (2) Some of the catch range is not in current_subr.
1504 In that case, the handler is *not* part of current_subr.
1506 Figuring out which is the case is not necessarily obvious,
1507 in the presence of clever code generators (and obfuscators).
1508 We make a simplifying assumption that in case (2) we
1509 have that the current_subr is entirely within the catch range.
1510 In that case we can assume if that if a caller (the jsr) of
1511 a subroutine is within the catch range, then the handler is
1512 *not* part of the subroutine, and vice versa. */
1514 current_subr = save_current_subr;
1515 for ( ; current_subr != NULL_TREE;
1516 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1518 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1519 /* There could be multiple return_labels, but
1520 we only need to check one. */
1521 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1522 if (return_pc <= ranges->start_pc
1523 || return_pc > ranges->end_pc)
1524 break;
1527 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1529 tree handler = TREE_VALUE (chain);
1530 tree type = TREE_PURPOSE (chain);
1532 if (type == NULL_TREE) /* a finally handler */
1533 type = throwable_type_node;
1535 type_map[index] = promote_type (type);
1537 PUSH_PENDING (handler);
1540 stack_pointer = save_stack_pointer;
1541 current_subr = save_current_subr;
1542 type_map[index] = save_type;
1543 prev_eh_ranges = eh_ranges;
1547 return 1;
1549 pop_type_error:
1550 error ("verification error at PC=%d", oldpc);
1551 if (message != NULL)
1552 error ("%s", message);
1553 error ("%s", pmessage);
1554 free (pmessage);
1555 return 0;
1557 stack_overflow:
1558 message = "stack overflow";
1559 goto verify_error;
1561 bad_pc:
1562 message = "program counter out of range";
1563 goto verify_error;
1565 error_with_index:
1566 error ("verification error at PC=%d", oldpc);
1567 error (message, index);
1568 return 0;
1570 verify_error:
1571 error ("verification error at PC=%d", oldpc);
1572 error ("%s", message);
1573 return 0;