OSDN Git Service

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