OSDN Git Service

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