OSDN Git Service

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