OSDN Git Service

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