1 /* Handle verification of bytecoded methods for the GNU compiler for
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)
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. */
29 #include "coretypes.h"
32 #include "java-tree.h"
34 #include "java-opcodes.h"
36 #include "java-except.h"
39 static void push_pending_label
PARAMS ((tree
));
40 static tree merge_types
PARAMS ((tree
, tree
));
41 static const char *check_pending_block
PARAMS ((tree
));
42 static void type_stack_dup
PARAMS ((int, int));
43 static int start_pc_cmp
PARAMS ((const PTR
, const PTR
));
44 static char *pop_argument_types
PARAMS ((tree
));
46 extern int stack_pointer
;
48 /* During verification, start of the current subroutine (jsr target). */
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. */
56 /* Append TARGET_LABEL to the pending_block stack unless already in it. */
59 push_pending_label (target_label
)
62 if (! LABEL_CHANGED (target_label
))
64 LABEL_PENDING_CHAIN (target_label
) = pending_blocks
;
65 pending_blocks
= target_label
;
66 LABEL_CHANGED (target_label
) = 1;
70 /* Note that TARGET_LABEL is a possible successor instruction.
71 Merge the type state etc.
72 Return NULL on success, or an error message on failure. */
75 check_pending_block (target_label
)
78 int changed
= merge_type_state (target_label
);
83 return "types could not be merged";
84 push_pending_label (target_label
);
87 if (current_subr
== NULL
)
89 if (LABEL_IN_SUBR (target_label
))
90 return "might transfer control into subroutine";
94 if (LABEL_IN_SUBR (target_label
))
96 if (LABEL_SUBR_START (target_label
) != current_subr
)
97 return "transfer out of subroutine";
99 else if (! LABEL_VERIFIED (target_label
))
101 LABEL_IN_SUBR (target_label
) = 1;
102 LABEL_SUBR_START (target_label
) = current_subr
;
105 return "transfer out of subroutine";
110 /* Count the number of nested jsr calls needed to reach LABEL. */
113 subroutine_nesting (tree label
)
116 while (label
!= NULL_TREE
&& LABEL_IN_SUBR (label
))
118 if (! LABEL_IS_SUBR_START(label
))
119 label
= LABEL_SUBR_START (label
);
120 label
= LABEL_SUBR_CONTEXT (label
);
126 /* Return the "merged" types of TYPE1 and TYPE2.
127 If either is primitive, the other must match (after promotion to int).
128 For reference types, return the common super-class.
129 Return TYPE_UNKNOWN if the types cannot be merged. */
132 merge_types (type1
, type2
)
137 if (type1
== TYPE_UNKNOWN
|| type2
== TYPE_UNKNOWN
138 || type1
== TYPE_RETURN_ADDR
|| type2
== TYPE_RETURN_ADDR
)
140 if (TREE_CODE (type1
) == POINTER_TYPE
&& TREE_CODE (type2
) == POINTER_TYPE
)
144 /* ptr_type_node is only used for a null reference,
145 which is compatible with any reference type. */
146 if (type1
== ptr_type_node
|| type2
== object_ptr_type_node
)
148 if (type2
== ptr_type_node
|| type1
== object_ptr_type_node
)
151 tt1
= TREE_TYPE (type1
);
152 tt2
= TREE_TYPE (type2
);
154 /* If tt{1,2} haven't been properly loaded, now is a good time
156 if (!TYPE_SIZE (tt1
))
159 safe_layout_class (tt1
);
162 if (!TYPE_SIZE (tt2
))
165 safe_layout_class (tt2
);
168 if (TYPE_ARRAY_P (tt1
) || TYPE_ARRAY_P (tt2
))
170 if (TYPE_ARRAY_P (tt1
) == TYPE_ARRAY_P (tt2
))
172 tree el_type1
= TYPE_ARRAY_ELEMENT (tt1
);
173 tree el_type2
= TYPE_ARRAY_ELEMENT (tt2
);
174 tree el_type
= NULL_TREE
;
175 if (el_type1
== el_type2
)
177 else if (TREE_CODE (el_type1
) == POINTER_TYPE
178 && TREE_CODE (el_type2
) == POINTER_TYPE
)
179 el_type
= merge_types (el_type1
, el_type2
);
180 if (el_type
!= NULL_TREE
)
182 HOST_WIDE_INT len1
= java_array_type_length (tt1
);
183 HOST_WIDE_INT len2
= java_array_type_length (tt2
);
186 else if (el_type1
== el_type2
)
188 return promote_type (build_java_array_type (el_type
, len1
));
191 return object_ptr_type_node
;
194 if (CLASS_INTERFACE (TYPE_NAME (tt1
)))
196 /* FIXME: should see if two interfaces have a common
198 if (CLASS_INTERFACE (TYPE_NAME (tt2
)))
200 /* This is a kludge, but matches what Sun's verifier does.
201 It can be tricked, but is safe as long as type errors
202 (i.e. interface method calls) are caught at run-time. */
203 return object_ptr_type_node
;
207 if (can_widen_reference_to (tt2
, tt1
))
210 return object_ptr_type_node
;
213 else if (CLASS_INTERFACE (TYPE_NAME (tt2
)))
215 if (can_widen_reference_to (tt1
, tt2
))
218 return object_ptr_type_node
;
224 depth1
= class_depth (type1
);
225 depth2
= class_depth (type2
);
226 for ( ; depth1
> depth2
; depth1
--)
227 type1
= TYPE_BINFO_BASETYPE (type1
, 0);
228 for ( ; depth2
> depth1
; depth2
--)
229 type2
= TYPE_BINFO_BASETYPE (type2
, 0);
230 while (type1
!= type2
)
232 type1
= TYPE_BINFO_BASETYPE (type1
, 0);
233 type2
= TYPE_BINFO_BASETYPE (type2
, 0);
235 return promote_type (type1
);
237 if (INTEGRAL_TYPE_P (type1
) && INTEGRAL_TYPE_P (type2
)
238 && TYPE_PRECISION (type1
) <= 32 && TYPE_PRECISION (type2
) <= 32)
239 return int_type_node
;
243 /* Merge the current type state with that at LABEL.
244 Return -1 the the states are incompatible (i.e. on error),
245 0 if there was no change, and 1 if there was a change. */
248 merge_type_state (label
)
251 int nlocals
= DECL_MAX_LOCALS (current_function_decl
);
252 int cur_length
= stack_pointer
+ nlocals
;
253 tree vec
= LABEL_TYPE_STATE (label
);
255 if (vec
== NULL_TREE
)
259 vec
= make_tree_vec (cur_length
);
260 LABEL_TYPE_STATE (label
) = vec
;
262 while (--cur_length
>= 0)
263 TREE_VEC_ELT (vec
, cur_length
) = type_map
[cur_length
];
270 if (LABEL_IS_SUBR_START (label
) && LABEL_VERIFIED (label
)
271 && current_subr
!= label
)
272 return_map
= LABEL_RETURN_TYPE_STATE (label
);
274 return_map
= NULL_TREE
;
275 if (TREE_VEC_LENGTH (vec
) != cur_length
)
279 for (i
= 0; i
< cur_length
; i
++)
281 tree old_type
= TREE_VEC_ELT (vec
, i
);
282 tree new_type
= merge_types (old_type
, type_map
[i
]);
283 if (TREE_VEC_ELT (vec
, i
) != new_type
)
285 /* If there has been a change, note that since we must re-verify.
286 However, if the label is the start of a subroutine,
287 we don't care about local variables that are neither
288 set nor used in the sub-routine. */
289 if (return_map
== NULL_TREE
|| i
>= nlocals
290 || TREE_VEC_ELT (return_map
, i
) != TYPE_UNUSED
291 || (TYPE_IS_WIDE (new_type
)
292 && TREE_VEC_ELT (return_map
, i
+1) != TYPE_UNUSED
))
295 TREE_VEC_ELT (vec
, i
) = new_type
;
296 if (new_type
== TYPE_UNKNOWN
)
301 else if (TYPE_IS_WIDE (new_type
))
308 /* Handle dup-like operations. */
311 type_stack_dup (size
, offset
)
316 for (index
= 0; index
< size
+ offset
; index
++)
318 type
[index
] = stack_type_map
[stack_pointer
- 1];
319 if (type
[index
] == void_type_node
)
322 type
[index
] = stack_type_map
[stack_pointer
- 2];
323 if (! TYPE_IS_WIDE (type
[index
]))
325 if (index
== size
|| index
== size
+ offset
)
326 /* Dup operation splits 64-bit number. */
329 pop_type (type
[index
]);
331 for (index
= size
; --index
>= 0; )
333 if (type
[index
] != void_type_node
)
334 push_type (type
[index
]);
337 for (index
= size
+ offset
; --index
>= 0; )
339 if (type
[index
] != void_type_node
)
340 push_type (type
[index
]);
344 /* This keeps track of a start PC and corresponding initial index. */
351 /* A helper that is used when sorting exception ranges. */
353 start_pc_cmp (xp
, yp
)
357 const struct pc_index
*x
= (const struct pc_index
*) xp
;
358 const struct pc_index
*y
= (const struct pc_index
*) yp
;
359 return x
->start_pc
- y
->start_pc
;
362 /* This causes the next iteration to ignore the next instruction
363 and look for some other unhandled instruction. */
364 #define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
365 #define INVALID_PC (-1)
367 #define VERIFICATION_ERROR(MESSAGE) \
368 do { message = MESSAGE; goto verify_error; } while (0)
370 #define VERIFICATION_ERROR_WITH_INDEX(MESSAGE) \
371 do { message = MESSAGE; goto error_with_index; } while (0)
373 /* Recursive helper function to pop argument types during verifiation.
374 ARG_TYPES is the list of formal parameter types.
375 Return NULL on success and a freshly malloc'd error message on failure. */
378 pop_argument_types (arg_types
)
381 if (arg_types
== end_params_node
)
383 if (TREE_CODE (arg_types
) == TREE_LIST
)
385 char *message
= pop_argument_types (TREE_CHAIN (arg_types
));
387 pop_type_0 (TREE_VALUE (arg_types
), &message
);
393 #define POP_TYPE(TYPE, MESSAGE) \
394 do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
395 if (pmessage != NULL) goto pop_type_error; \
398 #define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
399 do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
400 if (pmessage != NULL) goto pop_type_error; \
403 #define PUSH_TYPE(TYPE) \
404 do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
406 #define PUSH_PENDING(LABEL) \
407 do { tree tmplab = LABEL; \
408 if ((message = check_pending_block (tmplab)) != NULL) \
409 { oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
412 #define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
414 #define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? (abort (), 0) : 1)
417 #define BCODE byte_ops
419 /* Verify the bytecodes of the current method.
420 Return 1 on success, 0 on failure. */
422 verify_jvm_instructions (jcf
, byte_ops
, length
)
424 const unsigned char *byte_ops
;
431 int oldpc
= 0; /* PC of start of instruction. */
432 int prevpc
= 0; /* If >= 0, PC of previous instruction. */
433 const char *message
= 0;
437 register unsigned char *p
;
438 struct eh_range
*prev_eh_ranges
= NULL_EH_RANGE
;
439 struct eh_range
*eh_ranges
;
440 tree return_type
= TREE_TYPE (TREE_TYPE (current_function_decl
));
441 struct pc_index
*starts
;
446 pending_blocks
= NULL_TREE
;
448 /* Handle the exception table. */
449 method_init_exceptions ();
450 JCF_SEEK (jcf
, DECL_CODE_OFFSET (current_function_decl
) + length
);
451 eh_count
= JCF_readu2 (jcf
);
453 /* We read the exception handlers in order of increasing start PC.
454 To do this we first read and sort the start PCs. */
455 starts
= xmalloc (eh_count
* sizeof (struct pc_index
));
456 for (i
= 0; i
< eh_count
; ++i
)
458 starts
[i
].start_pc
= GET_u2 (jcf
->read_ptr
+ 8 * i
);
461 qsort (starts
, eh_count
, sizeof (struct pc_index
), start_pc_cmp
);
463 for (i
= 0; i
< eh_count
; ++i
)
465 int start_pc
, end_pc
, handler_pc
, catch_type
;
467 p
= jcf
->read_ptr
+ 8 * starts
[i
].index
;
469 start_pc
= GET_u2 (p
);
470 end_pc
= GET_u2 (p
+2);
471 handler_pc
= GET_u2 (p
+4);
472 catch_type
= GET_u2 (p
+6);
474 if (start_pc
< 0 || start_pc
>= length
475 || end_pc
< 0 || end_pc
> length
|| start_pc
>= end_pc
476 || handler_pc
< 0 || handler_pc
>= length
477 || ! (instruction_bits
[start_pc
] & BCODE_INSTRUCTION_START
)
478 || (end_pc
< length
&&
479 ! (instruction_bits
[end_pc
] & BCODE_INSTRUCTION_START
))
480 || ! (instruction_bits
[handler_pc
] & BCODE_INSTRUCTION_START
))
482 error ("bad pc in exception_table");
487 if (handler_pc
>= start_pc
&& handler_pc
< end_pc
)
488 warning ("exception handler inside code that is being protected");
490 add_handler (start_pc
, end_pc
,
491 lookup_label (handler_pc
),
492 catch_type
== 0 ? NULL_TREE
493 : get_class_constant (jcf
, catch_type
));
495 instruction_bits
[handler_pc
] |= BCODE_EXCEPTION_TARGET
;
499 handle_nested_ranges ();
504 if (((PC
!= INVALID_PC
505 && instruction_bits
[PC
] & BCODE_TARGET
) != 0)
508 PUSH_PENDING (lookup_label (PC
));
511 /* Check if there are any more pending blocks in the current
512 subroutine. Because we push pending blocks in a
513 last-in-first-out order, and because we don't push anything
514 from our caller until we are done with this subroutine or
515 anything nested in it, then we are done if the top of the
516 pending_blocks stack is not in a subroutine, or it is in our
521 if (pending_blocks
== NULL_TREE
522 || (subroutine_nesting (pending_blocks
)
523 < subroutine_nesting (current_subr
)))
525 int size
= DECL_MAX_LOCALS(current_function_decl
)+stack_pointer
;
526 tree ret_map
= LABEL_RETURN_TYPE_STATE (current_subr
);
527 tmp
= LABEL_RETURN_LABELS (current_subr
);
529 /* FIXME: If we exit a subroutine via a throw, we might
530 have returned to an earlier caller. Obviously a
531 "ret" can only return one level, but a throw may
532 return many levels.*/
533 current_subr
= LABEL_SUBR_CONTEXT (current_subr
);
535 if (RETURN_MAP_ADJUSTED (ret_map
))
537 /* Since we are done with this subroutine , set up
538 the (so far known) return address as pending -
539 with the merged type state. */
540 for ( ; tmp
!= NULL_TREE
; tmp
= TREE_CHAIN (tmp
))
542 tree return_label
= TREE_VALUE (tmp
);
543 tree return_state
= LABEL_TYPE_STATE (return_label
);
544 if (return_state
== NULL_TREE
)
546 /* This means means we had not verified the
547 subroutine earlier, so this is the first jsr to
548 call it. In this case, the type_map of the return
549 address is just the current type_map - and that
550 is handled by the following PUSH_PENDING. */
554 /* In this case we have to do a merge. But first
555 restore the type_map for unused slots to those
556 that were in effect at the jsr. */
557 for (index
= size
; --index
>= 0; )
559 type_map
[index
] = TREE_VEC_ELT (ret_map
, index
);
560 if (type_map
[index
] == TYPE_UNUSED
)
562 = TREE_VEC_ELT (return_state
, index
);
565 PUSH_PENDING (return_label
);
570 if (PC
== INVALID_PC
)
572 label
= pending_blocks
;
573 if (label
== NULL_TREE
)
574 break; /* We're done! */
575 pending_blocks
= LABEL_PENDING_CHAIN (label
);
576 LABEL_CHANGED (label
) = 0;
578 if (LABEL_IN_SUBR (label
))
579 current_subr
= LABEL_SUBR_START (label
);
581 current_subr
= NULL_TREE
;
583 /* Restore type_map and stack_pointer from
584 LABEL_TYPE_STATE (label), and continue
585 compiling from there. */
586 load_type_state (label
);
587 PC
= LABEL_PC (label
);
589 else if (PC
>= length
)
590 VERIFICATION_ERROR ("falling through end of method");
592 /* fprintf (stderr, "** %d\n", PC); */
596 if (!(instruction_bits
[PC
] & BCODE_INSTRUCTION_START
) && ! wide
)
597 VERIFICATION_ERROR ("PC not at instruction start");
599 instruction_bits
[PC
] |= BCODE_VERIFIED
;
601 eh_ranges
= find_handler (oldpc
);
603 op_code
= byte_ops
[PC
++];
606 int is_static
, is_putting
;
609 case OPCODE_iconst_m1
:
610 case OPCODE_iconst_0
: case OPCODE_iconst_1
: case OPCODE_iconst_2
:
611 case OPCODE_iconst_3
: case OPCODE_iconst_4
: case OPCODE_iconst_5
:
612 i
= op_code
- OPCODE_iconst_0
;
615 if (byte_ops
[PC
] == OPCODE_newarray
616 || byte_ops
[PC
] == OPCODE_anewarray
)
618 PUSH_TYPE (int_type_node
); break;
619 case OPCODE_lconst_0
: case OPCODE_lconst_1
:
620 PUSH_TYPE (long_type_node
); break;
621 case OPCODE_fconst_0
: case OPCODE_fconst_1
: case OPCODE_fconst_2
:
622 PUSH_TYPE (float_type_node
); break;
623 case OPCODE_dconst_0
: case OPCODE_dconst_1
:
624 PUSH_TYPE (double_type_node
); break;
631 case OPCODE_iload
: type
= int_type_node
; goto general_load
;
632 case OPCODE_lload
: type
= long_type_node
; goto general_load
;
633 case OPCODE_fload
: type
= float_type_node
; goto general_load
;
634 case OPCODE_dload
: type
= double_type_node
; goto general_load
;
635 case OPCODE_aload
: type
= ptr_type_node
; goto general_load
;
637 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
640 case OPCODE_iload_0
: type
= int_type_node
; index
= 0; goto load
;
641 case OPCODE_iload_1
: type
= int_type_node
; index
= 1; goto load
;
642 case OPCODE_iload_2
: type
= int_type_node
; index
= 2; goto load
;
643 case OPCODE_iload_3
: type
= int_type_node
; index
= 3; goto load
;
644 case OPCODE_lload_0
: type
= long_type_node
; index
= 0; goto load
;
645 case OPCODE_lload_1
: type
= long_type_node
; index
= 1; goto load
;
646 case OPCODE_lload_2
: type
= long_type_node
; index
= 2; goto load
;
647 case OPCODE_lload_3
: type
= long_type_node
; index
= 3; goto load
;
648 case OPCODE_fload_0
: type
= float_type_node
; index
= 0; goto load
;
649 case OPCODE_fload_1
: type
= float_type_node
; index
= 1; goto load
;
650 case OPCODE_fload_2
: type
= float_type_node
; index
= 2; goto load
;
651 case OPCODE_fload_3
: type
= float_type_node
; index
= 3; goto load
;
652 case OPCODE_dload_0
: type
= double_type_node
; index
= 0; goto load
;
653 case OPCODE_dload_1
: type
= double_type_node
; index
= 1; goto load
;
654 case OPCODE_dload_2
: type
= double_type_node
; index
= 2; goto load
;
655 case OPCODE_dload_3
: type
= double_type_node
; index
= 3; goto load
;
656 case OPCODE_aload_0
: type
= ptr_type_node
; index
= 0; goto load
;
657 case OPCODE_aload_1
: type
= ptr_type_node
; index
= 1; goto load
;
658 case OPCODE_aload_2
: type
= ptr_type_node
; index
= 2; goto load
;
659 case OPCODE_aload_3
: type
= ptr_type_node
; index
= 3; goto load
;
662 || (index
+ TYPE_IS_WIDE (type
)
663 >= DECL_MAX_LOCALS (current_function_decl
)))
664 VERIFICATION_ERROR_WITH_INDEX
665 ("invalid local variable index %d in load");
666 tmp
= type_map
[index
];
667 if (tmp
== TYPE_UNKNOWN
)
668 VERIFICATION_ERROR_WITH_INDEX
669 ("loading local variable %d which has unknown type");
670 else if (tmp
== TYPE_SECOND
671 || (TYPE_IS_WIDE (type
)
672 && type_map
[index
+1] != void_type_node
)
673 || (type
== ptr_type_node
674 ? TREE_CODE (tmp
) != POINTER_TYPE
675 : type
== int_type_node
676 ? (! INTEGRAL_TYPE_P (tmp
) || TYPE_PRECISION (tmp
) > 32)
678 VERIFICATION_ERROR_WITH_INDEX
679 ("loading local variable %d which has invalid type");
682 case OPCODE_istore
: type
= int_type_node
; goto general_store
;
683 case OPCODE_lstore
: type
= long_type_node
; goto general_store
;
684 case OPCODE_fstore
: type
= float_type_node
; goto general_store
;
685 case OPCODE_dstore
: type
= double_type_node
; goto general_store
;
686 case OPCODE_astore
: type
= object_ptr_type_node
; goto general_store
;
688 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
691 case OPCODE_istore_0
: type
= int_type_node
; index
= 0; goto store
;
692 case OPCODE_istore_1
: type
= int_type_node
; index
= 1; goto store
;
693 case OPCODE_istore_2
: type
= int_type_node
; index
= 2; goto store
;
694 case OPCODE_istore_3
: type
= int_type_node
; index
= 3; goto store
;
695 case OPCODE_lstore_0
: type
= long_type_node
; index
=0; goto store
;
696 case OPCODE_lstore_1
: type
= long_type_node
; index
=1; goto store
;
697 case OPCODE_lstore_2
: type
= long_type_node
; index
=2; goto store
;
698 case OPCODE_lstore_3
: type
= long_type_node
; index
=3; goto store
;
699 case OPCODE_fstore_0
: type
=float_type_node
; index
=0; goto store
;
700 case OPCODE_fstore_1
: type
=float_type_node
; index
=1; goto store
;
701 case OPCODE_fstore_2
: type
=float_type_node
; index
=2; goto store
;
702 case OPCODE_fstore_3
: type
=float_type_node
; index
=3; goto store
;
703 case OPCODE_dstore_0
: type
=double_type_node
; index
=0; goto store
;
704 case OPCODE_dstore_1
: type
=double_type_node
; index
=1; goto store
;
705 case OPCODE_dstore_2
: type
=double_type_node
; index
=2; goto store
;
706 case OPCODE_dstore_3
: type
=double_type_node
; index
=3; goto store
;
707 case OPCODE_astore_0
: type
= ptr_type_node
; index
= 0; goto store
;
708 case OPCODE_astore_1
: type
= ptr_type_node
; index
= 1; goto store
;
709 case OPCODE_astore_2
: type
= ptr_type_node
; index
= 2; goto store
;
710 case OPCODE_astore_3
: type
= ptr_type_node
; index
= 3; goto store
;
713 || (index
+ TYPE_IS_WIDE (type
)
714 >= DECL_MAX_LOCALS (current_function_decl
)))
716 VERIFICATION_ERROR_WITH_INDEX
717 ("invalid local variable index %d in store");
720 POP_TYPE_CONV (type
, type
, NULL
);
721 type_map
[index
] = type
;
723 /* If local variable changed, we need to reconsider eh handlers. */
724 prev_eh_ranges
= NULL_EH_RANGE
;
726 /* Allocate decl and rtx for this variable now, so if we're not
727 optmizing, we get a temporary that survives the whole method. */
728 find_local_variable (index
, type
, oldpc
);
730 if (TYPE_IS_WIDE (type
))
731 type_map
[index
+1] = TYPE_SECOND
;
732 /* ... fall through to note_used ... */
734 /* For store or load, note that local variable INDEX is used.
735 This is needed to verify try-finally sub-routines. */
738 tree vec
= LABEL_RETURN_TYPE_STATE (current_subr
);
739 tree subr_vec
= LABEL_TYPE_STATE (current_subr
);
740 int len
= 1 + TYPE_IS_WIDE (type
);
743 if (TREE_VEC_ELT (vec
, index
) == TYPE_UNUSED
)
744 TREE_VEC_ELT (vec
, index
) = TREE_VEC_ELT (subr_vec
, index
);
759 type
= int_type_node
; goto binop
;
764 type
= int_type_node
; goto unop
;
773 type
= long_type_node
; goto binop
;
775 type
= long_type_node
; goto unop
;
776 case OPCODE_fadd
: case OPCODE_fsub
:
777 case OPCODE_fmul
: case OPCODE_fdiv
: case OPCODE_frem
:
778 type
= float_type_node
; goto binop
;
780 type
= float_type_node
; goto unop
;
781 case OPCODE_dadd
: case OPCODE_dsub
:
782 case OPCODE_dmul
: case OPCODE_ddiv
: case OPCODE_drem
:
783 type
= double_type_node
; goto binop
;
785 type
= double_type_node
; goto unop
;
798 pop_type (int_type_node
);
799 pop_type (long_type_node
);
800 PUSH_TYPE (long_type_node
);
803 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
806 if (index
< 0 || index
>= DECL_MAX_LOCALS (current_function_decl
))
807 VERIFICATION_ERROR ("invalid local variable index in iinc");
808 tmp
= type_map
[index
];
810 || ! INTEGRAL_TYPE_P (tmp
) || TYPE_PRECISION (tmp
) > 32)
811 VERIFICATION_ERROR ("invalid local variable type in iinc");
814 pop_type (int_type_node
); PUSH_TYPE (long_type_node
); break;
816 pop_type (int_type_node
); PUSH_TYPE (float_type_node
); break;
818 pop_type (int_type_node
); PUSH_TYPE (double_type_node
); break;
820 pop_type (long_type_node
); PUSH_TYPE (int_type_node
); break;
822 pop_type (long_type_node
); PUSH_TYPE (float_type_node
); break;
824 pop_type (long_type_node
); PUSH_TYPE (double_type_node
); break;
826 pop_type (float_type_node
); PUSH_TYPE (int_type_node
); break;
828 pop_type (float_type_node
); PUSH_TYPE (long_type_node
); break;
830 pop_type (float_type_node
); PUSH_TYPE (double_type_node
); break;
832 pop_type (double_type_node
); PUSH_TYPE (int_type_node
); break;
834 pop_type (double_type_node
); PUSH_TYPE (long_type_node
); break;
836 pop_type (double_type_node
); PUSH_TYPE (float_type_node
); break;
838 type
= long_type_node
; goto compare
;
841 type
= float_type_node
; goto compare
;
844 type
= double_type_node
; goto compare
;
846 pop_type (type
); pop_type (type
);
847 PUSH_TYPE (int_type_node
); break;
854 pop_type (int_type_node
); goto cond
;
856 case OPCODE_ifnonnull
:
857 pop_type (ptr_type_node
); goto cond
;
858 case OPCODE_if_icmpeq
:
859 case OPCODE_if_icmpne
:
860 case OPCODE_if_icmplt
:
861 case OPCODE_if_icmpge
:
862 case OPCODE_if_icmpgt
:
863 case OPCODE_if_icmple
:
864 pop_type (int_type_node
); pop_type (int_type_node
); goto cond
;
865 case OPCODE_if_acmpeq
:
866 case OPCODE_if_acmpne
:
867 pop_type (object_ptr_type_node
); pop_type (object_ptr_type_node
);
870 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s2
));
873 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s2
));
877 switch (byte_ops
[PC
])
879 case OPCODE_iload
: case OPCODE_lload
:
880 case OPCODE_fload
: case OPCODE_dload
: case OPCODE_aload
:
881 case OPCODE_istore
: case OPCODE_lstore
:
882 case OPCODE_fstore
: case OPCODE_dstore
: case OPCODE_astore
:
888 VERIFICATION_ERROR ("invalid use of wide instruction");
891 case OPCODE_return
: type
= void_type_node
; goto ret
;
893 if ((TREE_CODE (return_type
) == BOOLEAN_TYPE
894 || TREE_CODE (return_type
) == CHAR_TYPE
895 || TREE_CODE (return_type
) == INTEGER_TYPE
)
896 && TYPE_PRECISION (return_type
) <= 32)
901 case OPCODE_lreturn
: type
= long_type_node
; goto ret
;
902 case OPCODE_freturn
: type
= float_type_node
; goto ret
;
903 case OPCODE_dreturn
: type
= double_type_node
; goto ret
;
905 if (TREE_CODE (return_type
) == POINTER_TYPE
)
911 if (type
!= return_type
)
912 VERIFICATION_ERROR ("incorrect ?return opcode");
913 if (type
!= void_type_node
)
914 POP_TYPE(type
, "return value has wrong type");
917 case OPCODE_getstatic
: is_putting
= 0; is_static
= 1; goto field
;
918 case OPCODE_putstatic
: is_putting
= 1; is_static
= 1; goto field
;
919 case OPCODE_getfield
: is_putting
= 0; is_static
= 0; goto field
;
920 case OPCODE_putfield
: is_putting
= 1; is_static
= 0; goto field
;
923 tree field_signature
, field_type
;
924 index
= IMMEDIATE_u2
;
925 if (index
<= 0 || index
>= JPOOL_SIZE(current_jcf
))
926 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d");
927 if (JPOOL_TAG (current_jcf
, index
) != CONSTANT_Fieldref
)
929 ("field instruction does not reference a Fieldref");
930 field_signature
= COMPONENT_REF_SIGNATURE (¤t_jcf
->cpool
, index
);
931 field_type
= get_type_from_signature (field_signature
);
933 POP_TYPE (field_type
, "incorrect type for field");
936 int clindex
= COMPONENT_REF_CLASS_INDEX (¤t_jcf
->cpool
,
938 tree self_type
= get_class_constant (current_jcf
, clindex
);
939 /* Defer actual checking until next pass. */
940 POP_TYPE(self_type
, "incorrect type for field reference");
943 PUSH_TYPE (field_type
);
947 PUSH_TYPE (get_class_constant (jcf
, IMMEDIATE_u2
));
949 case OPCODE_dup
: wide
= 1; index
= 0; goto dup
;
950 case OPCODE_dup_x1
: wide
= 1; index
= 1; goto dup
;
951 case OPCODE_dup_x2
: wide
= 1; index
= 2; goto dup
;
952 case OPCODE_dup2
: wide
= 2; index
= 0; goto dup
;
953 case OPCODE_dup2_x1
: wide
= 2; index
= 1; goto dup
;
954 case OPCODE_dup2_x2
: wide
= 2; index
= 2; goto dup
;
956 if (wide
+ index
> stack_pointer
)
957 VERIFICATION_ERROR ("stack underflow - dup* operation");
958 type_stack_dup (wide
, index
);
961 case OPCODE_pop
: index
= 1; goto pop
;
962 case OPCODE_pop2
: index
= 2; goto pop
;
964 if (stack_pointer
< index
)
965 VERIFICATION_ERROR ("stack underflow");
966 stack_pointer
-= index
;
969 if (stack_pointer
< 2)
970 VERIFICATION_ERROR ("stack underflow (in swap)");
973 tree type1
= stack_type_map
[stack_pointer
- 1];
974 tree type2
= stack_type_map
[stack_pointer
- 2];
975 if (type1
== void_type_node
|| type2
== void_type_node
)
976 VERIFICATION_ERROR ("verifier (swap): double or long value");
977 stack_type_map
[stack_pointer
- 2] = type1
;
978 stack_type_map
[stack_pointer
- 1] = type2
;
981 case OPCODE_ldc
: index
= IMMEDIATE_u1
; goto ldc
;
984 index
= IMMEDIATE_u2
; goto ldc
;
986 if (index
<= 0 || index
>= JPOOL_SIZE(current_jcf
))
987 VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc");
989 switch (JPOOL_TAG (current_jcf
, index
) & ~CONSTANT_ResolvedFlag
)
991 case CONSTANT_Integer
: type
= int_type_node
; goto check_ldc
;
992 case CONSTANT_Float
: type
= float_type_node
; goto check_ldc
;
993 case CONSTANT_String
: type
= string_type_node
; goto check_ldc
;
994 case CONSTANT_Long
: type
= long_type_node
; goto check_ldc
;
995 case CONSTANT_Double
: type
= double_type_node
; goto check_ldc
;
997 if (TYPE_IS_WIDE (type
) == (op_code
== OPCODE_ldc2_w
))
999 /* ... else fall through ... */
1001 VERIFICATION_ERROR ("bad constant pool tag in ldc");
1003 if (type
== int_type_node
)
1005 i
= TREE_INT_CST_LOW (get_constant (current_jcf
, index
));
1011 case OPCODE_invokevirtual
:
1012 case OPCODE_invokespecial
:
1013 case OPCODE_invokestatic
:
1014 case OPCODE_invokeinterface
:
1016 tree sig
, method_name
, method_type
, self_type
;
1017 int self_is_interface
, tag
;
1018 index
= IMMEDIATE_u2
;
1019 if (index
<= 0 || index
>= JPOOL_SIZE(current_jcf
))
1020 VERIFICATION_ERROR_WITH_INDEX
1021 ("bad constant pool index %d for invoke");
1022 tag
= JPOOL_TAG (current_jcf
, index
);
1023 if (op_code
== OPCODE_invokeinterface
)
1025 if (tag
!= CONSTANT_InterfaceMethodref
)
1027 ("invokeinterface does not reference an InterfaceMethodref");
1031 if (tag
!= CONSTANT_Methodref
)
1032 VERIFICATION_ERROR ("invoke does not reference a Methodref");
1034 sig
= COMPONENT_REF_SIGNATURE (¤t_jcf
->cpool
, index
);
1035 self_type
= get_class_constant
1036 (current_jcf
, COMPONENT_REF_CLASS_INDEX (¤t_jcf
->cpool
,
1038 if (! CLASS_LOADED_P (self_type
))
1039 load_class (self_type
, 1);
1040 self_is_interface
= CLASS_INTERFACE (TYPE_NAME (self_type
));
1041 method_name
= COMPONENT_REF_NAME (¤t_jcf
->cpool
, index
);
1042 method_type
= parse_signature_string (IDENTIFIER_POINTER (sig
),
1043 IDENTIFIER_LENGTH (sig
));
1044 if (TREE_CODE (method_type
) != FUNCTION_TYPE
)
1045 VERIFICATION_ERROR ("bad method signature");
1046 pmessage
= pop_argument_types (TYPE_ARG_TYPES (method_type
));
1047 if (pmessage
!= NULL
)
1049 message
= "invalid argument type";
1050 goto pop_type_error
;
1053 /* Can't invoke <clinit> */
1054 if (ID_CLINIT_P (method_name
))
1055 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
1056 /* Apart invokespecial, can't invoke <init> */
1057 if (op_code
!= OPCODE_invokespecial
&& ID_INIT_P (method_name
))
1058 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
1060 if (op_code
!= OPCODE_invokestatic
)
1061 POP_TYPE (self_type
,
1062 "stack type not subclass of invoked method's class");
1066 case OPCODE_invokeinterface
:
1068 int nargs
= IMMEDIATE_u1
;
1069 int notZero
= IMMEDIATE_u1
;
1071 if (!nargs
|| notZero
)
1073 ("invalid argument number in invokeinterface");
1074 /* If we verify/resolve the constant pool, as we should,
1075 this test (and the one just following) are redundant. */
1076 if (! self_is_interface
)
1077 VERIFICATION_ERROR ("invokeinterface calls method not in interface");
1080 if (self_is_interface
)
1081 VERIFICATION_ERROR ("method in interface called");
1085 if (TREE_TYPE (method_type
) != void_type_node
)
1086 PUSH_TYPE (TREE_TYPE (method_type
));
1090 case OPCODE_arraylength
:
1091 /* Type checking actually made during code generation */
1092 pop_type( ptr_type_node
);
1093 PUSH_TYPE( int_type_node
);
1096 /* Q&D verification *or* more checking done during code generation
1097 for byte/boolean/char/short, the value popped is a int coerced
1098 into the right type before being stored. */
1099 case OPCODE_iastore
: type
= int_type_node
; goto astore
;
1100 case OPCODE_lastore
: type
= long_type_node
; goto astore
;
1101 case OPCODE_fastore
: type
= float_type_node
; goto astore
;
1102 case OPCODE_dastore
: type
= double_type_node
; goto astore
;
1103 case OPCODE_aastore
: type
= ptr_type_node
; goto astore
;
1104 case OPCODE_bastore
: type
= int_type_node
; goto astore
;
1105 case OPCODE_castore
: type
= int_type_node
; goto astore
;
1106 case OPCODE_sastore
: type
= int_type_node
; goto astore
;
1108 /* FIXME - need better verification here */
1109 pop_type (type
); /* new value */
1110 pop_type (int_type_node
); /* index */
1111 pop_type (ptr_type_node
); /* array */
1114 /* Q&D verification *or* more checking done during code generation
1115 for byte/boolean/char/short, the value pushed is a int. */
1116 case OPCODE_iaload
: type
= int_type_node
; goto aload
;
1117 case OPCODE_laload
: type
= long_type_node
; goto aload
;
1118 case OPCODE_faload
: type
= float_type_node
; goto aload
;
1119 case OPCODE_daload
: type
= double_type_node
; goto aload
;
1120 case OPCODE_aaload
: type
= ptr_type_node
; goto aload
;
1121 case OPCODE_baload
: type
= promote_type (byte_type_node
); goto aload
;
1122 case OPCODE_caload
: type
= promote_type (char_type_node
); goto aload
;
1123 case OPCODE_saload
: type
= promote_type (short_type_node
); goto aload
;
1125 pop_type (int_type_node
);
1126 tmp
= pop_type (ptr_type_node
);
1127 if (is_array_type_p (tmp
))
1128 type
= TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp
));
1129 else if (tmp
!= TYPE_NULL
)
1130 VERIFICATION_ERROR ("array load from non-array type");
1134 case OPCODE_anewarray
:
1135 type
= get_class_constant (current_jcf
, IMMEDIATE_u2
);
1136 type
= promote_type (type
);
1139 case OPCODE_newarray
:
1140 index
= IMMEDIATE_u1
;
1141 type
= decode_newarray_type (index
);
1142 if (type
== NULL_TREE
)
1143 VERIFICATION_ERROR ("invalid type code in newarray opcode");
1147 if (int_value
>= 0 && prevpc
>= 0)
1149 /* If previous instruction pushed int constant,
1150 we want to use it. */
1151 switch (byte_ops
[prevpc
])
1153 case OPCODE_iconst_0
: case OPCODE_iconst_1
:
1154 case OPCODE_iconst_2
: case OPCODE_iconst_3
:
1155 case OPCODE_iconst_4
: case OPCODE_iconst_5
:
1156 case OPCODE_bipush
: case OPCODE_sipush
:
1157 case OPCODE_ldc
: case OPCODE_ldc_w
:
1165 type
= build_java_array_type (type
, int_value
);
1166 pop_type (int_type_node
);
1170 case OPCODE_multianewarray
:
1173 index
= IMMEDIATE_u2
;
1174 ndim
= IMMEDIATE_u1
;
1177 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
1179 for( i
= 0; i
< ndim
; i
++ )
1180 pop_type (int_type_node
);
1181 PUSH_TYPE (get_class_constant (current_jcf
, index
));
1185 case OPCODE_aconst_null
:
1186 PUSH_TYPE (ptr_type_node
);
1190 /* FIXME: athrow also empties the stack. */
1191 POP_TYPE (throwable_type_node
, "missing throwable at athrow" );
1195 case OPCODE_checkcast
:
1196 POP_TYPE (object_ptr_type_node
,
1197 "checkcast operand is not a pointer");
1198 type
= get_class_constant (current_jcf
, IMMEDIATE_u2
);
1201 case OPCODE_instanceof
:
1202 POP_TYPE (object_ptr_type_node
,
1203 "instanceof operand is not a pointer");
1204 get_class_constant (current_jcf
, IMMEDIATE_u2
);
1205 PUSH_TYPE (int_type_node
);
1208 case OPCODE_tableswitch
:
1212 POP_TYPE (int_type_node
, "missing int for tableswitch");
1216 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
1218 PUSH_PENDING (lookup_label (oldpc
+IMMEDIATE_s4
));
1220 high
= IMMEDIATE_s4
;
1223 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1225 while (low
++ <= high
)
1226 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
1231 case OPCODE_lookupswitch
:
1233 jint npairs
, last
= 0, not_registered
= 1;
1235 POP_TYPE (int_type_node
, "missing int for lookupswitch");
1239 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1242 PUSH_PENDING (lookup_label (oldpc
+IMMEDIATE_s4
));
1243 npairs
= IMMEDIATE_s4
;
1246 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1250 int match
= IMMEDIATE_s4
;
1253 else if (last
>= match
)
1254 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1257 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
1263 case OPCODE_monitorenter
:
1265 case OPCODE_monitorexit
:
1266 pop_type (ptr_type_node
);
1270 PUSH_PENDING (lookup_label (oldpc
+ IMMEDIATE_s4
));
1276 tree target
= lookup_label (oldpc
+ IMMEDIATE_s2
);
1277 tree return_label
= lookup_label (PC
);
1278 PUSH_TYPE (return_address_type_node
);
1279 /* The return label chain will be null if this is the first
1280 time we've seen this jsr target. */
1281 if (LABEL_RETURN_LABEL (target
) == NULL_TREE
)
1283 tree return_type_map
;
1284 int nlocals
= DECL_MAX_LOCALS (current_function_decl
);
1285 index
= nlocals
+ DECL_MAX_STACK (current_function_decl
);
1286 return_type_map
= make_tree_vec (index
);
1287 while (index
> nlocals
)
1288 TREE_VEC_ELT (return_type_map
, --index
) = TYPE_UNKNOWN
;
1290 TREE_VEC_ELT (return_type_map
, --index
) = TYPE_UNUSED
;
1291 LABEL_RETURN_LABEL (target
)
1292 = build_decl (LABEL_DECL
, NULL_TREE
, TREE_TYPE (target
));
1293 LABEL_PC (LABEL_RETURN_LABEL (target
)) = -1;
1294 LABEL_RETURN_TYPE_STATE (target
) = return_type_map
;
1295 LABEL_IS_SUBR_START (target
) = 1;
1296 LABEL_IN_SUBR (target
) = 1;
1297 LABEL_SUBR_START (target
) = target
;
1298 LABEL_SUBR_CONTEXT (target
) = current_subr
;
1300 else if (! LABEL_IS_SUBR_START (target
)
1301 || LABEL_SUBR_CONTEXT (target
) != current_subr
)
1302 VERIFICATION_ERROR ("label part of different subroutines");
1304 i
= merge_type_state (target
);
1308 VERIFICATION_ERROR ("types could not be merged at jsr");
1309 push_pending_label (target
);
1311 current_subr
= target
;
1313 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1314 if (! value_member (return_label
, LABEL_RETURN_LABELS (target
)))
1316 LABEL_RETURN_LABELS (target
)
1317 = tree_cons (NULL_TREE
, return_label
,
1318 LABEL_RETURN_LABELS (target
));
1321 if (LABEL_VERIFIED (target
))
1323 tree return_map
= LABEL_RETURN_TYPE_STATE (target
);
1324 int len
= TREE_VEC_LENGTH (return_map
);
1325 stack_pointer
= len
- DECL_MAX_LOCALS (current_function_decl
);
1328 if (TREE_VEC_ELT (return_map
, len
) != TYPE_UNUSED
)
1329 type_map
[len
] = TREE_VEC_ELT (return_map
, len
);
1331 current_subr
= LABEL_SUBR_CONTEXT (target
);
1332 if (RETURN_MAP_ADJUSTED (return_map
))
1333 PUSH_PENDING (return_label
);
1340 if (current_subr
== NULL
)
1341 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1344 tree ret_map
= LABEL_RETURN_TYPE_STATE (current_subr
);
1345 int size
= DECL_MAX_LOCALS(current_function_decl
)+stack_pointer
;
1346 index
= wide
? IMMEDIATE_u2
: IMMEDIATE_u1
;
1349 if (index
< 0 || index
>= DECL_MAX_LOCALS (current_function_decl
)
1350 || type_map
[index
] != TYPE_RETURN_ADDR
)
1351 VERIFICATION_ERROR ("invalid ret index");
1353 /* The next chunk of code is similar to an inlined version of
1354 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1355 * The main differences are that LABEL_RETURN_LABEL is
1356 * pre-allocated by the jsr (but we don't know the size then);
1357 * and that we have to handle TYPE_UNUSED. */
1359 if (! RETURN_MAP_ADJUSTED (ret_map
))
1360 { /* First return from this subroutine - fix stack pointer. */
1361 TREE_VEC_LENGTH (ret_map
) = size
;
1362 for (index
= size
; --index
>= 0; )
1364 if (TREE_VEC_ELT (ret_map
, index
) != TYPE_UNUSED
)
1365 TREE_VEC_ELT (ret_map
, index
) = type_map
[index
];
1367 RETURN_MAP_ADJUSTED (ret_map
) = 1;
1371 if (TREE_VEC_LENGTH (ret_map
) != size
)
1372 VERIFICATION_ERROR ("inconsistent stack size on ret");
1373 for (index
= 0; index
< size
; index
++)
1375 tree type
= TREE_VEC_ELT (ret_map
, index
);
1376 if (type
!= TYPE_UNUSED
)
1378 type
= merge_types (type
, type_map
[index
]);
1379 TREE_VEC_ELT (ret_map
, index
) = type
;
1380 if (type
== TYPE_UNKNOWN
)
1382 if (index
>= size
- stack_pointer
)
1384 ("inconsistent types on ret from jsr");
1386 else if (TYPE_IS_WIDE (type
))
1398 error ("unknown opcode %d@pc=%d during verification", op_code
, PC
-1);
1404 /* The following test is true if we have entered or exited an exception
1405 handler range *or* we have done a store to a local variable.
1406 In either case we need to consider any exception handlers that
1407 might "follow" this instruction. */
1409 if (eh_ranges
!= prev_eh_ranges
)
1411 int save_stack_pointer
= stack_pointer
;
1412 int index
= DECL_MAX_LOCALS (current_function_decl
);
1413 tree save_type
= type_map
[index
];
1414 tree save_current_subr
= current_subr
;
1415 struct eh_range
*ranges
= find_handler (oldpc
);
1417 for (; ranges
!= NULL_EH_RANGE
; ranges
= ranges
->outer
)
1419 tree chain
= ranges
->handlers
;
1421 /* We need to determine if the handler is part of current_subr.
1422 The are two cases: (1) The exception catch range
1423 is entirely within current_subr. In that case the handler
1424 is also part of current_subr.
1425 (2) Some of the catch range is not in current_subr.
1426 In that case, the handler is *not* part of current_subr.
1428 Figuring out which is the case is not necessarily obvious,
1429 in the presence of clever code generators (and obfuscators).
1430 We make a simplifying assumption that in case (2) we
1431 have that the current_subr is entirely within the catch range.
1432 In that case we can assume if that if a caller (the jsr) of
1433 a subroutine is within the catch range, then the handler is
1434 *not* part of the subroutine, and vice versa. */
1436 current_subr
= save_current_subr
;
1437 for ( ; current_subr
!= NULL_TREE
;
1438 current_subr
= LABEL_SUBR_CONTEXT (current_subr
))
1440 tree return_labels
= LABEL_RETURN_LABELS (current_subr
);
1441 /* There could be multiple return_labels, but
1442 we only need to check one. */
1443 int return_pc
= LABEL_PC (TREE_VALUE (return_labels
));
1444 if (return_pc
<= ranges
->start_pc
1445 || return_pc
> ranges
->end_pc
)
1449 for ( ; chain
!= NULL_TREE
; chain
= TREE_CHAIN (chain
))
1451 tree handler
= TREE_VALUE (chain
);
1452 tree type
= TREE_PURPOSE (chain
);
1453 if (type
== NULL_TREE
) /* a finally handler */
1454 type
= throwable_type_node
;
1455 type_map
[index
] = promote_type (type
);
1457 PUSH_PENDING (handler
);
1460 stack_pointer
= save_stack_pointer
;
1461 current_subr
= save_current_subr
;
1462 type_map
[index
] = save_type
;
1463 prev_eh_ranges
= eh_ranges
;
1468 error ("verification error at PC=%d", oldpc
);
1469 if (message
!= NULL
)
1470 error ("%s", message
);
1471 error ("%s", pmessage
);
1475 message
= "stack overflow";
1478 message
= "program counter out of range";
1481 error ("verification error at PC=%d", oldpc
);
1482 error (message
, index
);
1485 error ("verification error at PC=%d", oldpc
);
1486 error ("%s", message
);