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