OSDN Git Service

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