OSDN Git Service

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