OSDN Git Service

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