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