OSDN Git Service

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