1 /* Handle verification of bytecoded methods for the GNU compiler for
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
28 #include "coretypes.h"
31 #include "java-tree.h"
33 #include "java-opcodes.h"
35 #include "java-except.h"
38 static void push_pending_label PARAMS ((tree));
39 static tree merge_types PARAMS ((tree, tree));
40 static const char *check_pending_block PARAMS ((tree));
41 static void type_stack_dup PARAMS ((int, int));
42 static int start_pc_cmp PARAMS ((const PTR, const PTR));
43 static char *pop_argument_types PARAMS ((tree));
45 extern int stack_pointer;
47 /* During verification, start of the current subroutine (jsr target). */
50 /* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
51 A pending block is one that has LABEL_CHANGED set, which means
52 it requires (re-) verification. */
55 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
58 push_pending_label (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. */
74 check_pending_block (target_label)
77 int changed = merge_type_state (target_label);
82 return "types could not be merged";
83 push_pending_label (target_label);
86 if (current_subr == NULL)
88 if (LABEL_IN_SUBR (target_label))
89 return "might transfer control into subroutine";
93 if (LABEL_IN_SUBR (target_label))
95 if (LABEL_SUBR_START (target_label) != current_subr)
96 return "transfer out of subroutine";
98 else if (! LABEL_VERIFIED (target_label))
100 LABEL_IN_SUBR (target_label) = 1;
101 LABEL_SUBR_START (target_label) = current_subr;
104 return "transfer out of subroutine";
109 /* Count the number of nested jsr calls needed to reach LABEL. */
112 subroutine_nesting (tree label)
115 while (label != NULL_TREE && LABEL_IN_SUBR (label))
117 if (! LABEL_IS_SUBR_START(label))
118 label = LABEL_SUBR_START (label);
119 label = LABEL_SUBR_CONTEXT (label);
125 /* Return the "merged" types of TYPE1 and TYPE2.
126 If either is primitive, the other must match (after promotion to int).
127 For reference types, return the common super-class.
128 Return TYPE_UNKNOWN if the types cannot be merged. */
131 merge_types (type1, type2)
136 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
137 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
139 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
143 /* ptr_type_node is only used for a null reference,
144 which is compatible with any reference type. */
145 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
147 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
150 tt1 = TREE_TYPE (type1);
151 tt2 = TREE_TYPE (type2);
153 /* If tt{1,2} haven't been properly loaded, now is a good time
155 if (!TYPE_SIZE (tt1))
158 safe_layout_class (tt1);
161 if (!TYPE_SIZE (tt2))
164 safe_layout_class (tt2);
167 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
169 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
171 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
172 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
173 tree el_type = NULL_TREE;
174 if (el_type1 == el_type2)
176 else if (TREE_CODE (el_type1) == POINTER_TYPE
177 && TREE_CODE (el_type2) == POINTER_TYPE)
178 el_type = merge_types (el_type1, el_type2);
179 if (el_type != NULL_TREE)
181 HOST_WIDE_INT len1 = java_array_type_length (tt1);
182 HOST_WIDE_INT len2 = java_array_type_length (tt2);
185 else if (el_type1 == el_type2)
187 return promote_type (build_java_array_type (el_type, len1));
190 return object_ptr_type_node;
193 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
195 /* FIXME: should see if two interfaces have a common
197 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
199 /* This is a kludge, but matches what Sun's verifier does.
200 It can be tricked, but is safe as long as type errors
201 (i.e. interface method calls) are caught at run-time. */
202 return object_ptr_type_node;
206 if (can_widen_reference_to (tt2, tt1))
209 return object_ptr_type_node;
212 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
214 if (can_widen_reference_to (tt1, tt2))
217 return object_ptr_type_node;
223 depth1 = class_depth (type1);
224 depth2 = class_depth (type2);
225 for ( ; depth1 > depth2; depth1--)
226 type1 = TYPE_BINFO_BASETYPE (type1, 0);
227 for ( ; depth2 > depth1; depth2--)
228 type2 = TYPE_BINFO_BASETYPE (type2, 0);
229 while (type1 != type2)
231 type1 = TYPE_BINFO_BASETYPE (type1, 0);
232 type2 = TYPE_BINFO_BASETYPE (type2, 0);
234 return promote_type (type1);
236 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
237 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
238 return int_type_node;
242 /* Merge the current type state with that at LABEL.
243 Return -1 the the states are incompatible (i.e. on error),
244 0 if there was no change, and 1 if there was a change. */
247 merge_type_state (label)
250 int nlocals = DECL_MAX_LOCALS (current_function_decl);
251 int cur_length = stack_pointer + nlocals;
252 tree vec = LABEL_TYPE_STATE (label);
254 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];
269 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
270 && current_subr != label)
271 return_map = LABEL_RETURN_TYPE_STATE (label);
273 return_map = NULL_TREE;
274 if (TREE_VEC_LENGTH (vec) != cur_length)
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 sub-routine. */
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))
294 TREE_VEC_ELT (vec, i) = new_type;
295 if (new_type == TYPE_UNKNOWN)
300 else if (TYPE_IS_WIDE (new_type))
307 /* Handle dup-like operations. */
310 type_stack_dup (size, offset)
315 for (index = 0; index < size + offset; index++)
317 type[index] = stack_type_map[stack_pointer - 1];
318 if (type[index] == void_type_node)
321 type[index] = stack_type_map[stack_pointer - 2];
322 if (! TYPE_IS_WIDE (type[index]))
324 if (index == size || index == size + offset)
325 /* Dup operation splits 64-bit number. */
328 pop_type (type[index]);
330 for (index = size; --index >= 0; )
332 if (type[index] != void_type_node)
333 push_type (type[index]);
336 for (index = size + offset; --index >= 0; )
338 if (type[index] != void_type_node)
339 push_type (type[index]);
343 /* This keeps track of a start PC and corresponding initial index. */
350 /* A helper that is used when sorting exception ranges. */
352 start_pc_cmp (xp, yp)
356 const struct pc_index *x = (const struct pc_index *) xp;
357 const struct pc_index *y = (const struct pc_index *) yp;
358 return x->start_pc - y->start_pc;
361 /* This causes the next iteration to ignore the next instruction
362 and look for some other unhandled instruction. */
363 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
364 #define INVALID_PC (-1)
366 #define VERIFICATION_ERROR(MESSAGE) \
367 do { message = MESSAGE; goto verify_error; } while (0)
369 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
370 do { message = MESSAGE; goto error_with_index; } while (0)
372 /* Recursive helper function to pop argument types during verifiation.
373 ARG_TYPES is the list of formal parameter types.
374 Return NULL on success and a freshly malloc'd error message on failure. */
377 pop_argument_types (arg_types)
380 if (arg_types == end_params_node)
382 if (TREE_CODE (arg_types) == TREE_LIST)
384 char *message = pop_argument_types (TREE_CHAIN (arg_types));
386 pop_type_0 (TREE_VALUE (arg_types), &message);
392 #define POP_TYPE(TYPE, MESSAGE) \
393 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
394 if (pmessage != NULL) goto pop_type_error; \
397 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
398 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
399 if (pmessage != NULL) goto pop_type_error; \
402 #define PUSH_TYPE(TYPE) \
403 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
405 #define PUSH_PENDING(LABEL) \
406 do { tree tmplab = LABEL; \
407 if ((message = check_pending_block (tmplab)) != NULL) \
408 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
411 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
413 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
416 #define BCODE byte_ops
418 /* Verify the bytecodes of the current method.
419 Return 1 on success, 0 on failure. */
421 verify_jvm_instructions (jcf, byte_ops, length)
423 const unsigned char *byte_ops;
430 int oldpc = 0; /* PC of start of instruction. */
431 int prevpc = 0; /* If >= 0, PC of previous instruction. */
432 const char *message = 0;
436 register unsigned char *p;
437 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
438 struct eh_range *eh_ranges;
439 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
440 struct pc_index *starts;
445 pending_blocks = NULL_TREE;
447 /* Handle the exception table. */
448 method_init_exceptions ();
449 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
450 eh_count = JCF_readu2 (jcf);
452 /* We read the exception handlers in order of increasing start PC.
453 To do this we first read and sort the start PCs. */
454 starts = xmalloc (eh_count * sizeof (struct pc_index));
455 for (i = 0; i < eh_count; ++i)
457 starts[i].start_pc = GET_u2 (jcf->read_ptr + 8 * i);
460 qsort (starts, eh_count, sizeof (struct pc_index), start_pc_cmp);
462 for (i = 0; i < eh_count; ++i)
464 int start_pc, end_pc, handler_pc, catch_type;
466 p = jcf->read_ptr + 8 * starts[i].index;
468 start_pc = GET_u2 (p);
469 end_pc = GET_u2 (p+2);
470 handler_pc = GET_u2 (p+4);
471 catch_type = GET_u2 (p+6);
473 if (start_pc < 0 || start_pc >= length
474 || end_pc < 0 || end_pc > length || start_pc >= end_pc
475 || handler_pc < 0 || handler_pc >= length
476 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
477 || (end_pc < length &&
478 ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START))
479 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
481 error ("bad pc in exception_table");
486 if (handler_pc >= start_pc && handler_pc < end_pc)
487 warning ("exception handler inside code that is being protected");
489 add_handler (start_pc, end_pc,
490 lookup_label (handler_pc),
491 catch_type == 0 ? NULL_TREE
492 : get_class_constant (jcf, catch_type));
494 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
498 handle_nested_ranges ();
503 if (((PC != INVALID_PC
504 && instruction_bits [PC] & BCODE_TARGET) != 0)
507 PUSH_PENDING (lookup_label (PC));
510 /* Check if there are any more pending blocks in the current
511 subroutine. Because we push pending blocks in a
512 last-in-first-out order, and because we don't push anything
513 from our caller until we are done with this subroutine or
514 anything nested in it, then we are done if the top of the
515 pending_blocks stack is not in a subroutine, or it is in our
520 if (pending_blocks == NULL_TREE
521 || (subroutine_nesting (pending_blocks)
522 < subroutine_nesting (current_subr)))
524 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
525 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
526 tmp = LABEL_RETURN_LABELS (current_subr);
528 /* FIXME: If we exit a subroutine via a throw, we might
529 have returned to an earlier caller. Obviously a
530 "ret" can only return one level, but a throw may
531 return many levels.*/
532 current_subr = LABEL_SUBR_CONTEXT (current_subr);
534 if (RETURN_MAP_ADJUSTED (ret_map))
536 /* Since we are done with this subroutine , set up
537 the (so far known) return address as pending -
538 with the merged type state. */
539 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
541 tree return_label = TREE_VALUE (tmp);
542 tree return_state = LABEL_TYPE_STATE (return_label);
543 if (return_state == NULL_TREE)
545 /* This means means we had not verified the
546 subroutine earlier, so this is the first jsr to
547 call it. In this case, the type_map of the return
548 address is just the current type_map - and that
549 is handled by the following PUSH_PENDING. */
553 /* In this case we have to do a merge. But first
554 restore the type_map for unused slots to those
555 that were in effect at the jsr. */
556 for (index = size; --index >= 0; )
558 type_map[index] = TREE_VEC_ELT (ret_map, index);
559 if (type_map[index] == TYPE_UNUSED)
561 = TREE_VEC_ELT (return_state, index);
564 PUSH_PENDING (return_label);
569 if (PC == INVALID_PC)
571 label = pending_blocks;
572 if (label == NULL_TREE)
573 break; /* We're done! */
574 pending_blocks = LABEL_PENDING_CHAIN (label);
575 LABEL_CHANGED (label) = 0;
577 if (LABEL_IN_SUBR (label))
578 current_subr = LABEL_SUBR_START (label);
580 current_subr = NULL_TREE;
582 /* Restore type_map and stack_pointer from
583 LABEL_TYPE_STATE (label), and continue
584 compiling from there. */
585 load_type_state (label);
586 PC = LABEL_PC (label);
588 else if (PC >= length)
589 VERIFICATION_ERROR ("falling through end of method");
591 /* fprintf (stderr, "** %d\n", PC); */
595 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
596 VERIFICATION_ERROR ("PC not at instruction start");
598 instruction_bits[PC] |= BCODE_VERIFIED;
600 eh_ranges = find_handler (oldpc);
602 op_code = byte_ops[PC++];
605 int is_static, is_putting;
608 case OPCODE_iconst_m1:
609 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
610 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
611 i = op_code - OPCODE_iconst_0;
614 if (byte_ops[PC] == OPCODE_newarray
615 || byte_ops[PC] == OPCODE_anewarray)
617 PUSH_TYPE (int_type_node); break;
618 case OPCODE_lconst_0: case OPCODE_lconst_1:
619 PUSH_TYPE (long_type_node); break;
620 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
621 PUSH_TYPE (float_type_node); break;
622 case OPCODE_dconst_0: case OPCODE_dconst_1:
623 PUSH_TYPE (double_type_node); break;
630 case OPCODE_iload: type = int_type_node; goto general_load;
631 case OPCODE_lload: type = long_type_node; goto general_load;
632 case OPCODE_fload: type = float_type_node; goto general_load;
633 case OPCODE_dload: type = double_type_node; goto general_load;
634 case OPCODE_aload: type = ptr_type_node; goto general_load;
636 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
639 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
640 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
641 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
642 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
643 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
644 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
645 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
646 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
647 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
648 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
649 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
650 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
651 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
652 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
653 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
654 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
655 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
656 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
657 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
658 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
661 || (index + TYPE_IS_WIDE (type)
662 >= DECL_MAX_LOCALS (current_function_decl)))
663 VERIFICATION_ERROR_WITH_INDEX
664 ("invalid local variable index %d in load");
665 tmp = type_map[index];
666 if (tmp == TYPE_UNKNOWN)
667 VERIFICATION_ERROR_WITH_INDEX
668 ("loading local variable %d which has unknown type");
669 else if (tmp == TYPE_SECOND
670 || (TYPE_IS_WIDE (type)
671 && type_map[index+1] != void_type_node)
672 || (type == ptr_type_node
673 ? TREE_CODE (tmp) != POINTER_TYPE
674 : type == int_type_node
675 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
677 VERIFICATION_ERROR_WITH_INDEX
678 ("loading local variable %d which has invalid type");
681 case OPCODE_istore: type = int_type_node; goto general_store;
682 case OPCODE_lstore: type = long_type_node; goto general_store;
683 case OPCODE_fstore: type = float_type_node; goto general_store;
684 case OPCODE_dstore: type = double_type_node; goto general_store;
685 case OPCODE_astore: type = object_ptr_type_node; goto general_store;
687 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
690 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
691 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
692 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
693 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
694 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
695 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
696 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
697 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
698 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
699 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
700 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
701 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
702 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
703 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
704 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
705 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
706 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
707 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
708 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
709 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
712 || (index + TYPE_IS_WIDE (type)
713 >= DECL_MAX_LOCALS (current_function_decl)))
715 VERIFICATION_ERROR_WITH_INDEX
716 ("invalid local variable index %d in store");
719 POP_TYPE_CONV (type, type, NULL);
720 type_map[index] = type;
722 /* If local variable changed, we need to reconsider eh handlers. */
723 prev_eh_ranges = NULL_EH_RANGE;
725 /* Allocate decl and rtx for this variable now, so if we're not
726 optmizing, we get a temporary that survives the whole method. */
727 find_local_variable (index, type, oldpc);
729 if (TYPE_IS_WIDE (type))
730 type_map[index+1] = TYPE_SECOND;
731 /* ... fall through to note_used ... */
733 /* For store or load, note that local variable INDEX is used.
734 This is needed to verify try-finally sub-routines. */
737 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
738 tree subr_vec = LABEL_TYPE_STATE (current_subr);
739 int len = 1 + TYPE_IS_WIDE (type);
742 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
743 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
758 type = int_type_node; goto binop;
763 type = int_type_node; goto unop;
772 type = long_type_node; goto binop;
774 type = long_type_node; goto unop;
775 case OPCODE_fadd: case OPCODE_fsub:
776 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
777 type = float_type_node; goto binop;
779 type = float_type_node; goto unop;
780 case OPCODE_dadd: case OPCODE_dsub:
781 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
782 type = double_type_node; goto binop;
784 type = double_type_node; goto unop;
797 pop_type (int_type_node);
798 pop_type (long_type_node);
799 PUSH_TYPE (long_type_node);
802 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
805 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
806 VERIFICATION_ERROR ("invalid local variable index in iinc");
807 tmp = type_map[index];
809 || ! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
810 VERIFICATION_ERROR ("invalid local variable type in iinc");
813 pop_type (int_type_node); PUSH_TYPE (long_type_node); break;
815 pop_type (int_type_node); PUSH_TYPE (float_type_node); break;
817 pop_type (int_type_node); PUSH_TYPE (double_type_node); break;
819 pop_type (long_type_node); PUSH_TYPE (int_type_node); break;
821 pop_type (long_type_node); PUSH_TYPE (float_type_node); break;
823 pop_type (long_type_node); PUSH_TYPE (double_type_node); break;
825 pop_type (float_type_node); PUSH_TYPE (int_type_node); break;
827 pop_type (float_type_node); PUSH_TYPE (long_type_node); break;
829 pop_type (float_type_node); PUSH_TYPE (double_type_node); break;
831 pop_type (double_type_node); PUSH_TYPE (int_type_node); break;
833 pop_type (double_type_node); PUSH_TYPE (long_type_node); break;
835 pop_type (double_type_node); PUSH_TYPE (float_type_node); break;
837 type = long_type_node; goto compare;
840 type = float_type_node; goto compare;
843 type = double_type_node; goto compare;
845 pop_type (type); pop_type (type);
846 PUSH_TYPE (int_type_node); break;
853 pop_type (int_type_node); goto cond;
855 case OPCODE_ifnonnull:
856 pop_type (ptr_type_node ); goto cond;
857 case OPCODE_if_icmpeq:
858 case OPCODE_if_icmpne:
859 case OPCODE_if_icmplt:
860 case OPCODE_if_icmpge:
861 case OPCODE_if_icmpgt:
862 case OPCODE_if_icmple:
863 pop_type (int_type_node); pop_type (int_type_node); goto cond;
864 case OPCODE_if_acmpeq:
865 case OPCODE_if_acmpne:
866 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
869 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
872 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
876 switch (byte_ops[PC])
878 case OPCODE_iload: case OPCODE_lload:
879 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
880 case OPCODE_istore: case OPCODE_lstore:
881 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
887 VERIFICATION_ERROR ("invalid use of wide instruction");
890 case OPCODE_return: type = void_type_node; goto ret;
892 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
893 || TREE_CODE (return_type) == CHAR_TYPE
894 || TREE_CODE (return_type) == INTEGER_TYPE)
895 && TYPE_PRECISION (return_type) <= 32)
900 case OPCODE_lreturn: type = long_type_node; goto ret;
901 case OPCODE_freturn: type = float_type_node; goto ret;
902 case OPCODE_dreturn: type = double_type_node; goto ret;
904 if (TREE_CODE (return_type) == POINTER_TYPE)
910 if (type != return_type)
911 VERIFICATION_ERROR ("incorrect ?return opcode");
912 if (type != void_type_node)
913 POP_TYPE(type, "return value has wrong type");
916 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
917 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
918 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
919 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
922 tree field_signature, field_type;
923 index = IMMEDIATE_u2;
924 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
925 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
926 if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref)
928 ("field instruction does not reference a Fieldref");
929 field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index);
930 field_type = get_type_from_signature (field_signature);
932 POP_TYPE (field_type, "incorrect type for field");
935 int clindex = COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
937 tree self_type = get_class_constant (current_jcf, clindex);
938 /* Defer actual checking until next pass. */
939 POP_TYPE(self_type, "incorrect type for field reference");
942 PUSH_TYPE (field_type);
946 PUSH_TYPE (get_class_constant (jcf, IMMEDIATE_u2));
948 case OPCODE_dup: wide = 1; index = 0; goto dup;
949 case OPCODE_dup_x1: wide = 1; index = 1; goto dup;
950 case OPCODE_dup_x2: wide = 1; index = 2; goto dup;
951 case OPCODE_dup2: wide = 2; index = 0; goto dup;
952 case OPCODE_dup2_x1: wide = 2; index = 1; goto dup;
953 case OPCODE_dup2_x2: wide = 2; index = 2; goto dup;
955 if (wide + index > stack_pointer)
956 VERIFICATION_ERROR ("stack underflow - dup* operation");
957 type_stack_dup (wide, index);
960 case OPCODE_pop: index = 1; goto pop;
961 case OPCODE_pop2: index = 2; goto pop;
963 if (stack_pointer < index)
964 VERIFICATION_ERROR ("stack underflow");
965 stack_pointer -= index;
968 if (stack_pointer < 2)
969 VERIFICATION_ERROR ("stack underflow (in swap)");
972 tree type1 = stack_type_map[stack_pointer - 1];
973 tree type2 = stack_type_map[stack_pointer - 2];
974 if (type1 == void_type_node || type2 == void_type_node)
975 VERIFICATION_ERROR ("verifier (swap): double or long value");
976 stack_type_map[stack_pointer - 2] = type1;
977 stack_type_map[stack_pointer - 1] = type2;
980 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
983 index = IMMEDIATE_u2; goto ldc;
985 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
986 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
988 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
990 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
991 case CONSTANT_Float: type = float_type_node; goto check_ldc;
992 case CONSTANT_String: type = string_type_node; goto check_ldc;
993 case CONSTANT_Long: type = long_type_node; goto check_ldc;
994 case CONSTANT_Double: type = double_type_node; goto check_ldc;
996 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
998 /* ... else fall through ... */
1000 VERIFICATION_ERROR ("bad constant pool tag in ldc");
1002 if (type == int_type_node)
1004 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
1010 case OPCODE_invokevirtual:
1011 case OPCODE_invokespecial:
1012 case OPCODE_invokestatic:
1013 case OPCODE_invokeinterface:
1015 tree sig, method_name, method_type, self_type;
1016 int self_is_interface, tag;
1017 index = IMMEDIATE_u2;
1018 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
1019 VERIFICATION_ERROR_WITH_INDEX
1020 ("bad constant pool index %d for invoke");
1021 tag = JPOOL_TAG (current_jcf, index);
1022 if (op_code == OPCODE_invokeinterface)
1024 if (tag != CONSTANT_InterfaceMethodref)
1026 ("invokeinterface does not reference an InterfaceMethodref");
1030 if (tag != CONSTANT_Methodref)
1031 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1033 sig = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index);
1034 self_type = get_class_constant
1035 (current_jcf, COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
1037 if (! CLASS_LOADED_P (self_type))
1038 load_class (self_type, 1);
1039 self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
1040 method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, index);
1041 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
1042 IDENTIFIER_LENGTH (sig));
1043 if (TREE_CODE (method_type) != FUNCTION_TYPE)
1044 VERIFICATION_ERROR ("bad method signature");
1045 pmessage = pop_argument_types (TYPE_ARG_TYPES (method_type));
1046 if (pmessage != NULL)
1048 message = "invalid argument type";
1049 goto pop_type_error;
1052 /* Can't invoke <clinit> */
1053 if (ID_CLINIT_P (method_name))
1054 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1055 /* Apart invokespecial, can't invoke <init> */
1056 if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
1057 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1059 if (op_code != OPCODE_invokestatic)
1060 POP_TYPE (self_type,
1061 "stack type not subclass of invoked method's class");
1065 case OPCODE_invokeinterface:
1067 int nargs = IMMEDIATE_u1;
1068 int notZero = IMMEDIATE_u1;
1070 if (!nargs || notZero)
1072 ("invalid argument number in invokeinterface");
1073 /* If we verify/resolve the constant pool, as we should,
1074 this test (and the one just following) are redundant. */
1075 if (! self_is_interface)
1076 VERIFICATION_ERROR ("invokeinterface calls method not in interface");
1079 if (self_is_interface)
1080 VERIFICATION_ERROR ("method in interface called");
1084 if (TREE_TYPE (method_type) != void_type_node)
1085 PUSH_TYPE (TREE_TYPE (method_type));
1089 case OPCODE_arraylength:
1090 /* Type checking actually made during code generation */
1091 pop_type( ptr_type_node );
1092 PUSH_TYPE( int_type_node );
1095 /* Q&D verification *or* more checking done during code generation
1096 for byte/boolean/char/short, the value popped is a int coerced
1097 into the right type before being stored. */
1098 case OPCODE_iastore: type = int_type_node; goto astore;
1099 case OPCODE_lastore: type = long_type_node; goto astore;
1100 case OPCODE_fastore: type = float_type_node; goto astore;
1101 case OPCODE_dastore: type = double_type_node; goto astore;
1102 case OPCODE_aastore: type = ptr_type_node; goto astore;
1103 case OPCODE_bastore: type = int_type_node; goto astore;
1104 case OPCODE_castore: type = int_type_node; goto astore;
1105 case OPCODE_sastore: type = int_type_node; goto astore;
1107 /* FIXME - need better verification here */
1108 pop_type (type); /* new value */
1109 pop_type (int_type_node); /* index */
1110 pop_type (ptr_type_node); /* array */
1113 /* Q&D verification *or* more checking done during code generation
1114 for byte/boolean/char/short, the value pushed is a int. */
1115 case OPCODE_iaload: type = int_type_node; goto aload;
1116 case OPCODE_laload: type = long_type_node; goto aload;
1117 case OPCODE_faload: type = float_type_node; goto aload;
1118 case OPCODE_daload: type = double_type_node; goto aload;
1119 case OPCODE_aaload: type = ptr_type_node; goto aload;
1120 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
1121 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
1122 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
1124 pop_type (int_type_node);
1125 tmp = pop_type (ptr_type_node);
1126 if (is_array_type_p (tmp))
1127 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
1128 else if (tmp != TYPE_NULL)
1129 VERIFICATION_ERROR ("array load from non-array type");
1133 case OPCODE_anewarray:
1134 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1135 type = promote_type (type);
1138 case OPCODE_newarray:
1139 index = IMMEDIATE_u1;
1140 type = decode_newarray_type (index);
1141 if (type == NULL_TREE)
1142 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1146 if (int_value >= 0 && prevpc >= 0)
1148 /* If previous instruction pushed int constant,
1149 we want to use it. */
1150 switch (byte_ops[prevpc])
1152 case OPCODE_iconst_0: case OPCODE_iconst_1:
1153 case OPCODE_iconst_2: case OPCODE_iconst_3:
1154 case OPCODE_iconst_4: case OPCODE_iconst_5:
1155 case OPCODE_bipush: case OPCODE_sipush:
1156 case OPCODE_ldc: case OPCODE_ldc_w:
1164 type = build_java_array_type (type, int_value);
1165 pop_type (int_type_node);
1169 case OPCODE_multianewarray:
1172 index = IMMEDIATE_u2;
1173 ndim = IMMEDIATE_u1;
1176 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
1178 for( i = 0; i < ndim; i++ )
1179 pop_type (int_type_node);
1180 PUSH_TYPE (get_class_constant (current_jcf, index));
1184 case OPCODE_aconst_null:
1185 PUSH_TYPE (ptr_type_node);
1189 /* FIXME: athrow also empties the stack. */
1190 POP_TYPE (throwable_type_node, "missing throwable at athrow" );
1194 case OPCODE_checkcast:
1195 POP_TYPE (object_ptr_type_node,
1196 "checkcast operand is not a pointer");
1197 type = get_class_constant (current_jcf, IMMEDIATE_u2);
1200 case OPCODE_instanceof:
1201 POP_TYPE (object_ptr_type_node,
1202 "instanceof operand is not a pointer");
1203 get_class_constant (current_jcf, IMMEDIATE_u2);
1204 PUSH_TYPE (int_type_node);
1207 case OPCODE_tableswitch:
1211 POP_TYPE (int_type_node, "missing int for tableswitch");
1215 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1217 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1219 high = IMMEDIATE_s4;
1222 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1224 while (low++ <= high)
1225 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1230 case OPCODE_lookupswitch:
1232 jint npairs, last = 0, not_registered = 1;
1234 POP_TYPE (int_type_node, "missing int for lookupswitch");
1238 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1241 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1242 npairs = IMMEDIATE_s4;
1245 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1249 int match = IMMEDIATE_s4;
1252 else if (last >= match)
1253 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1256 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1262 case OPCODE_monitorenter:
1264 case OPCODE_monitorexit:
1265 pop_type (ptr_type_node);
1269 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1275 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1276 tree return_label = lookup_label (PC);
1277 PUSH_TYPE (return_address_type_node);
1278 /* The return label chain will be null if this is the first
1279 time we've seen this jsr target. */
1280 if (LABEL_RETURN_LABEL (target) == NULL_TREE)
1282 tree return_type_map;
1283 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1284 index = nlocals + DECL_MAX_STACK (current_function_decl);
1285 return_type_map = make_tree_vec (index);
1286 while (index > nlocals)
1287 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1289 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
1290 LABEL_RETURN_LABEL (target)
1291 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1292 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
1293 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1294 LABEL_IS_SUBR_START (target) = 1;
1295 LABEL_IN_SUBR (target) = 1;
1296 LABEL_SUBR_START (target) = target;
1297 LABEL_SUBR_CONTEXT (target) = current_subr;
1299 else if (! LABEL_IS_SUBR_START (target)
1300 || LABEL_SUBR_CONTEXT (target) != current_subr)
1301 VERIFICATION_ERROR ("label part of different subroutines");
1303 i = merge_type_state (target);
1307 VERIFICATION_ERROR ("types could not be merged at jsr");
1308 push_pending_label (target);
1310 current_subr = target;
1312 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1313 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1315 LABEL_RETURN_LABELS (target)
1316 = tree_cons (NULL_TREE, return_label,
1317 LABEL_RETURN_LABELS (target));
1320 if (LABEL_VERIFIED (target))
1322 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1323 int len = TREE_VEC_LENGTH (return_map);
1324 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1327 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1328 type_map[len] = TREE_VEC_ELT (return_map, len);
1330 current_subr = LABEL_SUBR_CONTEXT (target);
1331 if (RETURN_MAP_ADJUSTED (return_map))
1332 PUSH_PENDING (return_label);
1339 if (current_subr == NULL)
1340 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1343 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1344 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
1345 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1348 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1349 || type_map[index] != TYPE_RETURN_ADDR)
1350 VERIFICATION_ERROR ("invalid ret index");
1352 /* The next chunk of code is similar to an inlined version of
1353 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1354 * The main differences are that LABEL_RETURN_LABEL is
1355 * pre-allocated by the jsr (but we don't know the size then);
1356 * and that we have to handle TYPE_UNUSED. */
1358 if (! RETURN_MAP_ADJUSTED (ret_map))
1359 { /* First return from this subroutine - fix stack pointer. */
1360 TREE_VEC_LENGTH (ret_map) = size;
1361 for (index = size; --index >= 0; )
1363 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1364 TREE_VEC_ELT (ret_map, index) = type_map[index];
1366 RETURN_MAP_ADJUSTED (ret_map) = 1;
1370 if (TREE_VEC_LENGTH (ret_map) != size)
1371 VERIFICATION_ERROR ("inconsistent stack size on ret");
1372 for (index = 0; index < size; index++)
1374 tree type = TREE_VEC_ELT (ret_map, index);
1375 if (type != TYPE_UNUSED)
1377 type = merge_types (type, type_map [index]);
1378 TREE_VEC_ELT (ret_map, index) = type;
1379 if (type == TYPE_UNKNOWN)
1381 if (index >= size - stack_pointer)
1383 ("inconsistent types on ret from jsr");
1385 else if (TYPE_IS_WIDE (type))
1397 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1403 /* The following test is true if we have entered or exited an exception
1404 handler range *or* we have done a store to a local variable.
1405 In either case we need to consider any exception handlers that
1406 might "follow" this instruction. */
1408 if (eh_ranges != prev_eh_ranges)
1410 int save_stack_pointer = stack_pointer;
1411 int index = DECL_MAX_LOCALS (current_function_decl);
1412 tree save_type = type_map[index];
1413 tree save_current_subr = current_subr;
1414 struct eh_range *ranges = find_handler (oldpc);
1416 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1418 tree chain = ranges->handlers;
1420 /* We need to determine if the handler is part of current_subr.
1421 The are two cases: (1) The exception catch range
1422 is entirely within current_subr. In that case the handler
1423 is also part of current_subr.
1424 (2) Some of the catch range is not in current_subr.
1425 In that case, the handler is *not* part of current_subr.
1427 Figuring out which is the case is not necessarily obvious,
1428 in the presence of clever code generators (and obfuscators).
1429 We make a simplifying assumption that in case (2) we
1430 have that the current_subr is entirely within the catch range.
1431 In that case we can assume if that if a caller (the jsr) of
1432 a subroutine is within the catch range, then the handler is
1433 *not* part of the subroutine, and vice versa. */
1435 current_subr = save_current_subr;
1436 for ( ; current_subr != NULL_TREE;
1437 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1439 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1440 /* There could be multiple return_labels, but
1441 we only need to check one. */
1442 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1443 if (return_pc <= ranges->start_pc
1444 || return_pc > ranges->end_pc)
1448 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1450 tree handler = TREE_VALUE (chain);
1451 tree type = TREE_PURPOSE (chain);
1452 if (type == NULL_TREE) /* a finally handler */
1453 type = throwable_type_node;
1454 type_map[index] = promote_type (type);
1456 PUSH_PENDING (handler);
1459 stack_pointer = save_stack_pointer;
1460 current_subr = save_current_subr;
1461 type_map[index] = save_type;
1462 prev_eh_ranges = eh_ranges;
1467 error ("verification error at PC=%d", oldpc);
1468 if (message != NULL)
1469 error ("%s", message);
1470 error ("%s", pmessage);
1474 message = "stack overflow";
1477 message = "program counter out of range";
1480 error ("verification error at PC=%d", oldpc);
1481 error (message, index);
1484 error ("verification error at PC=%d", oldpc);
1485 error ("%s", message);