OSDN Git Service

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