]> gcc.gnu.org Git - gcc.git/blame - gcc/java/verify.c
verify.c (verify_jvm_instructions): Better error messages.
[gcc.git] / gcc / java / verify.c
CommitLineData
e04a16fb
AG
1/* Handle verification of bytecoded methods for the GNU compiler for
2 the Java(TM) language.
9b318a74 3 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
e04a16fb
AG
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA.
21
22Java and all Java-based marks are trademarks or registered trademarks
23of Sun Microsystems, Inc. in the United States and other countries.
24The Free Software Foundation is independent of Sun Microsystems, Inc. */
25
e04a16fb 26#include "config.h"
1f43f4b4 27#include "system.h"
e04a16fb
AG
28#include "tree.h"
29#include "java-tree.h"
30#include "javaop.h"
31#include "java-opcodes.h"
32#include "jcf.h"
33#include "java-except.h"
1f43f4b4 34#include "toplev.h"
e04a16fb 35
4bcde32e
KG
36static void push_pending_label PROTO ((tree));
37static tree merge_types PROTO ((tree, tree));
38
e04a16fb
AG
39extern int stack_pointer;
40
41/* During verification, start of the current subroutine (jsr target). */
42tree current_subr;
43
44/* A list of pending blocks, chained using LABEL_PENDING_CHAIN.
45 A pending block is one that has LABEL_CHANGED set, which means
46 it requires (re-) verification. */
47tree pending_blocks;
48
49/* Append TARGET_LABEL to the pending_block stack unless already in it. */
50
4bcde32e 51static void
e04a16fb
AG
52push_pending_label (target_label)
53 tree target_label;
54{
55 if (! LABEL_CHANGED (target_label))
56 {
57 LABEL_PENDING_CHAIN (target_label) = pending_blocks;
58 pending_blocks = target_label;
59 LABEL_CHANGED (target_label) = 1;
60 }
61}
62
63/* Note that TARGET_LABEL is a possible successor instruction.
64 Merge the type state etc.
65 Return NULL on sucess, or an error message on failure. */
66
d4476be2 67static const char *
e04a16fb
AG
68check_pending_block (target_label)
69 tree target_label;
70{
71 int changed = merge_type_state (target_label);
72
73 if (changed)
74 {
75 if (changed < 0)
76 return "types could not be merged";
77 push_pending_label (target_label);
78 }
79
80 if (current_subr == NULL)
81 {
82 if (LABEL_IN_SUBR (target_label))
83 return "might transfer control into subroutine";
84 }
85 else
86 {
87 if (LABEL_IN_SUBR (target_label))
88 {
89 if (LABEL_SUBR_START (target_label) != current_subr)
90 return "transfer out of subroutine";
91 }
92 else if (! LABEL_VERIFIED (target_label))
93 {
94 LABEL_IN_SUBR (target_label) = 1;
95 LABEL_SUBR_START (target_label) = current_subr;
96 }
97 else
98 return "transfer out of subroutine";
99 }
100 return NULL;
101}
102
103/* Return the "merged" types of TYPE1 and TYPE2.
104 If either is primitive, the other must match (after promotion to int).
105 For reference types, return the common super-class.
106 Return TYPE_UNKNOWN if the types cannot be merged. */
107
4bcde32e 108static tree
e04a16fb
AG
109merge_types (type1, type2)
110 tree type1, type2;
111{
112 if (type1 == type2)
113 return type1;
114 if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
115 || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
116 return TYPE_UNKNOWN;
117 if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
118 {
119 int depth1, depth2;
120 tree tt1, tt2;
121 /* ptr_type_node is only used for a null reference,
122 which is compatible with any reference type. */
123 if (type1 == ptr_type_node || type2 == object_ptr_type_node)
124 return type2;
125 if (type2 == ptr_type_node || type1 == object_ptr_type_node)
126 return type1;
127
128 tt1 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type1));
129 tt2 = HANDLE_TO_CLASS_TYPE (TREE_TYPE (type2));
130
131 if (TYPE_ARRAY_P (tt1) || TYPE_ARRAY_P (tt2))
132 {
133 if (TYPE_ARRAY_P (tt1) == TYPE_ARRAY_P (tt2))
134 {
135 tree el_type1 = TYPE_ARRAY_ELEMENT (tt1);
136 tree el_type2 = TYPE_ARRAY_ELEMENT (tt2);
137 tree el_type = NULL_TREE;
138 if (el_type1 == el_type2)
139 el_type = el_type1;
140 else if (TREE_CODE (el_type1) == POINTER_TYPE
141 && TREE_CODE (el_type2) == POINTER_TYPE)
142 el_type = merge_types (el_type1, el_type2);
143 if (el_type != NULL_TREE)
144 {
145 HOST_WIDE_INT len1 = java_array_type_length (tt1);
146 HOST_WIDE_INT len2 = java_array_type_length (tt2);
147 if (len1 != len2)
148 len1 = -1;
149 else if (el_type1 == el_type2)
150 return type1;
151 return promote_type (build_java_array_type (el_type, len1));
152 }
153 }
154 return object_ptr_type_node;
155 }
46cf461c
PB
156
157 if (CLASS_INTERFACE (TYPE_NAME (tt1)))
158 {
159 if (CLASS_INTERFACE (TYPE_NAME (tt2)))
160 {
161 /* This is a kludge, but matches what Sun's verifier does.
162 It can be tricked, but is safe as long as type errors
163 (i.e. interface method calls) are caught at run-time. */
164 return object_ptr_type_node;
165 }
166 else
167 {
168 if (can_widen_reference_to (tt2, tt1))
169 return type1;
170 else
171 return TYPE_UNKNOWN;
172 }
173 }
174 else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
175 {
176 if (can_widen_reference_to (tt1, tt2))
177 return type2;
178 else
179 return TYPE_UNKNOWN;
180 }
181
e04a16fb
AG
182 type1 = tt1;
183 type2 = tt2;
184
185 depth1 = class_depth (type1);
186 depth2 = class_depth (type2);
187 for ( ; depth1 > depth2; depth1--)
188 type1 = TYPE_BINFO_BASETYPE (type1, 0);
189 for ( ; depth2 > depth1; depth2--)
190 type2 = TYPE_BINFO_BASETYPE (type2, 0);
191 while (type1 != type2)
192 {
193 type1 = TYPE_BINFO_BASETYPE (type1, 0);
194 type2 = TYPE_BINFO_BASETYPE (type2, 0);
195 }
196 return promote_type (type1);
197 }
198 if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)
199 && TYPE_PRECISION (type1) <= 32 && TYPE_PRECISION (type2) <= 32)
200 return int_type_node;
201 return TYPE_UNKNOWN;
202}
203
204/* Merge the current type state with that at LABEL.
205 Return -1 the the states are incompatible (i.e. on error),
206 0 if there was no change, and 1 if there was a change. */
207
208int
209merge_type_state (label)
210 tree label;
211{
212 int nlocals = DECL_MAX_LOCALS(current_function_decl);
213 int cur_length = stack_pointer + nlocals;
214 tree vec = LABEL_TYPE_STATE (label);
215 tree return_map;
216 if (vec == NULL_TREE)
217 {
218 vec = make_tree_vec (cur_length);
219 LABEL_TYPE_STATE (label) = vec;
220 while (--cur_length >= 0)
221 TREE_VEC_ELT (vec, cur_length) = type_map [cur_length];
222 return 1;
223 }
224 else
225 {
226 int i;
227 int changed = 0;
228 if (LABEL_IS_SUBR_START (label) && LABEL_VERIFIED (label)
229 && current_subr != label)
230 return_map = LABEL_RETURN_TYPE_STATE (label);
231 else
232 return_map = NULL_TREE;
233 if (TREE_VEC_LENGTH (vec) != cur_length)
234 {
235 return -1;
236 }
237 for (i = 0; i < cur_length; i++)
238 {
239 tree old_type = TREE_VEC_ELT (vec, i);
240 tree new_type = merge_types (old_type, type_map [i]);
241 if (TREE_VEC_ELT (vec, i) != new_type)
242 {
243 /* If there has been a change, note that since we must re-verify.
244 However, if the label is the start of a subroutine,
245 we don't care about local variables that are neither
246 set nor used in the sub-routine. */
247 if (return_map == NULL_TREE || i >= nlocals
248 || TREE_VEC_ELT (return_map, i) != TYPE_UNUSED
249 || (TYPE_IS_WIDE (new_type)
250 && TREE_VEC_ELT (return_map, i+1) != TYPE_UNUSED))
251 changed = 1;
252 }
253 TREE_VEC_ELT (vec, i) = new_type;
254 if (new_type == TYPE_UNKNOWN)
255 {
256 if (i >= nlocals)
257 return -1;
258 }
259 else if (TYPE_IS_WIDE (new_type))
260 i++;
261 }
262 return changed;
263 }
264}
265
266/* Handle dup-like operations. */
267
268static void
269type_stack_dup (size, offset)
270 int size, offset;
271{
272 tree type[4];
273 int index;
274 if (size + offset > stack_pointer)
275 error ("stack underflow - dup* operation");
276 for (index = 0; index < size + offset; index++)
277 {
278 type[index] = stack_type_map[stack_pointer - 1];
279 if (type[index] == void_type_node)
280 {
281 index++;
282 type[index] = stack_type_map[stack_pointer - 2];
283 if (! TYPE_IS_WIDE (type[index]))
284 fatal ("internal error - dup operation");
285 if (index == size || index == size + offset)
286 fatal ("dup operation splits 64-bit number");
287 }
288 pop_type (type[index]);
289 }
290 for (index = size; --index >= 0; )
291 {
292 if (type[index] != void_type_node)
293 push_type (type[index]);
294 }
295
296 for (index = size + offset; --index >= 0; )
297 {
298 if (type[index] != void_type_node)
299 push_type (type[index]);
300 }
301}
302
303/* This causes the next iteration to ignore the next instruction
304 and look for some other unhandled instruction. */
305#define INVALIDATE_PC (prevpc = -1, oldpc = PC, PC = INVALID_PC)
306#define INVALID_PC (-1)
307
308#define VERIFICATION_ERROR(MESSAGE) \
309 do { message = MESSAGE; goto verify_error; } while (0)
310
311#define PUSH_PENDING(LABEL) \
312 do { if ((message = check_pending_block (LABEL)) != NULL) \
313 goto verify_error; } while (0)
314
315#ifdef __GNUC__
316#define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; 1;})
317#else
318#define CHECK_PC_IN_RANGE(PC) (PC < 0 || PC > length ? \
319 (fatal("Bad byte codes.\n"), 0) : 1)
320#endif
321
322#define BCODE byte_ops
323
324/* Verify the bytecodes of the current method.
325 Return 1 on sucess, 0 on failure. */
326int
327verify_jvm_instructions (jcf, byte_ops, length)
328 JCF* jcf;
329 unsigned char* byte_ops;
330 long length;
331{
332 tree label;
333 int wide = 0;
334 int op_code;
335 int PC;
336 int oldpc; /* PC of start of instruction. */
337 int prevpc; /* If >= 0, PC of previous instruction. */
d4476be2 338 const char *message;
e04a16fb
AG
339 int i;
340 register unsigned char *p;
341 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
342 struct eh_range *eh_ranges;
ab45646c 343 tree return_type = TREE_TYPE (TREE_TYPE (current_function_decl));
e04a16fb
AG
344
345 jint int_value = -1;
346
347 pending_blocks = NULL_TREE;
348
349 /* Handle the exception table. */
350 method_init_exceptions ();
351 JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
352 i = JCF_readu2 (jcf);
353
354 /* We read the exception backwards. */
355 p = jcf->read_ptr + 8 * i;
356 while (--i >= 0)
357 {
358 int start_pc = GET_u2 (p-8);
359 int end_pc = GET_u2 (p-6);
360 int handler_pc = GET_u2 (p-4);
361 int catch_type = GET_u2 (p-2);
362 p -= 8;
363
364 if (start_pc < 0 || start_pc >= length
365 || end_pc < 0 || end_pc > length || start_pc >= end_pc
366 || handler_pc < 0 || handler_pc >= length
367 || (handler_pc >= start_pc && handler_pc < end_pc)
368 || ! (instruction_bits [start_pc] & BCODE_INSTRUCTION_START)
369 || ! (instruction_bits [end_pc] & BCODE_INSTRUCTION_START)
370 || ! (instruction_bits [handler_pc] & BCODE_INSTRUCTION_START))
371 {
372 error ("bad pc in exception_table");
373 return 0;
374 }
375
376 if (! add_handler (start_pc, end_pc,
377 lookup_label (handler_pc),
378 catch_type == 0 ? NULL_TREE
379 : get_class_constant (jcf, catch_type)))
380 {
381 error ("overlapping exception ranges are not supported");
382 return 0;
383 }
384
385 instruction_bits [handler_pc] |= BCODE_EXCEPTION_TARGET;
386 }
387
388 for (PC = 0;;)
389 {
390 int index;
391 tree type, tmp;
392 if (((PC != INVALID_PC
393 && instruction_bits [PC] & BCODE_TARGET) != 0)
394 || PC == 0)
395 {
396 PUSH_PENDING (lookup_label (PC));
397 INVALIDATE_PC;
398 }
399 if (PC == INVALID_PC)
400 {
401 label = pending_blocks;
402 if (label == NULL_TREE)
403 break; /* We're done! */
404 pending_blocks = LABEL_PENDING_CHAIN (label);
405 LABEL_CHANGED (label) = 0;
406
407 if (LABEL_IN_SUBR (label))
408 current_subr = LABEL_SUBR_START (label);
409 else
410 current_subr = NULL_TREE;
411
412 /* Restore type_map and stack_pointer from
413 LABEL_TYPE_STATE (label), and continue
414 compiling from there. */
415 load_type_state (label);
416 PC = LABEL_PC (label);
417 }
418 else if (PC >= length)
419 VERIFICATION_ERROR ("falling through end of method");
420
421 oldpc = PC;
422
423 if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
424 VERIFICATION_ERROR ("PC not at instruction start");
425
426 instruction_bits[PC] |= BCODE_VERIFIED;
427
428 eh_ranges = find_handler (oldpc);
429
430 op_code = byte_ops[PC++];
431 switch (op_code)
432 {
433 int is_static, is_putting;
434 case OPCODE_nop:
435 break;
436 case OPCODE_iconst_m1:
437 case OPCODE_iconst_0: case OPCODE_iconst_1: case OPCODE_iconst_2:
438 case OPCODE_iconst_3: case OPCODE_iconst_4: case OPCODE_iconst_5:
439 i = op_code - OPCODE_iconst_0;
440 goto push_int;
441 push_int:
442 if (byte_ops[PC] == OPCODE_newarray
443 || byte_ops[PC] == OPCODE_newarray)
444 int_value = i;
445 push_type (int_type_node); break;
446 case OPCODE_lconst_0: case OPCODE_lconst_1:
447 push_type (long_type_node); break;
448 case OPCODE_fconst_0: case OPCODE_fconst_1: case OPCODE_fconst_2:
449 push_type (float_type_node); break;
450 case OPCODE_dconst_0: case OPCODE_dconst_1:
451 push_type (double_type_node); break;
452 case OPCODE_bipush:
453 i = IMMEDIATE_s1;
454 goto push_int;
455 case OPCODE_sipush:
456 i = IMMEDIATE_s2;
457 goto push_int;
458 case OPCODE_iload: type = int_type_node; goto general_load;
459 case OPCODE_lload: type = long_type_node; goto general_load;
460 case OPCODE_fload: type = float_type_node; goto general_load;
461 case OPCODE_dload: type = double_type_node; goto general_load;
462 case OPCODE_aload: type = ptr_type_node; goto general_load;
463 general_load:
464 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
465 wide = 0;
466 goto load;
467 case OPCODE_iload_0: type = int_type_node; index = 0; goto load;
468 case OPCODE_iload_1: type = int_type_node; index = 1; goto load;
469 case OPCODE_iload_2: type = int_type_node; index = 2; goto load;
470 case OPCODE_iload_3: type = int_type_node; index = 3; goto load;
471 case OPCODE_lload_0: type = long_type_node; index = 0; goto load;
472 case OPCODE_lload_1: type = long_type_node; index = 1; goto load;
473 case OPCODE_lload_2: type = long_type_node; index = 2; goto load;
474 case OPCODE_lload_3: type = long_type_node; index = 3; goto load;
475 case OPCODE_fload_0: type = float_type_node; index = 0; goto load;
476 case OPCODE_fload_1: type = float_type_node; index = 1; goto load;
477 case OPCODE_fload_2: type = float_type_node; index = 2; goto load;
478 case OPCODE_fload_3: type = float_type_node; index = 3; goto load;
479 case OPCODE_dload_0: type = double_type_node; index = 0; goto load;
480 case OPCODE_dload_1: type = double_type_node; index = 1; goto load;
481 case OPCODE_dload_2: type = double_type_node; index = 2; goto load;
482 case OPCODE_dload_3: type = double_type_node; index = 3; goto load;
483 case OPCODE_aload_0: type = ptr_type_node; index = 0; goto load;
484 case OPCODE_aload_1: type = ptr_type_node; index = 1; goto load;
485 case OPCODE_aload_2: type = ptr_type_node; index = 2; goto load;
486 case OPCODE_aload_3: type = ptr_type_node; index = 3; goto load;
487 load:
488 if (index < 0
489 || (index + TYPE_IS_WIDE (type)
490 >= DECL_MAX_LOCALS (current_function_decl)))
491 VERIFICATION_ERROR ("invalid local variable index in load");
492 tmp = type_map[index];
493 if (tmp == TYPE_UNKNOWN || tmp == TYPE_SECOND
494 || (TYPE_IS_WIDE (type)
495 && type_map[index+1] != void_type_node)
496 || (type == ptr_type_node
497 ? TREE_CODE (tmp) != POINTER_TYPE
498 : type == int_type_node
499 ? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
500 : type != tmp))
501 VERIFICATION_ERROR("invalid local variable type in load");
502 push_type (tmp);
503 goto note_used;
504 case OPCODE_istore: type = int_type_node; goto general_store;
505 case OPCODE_lstore: type = long_type_node; goto general_store;
506 case OPCODE_fstore: type = float_type_node; goto general_store;
507 case OPCODE_dstore: type = double_type_node; goto general_store;
508 case OPCODE_astore: type = ptr_type_node; goto general_store;
509 general_store:
510 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
511 wide = 0;
512 goto store;
513 case OPCODE_istore_0: type = int_type_node; index = 0; goto store;
514 case OPCODE_istore_1: type = int_type_node; index = 1; goto store;
515 case OPCODE_istore_2: type = int_type_node; index = 2; goto store;
516 case OPCODE_istore_3: type = int_type_node; index = 3; goto store;
517 case OPCODE_lstore_0: type = long_type_node; index=0; goto store;
518 case OPCODE_lstore_1: type = long_type_node; index=1; goto store;
519 case OPCODE_lstore_2: type = long_type_node; index=2; goto store;
520 case OPCODE_lstore_3: type = long_type_node; index=3; goto store;
521 case OPCODE_fstore_0: type=float_type_node; index=0; goto store;
522 case OPCODE_fstore_1: type=float_type_node; index=1; goto store;
523 case OPCODE_fstore_2: type=float_type_node; index=2; goto store;
524 case OPCODE_fstore_3: type=float_type_node; index=3; goto store;
525 case OPCODE_dstore_0: type=double_type_node; index=0; goto store;
526 case OPCODE_dstore_1: type=double_type_node; index=1; goto store;
527 case OPCODE_dstore_2: type=double_type_node; index=2; goto store;
528 case OPCODE_dstore_3: type=double_type_node; index=3; goto store;
529 case OPCODE_astore_0: type = ptr_type_node; index = 0; goto store;
530 case OPCODE_astore_1: type = ptr_type_node; index = 1; goto store;
531 case OPCODE_astore_2: type = ptr_type_node; index = 2; goto store;
532 case OPCODE_astore_3: type = ptr_type_node; index = 3; goto store;
533 store:
534 if (index < 0
535 || (index + TYPE_IS_WIDE (type)
536 >= DECL_MAX_LOCALS (current_function_decl)))
537 {
538 VERIFICATION_ERROR ("invalid local variable index in store");
539 return 0;
540 }
541 type = pop_type (type);
542 type_map[index] = type;
543
544 /* If local variable changed, we need to reconsider eh handlers. */
545 prev_eh_ranges = NULL_EH_RANGE;
546
547 /* Allocate decl and rtx for this variable now, so if we're not
548 optmizing, we get a temporary that survives the whole method. */
549 find_local_variable (index, type, oldpc);
550
551 if (TYPE_IS_WIDE (type))
552 type_map[index+1] = TYPE_SECOND;
553 /* ... fall through to note_used ... */
554 note_used:
555 /* For store or load, note that local variable INDEX is used.
556 This is needed to verify try-finally sub-routines. */
557 if (current_subr)
558 {
559 tree vec = LABEL_RETURN_TYPE_STATE (current_subr);
560 tree subr_vec = LABEL_TYPE_STATE (current_subr);
561 int len = 1 + TYPE_IS_WIDE (type);
562 while (--len >= 0)
563 {
564 if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)
565 TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);
566 }
567 }
568 break;
569 case OPCODE_iadd:
570 case OPCODE_iand:
571 case OPCODE_idiv:
572 case OPCODE_imul:
573 case OPCODE_ior:
574 case OPCODE_irem:
575 case OPCODE_ishl:
576 case OPCODE_ishr:
577 case OPCODE_isub:
578 case OPCODE_iushr:
579 case OPCODE_ixor:
580 type = int_type_node; goto binop;
581 case OPCODE_ineg:
582 case OPCODE_i2c:
583 case OPCODE_i2b:
584 case OPCODE_i2s:
585 type = int_type_node; goto unop;
586 case OPCODE_ladd:
587 case OPCODE_land:
588 case OPCODE_ldiv:
589 case OPCODE_lsub:
590 case OPCODE_lmul:
591 case OPCODE_lrem:
592 case OPCODE_lor:
593 case OPCODE_lxor:
594 type = long_type_node; goto binop;
595 case OPCODE_lneg:
596 type = long_type_node; goto unop;
597 case OPCODE_fadd: case OPCODE_fsub:
598 case OPCODE_fmul: case OPCODE_fdiv: case OPCODE_frem:
599 type = float_type_node; goto binop;
600 case OPCODE_fneg:
601 type = float_type_node; goto unop;
602 case OPCODE_dadd: case OPCODE_dsub:
603 case OPCODE_dmul: case OPCODE_ddiv: case OPCODE_drem:
604 type = double_type_node; goto binop;
605 case OPCODE_dneg:
606 type = double_type_node; goto unop;
607 unop:
608 pop_type (type);
609 push_type (type);
610 break;
611 binop:
612 pop_type (type);
613 pop_type (type);
614 push_type (type);
615 break;
616 case OPCODE_lshl:
617 case OPCODE_lshr:
618 case OPCODE_lushr:
619 pop_type (int_type_node);
620 pop_type (long_type_node);
621 push_type (long_type_node);
622 break;
623 case OPCODE_iinc:
624 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
625 PC += wide + 1;
626 wide = 0;
627 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))
628 VERIFICATION_ERROR ("invalid local variable index in iinc");
629 tmp = type_map[index];
630 if (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)
631 VERIFICATION_ERROR ("invalid local variable type in iinc");
632 break;
633 case OPCODE_i2l:
634 pop_type (int_type_node); push_type (long_type_node); break;
635 case OPCODE_i2f:
636 pop_type (int_type_node); push_type (float_type_node); break;
637 case OPCODE_i2d:
638 pop_type (int_type_node); push_type (double_type_node); break;
639 case OPCODE_l2i:
640 pop_type (long_type_node); push_type (int_type_node); break;
641 case OPCODE_l2f:
642 pop_type (long_type_node); push_type (float_type_node); break;
643 case OPCODE_l2d:
644 pop_type (long_type_node); push_type (double_type_node); break;
645 case OPCODE_f2i:
646 pop_type (float_type_node); push_type (int_type_node); break;
647 case OPCODE_f2l:
648 pop_type (float_type_node); push_type (long_type_node); break;
649 case OPCODE_f2d:
650 pop_type (float_type_node); push_type (double_type_node); break;
651 case OPCODE_d2i:
652 pop_type (double_type_node); push_type (int_type_node); break;
653 case OPCODE_d2l:
654 pop_type (double_type_node); push_type (long_type_node); break;
655 case OPCODE_d2f:
656 pop_type (double_type_node); push_type (float_type_node); break;
657 case OPCODE_lcmp:
658 type = long_type_node; goto compare;
659 case OPCODE_fcmpl:
660 case OPCODE_fcmpg:
661 type = float_type_node; goto compare;
662 case OPCODE_dcmpl:
663 case OPCODE_dcmpg:
664 type = double_type_node; goto compare;
665 compare:
666 pop_type (type); pop_type (type);
667 push_type (int_type_node); break;
668 case OPCODE_ifeq:
669 case OPCODE_ifne:
670 case OPCODE_iflt:
671 case OPCODE_ifge:
672 case OPCODE_ifgt:
673 case OPCODE_ifle:
674 pop_type (int_type_node); goto cond;
675 case OPCODE_ifnull:
676 case OPCODE_ifnonnull:
677 pop_type (ptr_type_node ); goto cond;
678 case OPCODE_if_icmpeq:
679 case OPCODE_if_icmpne:
680 case OPCODE_if_icmplt:
681 case OPCODE_if_icmpge:
682 case OPCODE_if_icmpgt:
683 case OPCODE_if_icmple:
684 pop_type (int_type_node); pop_type (int_type_node); goto cond;
685 case OPCODE_if_acmpeq:
686 case OPCODE_if_acmpne:
687 pop_type (object_ptr_type_node); pop_type (object_ptr_type_node);
688 goto cond;
689 cond:
690 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
691 break;
692 case OPCODE_goto:
693 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));
694 INVALIDATE_PC;
695 break;
696 case OPCODE_wide:
697 switch (byte_ops[PC])
698 {
699 case OPCODE_iload: case OPCODE_lload:
700 case OPCODE_fload: case OPCODE_dload: case OPCODE_aload:
701 case OPCODE_istore: case OPCODE_lstore:
702 case OPCODE_fstore: case OPCODE_dstore: case OPCODE_astore:
703 case OPCODE_iinc:
704 case OPCODE_ret:
705 wide = 1;
706 break;
707 default:
708 VERIFICATION_ERROR ("invalid use of wide instruction");
709 }
710 break;
ab45646c
PB
711 case OPCODE_return: type = void_type_node; goto ret;
712 case OPCODE_ireturn:
713 if ((TREE_CODE (return_type) == BOOLEAN_TYPE
714 || TREE_CODE (return_type) == CHAR_TYPE
715 || TREE_CODE (return_type) == INTEGER_TYPE)
716 && TYPE_PRECISION (return_type) <= 32)
717 type = return_type;
718 else
719 type = NULL_TREE;
720 goto ret;
e04a16fb
AG
721 case OPCODE_lreturn: type = long_type_node; goto ret;
722 case OPCODE_freturn: type = float_type_node; goto ret;
723 case OPCODE_dreturn: type = double_type_node; goto ret;
ab45646c
PB
724 case OPCODE_areturn:
725 if (TREE_CODE (return_type) == POINTER_TYPE)
726 type = return_type;
727 else
728 type = NULL_TREE;
729 goto ret;
e04a16fb 730 ret:
ab45646c
PB
731 if (type != return_type)
732 VERIFICATION_ERROR ("incorrect ?return opcode");
733 if (type != void_type_node)
734 {
735 if (pop_type_0 (type) == NULL_TREE)
736 VERIFICATION_ERROR ("return value has wrong type");
737 }
e04a16fb
AG
738 INVALIDATE_PC;
739 break;
740 case OPCODE_getstatic: is_putting = 0; is_static = 1; goto field;
741 case OPCODE_putstatic: is_putting = 1; is_static = 1; goto field;
742 case OPCODE_getfield: is_putting = 0; is_static = 0; goto field;
743 case OPCODE_putfield: is_putting = 1; is_static = 0; goto field;
744 field:
745 {
746 int index = IMMEDIATE_u2;
e04a16fb
AG
747 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
748 tree field_type = get_type_from_signature (field_signature);
749 if (is_putting)
750 pop_type (field_type);
751 if (! is_static)
752 {
10b905f1
PB
753 int clindex = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
754 index);
755 tree self_type = get_class_constant (current_jcf, clindex);
e04a16fb 756 /* Defer actual checking until next pass. */
10b905f1
PB
757 if (pop_type_0 (self_type) == NULL_TREE)
758 VERIFICATION_ERROR ("incorrect type for field reference");
e04a16fb
AG
759 }
760 if (! is_putting)
761 push_type (field_type);
762 break;
763 }
764 case OPCODE_new:
765 push_type (get_class_constant (jcf, IMMEDIATE_u2));
766 break;
767 case OPCODE_dup: type_stack_dup (1, 0); break;
768 case OPCODE_dup_x1: type_stack_dup (1, 1); break;
769 case OPCODE_dup_x2: type_stack_dup (1, 2); break;
770 case OPCODE_dup2: type_stack_dup (2, 0); break;
771 case OPCODE_dup2_x1: type_stack_dup (2, 1); break;
772 case OPCODE_dup2_x2: type_stack_dup (2, 2); break;
773 case OPCODE_pop: index = 1; goto pop;
774 case OPCODE_pop2: index = 2; goto pop;
775 pop:
776 if (stack_pointer < index)
777 VERIFICATION_ERROR ("stack underflow");
778 stack_pointer -= index;
779 break;
780 case OPCODE_swap:
781 if (stack_pointer < 2)
782 VERIFICATION_ERROR ("stack underflow (in swap)");
783 else
784 {
785 tree type1 = stack_type_map[stack_pointer - 1];
786 tree type2 = stack_type_map[stack_pointer - 2];
787 if (type1 == void_type_node || type2 == void_type_node)
788 VERIFICATION_ERROR ("verifier (swap): double or long value");
789 stack_type_map[stack_pointer - 2] = type1;
790 stack_type_map[stack_pointer - 1] = type2;
791 }
792 break;
793 case OPCODE_ldc: index = IMMEDIATE_u1; goto ldc;
794 case OPCODE_ldc2_w:
795 case OPCODE_ldc_w:
796 index = IMMEDIATE_u2; goto ldc;
797 ldc:
798 if (index <= 0 || index >= JPOOL_SIZE(current_jcf))
799 VERIFICATION_ERROR ("bad constant pool index in ldc");
800 int_value = -1;
801 switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)
802 {
803 case CONSTANT_Integer: type = int_type_node; goto check_ldc;
804 case CONSTANT_Float: type = float_type_node; goto check_ldc;
805 case CONSTANT_String: type = string_type_node; goto check_ldc;
806 case CONSTANT_Long: type = long_type_node; goto check_ldc;
807 case CONSTANT_Double: type = double_type_node; goto check_ldc;
808 check_ldc:
809 if (TYPE_IS_WIDE (type) == (op_code == OPCODE_ldc2_w))
810 break;
811 /* ... else fall through ... */
812 default:
e04a16fb
AG
813 VERIFICATION_ERROR ("bad constant pool tag in ldc");
814 }
815 if (type == int_type_node)
816 {
817 i = TREE_INT_CST_LOW (get_constant (current_jcf, index));
818 goto push_int;
819 }
820 push_type (type);
821 break;
822
823 case OPCODE_invokevirtual:
824 case OPCODE_invokespecial:
825 case OPCODE_invokestatic:
826 case OPCODE_invokeinterface:
827 {
828 int index = IMMEDIATE_u2;
829 tree sig = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
830 tree self_type = get_class_constant
831 (current_jcf, COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
832 index));
833 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
834 tree method_type;
835 method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
836 IDENTIFIER_LENGTH (sig));
837 if (TREE_CODE (method_type) != FUNCTION_TYPE)
838 VERIFICATION_ERROR ("bad method signature");
839 pop_argument_types (TYPE_ARG_TYPES (method_type));
840
841 /* Can't invoke <clinit> */
842 if (method_name == clinit_identifier_node)
843 VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
844 /* Apart invokespecial, can't invoke <init> */
845 if (op_code != OPCODE_invokespecial
846 && method_name == init_identifier_node)
847 VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
848
849 if (op_code != OPCODE_invokestatic)
850 pop_type (self_type);
851
852 switch (op_code)
853 {
854 case OPCODE_invokeinterface:
855 {
856 int nargs = IMMEDIATE_u1;
857 int notZero = IMMEDIATE_u1;
858
859 if (!nargs || notZero)
860 VERIFICATION_ERROR
861 ("invalid argument number in invokeinterface");
862 break;
863 }
864 }
865
866 if (TREE_TYPE (method_type) != void_type_node)
867 push_type (TREE_TYPE (method_type));
868 break;
869 }
870
871 case OPCODE_arraylength:
872 /* Type checking actually made during code generation */
873 pop_type( ptr_type_node );
874 push_type( int_type_node );
875 break;
876
877 /* Q&D verification *or* more checking done during code generation
878 for byte/boolean/char/short, the value popped is a int coerced
879 into the right type before being stored. */
880 case OPCODE_iastore: type = int_type_node; goto astore;
881 case OPCODE_lastore: type = long_type_node; goto astore;
882 case OPCODE_fastore: type = float_type_node; goto astore;
883 case OPCODE_dastore: type = double_type_node; goto astore;
884 case OPCODE_aastore: type = ptr_type_node; goto astore;
885 case OPCODE_bastore: type = int_type_node; goto astore;
886 case OPCODE_castore: type = int_type_node; goto astore;
887 case OPCODE_sastore: type = int_type_node; goto astore;
888 astore:
889 /* FIXME - need better verification here */
890 pop_type (type); /* new value */
891 pop_type (int_type_node); /* index */
892 pop_type (ptr_type_node); /* array */
893 break;
894
895 /* Q&D verification *or* more checking done during code generation
896 for byte/boolean/char/short, the value pushed is a int. */
897 case OPCODE_iaload: type = int_type_node; goto aload;
898 case OPCODE_laload: type = long_type_node; goto aload;
899 case OPCODE_faload: type = float_type_node; goto aload;
900 case OPCODE_daload: type = double_type_node; goto aload;
901 case OPCODE_aaload: type = ptr_type_node; goto aload;
902 case OPCODE_baload: type = promote_type (byte_type_node); goto aload;
903 case OPCODE_caload: type = promote_type (char_type_node); goto aload;
904 case OPCODE_saload: type = promote_type (short_type_node); goto aload;
905 aload:
906 pop_type (int_type_node);
2dc219a1
PB
907 tmp = pop_type (ptr_type_node);
908 if (is_array_type_p (tmp))
909 type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
910 else if (tmp != TYPE_NULL)
e04a16fb 911 VERIFICATION_ERROR ("array load from non-array type");
2dc219a1 912 push_type (type);
e04a16fb
AG
913 break;
914
915 case OPCODE_anewarray:
916 type = get_class_constant (current_jcf, IMMEDIATE_u2);
917 type = promote_type (type);
918 goto newarray;
919
920 case OPCODE_newarray:
921 index = IMMEDIATE_u1;
922 type = decode_newarray_type (index);
923 if (type == NULL_TREE)
924 VERIFICATION_ERROR ("invalid type code in newarray opcode");
925 goto newarray;
926
927 newarray:
928 if (int_value >= 0 && prevpc >= 0)
929 {
930 /* If previous instruction pushed int constant,
931 we want to use it. */
932 switch (byte_ops[prevpc])
933 {
934 case OPCODE_iconst_0: case OPCODE_iconst_1:
935 case OPCODE_iconst_2: case OPCODE_iconst_3:
936 case OPCODE_iconst_4: case OPCODE_iconst_5:
937 case OPCODE_bipush: case OPCODE_sipush:
938 case OPCODE_ldc: case OPCODE_ldc_w:
939 break;
940 default:
941 int_value = -1;
942 }
943 }
944 else
945 int_value = -1;
946 type = build_java_array_type (type, int_value);
947 pop_type (int_type_node);
948 push_type (type);
949 break;
950
951 case OPCODE_multianewarray:
952 {
953 int ndim, i;
954 index = IMMEDIATE_u2;
955 ndim = IMMEDIATE_u1;
956
957 if( ndim < 1 )
958 VERIFICATION_ERROR ("number of dimension lower that 1 in multianewarray" );
959
960 for( i = 0; i < ndim; i++ )
961 pop_type (int_type_node);
962 push_type (get_class_constant (current_jcf, index));
963 break;
964 }
965
966 case OPCODE_aconst_null:
967 push_type (ptr_type_node);
968 break;
969
970 case OPCODE_athrow:
971 pop_type (throwable_type_node);
972 INVALIDATE_PC;
973 break;
974
975 case OPCODE_checkcast:
976 pop_type (ptr_type_node);
977 type = get_class_constant (current_jcf, IMMEDIATE_u2);
978 push_type (type);
979 break;
980 case OPCODE_instanceof:
981 pop_type (ptr_type_node);
982 get_class_constant (current_jcf, IMMEDIATE_u2);
e4de5a10 983 push_type (int_type_node);
e04a16fb
AG
984 break;
985
986 case OPCODE_tableswitch:
987 {
d4476be2 988 jint low, high;
e04a16fb 989
e4de5a10 990 pop_type (int_type_node);
e04a16fb
AG
991 while (PC%4)
992 {
993 if (byte_ops[PC++])
994 VERIFICATION_ERROR ("bad alignment in tableswitch pad");
995 }
996 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
997 low = IMMEDIATE_s4;
998 high = IMMEDIATE_s4;
999
1000 if (low > high)
1001 VERIFICATION_ERROR ("unsorted low/high value in tableswitch");
1002
1003 while (low++ <= high)
1004 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
66b48140 1005 INVALIDATE_PC;
e04a16fb
AG
1006 break;
1007 }
1008
1009 case OPCODE_lookupswitch:
1010 {
1011 jint npairs, last, not_registered = 1;
1012
e4de5a10 1013 pop_type (int_type_node);
e04a16fb
AG
1014 while (PC%4)
1015 {
1016 if (byte_ops[PC++])
1017 VERIFICATION_ERROR ("bad alignment in lookupswitch pad");
1018 }
1019
1020 PUSH_PENDING (lookup_label (oldpc+IMMEDIATE_s4));
1021 npairs = IMMEDIATE_s4;
1022
1023 if (npairs < 0)
1024 VERIFICATION_ERROR ("invalid number of targets in lookupswitch");
1025
1026 while (npairs--)
1027 {
1028 int match = IMMEDIATE_s4;
1029 if (not_registered)
1030 not_registered = 0;
1031 else if (last >= match)
1032 VERIFICATION_ERROR ("unsorted match value in lookupswitch");
1033
1034 last = match;
1035 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1036 }
66b48140 1037 INVALIDATE_PC;
e04a16fb
AG
1038 break;
1039 }
1040
1041 case OPCODE_monitorenter:
1042 /* fall thru */
1043 case OPCODE_monitorexit:
1044 pop_type (ptr_type_node);
1045 break;
1046
1047 case OPCODE_goto_w:
1048 PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
1049 INVALIDATE_PC;
1050 break;
1051
1052 case OPCODE_jsr:
1053 {
1054 tree target = lookup_label (oldpc + IMMEDIATE_s2);
1055 tree return_label = lookup_label (PC);
1056 push_type (return_address_type_node);
1057 if (! LABEL_VERIFIED (target))
1058 {
1059 /* first time seen */
1060 tree return_type_map;
1061 int nlocals = DECL_MAX_LOCALS (current_function_decl);
1062 index = nlocals + DECL_MAX_STACK (current_function_decl);
1063 return_type_map = make_tree_vec (index);
5a005d9e
PB
1064 while (index > nlocals)
1065 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
1066 while (index > 0)
1067 TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
e04a16fb
AG
1068 LABEL_RETURN_LABEL (target)
1069 = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
1070 LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
1071 LABEL_RETURN_TYPE_STATE (target) = return_type_map;
1072 LABEL_IS_SUBR_START (target) = 1;
1073 LABEL_IN_SUBR (target) = 1;
1074 LABEL_SUBR_START (target) = target;
1075 LABEL_SUBR_CONTEXT (target) = current_subr;
1076 }
1077 else if (! LABEL_IS_SUBR_START (target)
1078 || LABEL_SUBR_CONTEXT (target) != current_subr)
1079 VERIFICATION_ERROR ("label part of different subroutines");
1080
1081 i = merge_type_state (target);
1082 if (i != 0)
1083 {
1084 if (i < 0)
1085 VERIFICATION_ERROR ("types could not be merged at jsr");
1086 push_pending_label (target);
1087 }
1088 current_subr = target;
1089
1090 /* Chain return_pc onto LABEL_RETURN_LABELS (target) if needed. */
1091 if (! value_member (return_label, LABEL_RETURN_LABELS (target)))
1092 {
1093 LABEL_RETURN_LABELS (target)
1094 = tree_cons (NULL_TREE, return_label,
1095 LABEL_RETURN_LABELS (target));
1096 }
1097
1098 if (LABEL_VERIFIED (target))
1099 {
1100 tree return_map = LABEL_RETURN_TYPE_STATE (target);
1101 int len = TREE_VEC_LENGTH (return_map);
1102 stack_pointer = len - DECL_MAX_LOCALS (current_function_decl);
1103 while (--len >= 0)
1104 {
1105 if (TREE_VEC_ELT (return_map, len) != TYPE_UNUSED)
1106 type_map[len] = TREE_VEC_ELT (return_map, len);
1107 }
1108 current_subr = LABEL_SUBR_CONTEXT (target);
1109 PUSH_PENDING (return_label);
1110 }
1111
1112 INVALIDATE_PC;
1113 }
1114 break;
1115 case OPCODE_ret:
1116 if (current_subr == NULL)
1117 VERIFICATION_ERROR ("ret instruction not in a jsr subroutine");
1118 else
1119 {
1120 tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
1121 tree caller = LABEL_SUBR_CONTEXT (current_subr);
1122 int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
1123 index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;
1124 wide = 0;
1125 INVALIDATE_PC;
1126 if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl)
1127 || type_map[index] != TYPE_RETURN_ADDR)
1128 VERIFICATION_ERROR ("invalid ret index");
1129
1130 /* The next chunk of code is similar to an inlined version of
1131 * merge_type_state (LABEL_RETURN_LABEL (current_subr)).
1132 * The main differences are that LABEL_RETURN_LABEL is
1133 * pre-allocated by the jsr (but we don't know the size then);
1134 * and that we have to handle TYPE_UNUSED. */
1135
1136 if (! RETURN_MAP_ADJUSTED (ret_map))
1137 { /* First return from this subroutine - fix stack pointer. */
1138 TREE_VEC_LENGTH (ret_map) = size;
1139 for (index = size; --index >= 0; )
1140 {
1141 if (TREE_VEC_ELT (ret_map, index) != TYPE_UNUSED)
1142 TREE_VEC_ELT (ret_map, index) = type_map[index];
1143 }
1144 RETURN_MAP_ADJUSTED (ret_map) = 1;
1145 }
1146 else
1147 {
1148 if (TREE_VEC_LENGTH (ret_map) != size)
1149 VERIFICATION_ERROR ("inconsistent stack size on ret");
1150 for (index = 0; index < size; index++)
1151 {
1152 tree type = TREE_VEC_ELT (ret_map, index);
1153 if (type != TYPE_UNUSED)
1154 {
1155 type = merge_types (type, type_map [index]);
1156 TREE_VEC_ELT (ret_map, index) = type;
1157 if (type == TYPE_UNKNOWN)
1158 {
1159 if (index >= size - stack_pointer)
1160 VERIFICATION_ERROR
1161 ("inconsistent types on ret from jsr");
1162 }
1163 else if (TYPE_IS_WIDE (type))
1164 index++;
1165 }
1166 }
1167 }
1168
1169 /* Check if there are any more pending blocks in this subroutine.
1170 Because we push pending blocks in a last-in-first-out order,
1171 and because we don't push anything from our caller until we
1172 are done with this subroutine or anything nested in it,
1173 then we are done if the top of the pending_blocks stack is
1174 not in a subroutine, or it is in our caller. */
1175 if (pending_blocks == NULL_TREE
1176 || ! LABEL_IN_SUBR (pending_blocks)
1177 || LABEL_SUBR_START (pending_blocks) == caller)
1178 {
1179 /* Since we are done with this subroutine (i.e. this is the
1180 last ret from it), set up the (so far known) return
1181 address as pending - with the merged type state. */
1182 tmp = LABEL_RETURN_LABELS (current_subr);
1183 current_subr = caller;
1184 for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
1185 {
1186 tree return_label = TREE_VALUE (tmp);
1187 tree return_state = LABEL_TYPE_STATE (return_label);
1188 if (return_state == NULL_TREE)
1189 {
1190 /* This means means we had not verified the
1191 subroutine earlier, so this is the first jsr to
1192 call it. In this case, the type_map of the return
1193 address is just the current type_map - and that
1194 is handled by the following PUSH_PENDING. */
1195 }
1196 else
1197 {
1198 /* In this case we have to do a merge. But first
1199 restore the type_map for unused slots to those
1200 that were in effect at the jsr. */
1201 for (index = size; --index >= 0; )
1202 {
1203 type_map[index] = TREE_VEC_ELT (ret_map, index);
1204 if (type_map[index] == TYPE_UNUSED)
1205 type_map[index]
1206 = TREE_VEC_ELT (return_state, index);
1207 }
1208 }
1209 PUSH_PENDING (return_label);
1210 }
1211 }
1212 }
1213 break;
1214 case OPCODE_jsr_w:
1215 case OPCODE_ret_w:
1216 default:
1217 error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
1218 return 0;
1219 }
1220
1221 prevpc = oldpc;
1222
1223 /* The following test is true if we have entered or exited an exception
1224 handler range *or* we have done a store to a local variable.
1225 In either case we need to consider any exception handlers that
1226 might "follow" this instruction. */
1227
1228 if (eh_ranges != prev_eh_ranges)
1229 {
1230 int save_stack_pointer = stack_pointer;
1231 int index = DECL_MAX_LOCALS (current_function_decl);
1232 tree save_type = type_map[index];
1233 tree save_current_subr = current_subr;
1234 struct eh_range *ranges = find_handler (oldpc);
1235 stack_pointer = 1;
1236 for (; ranges != NULL_EH_RANGE; ranges = ranges->outer)
1237 {
1238 tree chain = ranges->handlers;
1239
1240 /* We need to determine if the handler is part of current_subr.
1241 The are two cases: (1) The exception catch range
1242 is entirely within current_subr. In that case the handler
1243 is also part of current_subr.
1244 (2) Some of the catch range is not in current_subr.
1245 In that case, the handler is *not* part of current_subr.
1246
1247 Figuring out which is the case is not necessarily obvious,
1248 in the presence of clever code generators (and obfuscators).
1249 We make a simplifying assumption that in case (2) we
1250 have that the current_subr is entirely within the catch range.
1251 In that case we can assume if that if a caller (the jsr) of
1252 a subroutine is within the catch range, then the handler is
1253 *not* part of the subroutine, and vice versa. */
1254
1255 current_subr = save_current_subr;
1256 for ( ; current_subr != NULL_TREE;
1257 current_subr = LABEL_SUBR_CONTEXT (current_subr))
1258 {
1259 tree return_labels = LABEL_RETURN_LABELS (current_subr);
1260 /* There could be multiple return_labels, but
1261 we only need to check one. */
1262 int return_pc = LABEL_PC (TREE_VALUE (return_labels));
1263 if (return_pc <= ranges->start_pc
1264 || return_pc > ranges->end_pc)
1265 break;
1266 }
1267
1268 for ( ; chain != NULL_TREE; chain = TREE_CHAIN (chain))
1269 {
1270 tree handler = TREE_VALUE (chain);
1271 tree type = TREE_PURPOSE (chain);
1272 if (type == NULL_TREE) /* a finally handler */
1273 type = throwable_type_node;
1274 type_map[index] = promote_type (type);
1275
1276 PUSH_PENDING (handler);
1277 }
1278 }
1279 stack_pointer = save_stack_pointer;
1280 current_subr = save_current_subr;
1281 type_map[index] = save_type;
1282 prev_eh_ranges = eh_ranges;
1283 }
1284 }
1285 return 1;
1286 bad_pc:
1287 message = "program counter out of range";
1288 goto verify_error;
1289 verify_error:
10b905f1
PB
1290 error ("verification error at PC=%d: %s", oldpc);
1291 error (message);
e04a16fb
AG
1292 return 0;
1293}
This page took 0.318286 seconds and 5 git commands to generate.