OSDN Git Service

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