OSDN Git Service

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