OSDN Git Service

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