OSDN Git Service

* expr.c (java_push_constant_from_pool): Handle 'ldc class'.
[pf3gnuchains/gcc-fork.git] / gcc / java / expr.c
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC 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 GCC 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 GCC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, 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 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
27
28 #include "config.h"
29 #include "system.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "tree.h"
33 #include "real.h"
34 #include "rtl.h"
35 #include "flags.h"
36 #include "expr.h"
37 #include "java-tree.h"
38 #include "javaop.h"
39 #include "java-opcodes.h"
40 #include "jcf.h"
41 #include "java-except.h"
42 #include "parse.h"
43 #include "toplev.h"
44 #include "except.h"
45 #include "ggc.h"
46 #include "tree-gimple.h"
47 #include "target.h"
48
49 static void flush_quick_stack (void);
50 static void push_value (tree);
51 static tree pop_value (tree);
52 static void java_stack_swap (void);
53 static void java_stack_dup (int, int);
54 static void build_java_athrow (tree);
55 static void build_java_jsr (int, int);
56 static void build_java_ret (tree);
57 static void expand_java_multianewarray (tree, int);
58 static void expand_java_arraystore (tree);
59 static void expand_java_arrayload (tree);
60 static void expand_java_array_length (void);
61 static tree build_java_monitor (tree, tree);
62 static void expand_java_pushc (int, tree);
63 static void expand_java_return (tree);
64 static void expand_load_internal (int, tree, int);
65 static void expand_java_NEW (tree);
66 static void expand_java_INSTANCEOF (tree);
67 static void expand_java_CHECKCAST (tree);
68 static void expand_iinc (unsigned int, int, int);
69 static void expand_java_binop (tree, enum tree_code);
70 static void note_label (int, int);
71 static void expand_compare (enum tree_code, tree, tree, int);
72 static void expand_test (enum tree_code, tree, int);
73 static void expand_cond (enum tree_code, tree, int);
74 static void expand_java_goto (int);
75 static tree expand_java_switch (tree, int);
76 static void expand_java_add_case (tree, int, int);
77 #if 0
78 static void expand_java_call (int, int);
79 static void expand_java_ret (tree); 
80 #endif
81 static tree pop_arguments (tree); 
82 static void expand_invoke (int, int, int); 
83 static void expand_java_field_op (int, int, int); 
84 static void java_push_constant_from_pool (struct JCF *, int); 
85 static void java_stack_pop (int); 
86 static tree build_java_throw_out_of_bounds_exception (tree); 
87 static tree build_java_check_indexed_type (tree, tree); 
88 static unsigned char peek_opcode_at_pc (struct JCF *, int, int);
89 static void promote_arguments (void);
90
91 static GTY(()) tree operand_type[59];
92
93 static GTY(()) tree methods_ident;
94 static GTY(()) tree ncode_ident;
95 tree dtable_ident = NULL_TREE;
96
97 /* Set to nonzero value in order to emit class initialization code
98    before static field references.  */
99 int always_initialize_class_p = 0;
100
101 /* We store the stack state in two places:
102    Within a basic block, we use the quick_stack, which is a
103    pushdown list (TREE_LISTs) of expression nodes.
104    This is the top part of the stack;  below that we use find_stack_slot.
105    At the end of a basic block, the quick_stack must be flushed
106    to the stack slot array (as handled by find_stack_slot).
107    Using quick_stack generates better code (especially when
108    compiled without optimization), because we do not have to
109    explicitly store and load trees to temporary variables.
110
111    If a variable is on the quick stack, it means the value of variable
112    when the quick stack was last flushed.  Conceptually, flush_quick_stack
113    saves all the quick_stack elements in parallel.  However, that is
114    complicated, so it actually saves them (i.e. copies each stack value
115    to is home virtual register) from low indexes.  This allows a quick_stack
116    element at index i (counting from the bottom of stack the) to references
117    slot virtuals for register that are >= i, but not those that are deeper.
118    This convention makes most operations easier.  For example iadd works
119    even when the stack contains (reg[0], reg[1]):  It results in the
120    stack containing (reg[0]+reg[1]), which is OK.  However, some stack
121    operations are more complicated.  For example dup given a stack
122    containing (reg[0]) would yield (reg[0], reg[0]), which would violate
123    the convention, since stack value 1 would refer to a register with
124    lower index (reg[0]), which flush_quick_stack does not safely handle.
125    So dup cannot just add an extra element to the quick_stack, but iadd can.
126 */
127
128 static GTY(()) tree quick_stack;
129
130 /* A free-list of unused permanent TREE_LIST nodes.  */
131 static GTY((deletable)) tree tree_list_free_list;
132
133 /* The physical memory page size used in this computer.  See
134    build_field_ref().  */
135 static GTY(()) tree page_size;
136
137 /* The stack pointer of the Java virtual machine.
138    This does include the size of the quick_stack. */
139
140 int stack_pointer;
141
142 const unsigned char *linenumber_table;
143 int linenumber_count;
144
145 /* Largest pc so far in this method that has been passed to lookup_label. */
146 int highest_label_pc_this_method = -1;
147
148 /* Base value for this method to add to pc to get generated label. */
149 int start_label_pc_this_method = 0;
150
151 void
152 init_expr_processing (void)
153 {
154   operand_type[21] = operand_type[54] = int_type_node;
155   operand_type[22] = operand_type[55] = long_type_node;
156   operand_type[23] = operand_type[56] = float_type_node;
157   operand_type[24] = operand_type[57] = double_type_node;
158   operand_type[25] = operand_type[58] = ptr_type_node;
159 }
160
161 tree
162 java_truthvalue_conversion (tree expr)
163 {
164   /* It is simpler and generates better code to have only TRUTH_*_EXPR
165      or comparison expressions as truth values at this level.
166
167      This function should normally be identity for Java.  */
168
169   switch (TREE_CODE (expr))
170     {
171     case EQ_EXPR:   case NE_EXPR:   case UNEQ_EXPR: case LTGT_EXPR:
172     case LE_EXPR:   case GE_EXPR:   case LT_EXPR:   case GT_EXPR:
173     case UNLE_EXPR: case UNGE_EXPR: case UNLT_EXPR: case UNGT_EXPR:
174     case ORDERED_EXPR: case UNORDERED_EXPR:
175     case TRUTH_ANDIF_EXPR:
176     case TRUTH_ORIF_EXPR:
177     case TRUTH_AND_EXPR:
178     case TRUTH_OR_EXPR:
179     case TRUTH_XOR_EXPR:
180     case TRUTH_NOT_EXPR:
181     case ERROR_MARK:
182       return expr;
183
184     case INTEGER_CST:
185       return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
186
187     case REAL_CST:
188       return real_zerop (expr) ? boolean_false_node : boolean_true_node;
189
190     /* are these legal? XXX JH */
191     case NEGATE_EXPR:
192     case ABS_EXPR:
193     case FLOAT_EXPR:
194       /* These don't change whether an object is nonzero or zero.  */
195       return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
196
197     case COND_EXPR:
198       /* Distribute the conversion into the arms of a COND_EXPR.  */
199       return fold_build3 (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
200                           java_truthvalue_conversion (TREE_OPERAND (expr, 1)),
201                           java_truthvalue_conversion (TREE_OPERAND (expr, 2)));
202
203     case NOP_EXPR:
204       /* If this is widening the argument, we can ignore it.  */
205       if (TYPE_PRECISION (TREE_TYPE (expr))
206           >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
207         return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
208       /* fall through to default */
209
210     default:
211       return fold_build2 (NE_EXPR, boolean_type_node,
212                           expr, boolean_false_node);
213     }
214 }
215
216 /* Save any stack slots that happen to be in the quick_stack into their
217    home virtual register slots.
218
219    The copy order is from low stack index to high, to support the invariant
220    that the expression for a slot may contain decls for stack slots with
221    higher (or the same) index, but not lower. */
222
223 static void
224 flush_quick_stack (void)
225 {
226   int stack_index = stack_pointer;
227   tree prev, cur, next;
228
229   /* First reverse the quick_stack, and count the number of slots it has. */
230   for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
231     {
232       next = TREE_CHAIN (cur);
233       TREE_CHAIN (cur) = prev;
234       prev = cur;
235       stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
236     }
237   quick_stack = prev;
238
239   while (quick_stack != NULL_TREE)
240     {
241       tree decl;
242       tree node = quick_stack, type;
243       quick_stack = TREE_CHAIN (node);
244       TREE_CHAIN (node) = tree_list_free_list;
245       tree_list_free_list = node;
246       node = TREE_VALUE (node);
247       type = TREE_TYPE (node);
248
249       decl = find_stack_slot (stack_index, type);
250       if (decl != node)
251         java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (node), decl, node));
252       stack_index += 1 + TYPE_IS_WIDE (type);
253     }
254 }
255
256 /* Push TYPE on the type stack.
257    Return true on success, 0 on overflow. */
258
259 int
260 push_type_0 (tree type)
261 {
262   int n_words;
263   type = promote_type (type);
264   n_words = 1 + TYPE_IS_WIDE (type);
265   if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
266     return 0;
267   /* Allocate decl for this variable now, so we get a temporary that
268      survives the whole method. */
269   find_stack_slot (stack_pointer, type);
270   stack_type_map[stack_pointer++] = type;
271   n_words--;
272   while (--n_words >= 0)
273     stack_type_map[stack_pointer++] = TYPE_SECOND;
274   return 1;
275 }
276
277 void
278 push_type (tree type)
279 {
280   int r = push_type_0 (type);
281   gcc_assert (r);
282 }
283
284 static void
285 push_value (tree value)
286 {
287   tree type = TREE_TYPE (value);
288   if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
289     {
290       type = promote_type (type);
291       value = convert (type, value);
292     }
293   push_type (type);
294   if (tree_list_free_list == NULL_TREE)
295     quick_stack = tree_cons (NULL_TREE, value, quick_stack);
296   else
297     {
298       tree node = tree_list_free_list;
299       tree_list_free_list = TREE_CHAIN (tree_list_free_list);
300       TREE_VALUE (node) = value;
301       TREE_CHAIN (node) = quick_stack;
302       quick_stack = node;
303     }
304 }
305
306 /* Pop a type from the type stack.
307    TYPE is the expected type.   Return the actual type, which must be
308    convertible to TYPE.
309    On an error, *MESSAGEP is set to a freshly malloc'd error message. */
310
311 tree
312 pop_type_0 (tree type, char **messagep)
313 {
314   int n_words;
315   tree t;
316   *messagep = NULL;
317   if (TREE_CODE (type) == RECORD_TYPE)
318     type = promote_type (type);
319   n_words = 1 + TYPE_IS_WIDE (type);
320   if (stack_pointer < n_words)
321     {
322       *messagep = xstrdup ("stack underflow");
323       return type;
324     }
325   while (--n_words > 0)
326     {
327       if (stack_type_map[--stack_pointer] != void_type_node)
328         {
329           *messagep = xstrdup ("Invalid multi-word value on type stack");
330           return type;
331         }
332     }
333   t = stack_type_map[--stack_pointer];
334   if (type == NULL_TREE || t == type)
335     return t;
336   if (TREE_CODE (t) == TREE_LIST)
337     {      
338       do
339         {
340           tree tt = TREE_PURPOSE (t);
341           if (! can_widen_reference_to (tt, type))
342             {
343               t = tt;
344               goto fail;
345             }
346           t = TREE_CHAIN (t);
347         }
348       while (t);
349       return t;
350     }
351   if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
352       && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
353     return t;
354   if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
355     {
356       /* If the expected type we've been passed is object or ptr
357          (i.e. void*), the caller needs to know the real type.  */
358       if (type == ptr_type_node || type == object_ptr_type_node)
359         return t;
360
361       /* Since the verifier has already run, we know that any
362          types we see will be compatible.  In BC mode, this fact
363          may be checked at runtime, but if that is so then we can
364          assume its truth here as well.  So, we always succeed
365          here, with the expected type.  */
366       return type;
367     }
368
369   if (! flag_verify_invocations && flag_indirect_dispatch
370       && t == object_ptr_type_node)
371     {
372       if (type != ptr_type_node)
373         warning (0, "need to insert runtime check for %s", 
374                  xstrdup (lang_printable_name (type, 0)));
375       return type;
376     }
377
378   /* lang_printable_name uses a static buffer, so we must save the result
379      from calling it the first time.  */
380  fail:
381   {
382     char *temp = xstrdup (lang_printable_name (type, 0));
383     /* If the stack contains a multi-word type, keep popping the stack until 
384        the real type is found.  */
385     while (t == void_type_node)
386       t = stack_type_map[--stack_pointer];
387     *messagep = concat ("expected type '", temp,
388                         "' but stack contains '", lang_printable_name (t, 0),
389                         "'", NULL);
390     free (temp);
391   }
392   return type;
393 }
394
395 /* Pop a type from the type stack.
396    TYPE is the expected type.  Return the actual type, which must be
397    convertible to TYPE, otherwise call error. */
398
399 tree
400 pop_type (tree type)
401 {
402   char *message = NULL;
403   type = pop_type_0 (type, &message);
404   if (message != NULL)
405     {
406       error ("%s", message);
407       free (message);
408     }
409   return type;
410 }
411
412 \f
413 /* Return true if two type assertions are equal.  */
414
415 static int
416 type_assertion_eq (const void * k1_p, const void * k2_p)
417 {
418   type_assertion k1 = *(type_assertion *)k1_p;
419   type_assertion k2 = *(type_assertion *)k2_p;
420   return (k1.assertion_code == k2.assertion_code
421           && k1.op1 == k2.op1
422           && k1.op2 == k2.op2);
423 }
424
425 /* Hash a type assertion.  */
426
427 static hashval_t
428 type_assertion_hash (const void *p)
429 {
430   const type_assertion *k_p = p;
431   hashval_t hash = iterative_hash (&k_p->assertion_code, sizeof
432                                    k_p->assertion_code, 0);
433   hash = iterative_hash (&k_p->op1, sizeof k_p->op1, hash);
434   return iterative_hash (&k_p->op2, sizeof k_p->op2, hash);
435 }
436
437 /* Add an entry to the type assertion table for the given class.  
438    CLASS is the class for which this assertion will be evaluated by the 
439    runtime during loading/initialization.
440    ASSERTION_CODE is the 'opcode' or type of this assertion: see java-tree.h.
441    OP1 and OP2 are the operands. The tree type of these arguments may be
442    specific to each assertion_code. */
443
444 void
445 add_type_assertion (tree class, int assertion_code, tree op1, tree op2)
446 {
447   htab_t assertions_htab;
448   type_assertion as;
449   void **as_pp;
450
451   assertions_htab = TYPE_ASSERTIONS (class);
452   if (assertions_htab == NULL)
453     {
454       assertions_htab = htab_create_ggc (7, type_assertion_hash, 
455                                          type_assertion_eq, NULL);
456       TYPE_ASSERTIONS (current_class) = assertions_htab;
457     }
458
459   as.assertion_code = assertion_code;
460   as.op1 = op1;
461   as.op2 = op2;
462
463   as_pp = htab_find_slot (assertions_htab, &as, INSERT);
464
465   /* Don't add the same assertion twice.  */
466   if (*as_pp)
467     return;
468
469   *as_pp = ggc_alloc (sizeof (type_assertion));
470   **(type_assertion **)as_pp = as;
471 }
472
473 \f
474 /* Return 1 if SOURCE_TYPE can be safely widened to TARGET_TYPE.
475    Handles array types and interfaces.  */
476
477 int
478 can_widen_reference_to (tree source_type, tree target_type)
479 {
480   if (source_type == ptr_type_node || target_type == object_ptr_type_node)
481     return 1;
482
483   /* Get rid of pointers  */
484   if (TREE_CODE (source_type) == POINTER_TYPE)
485     source_type = TREE_TYPE (source_type);
486   if (TREE_CODE (target_type) == POINTER_TYPE)
487     target_type = TREE_TYPE (target_type);
488
489   if (source_type == target_type)
490     return 1;
491
492   /* FIXME: This is very pessimistic, in that it checks everything,
493      even if we already know that the types are compatible.  If we're
494      to support full Java class loader semantics, we need this.
495      However, we could do something more optimal.  */
496   if (! flag_verify_invocations)
497     {
498       add_type_assertion (current_class, JV_ASSERT_TYPES_COMPATIBLE, 
499                           source_type, target_type);
500
501       if (!quiet_flag)
502        warning (0, "assert: %s is assign compatible with %s", 
503                 xstrdup (lang_printable_name (target_type, 0)),
504                 xstrdup (lang_printable_name (source_type, 0)));
505       /* Punt everything to runtime.  */
506       return 1;
507     }
508
509   if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
510     {
511       return 1;
512     }
513   else
514     {
515       if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
516         {
517           HOST_WIDE_INT source_length, target_length;
518           if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
519             {
520               /* An array implements Cloneable and Serializable.  */
521               tree name = DECL_NAME (TYPE_NAME (target_type));
522               return (name == java_lang_cloneable_identifier_node
523                       || name == java_io_serializable_identifier_node);
524             }
525           target_length = java_array_type_length (target_type);
526           if (target_length >= 0)
527             {
528               source_length = java_array_type_length (source_type);
529               if (source_length != target_length)
530                 return 0;
531             }
532           source_type = TYPE_ARRAY_ELEMENT (source_type);
533           target_type = TYPE_ARRAY_ELEMENT (target_type);
534           if (source_type == target_type)
535             return 1;
536           if (TREE_CODE (source_type) != POINTER_TYPE
537               || TREE_CODE (target_type) != POINTER_TYPE)
538             return 0;
539           return can_widen_reference_to (source_type, target_type);
540         }
541       else
542         {
543           int source_depth = class_depth (source_type);
544           int target_depth = class_depth (target_type);
545
546           if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
547             {
548               if (! quiet_flag)
549                 warning (0, "assert: %s is assign compatible with %s", 
550                          xstrdup (lang_printable_name (target_type, 0)),
551                          xstrdup (lang_printable_name (source_type, 0)));
552               return 1;
553             }
554
555           /* class_depth can return a negative depth if an error occurred */
556           if (source_depth < 0 || target_depth < 0)
557             return 0;
558
559           if (CLASS_INTERFACE (TYPE_NAME (target_type)))
560             {
561               /* target_type is OK if source_type or source_type ancestors
562                  implement target_type. We handle multiple sub-interfaces  */
563               tree binfo, base_binfo;
564               int i;
565
566               for (binfo = TYPE_BINFO (source_type), i = 0;
567                    BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
568                 if (can_widen_reference_to
569                     (BINFO_TYPE (base_binfo), target_type))
570                   return 1;
571               
572               if (!i)
573                 return 0;
574             }
575
576           for ( ; source_depth > target_depth;  source_depth--) 
577             {
578               source_type
579                 = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (source_type), 0));
580             }
581           return source_type == target_type;
582         }
583     }
584 }
585
586 static tree
587 pop_value (tree type)
588 {
589   type = pop_type (type);
590   if (quick_stack)
591     {
592       tree node = quick_stack;
593       quick_stack = TREE_CHAIN (quick_stack);
594       TREE_CHAIN (node) = tree_list_free_list;
595       tree_list_free_list = node;
596       node = TREE_VALUE (node);
597       return node;
598     }
599   else
600     return find_stack_slot (stack_pointer, promote_type (type));
601 }
602
603
604 /* Pop and discard the top COUNT stack slots. */
605
606 static void
607 java_stack_pop (int count)
608 {
609   while (count > 0)
610     {
611       tree type, val;
612
613       gcc_assert (stack_pointer != 0);
614
615       type = stack_type_map[stack_pointer - 1];
616       if (type == TYPE_SECOND)
617         {
618           count--;
619           gcc_assert (stack_pointer != 1 && count > 0);
620
621           type = stack_type_map[stack_pointer - 2];
622         }
623       val = pop_value (type);
624       count--;
625     }
626 }
627
628 /* Implement the 'swap' operator (to swap two top stack slots). */
629
630 static void
631 java_stack_swap (void)
632 {
633   tree type1, type2;
634   tree temp;
635   tree decl1, decl2;
636
637   if (stack_pointer < 2
638       || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
639       || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
640       || type1 == TYPE_SECOND || type2 == TYPE_SECOND
641       || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
642     /* Bad stack swap.  */
643     abort ();
644   /* Bad stack swap.  */
645
646   flush_quick_stack ();
647   decl1 = find_stack_slot (stack_pointer - 1, type1);
648   decl2 = find_stack_slot (stack_pointer - 2, type2);
649   temp = build_decl (VAR_DECL, NULL_TREE, type1);
650   java_add_local_var (temp);
651   java_add_stmt (build2 (MODIFY_EXPR, type1, temp, decl1));
652   java_add_stmt (build2 (MODIFY_EXPR, type2, 
653                          find_stack_slot (stack_pointer - 1, type2),
654                          decl2));
655   java_add_stmt (build2 (MODIFY_EXPR, type1, 
656                          find_stack_slot (stack_pointer - 2, type1),
657                          temp));
658   stack_type_map[stack_pointer - 1] = type2;
659   stack_type_map[stack_pointer - 2] = type1;
660 }
661
662 static void
663 java_stack_dup (int size, int offset)
664 {
665   int low_index = stack_pointer - size - offset;
666   int dst_index;
667   if (low_index < 0)
668     error ("stack underflow - dup* operation");
669
670   flush_quick_stack ();
671
672   stack_pointer += size;
673   dst_index = stack_pointer;
674
675   for (dst_index = stack_pointer;  --dst_index >= low_index; )
676     {
677       tree type;
678       int src_index = dst_index - size;
679       if (src_index < low_index)
680         src_index = dst_index + size + offset;
681       type = stack_type_map [src_index];
682       if (type == TYPE_SECOND)
683         {
684           /* Dup operation splits 64-bit number.  */
685           gcc_assert (src_index > low_index);
686
687           stack_type_map[dst_index] = type;
688           src_index--;  dst_index--;
689           type = stack_type_map[src_index];
690           gcc_assert (TYPE_IS_WIDE (type));
691         }
692       else
693         gcc_assert (! TYPE_IS_WIDE (type));
694
695       if (src_index != dst_index)
696         {
697           tree src_decl = find_stack_slot (src_index, type);
698           tree dst_decl = find_stack_slot (dst_index, type);
699
700           java_add_stmt 
701             (build2 (MODIFY_EXPR, TREE_TYPE (dst_decl), dst_decl, src_decl));
702           stack_type_map[dst_index] = type;
703         }
704     }
705 }
706
707 /* Calls _Jv_Throw or _Jv_Sjlj_Throw.  Discard the contents of the
708    value stack. */
709
710 static void
711 build_java_athrow (tree node)
712 {
713   tree call;
714
715   call = build3 (CALL_EXPR,
716                  void_type_node,
717                  build_address_of (throw_node),
718                  build_tree_list (NULL_TREE, node),
719                  NULL_TREE);
720   TREE_SIDE_EFFECTS (call) = 1;
721   java_add_stmt (call);
722   java_stack_pop (stack_pointer);
723 }
724
725 /* Implementation for jsr/ret */
726
727 static void
728 build_java_jsr (int target_pc, int return_pc)
729 {
730   tree where =  lookup_label (target_pc);
731   tree ret = lookup_label (return_pc);
732   tree ret_label = fold_build1 (ADDR_EXPR, return_address_type_node, ret);
733   push_value (ret_label);
734   flush_quick_stack ();
735   java_add_stmt (build1 (GOTO_EXPR, void_type_node, where));
736
737   /* Do not need to emit the label here.  We noted the existence of the
738      label as a jump target in note_instructions; we'll emit the label
739      for real at the beginning of the expand_byte_code loop.  */
740 }
741
742 static void
743 build_java_ret (tree location)
744 {
745   java_add_stmt (build1 (GOTO_EXPR, void_type_node, location));
746 }
747  
748 /* Implementation of operations on array: new, load, store, length */
749
750 tree
751 decode_newarray_type (int atype)
752 {
753   switch (atype)
754     {
755     case 4:  return boolean_type_node;
756     case 5:  return char_type_node;
757     case 6:  return float_type_node;
758     case 7:  return double_type_node;
759     case 8:  return byte_type_node;
760     case 9:  return short_type_node;
761     case 10: return int_type_node;
762     case 11: return long_type_node;
763     default: return NULL_TREE;
764     }
765 }
766
767 /* Map primitive type to the code used by OPCODE_newarray. */
768
769 int
770 encode_newarray_type (tree type)
771 {
772   if (type == boolean_type_node)
773     return 4;
774   else if (type == char_type_node)
775     return 5;
776   else if (type == float_type_node)
777     return 6;
778   else if (type == double_type_node)
779     return 7;
780   else if (type == byte_type_node)
781     return 8;
782   else if (type == short_type_node)
783     return 9;
784   else if (type == int_type_node)
785     return 10;
786   else if (type == long_type_node)
787     return 11;
788   else
789     gcc_unreachable ();
790 }
791
792 /* Build a call to _Jv_ThrowBadArrayIndex(), the
793    ArrayIndexOfBoundsException exception handler.  */
794
795 static tree
796 build_java_throw_out_of_bounds_exception (tree index)
797 {
798   tree node = build3 (CALL_EXPR, int_type_node,
799                       build_address_of (soft_badarrayindex_node), 
800                       build_tree_list (NULL_TREE, index), NULL_TREE);
801   TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
802   return (node);
803 }
804
805 /* Return the length of an array. Doesn't perform any checking on the nature
806    or value of the array NODE. May be used to implement some bytecodes.  */
807
808 tree
809 build_java_array_length_access (tree node)
810 {
811   tree type = TREE_TYPE (node);
812   tree array_type = TREE_TYPE (type);
813   HOST_WIDE_INT length;
814
815   if (!is_array_type_p (type))
816     {
817       /* With the new verifier, we will see an ordinary pointer type
818          here.  In this case, we just use an arbitrary array type.  */
819       array_type = build_java_array_type (object_ptr_type_node, -1);
820       type = promote_type (array_type);
821     }
822
823   length = java_array_type_length (type);
824   if (length >= 0)
825     return build_int_cst (NULL_TREE, length);
826
827   node = build3 (COMPONENT_REF, int_type_node,
828                  build_java_indirect_ref (array_type, node,
829                                           flag_check_references),
830                  lookup_field (&array_type, get_identifier ("length")),
831                  NULL_TREE);
832   IS_ARRAY_LENGTH_ACCESS (node) = 1;
833   return node;
834 }
835
836 /* Optionally checks a reference against the NULL pointer.  ARG1: the
837    expr, ARG2: we should check the reference.  Don't generate extra
838    checks if we're not generating code.  */
839
840 tree 
841 java_check_reference (tree expr, int check)
842 {
843   if (!flag_syntax_only && check)
844     {
845       expr = save_expr (expr);
846       expr = build3 (COND_EXPR, TREE_TYPE (expr),
847                      build2 (EQ_EXPR, boolean_type_node,
848                              expr, null_pointer_node),
849                      build3 (CALL_EXPR, void_type_node, 
850                              build_address_of (soft_nullpointer_node),
851                              NULL_TREE, NULL_TREE),
852                      expr);
853     }
854
855   return expr;
856 }
857
858 /* Reference an object: just like an INDIRECT_REF, but with checking.  */
859
860 tree
861 build_java_indirect_ref (tree type, tree expr, int check)
862 {
863   tree t;
864   t = java_check_reference (expr, check);
865   t = convert (build_pointer_type (type), t);
866   return build1 (INDIRECT_REF, type, t);
867 }
868
869 /* Implement array indexing (either as l-value or r-value).
870    Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
871    Optionally performs bounds checking and/or test to NULL.
872    At this point, ARRAY should have been verified as an array.  */
873
874 tree
875 build_java_arrayaccess (tree array, tree type, tree index)
876 {
877   tree node, throw = NULL_TREE;
878   tree data_field;
879   tree ref;
880   tree array_type = TREE_TYPE (TREE_TYPE (array));
881
882   if (!is_array_type_p (TREE_TYPE (array)))
883     {
884       /* With the new verifier, we will see an ordinary pointer type
885          here.  In this case, we just use the correct array type.  */
886       array_type = build_java_array_type (type, -1);
887     }
888
889   if (flag_bounds_check)
890     {
891       /* Generate:
892        * (unsigned jint) INDEX >= (unsigned jint) LEN
893        *    && throw ArrayIndexOutOfBoundsException.
894        * Note this is equivalent to and more efficient than:
895        * INDEX < 0 || INDEX >= LEN && throw ... */
896       tree test;
897       tree len = convert (unsigned_int_type_node,
898                           build_java_array_length_access (array));
899       test = fold_build2 (GE_EXPR, boolean_type_node, 
900                           convert (unsigned_int_type_node, index),
901                           len);
902       if (! integer_zerop (test))
903         {
904           throw = build2 (TRUTH_ANDIF_EXPR, int_type_node, test,
905                           build_java_throw_out_of_bounds_exception (index));
906           /* allows expansion within COMPOUND */
907           TREE_SIDE_EFFECTS( throw ) = 1;
908         }
909     }
910
911   /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
912      to have the bounds check evaluated first. */
913   if (throw != NULL_TREE)
914     index = build2 (COMPOUND_EXPR, int_type_node, throw, index);
915  
916   data_field = lookup_field (&array_type, get_identifier ("data"));
917
918   ref = build3 (COMPONENT_REF, TREE_TYPE (data_field),    
919                 build_java_indirect_ref (array_type, array, 
920                                          flag_check_references),
921                 data_field, NULL_TREE);
922   
923   node = build4 (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
924   return node;
925 }
926
927 /* Generate code to throw an ArrayStoreException if OBJECT is not assignable
928    (at runtime) to an element of ARRAY.  A NOP_EXPR is returned if it can
929    determine that no check is required. */
930
931 tree
932 build_java_arraystore_check (tree array, tree object)
933 {
934   tree check, element_type, source;
935   tree array_type_p = TREE_TYPE (array);
936   tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));
937
938   if (! flag_verify_invocations)
939     {
940       /* With the new verifier, we don't track precise types.  FIXME:
941          performance regression here.  */
942       element_type = TYPE_NAME (object_type_node);
943     }
944   else
945     {
946       gcc_assert (is_array_type_p (array_type_p));
947
948       /* Get the TYPE_DECL for ARRAY's element type. */
949       element_type
950         = TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
951     }
952
953   gcc_assert (TREE_CODE (element_type) == TYPE_DECL
954               && TREE_CODE (object_type) == TYPE_DECL);
955
956   if (!flag_store_check)
957     return build1 (NOP_EXPR, array_type_p, array);
958
959   /* No check is needed if the element type is final.  Also check that
960      element_type matches object_type, since in the bytecode
961      compilation case element_type may be the actual element type of
962      the array rather than its declared type.  However, if we're doing
963      indirect dispatch, we can't do the `final' optimization.  */
964   if (element_type == object_type
965       && ! flag_indirect_dispatch
966       && CLASS_FINAL (element_type))
967     return build1 (NOP_EXPR, array_type_p, array);
968   
969   /* OBJECT might be wrapped by a SAVE_EXPR. */
970   if (TREE_CODE (object) == SAVE_EXPR)
971     source = TREE_OPERAND (object, 0);
972   else
973     source = object;
974   
975   /* Avoid the check if OBJECT was just loaded from the same array. */
976   if (TREE_CODE (source) == ARRAY_REF)
977     {
978       tree target;
979       source = TREE_OPERAND (source, 0); /* COMPONENT_REF. */
980       source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
981       source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
982       if (TREE_CODE (source) == SAVE_EXPR)
983         source = TREE_OPERAND (source, 0);
984       
985       target = array;
986       if (TREE_CODE (target) == SAVE_EXPR)
987         target = TREE_OPERAND (target, 0);
988       
989       if (source == target)
990         return build1 (NOP_EXPR, array_type_p, array);
991     }
992
993   /* Build an invocation of _Jv_CheckArrayStore */
994   check = build3 (CALL_EXPR, void_type_node,
995                   build_address_of (soft_checkarraystore_node),
996                   tree_cons (NULL_TREE, array,
997                              build_tree_list (NULL_TREE, object)),
998                   NULL_TREE);
999   TREE_SIDE_EFFECTS (check) = 1;
1000
1001   return check;
1002 }
1003
1004 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
1005    ARRAY_NODE. This function is used to retrieve something less vague than
1006    a pointer type when indexing the first dimension of something like [[<t>.
1007    May return a corrected type, if necessary, otherwise INDEXED_TYPE is
1008    return unchanged.  */
1009
1010 static tree
1011 build_java_check_indexed_type (tree array_node ATTRIBUTE_UNUSED,
1012                                tree indexed_type)
1013 {
1014   /* We used to check to see if ARRAY_NODE really had array type.
1015      However, with the new verifier, this is not necessary, as we know
1016      that the object will be an array of the appropriate type.  */
1017
1018   return indexed_type;
1019 }
1020
1021 /* newarray triggers a call to _Jv_NewPrimArray. This function should be 
1022    called with an integer code (the type of array to create), and the length
1023    of the array to create.  */
1024
1025 tree
1026 build_newarray (int atype_value, tree length)
1027 {
1028   tree type_arg;
1029
1030   tree prim_type = decode_newarray_type (atype_value);
1031   tree type
1032     = build_java_array_type (prim_type,
1033                              host_integerp (length, 0) == INTEGER_CST
1034                              ? tree_low_cst (length, 0) : -1);
1035
1036   /* If compiling to native, pass a reference to the primitive type class 
1037      and save the runtime some work. However, the bytecode generator
1038      expects to find the type_code int here. */
1039   if (flag_emit_class_files)
1040     type_arg = build_int_cst (NULL_TREE, atype_value);
1041   else
1042     type_arg = build_class_ref (prim_type);
1043
1044   return build3 (CALL_EXPR, promote_type (type),
1045                  build_address_of (soft_newarray_node),
1046                  tree_cons (NULL_TREE, 
1047                             type_arg,
1048                             build_tree_list (NULL_TREE, length)),
1049                  NULL_TREE);
1050 }
1051
1052 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
1053    of the dimension. */
1054
1055 tree
1056 build_anewarray (tree class_type, tree length)
1057 {
1058   tree type
1059     = build_java_array_type (class_type,
1060                              host_integerp (length, 0)
1061                              ? tree_low_cst (length, 0) : -1);
1062
1063   return build3 (CALL_EXPR, promote_type (type),
1064                  build_address_of (soft_anewarray_node),
1065                  tree_cons (NULL_TREE, length,
1066                             tree_cons (NULL_TREE, build_class_ref (class_type),
1067                                        build_tree_list (NULL_TREE,
1068                                                         null_pointer_node))),
1069                  NULL_TREE);
1070 }
1071
1072 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
1073
1074 tree
1075 build_new_array (tree type, tree length)
1076 {
1077   if (JPRIMITIVE_TYPE_P (type))
1078     return build_newarray (encode_newarray_type (type), length);
1079   else
1080     return build_anewarray (TREE_TYPE (type), length);
1081 }
1082
1083 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
1084    class pointer, a number of dimensions and the matching number of
1085    dimensions. The argument list is NULL terminated.  */
1086
1087 static void
1088 expand_java_multianewarray (tree class_type, int ndim)
1089 {
1090   int i;
1091   tree args = build_tree_list( NULL_TREE, null_pointer_node );
1092
1093   for( i = 0; i < ndim; i++ )
1094     args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
1095
1096   push_value (build3 (CALL_EXPR,
1097                       promote_type (class_type),
1098                       build_address_of (soft_multianewarray_node),
1099                       tree_cons (NULL_TREE, build_class_ref (class_type),
1100                                  tree_cons (NULL_TREE, 
1101                                             build_int_cst (NULL_TREE, ndim),
1102                                             args)),
1103                       NULL_TREE));
1104 }
1105
1106 /*  ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
1107     ARRAY is an array type. May expand some bound checking and NULL
1108     pointer checking. RHS_TYPE_NODE we are going to store. In the case
1109     of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
1110     INT. In those cases, we make the conversion.
1111
1112     if ARRAy is a reference type, the assignment is checked at run-time
1113     to make sure that the RHS can be assigned to the array element
1114     type. It is not necessary to generate this code if ARRAY is final.  */
1115
1116 static void
1117 expand_java_arraystore (tree rhs_type_node)
1118 {
1119   tree rhs_node    = pop_value ((INTEGRAL_TYPE_P (rhs_type_node) 
1120                                  && TYPE_PRECISION (rhs_type_node) <= 32) ? 
1121                                  int_type_node : rhs_type_node);
1122   tree index = pop_value (int_type_node);
1123   tree array_type, array;
1124
1125   /* If we're processing an `aaload' we might as well just pick
1126      `Object'.  */
1127   if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
1128     {
1129       array_type = build_java_array_type (object_ptr_type_node, -1);
1130       rhs_type_node = object_ptr_type_node;
1131     }
1132   else
1133     array_type = build_java_array_type (rhs_type_node, -1);
1134
1135   array = pop_value (array_type);
1136   array = build1 (NOP_EXPR, promote_type (array_type), array);
1137
1138   rhs_type_node    = build_java_check_indexed_type (array, rhs_type_node);
1139
1140   flush_quick_stack ();
1141
1142   index = save_expr (index);
1143   array = save_expr (array);
1144
1145   if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
1146     {
1147       tree check = build_java_arraystore_check (array, rhs_node);
1148       java_add_stmt (check);
1149     }
1150   
1151   array = build_java_arrayaccess (array, rhs_type_node, index);
1152   java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (array), array, rhs_node));  
1153 }
1154
1155 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes 
1156    sure that LHS is an array type. May expand some bound checking and NULL
1157    pointer checking.  
1158    LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
1159    BOOLEAN/SHORT, we push a promoted type back to the stack.
1160 */
1161
1162 static void
1163 expand_java_arrayload (tree lhs_type_node)
1164 {
1165   tree load_node;
1166   tree index_node = pop_value (int_type_node);
1167   tree array_type;
1168   tree array_node;
1169
1170   /* If we're processing an `aaload' we might as well just pick
1171      `Object'.  */
1172   if (TREE_CODE (lhs_type_node) == POINTER_TYPE)
1173     {
1174       array_type = build_java_array_type (object_ptr_type_node, -1);
1175       lhs_type_node = object_ptr_type_node;
1176     }
1177   else
1178     array_type = build_java_array_type (lhs_type_node, -1);
1179   array_node = pop_value (array_type);
1180   array_node = build1 (NOP_EXPR, promote_type (array_type), array_node);
1181
1182   index_node = save_expr (index_node);
1183   array_node = save_expr (array_node);
1184
1185   lhs_type_node = build_java_check_indexed_type (array_node,
1186                                                  lhs_type_node);
1187   load_node = build_java_arrayaccess (array_node,
1188                                       lhs_type_node,
1189                                       index_node);
1190   if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1191     load_node = fold_build1 (NOP_EXPR, int_type_node, load_node);
1192   push_value (load_node);
1193 }
1194
1195 /* Expands .length. Makes sure that we deal with and array and may expand
1196    a NULL check on the array object.  */
1197
1198 static void
1199 expand_java_array_length (void)
1200 {
1201   tree array  = pop_value (ptr_type_node);
1202   tree length = build_java_array_length_access (array);
1203
1204   push_value (length);
1205 }
1206
1207 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1208    either soft_monitorenter_node or soft_monitorexit_node.  */
1209
1210 static tree
1211 build_java_monitor (tree call, tree object)
1212 {
1213   return build3 (CALL_EXPR,
1214                  void_type_node,
1215                  build_address_of (call),
1216                  build_tree_list (NULL_TREE, object),
1217                  NULL_TREE);
1218 }
1219
1220 /* Emit code for one of the PUSHC instructions. */
1221
1222 static void
1223 expand_java_pushc (int ival, tree type)
1224 {
1225   tree value;
1226   if (type == ptr_type_node && ival == 0)
1227     value = null_pointer_node;
1228   else if (type == int_type_node || type == long_type_node)
1229     value = build_int_cst (type, ival);
1230   else if (type == float_type_node || type == double_type_node)
1231     {
1232       REAL_VALUE_TYPE x;
1233       REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1234       value = build_real (type, x);
1235     }
1236   else
1237     gcc_unreachable ();
1238
1239   push_value (value);
1240 }
1241
1242 static void
1243 expand_java_return (tree type)
1244 {
1245   if (type == void_type_node)
1246     java_add_stmt (build1 (RETURN_EXPR, void_type_node, NULL));   
1247   else
1248     {
1249       tree retval = pop_value (type);
1250       tree res = DECL_RESULT (current_function_decl);
1251       retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1252
1253       /* Handle the situation where the native integer type is smaller
1254          than the JVM integer. It can happen for many cross compilers.
1255          The whole if expression just goes away if INT_TYPE_SIZE < 32
1256          is false. */
1257       if (INT_TYPE_SIZE < 32
1258           && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1259               < GET_MODE_SIZE (TYPE_MODE (type))))
1260         retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1261       
1262       TREE_SIDE_EFFECTS (retval) = 1;
1263       java_add_stmt (build1 (RETURN_EXPR, TREE_TYPE (retval), retval));
1264     }
1265 }
1266
1267 static void
1268 expand_load_internal (int index, tree type, int pc)
1269 {
1270   tree copy;
1271   tree var = find_local_variable (index, type, pc);
1272
1273   /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1274      on the stack.  If there is an assignment to this VAR_DECL between
1275      the stack push and the use, then the wrong code could be
1276      generated.  To avoid this we create a new local and copy our
1277      value into it.  Then we push this new local on the stack.
1278      Hopefully this all gets optimized out.  */
1279   copy = build_decl (VAR_DECL, NULL_TREE, type);
1280   if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
1281       && TREE_TYPE (copy) != TREE_TYPE (var))
1282     var = convert (type, var);
1283   java_add_local_var (copy);
1284   java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (var), copy, var));
1285   
1286   push_value (copy);
1287 }
1288
1289 tree
1290 build_address_of (tree value)
1291 {
1292   return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1293 }
1294
1295 bool
1296 class_has_finalize_method (tree type)
1297 {
1298   tree super = CLASSTYPE_SUPER (type);
1299
1300   if (super == NULL_TREE)
1301     return false;       /* Every class with a real finalizer inherits   */
1302                         /* from java.lang.Object.                       */
1303   else
1304     return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1305 }
1306
1307 tree
1308 java_create_object (tree type)
1309 {
1310   tree alloc_node = (class_has_finalize_method (type) 
1311                      ? alloc_object_node
1312                      : alloc_no_finalizer_node);
1313   
1314   return build3 (CALL_EXPR, promote_type (type),
1315                  build_address_of (alloc_node),
1316                  build_tree_list (NULL_TREE, build_class_ref (type)),
1317                  NULL_TREE);
1318 }
1319
1320 static void
1321 expand_java_NEW (tree type)
1322 {
1323   tree alloc_node;
1324
1325   alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1326                                                  : alloc_no_finalizer_node);
1327   if (! CLASS_LOADED_P (type))
1328     load_class (type, 1);
1329   safe_layout_class (type);
1330   push_value (build3 (CALL_EXPR, promote_type (type),
1331                       build_address_of (alloc_node),
1332                       build_tree_list (NULL_TREE, build_class_ref (type)),
1333                       NULL_TREE));
1334 }
1335
1336 /* This returns an expression which will extract the class of an
1337    object.  */
1338
1339 tree
1340 build_get_class (tree value)
1341 {
1342   tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1343   tree vtable_field = lookup_field (&object_type_node,
1344                                     get_identifier ("vtable"));
1345   tree tmp = build3 (COMPONENT_REF, dtable_ptr_type,
1346                      build_java_indirect_ref (object_type_node, value,
1347                                               flag_check_references),
1348                      vtable_field, NULL_TREE);
1349   return build3 (COMPONENT_REF, class_ptr_type,
1350                  build1 (INDIRECT_REF, dtable_type, tmp),
1351                  class_field, NULL_TREE);
1352 }
1353
1354 /* This builds the tree representation of the `instanceof' operator.
1355    It tries various tricks to optimize this in cases where types are
1356    known.  */
1357
1358 tree
1359 build_instanceof (tree value, tree type)
1360 {
1361   tree expr;
1362   tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1363   tree valtype = TREE_TYPE (TREE_TYPE (value));
1364   tree valclass = TYPE_NAME (valtype);
1365   tree klass;
1366
1367   /* When compiling from bytecode, we need to ensure that TYPE has
1368      been loaded.  */
1369   if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1370     {
1371       load_class (type, 1);
1372       safe_layout_class (type);
1373       if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1374         return error_mark_node;
1375     }
1376   klass = TYPE_NAME (type);
1377
1378   if (type == object_type_node || inherits_from_p (valtype, type))
1379     {
1380       /* Anything except `null' is an instance of Object.  Likewise,
1381          if the object is known to be an instance of the class, then
1382          we only need to check for `null'.  */
1383       expr = build2 (NE_EXPR, itype, value, null_pointer_node);
1384     }
1385   else if (flag_verify_invocations
1386            && ! TYPE_ARRAY_P (type)
1387            && ! TYPE_ARRAY_P (valtype)
1388            && DECL_P (klass) && DECL_P (valclass)
1389            && ! CLASS_INTERFACE (valclass)
1390            && ! CLASS_INTERFACE (klass)
1391            && ! inherits_from_p (type, valtype)
1392            && (CLASS_FINAL (klass)
1393                || ! inherits_from_p (valtype, type)))
1394     {
1395       /* The classes are from different branches of the derivation
1396          tree, so we immediately know the answer.  */
1397       expr = boolean_false_node;
1398     }
1399   else if (DECL_P (klass) && CLASS_FINAL (klass))
1400     {
1401       tree save = save_expr (value);
1402       expr = build3 (COND_EXPR, itype,
1403                      build2 (NE_EXPR, boolean_type_node,
1404                              save, null_pointer_node),
1405                      build2 (EQ_EXPR, itype,
1406                              build_get_class (save),
1407                              build_class_ref (type)),
1408                      boolean_false_node);
1409     }
1410   else
1411     {
1412       expr = build3 (CALL_EXPR, itype,
1413                      build_address_of (soft_instanceof_node),
1414                      tree_cons (NULL_TREE, value,
1415                                 build_tree_list (NULL_TREE,
1416                                                  build_class_ref (type))),
1417                      NULL_TREE);
1418     }
1419   TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1420   return expr;
1421 }
1422
1423 static void
1424 expand_java_INSTANCEOF (tree type)
1425 {
1426   tree value = pop_value (object_ptr_type_node);
1427   value = build_instanceof (value, type);
1428   push_value (value);
1429 }
1430
1431 static void
1432 expand_java_CHECKCAST (tree type)
1433 {
1434   tree value = pop_value (ptr_type_node);
1435   value = build3 (CALL_EXPR, promote_type (type),
1436                   build_address_of (soft_checkcast_node),
1437                   tree_cons (NULL_TREE, build_class_ref (type),
1438                              build_tree_list (NULL_TREE, value)),
1439                   NULL_TREE);
1440   push_value (value);
1441 }
1442
1443 static void
1444 expand_iinc (unsigned int local_var_index, int ival, int pc)
1445 {
1446   tree local_var, res;
1447   tree constant_value;
1448
1449   flush_quick_stack ();
1450   local_var = find_local_variable (local_var_index, int_type_node, pc);
1451   constant_value = build_int_cst (NULL_TREE, ival);
1452   res = fold_build2 (PLUS_EXPR, int_type_node, local_var, constant_value);
1453   java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (local_var), local_var, res));
1454   update_aliases (local_var, local_var_index, pc);
1455 }
1456
1457
1458 tree
1459 build_java_soft_divmod (enum tree_code op, tree type, tree op1, tree op2)
1460 {
1461   tree call = NULL;
1462   tree arg1 = convert (type, op1);
1463   tree arg2 = convert (type, op2);
1464
1465   if (type == int_type_node)
1466     {     
1467       switch (op)
1468         {
1469         case TRUNC_DIV_EXPR:
1470           call = soft_idiv_node;
1471           break;
1472         case TRUNC_MOD_EXPR:
1473           call = soft_irem_node;
1474           break;
1475         default:
1476           break;
1477         }
1478     }
1479   else if (type == long_type_node)
1480     {     
1481       switch (op)
1482         {
1483         case TRUNC_DIV_EXPR:
1484           call = soft_ldiv_node;
1485           break;
1486         case TRUNC_MOD_EXPR:
1487           call = soft_lrem_node;
1488           break;
1489         default:
1490           break;
1491         }
1492     }
1493
1494   gcc_assert (call);
1495   call = build3 (CALL_EXPR, type,
1496                  build_address_of (call),
1497                  tree_cons (NULL_TREE, arg1,
1498                             build_tree_list (NULL_TREE, arg2)),
1499                  NULL_TREE);
1500           
1501   return call;
1502 }
1503
1504 tree
1505 build_java_binop (enum tree_code op, tree type, tree arg1, tree arg2)
1506 {
1507   tree mask;
1508   switch (op)
1509     {
1510     case URSHIFT_EXPR:
1511       {
1512         tree u_type = java_unsigned_type (type);
1513         arg1 = convert (u_type, arg1);
1514         arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1515         return convert (type, arg1);
1516       }
1517     case LSHIFT_EXPR:
1518     case RSHIFT_EXPR:
1519       mask = build_int_cst (NULL_TREE,
1520                             TYPE_PRECISION (TREE_TYPE (arg1)) - 1);
1521       arg2 = fold_build2 (BIT_AND_EXPR, int_type_node, arg2, mask);
1522       break;
1523
1524     case COMPARE_L_EXPR:  /* arg1 > arg2 ?  1 : arg1 == arg2 ? 0 : -1 */
1525     case COMPARE_G_EXPR:  /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 :  1 */
1526       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1527       {
1528         tree ifexp1 = fold_build2 (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1529                                    boolean_type_node, arg1, arg2);
1530         tree ifexp2 = fold_build2 (EQ_EXPR, boolean_type_node, arg1, arg2);
1531         tree second_compare = fold_build3 (COND_EXPR, int_type_node,
1532                                            ifexp2, integer_zero_node,
1533                                            op == COMPARE_L_EXPR
1534                                            ? integer_minus_one_node
1535                                            : integer_one_node);
1536         return fold_build3 (COND_EXPR, int_type_node, ifexp1,
1537                             op == COMPARE_L_EXPR ? integer_one_node
1538                             : integer_minus_one_node,
1539                             second_compare);
1540       }
1541     case COMPARE_EXPR:
1542       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1543       {
1544         tree ifexp1 = fold_build2 (LT_EXPR, boolean_type_node, arg1, arg2);
1545         tree ifexp2 = fold_build2 (GT_EXPR, boolean_type_node, arg1, arg2);
1546         tree second_compare = fold_build3 (COND_EXPR, int_type_node,
1547                                            ifexp2, integer_one_node,
1548                                            integer_zero_node);
1549         return fold_build3 (COND_EXPR, int_type_node,
1550                             ifexp1, integer_minus_one_node, second_compare);
1551       }      
1552     case TRUNC_DIV_EXPR:
1553     case TRUNC_MOD_EXPR:
1554       if (TREE_CODE (type) == REAL_TYPE
1555           && op == TRUNC_MOD_EXPR)
1556         {
1557           tree call;
1558           if (type != double_type_node)
1559             {
1560               arg1 = convert (double_type_node, arg1);
1561               arg2 = convert (double_type_node, arg2);
1562             }
1563           call = build3 (CALL_EXPR, double_type_node,
1564                          build_address_of (soft_fmod_node),
1565                          tree_cons (NULL_TREE, arg1,
1566                                     build_tree_list (NULL_TREE, arg2)),
1567                          NULL_TREE);
1568           if (type != double_type_node)
1569             call = convert (type, call);
1570           return call;
1571         }
1572       
1573       if (TREE_CODE (type) == INTEGER_TYPE
1574           && flag_use_divide_subroutine
1575           && ! flag_syntax_only)
1576         return build_java_soft_divmod (op, type, arg1, arg2);
1577       
1578       break;
1579     default:  ;
1580     }
1581   return fold_build2 (op, type, arg1, arg2);
1582 }
1583
1584 static void
1585 expand_java_binop (tree type, enum tree_code op)
1586 {
1587   tree larg, rarg;
1588   tree ltype = type;
1589   tree rtype = type;
1590   switch (op)
1591     {
1592     case LSHIFT_EXPR:
1593     case RSHIFT_EXPR:
1594     case URSHIFT_EXPR:
1595       rtype = int_type_node;
1596       rarg = pop_value (rtype);
1597       break;
1598     default:
1599       rarg = pop_value (rtype);
1600     }
1601   larg = pop_value (ltype);
1602   push_value (build_java_binop (op, type, larg, rarg));
1603 }
1604
1605 /* Lookup the field named NAME in *TYPEP or its super classes.
1606    If not found, return NULL_TREE.
1607    (If the *TYPEP is not found, or if the field reference is
1608    ambiguous, return error_mark_node.)
1609    If found, return the FIELD_DECL, and set *TYPEP to the
1610    class containing the field. */
1611
1612 tree
1613 lookup_field (tree *typep, tree name)
1614 {
1615   if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1616     {
1617       load_class (*typep, 1);
1618       safe_layout_class (*typep);
1619       if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1620         return error_mark_node;
1621     }
1622   do
1623     {
1624       tree field, binfo, base_binfo;
1625       tree save_field;
1626       int i;
1627
1628       for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1629         if (DECL_NAME (field) == name)
1630           return field;
1631
1632       /* Process implemented interfaces. */
1633       save_field = NULL_TREE;
1634       for (binfo = TYPE_BINFO (*typep), i = 0;
1635            BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
1636         {
1637           tree t = BINFO_TYPE (base_binfo);
1638           if ((field = lookup_field (&t, name)))
1639             {
1640               if (save_field == field)
1641                 continue;
1642               if (save_field == NULL_TREE)
1643                 save_field = field;
1644               else
1645                 {
1646                   tree i1 = DECL_CONTEXT (save_field);
1647                   tree i2 = DECL_CONTEXT (field);
1648                   error ("reference %qs is ambiguous: appears in interface %qs and interface %qs",
1649                          IDENTIFIER_POINTER (name),
1650                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1651                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1652                   return error_mark_node;
1653                 }
1654             }
1655         }
1656
1657       if (save_field != NULL_TREE)
1658         return save_field;
1659
1660       *typep = CLASSTYPE_SUPER (*typep);
1661     } while (*typep);
1662   return NULL_TREE;
1663 }
1664
1665 /* Look up the field named NAME in object SELF_VALUE,
1666    which has class SELF_CLASS (a non-handle RECORD_TYPE).
1667    SELF_VALUE is NULL_TREE if looking for a static field. */
1668
1669 tree
1670 build_field_ref (tree self_value, tree self_class, tree name)
1671 {
1672   tree base_class = self_class;
1673   tree field_decl = lookup_field (&base_class, name);
1674   if (field_decl == NULL_TREE)
1675     {
1676       error ("field %qs not found", IDENTIFIER_POINTER (name));
1677       return error_mark_node;
1678     }
1679   if (self_value == NULL_TREE)
1680     {
1681       return build_static_field_ref (field_decl);
1682     }
1683   else
1684     {
1685       tree base_type = promote_type (base_class);
1686
1687       /* CHECK is true if self_value is not the this pointer.  */
1688       int check = (! (DECL_P (self_value)
1689                       && DECL_NAME (self_value) == this_identifier_node));
1690
1691       /* Determine whether a field offset from NULL will lie within
1692          Page 0: this is necessary on those GNU/Linux/BSD systems that
1693          trap SEGV to generate NullPointerExceptions.  
1694
1695          We assume that Page 0 will be mapped with NOPERM, and that
1696          memory may be allocated from any other page, so only field
1697          offsets < pagesize are guaranteed to trap.  We also assume
1698          the smallest page size we'll encounter is 4k bytes.  */
1699       if (! flag_syntax_only && check && ! flag_check_references 
1700           && ! flag_indirect_dispatch)
1701         {
1702           tree field_offset = byte_position (field_decl);
1703           if (! page_size)
1704             page_size = size_int (4096);              
1705           check = ! INT_CST_LT_UNSIGNED (field_offset, page_size);
1706         }
1707
1708       if (base_type != TREE_TYPE (self_value))
1709         self_value = fold_build1 (NOP_EXPR, base_type, self_value);
1710       if (! flag_syntax_only && flag_indirect_dispatch)
1711         {
1712           tree otable_index
1713             = build_int_cst (NULL_TREE, get_symbol_table_index 
1714                              (field_decl, &TYPE_OTABLE_METHODS (output_class)));
1715           tree field_offset
1716             = build4 (ARRAY_REF, integer_type_node,
1717                       TYPE_OTABLE_DECL (output_class), otable_index,
1718                       NULL_TREE, NULL_TREE);
1719           tree address;
1720
1721           if (DECL_CONTEXT (field_decl) != output_class)
1722             field_offset
1723               = build3 (COND_EXPR, TREE_TYPE (field_offset),
1724                         build2 (EQ_EXPR, boolean_type_node,
1725                                 field_offset, integer_zero_node),
1726                         build3 (CALL_EXPR, void_type_node, 
1727                                 build_address_of (soft_nosuchfield_node),
1728                                 build_tree_list (NULL_TREE, otable_index), 
1729                                 NULL_TREE),
1730                         field_offset);
1731           
1732           field_offset = fold (convert (sizetype, field_offset));
1733           self_value = java_check_reference (self_value, check);
1734           address 
1735             = fold_build2 (PLUS_EXPR, 
1736                            build_pointer_type (TREE_TYPE (field_decl)),
1737                            self_value, field_offset);
1738           return fold_build1 (INDIRECT_REF, TREE_TYPE (field_decl), address);
1739         }
1740
1741       self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1742                                             self_value, check);
1743       return fold_build3 (COMPONENT_REF, TREE_TYPE (field_decl),
1744                           self_value, field_decl, NULL_TREE);
1745     }
1746 }
1747
1748 tree
1749 lookup_label (int pc)
1750 {
1751   tree name;
1752   char buf[32];
1753   if (pc > highest_label_pc_this_method)
1754     highest_label_pc_this_method = pc;
1755   ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", start_label_pc_this_method + pc);
1756   name = get_identifier (buf);
1757   if (IDENTIFIER_LOCAL_VALUE (name))
1758     return IDENTIFIER_LOCAL_VALUE (name);
1759   else
1760     {
1761       /* The type of the address of a label is return_address_type_node. */
1762       tree decl = create_label_decl (name);
1763       LABEL_PC (decl) = pc;
1764       return pushdecl (decl);
1765     }
1766 }
1767
1768 /* Generate a unique name for the purpose of loops and switches
1769    labels, and try-catch-finally blocks label or temporary variables.  */
1770
1771 tree
1772 generate_name (void)
1773 {
1774   static int l_number = 0;
1775   char buff [32];
1776   ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1777   l_number++;
1778   return get_identifier (buff);
1779 }
1780
1781 tree
1782 create_label_decl (tree name)
1783 {
1784   tree decl;
1785   decl = build_decl (LABEL_DECL, name, 
1786                      TREE_TYPE (return_address_type_node));
1787   DECL_CONTEXT (decl) = current_function_decl;
1788   DECL_IGNORED_P (decl) = 1;
1789   return decl;
1790 }
1791
1792 /* This maps a bytecode offset (PC) to various flags. */
1793 char *instruction_bits;
1794
1795 static void
1796 note_label (int current_pc ATTRIBUTE_UNUSED, int target_pc)
1797 {
1798   lookup_label (target_pc);
1799   instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1800 }
1801
1802 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1803    where CONDITION is one of one the compare operators. */
1804
1805 static void
1806 expand_compare (enum tree_code condition, tree value1, tree value2,
1807                 int target_pc)
1808 {
1809   tree target = lookup_label (target_pc);
1810   tree cond = fold_build2 (condition, boolean_type_node, value1, value2);
1811   java_add_stmt 
1812     (build3 (COND_EXPR, void_type_node, java_truthvalue_conversion (cond),
1813              build1 (GOTO_EXPR, void_type_node, target), 
1814              build_java_empty_stmt ()));
1815 }
1816
1817 /* Emit code for a TEST-type opcode. */
1818
1819 static void
1820 expand_test (enum tree_code condition, tree type, int target_pc)
1821 {
1822   tree value1, value2;
1823   flush_quick_stack ();
1824   value1 = pop_value (type);
1825   value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1826   expand_compare (condition, value1, value2, target_pc);
1827 }
1828
1829 /* Emit code for a COND-type opcode. */
1830
1831 static void
1832 expand_cond (enum tree_code condition, tree type, int target_pc)
1833 {
1834   tree value1, value2;
1835   flush_quick_stack ();
1836   /* note: pop values in opposite order */
1837   value2 = pop_value (type);
1838   value1 = pop_value (type);
1839   /* Maybe should check value1 and value2 for type compatibility ??? */
1840   expand_compare (condition, value1, value2, target_pc);
1841 }
1842
1843 static void
1844 expand_java_goto (int target_pc)
1845 {
1846   tree target_label = lookup_label (target_pc);
1847   flush_quick_stack ();
1848   java_add_stmt (build1 (GOTO_EXPR, void_type_node, target_label));
1849 }
1850
1851 static tree
1852 expand_java_switch (tree selector, int default_pc)
1853 {
1854   tree switch_expr, x;
1855
1856   flush_quick_stack ();
1857   switch_expr = build3 (SWITCH_EXPR, TREE_TYPE (selector), selector,
1858                         NULL_TREE, NULL_TREE);
1859   java_add_stmt (switch_expr);
1860
1861   x = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
1862               create_artificial_label ());
1863   append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1864
1865   x = build1 (GOTO_EXPR, void_type_node, lookup_label (default_pc));
1866   append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1867
1868   return switch_expr;
1869 }
1870
1871 static void
1872 expand_java_add_case (tree switch_expr, int match, int target_pc)
1873 {
1874   tree value, x;
1875
1876   value = build_int_cst (TREE_TYPE (switch_expr), match);
1877   
1878   x = build3 (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
1879               create_artificial_label ());
1880   append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1881
1882   x = build1 (GOTO_EXPR, void_type_node, lookup_label (target_pc));
1883   append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1884 }
1885
1886 static tree
1887 pop_arguments (tree arg_types)
1888 {
1889   if (arg_types == end_params_node)
1890     return NULL_TREE;
1891   if (TREE_CODE (arg_types) == TREE_LIST)
1892     {
1893       tree tail = pop_arguments (TREE_CHAIN (arg_types));
1894       tree type = TREE_VALUE (arg_types);
1895       tree arg = pop_value (type);
1896
1897       /* We simply cast each argument to its proper type.  This is
1898          needed since we lose type information coming out of the
1899          verifier.  We also have to do this when we pop an integer
1900          type that must be promoted for the function call.  */
1901       if (TREE_CODE (type) == POINTER_TYPE)
1902         arg = build1 (NOP_EXPR, type, arg);
1903       else if (targetm.calls.promote_prototypes (type)
1904                && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1905                && INTEGRAL_TYPE_P (type))
1906         arg = convert (integer_type_node, arg);
1907       return tree_cons (NULL_TREE, arg, tail);
1908     }
1909   gcc_unreachable ();
1910 }
1911
1912 /* Attach to PTR (a block) the declaration found in ENTRY. */
1913
1914 int
1915 attach_init_test_initialization_flags (void **entry, void *ptr)
1916 {
1917   tree block = (tree)ptr;
1918   struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
1919
1920   if (block != error_mark_node)
1921     {
1922       if (TREE_CODE (block) == BIND_EXPR)
1923         {
1924           tree body = BIND_EXPR_BODY (block);
1925           TREE_CHAIN (ite->value) = BIND_EXPR_VARS (block);
1926           BIND_EXPR_VARS (block) = ite->value;
1927           body = build2 (COMPOUND_EXPR, void_type_node,
1928                          build1 (DECL_EXPR, void_type_node, ite->value), body);
1929           BIND_EXPR_BODY (block) = body;
1930         }
1931       else
1932         {
1933           tree body = BLOCK_SUBBLOCKS (block);
1934           TREE_CHAIN (ite->value) = BLOCK_EXPR_DECLS (block);
1935           BLOCK_EXPR_DECLS (block) = ite->value;
1936           body = build2 (COMPOUND_EXPR, void_type_node,
1937                          build1 (DECL_EXPR, void_type_node, ite->value), body);
1938           BLOCK_SUBBLOCKS (block) = body;
1939         }
1940       
1941     }
1942   return true;
1943 }
1944
1945 /* Build an expression to initialize the class CLAS.
1946    if EXPR is non-NULL, returns an expression to first call the initializer
1947    (if it is needed) and then calls EXPR. */
1948
1949 tree
1950 build_class_init (tree clas, tree expr)
1951 {
1952   tree init;
1953
1954   /* An optimization: if CLAS is a superclass of the class we're
1955      compiling, we don't need to initialize it.  However, if CLAS is
1956      an interface, it won't necessarily be initialized, even if we
1957      implement it.  */
1958   if ((! CLASS_INTERFACE (TYPE_NAME (clas))
1959        && inherits_from_p (current_class, clas))
1960       || current_class == clas)
1961     return expr;
1962
1963   if (always_initialize_class_p)
1964     {
1965       init = build3 (CALL_EXPR, void_type_node,
1966                      build_address_of (soft_initclass_node),
1967                      build_tree_list (NULL_TREE, build_class_ref (clas)),
1968                      NULL_TREE);
1969       TREE_SIDE_EFFECTS (init) = 1;
1970     }
1971   else
1972     {
1973       tree *init_test_decl;
1974       tree decl;
1975       init_test_decl = java_treetreehash_new
1976         (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);
1977
1978       if (*init_test_decl == NULL)
1979         {
1980           /* Build a declaration and mark it as a flag used to track
1981              static class initializations. */
1982           decl = build_decl (VAR_DECL, NULL_TREE,
1983                              boolean_type_node);
1984           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
1985           LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
1986           DECL_CONTEXT (decl) = current_function_decl;
1987           DECL_FUNCTION_INIT_TEST_CLASS (decl) = clas;
1988           /* Tell the check-init code to ignore this decl when not
1989              optimizing class initialization. */
1990           if (!STATIC_CLASS_INIT_OPT_P ())
1991             DECL_BIT_INDEX (decl) = -1;
1992           DECL_INITIAL (decl) = boolean_false_node;
1993           /* Don't emit any symbolic debugging info for this decl.  */
1994           DECL_IGNORED_P (decl) = 1;      
1995           *init_test_decl = decl;
1996         }
1997
1998       init = build3 (CALL_EXPR, void_type_node,
1999                      build_address_of (soft_initclass_node),
2000                      build_tree_list (NULL_TREE, build_class_ref (clas)),
2001                      NULL_TREE);
2002       TREE_SIDE_EFFECTS (init) = 1;
2003       init = build3 (COND_EXPR, void_type_node,
2004                      build2 (EQ_EXPR, boolean_type_node, 
2005                              *init_test_decl, boolean_false_node),
2006                      init, integer_zero_node);
2007       TREE_SIDE_EFFECTS (init) = 1;
2008       init = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, 
2009                      build2 (MODIFY_EXPR, boolean_type_node,
2010                              *init_test_decl, boolean_true_node));
2011       TREE_SIDE_EFFECTS (init) = 1;
2012     }
2013
2014   if (expr != NULL_TREE)
2015     {
2016       expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
2017       TREE_SIDE_EFFECTS (expr) = 1;
2018       return expr;
2019     }
2020   return init;
2021 }
2022
2023 \f
2024
2025 /* Rewrite expensive calls that require stack unwinding at runtime to
2026    cheaper alternatives.  The logic here performs thse
2027    transformations:
2028
2029    java.lang.Class.forName("foo") -> java.lang.Class.forName("foo", class$)
2030    java.lang.Class.getClassLoader() -> java.lang.Class.getClassLoader(class$)
2031
2032 */
2033
2034 typedef struct
2035 {
2036   const char *classname;
2037   const char *method;
2038   const char *signature;
2039   const char *new_signature;
2040   int flags;
2041   tree (*rewrite_arglist) (tree arglist);
2042 } rewrite_rule;
2043
2044 /* Add this.class to the end of an arglist.  */
2045
2046 static tree 
2047 rewrite_arglist_getclass (tree arglist)
2048 {
2049   return chainon (arglist, 
2050                   tree_cons (NULL_TREE, build_class_ref (output_class), NULL_TREE));
2051 }
2052
2053 static rewrite_rule rules[] =
2054   {{"java.lang.Class", "getClassLoader", "()Ljava/lang/ClassLoader;", 
2055     "(Ljava/lang/Class;)Ljava/lang/ClassLoader;", 
2056     ACC_FINAL|ACC_PRIVATE, rewrite_arglist_getclass},
2057    {"java.lang.Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
2058     "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
2059     ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getclass},
2060    {NULL, NULL, NULL, NULL, 0, NULL}};
2061
2062 /* Scan the rules list for replacements for *METHOD_P and replace the
2063    args accordingly.  */
2064
2065 void
2066 maybe_rewrite_invocation (tree *method_p, tree *arg_list_p, 
2067                           tree *method_signature_p)
2068 {
2069   tree context = DECL_NAME (TYPE_NAME (DECL_CONTEXT (*method_p)));
2070   rewrite_rule *p;
2071   for (p = rules; p->classname; p++)
2072     {
2073       if (get_identifier (p->classname) == context)
2074         {
2075           tree method = DECL_NAME (*method_p);
2076           if (get_identifier (p->method) == method
2077               && get_identifier (p->signature) == *method_signature_p)
2078             {
2079               tree maybe_method
2080                 = lookup_java_method (DECL_CONTEXT (*method_p),
2081                                       method,
2082                                       get_identifier (p->new_signature));
2083               if (! maybe_method && ! flag_verify_invocations)
2084                 {
2085                   maybe_method
2086                     = add_method (DECL_CONTEXT (*method_p), p->flags, 
2087                                   method, get_identifier (p->new_signature));
2088                   DECL_EXTERNAL (maybe_method) = 1;
2089                 }
2090               *method_p = maybe_method;
2091               gcc_assert (*method_p);
2092               *arg_list_p = p->rewrite_arglist (*arg_list_p);
2093               *method_signature_p = get_identifier (p->new_signature);
2094
2095               break;
2096             }
2097         }
2098     }
2099 }
2100
2101 \f
2102
2103 tree
2104 build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
2105                         tree self_type, tree method_signature ATTRIBUTE_UNUSED,
2106                         tree arg_list ATTRIBUTE_UNUSED)
2107 {
2108   tree func;
2109   if (is_compiled_class (self_type))
2110     {
2111       /* With indirect dispatch we have to use indirect calls for all
2112          publicly visible methods or gcc will use PLT indirections
2113          to reach them.  We also have to use indirect dispatch for all
2114          external methods.  */
2115       if (! flag_indirect_dispatch 
2116           || (! DECL_EXTERNAL (method) && ! TREE_PUBLIC (method)))
2117         {
2118           func = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (method)),
2119                          method);
2120         }
2121       else
2122         {
2123           tree table_index
2124             = build_int_cst (NULL_TREE, get_symbol_table_index 
2125                              (method, &TYPE_ATABLE_METHODS (output_class)));
2126           func 
2127             = build4 (ARRAY_REF,  
2128                       TREE_TYPE (TREE_TYPE (TYPE_ATABLE_DECL (output_class))),
2129                       TYPE_ATABLE_DECL (output_class), table_index,
2130                       NULL_TREE, NULL_TREE);
2131         }
2132       func = convert (method_ptr_type_node, func);
2133     }
2134   else
2135     {
2136       /* We don't know whether the method has been (statically) compiled.
2137          Compile this code to get a reference to the method's code:
2138
2139          SELF_TYPE->methods[METHOD_INDEX].ncode
2140
2141       */
2142
2143       int method_index = 0;
2144       tree meth, ref;
2145
2146       /* The method might actually be declared in some superclass, so
2147          we have to use its class context, not the caller's notion of
2148          where the method is.  */
2149       self_type = DECL_CONTEXT (method);
2150       ref = build_class_ref (self_type);
2151       ref = build1 (INDIRECT_REF, class_type_node, ref);
2152       if (ncode_ident == NULL_TREE)
2153         ncode_ident = get_identifier ("ncode");
2154       if (methods_ident == NULL_TREE)
2155         methods_ident = get_identifier ("methods");
2156       ref = build3 (COMPONENT_REF, method_ptr_type_node, ref,
2157                     lookup_field (&class_type_node, methods_ident),
2158                     NULL_TREE);
2159       for (meth = TYPE_METHODS (self_type);
2160            ; meth = TREE_CHAIN (meth))
2161         {
2162           if (method == meth)
2163             break;
2164           if (meth == NULL_TREE)
2165             fatal_error ("method '%s' not found in class",
2166                          IDENTIFIER_POINTER (DECL_NAME (method)));
2167           method_index++;
2168         }
2169       method_index *= int_size_in_bytes (method_type_node);
2170       ref = fold_build2 (PLUS_EXPR, method_ptr_type_node,
2171                          ref, build_int_cst (NULL_TREE, method_index));
2172       ref = build1 (INDIRECT_REF, method_type_node, ref);
2173       func = build3 (COMPONENT_REF, nativecode_ptr_type_node,
2174                      ref, lookup_field (&method_type_node, ncode_ident),
2175                      NULL_TREE);
2176     }
2177   return func;
2178 }
2179
2180 tree
2181 invoke_build_dtable (int is_invoke_interface, tree arg_list)
2182 {
2183   tree dtable, objectref;
2184
2185   TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
2186
2187   /* If we're dealing with interfaces and if the objectref
2188      argument is an array then get the dispatch table of the class
2189      Object rather than the one from the objectref.  */
2190   objectref = (is_invoke_interface 
2191                && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list)))
2192                ? build_class_ref (object_type_node) : TREE_VALUE (arg_list));
2193
2194   if (dtable_ident == NULL_TREE)
2195     dtable_ident = get_identifier ("vtable");
2196   dtable = build_java_indirect_ref (object_type_node, objectref, 
2197                                     flag_check_references);
2198   dtable = build3 (COMPONENT_REF, dtable_ptr_type, dtable,
2199                    lookup_field (&object_type_node, dtable_ident), NULL_TREE);
2200
2201   return dtable;
2202 }
2203
2204 /* Determine the index in SYMBOL_TABLE for a reference to the decl
2205    T. If this decl has not been seen before, it will be added to the
2206    [oa]table_methods. If it has, the existing table slot will be
2207    reused.  */
2208
2209 int
2210 get_symbol_table_index (tree t, tree *symbol_table)
2211 {
2212   int i = 1;
2213   tree method_list;
2214
2215   if (*symbol_table == NULL_TREE)
2216     {
2217       *symbol_table = build_tree_list (t, t);
2218       return 1;
2219     }
2220   
2221   method_list = *symbol_table;
2222   
2223   while (1)
2224     {
2225       tree value = TREE_VALUE (method_list);
2226       if (value == t)
2227         return i;
2228       i++;
2229       if (TREE_CHAIN (method_list) == NULL_TREE)
2230         break;
2231       else
2232         method_list = TREE_CHAIN (method_list);
2233     }
2234
2235   TREE_CHAIN (method_list) = build_tree_list (t, t);
2236   return i;
2237 }
2238
2239 tree 
2240 build_invokevirtual (tree dtable, tree method)
2241 {
2242   tree func;
2243   tree nativecode_ptr_ptr_type_node
2244     = build_pointer_type (nativecode_ptr_type_node);
2245   tree method_index;
2246   tree otable_index;
2247
2248   if (flag_indirect_dispatch)
2249     {
2250       gcc_assert (! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))));
2251
2252       otable_index 
2253         = build_int_cst (NULL_TREE, get_symbol_table_index 
2254                          (method, &TYPE_OTABLE_METHODS (output_class)));
2255       method_index = build4 (ARRAY_REF, integer_type_node, 
2256                              TYPE_OTABLE_DECL (output_class), 
2257                              otable_index, NULL_TREE, NULL_TREE);
2258     }
2259   else
2260     {
2261       /* We fetch the DECL_VINDEX field directly here, rather than
2262          using get_method_index().  DECL_VINDEX is the true offset
2263          from the vtable base to a method, regrdless of any extra
2264          words inserted at the start of the vtable.  */
2265       method_index = DECL_VINDEX (method);
2266       method_index = size_binop (MULT_EXPR, method_index,
2267                                  TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
2268       if (TARGET_VTABLE_USES_DESCRIPTORS)
2269         method_index = size_binop (MULT_EXPR, method_index,
2270                                    size_int (TARGET_VTABLE_USES_DESCRIPTORS));
2271     }
2272
2273   func = fold_build2 (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
2274                       convert (nativecode_ptr_ptr_type_node, method_index));
2275
2276   if (TARGET_VTABLE_USES_DESCRIPTORS)
2277     func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
2278   else
2279     func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
2280
2281   return func;
2282 }
2283
2284 static GTY(()) tree class_ident;
2285 tree
2286 build_invokeinterface (tree dtable, tree method)
2287 {
2288   tree lookup_arg;
2289   tree interface;
2290   tree idx;
2291
2292   /* We expand invokeinterface here.  */
2293             
2294   if (class_ident == NULL_TREE)
2295     class_ident = get_identifier ("class");
2296
2297   dtable = build_java_indirect_ref (dtable_type, dtable,
2298                                     flag_check_references);
2299   dtable = build3 (COMPONENT_REF, class_ptr_type, dtable,
2300                    lookup_field (&dtable_type, class_ident), NULL_TREE);
2301
2302   interface = DECL_CONTEXT (method);
2303   gcc_assert (CLASS_INTERFACE (TYPE_NAME (interface)));
2304   layout_class_methods (interface);
2305   
2306   if (flag_indirect_dispatch)
2307     {
2308       int itable_index 
2309         = 2 * (get_symbol_table_index 
2310                (method, &TYPE_ITABLE_METHODS (output_class)));
2311       interface 
2312         = build4 (ARRAY_REF, 
2313                  TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
2314                  TYPE_ITABLE_DECL (output_class), 
2315                   build_int_cst (NULL_TREE, itable_index-1),
2316                   NULL_TREE, NULL_TREE);
2317       idx 
2318         = build4 (ARRAY_REF, 
2319                  TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
2320                  TYPE_ITABLE_DECL (output_class), 
2321                   build_int_cst (NULL_TREE, itable_index),
2322                   NULL_TREE, NULL_TREE);
2323       interface = convert (class_ptr_type, interface);
2324       idx = convert (integer_type_node, idx);
2325     }
2326   else
2327     {
2328       idx = build_int_cst (NULL_TREE, 
2329                            get_interface_method_index (method, interface));
2330       interface = build_class_ref (interface);
2331     }
2332                                                           
2333   lookup_arg = tree_cons (NULL_TREE, dtable,
2334                           tree_cons (NULL_TREE, interface,
2335                                      build_tree_list (NULL_TREE, idx)));
2336
2337   return build3 (CALL_EXPR, ptr_type_node, 
2338                  build_address_of (soft_lookupinterfacemethod_node),
2339                  lookup_arg, NULL_TREE);
2340 }
2341   
2342 /* Expand one of the invoke_* opcodes.
2343    OPCODE is the specific opcode.
2344    METHOD_REF_INDEX is an index into the constant pool.
2345    NARGS is the number of arguments, or -1 if not specified. */
2346
2347 static void
2348 expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
2349 {
2350   tree method_signature
2351     = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
2352   tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool,
2353                                          method_ref_index);
2354   tree self_type
2355     = get_class_constant (current_jcf,
2356                           COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool,
2357                           method_ref_index));
2358   const char *const self_name
2359     = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2360   tree call, func, method, arg_list, method_type;
2361   tree check = NULL_TREE;
2362
2363   if (! CLASS_LOADED_P (self_type))
2364     {
2365       load_class (self_type, 1);
2366       safe_layout_class (self_type);
2367       if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2368         fatal_error ("failed to find class '%s'", self_name);
2369     }
2370   layout_class_methods (self_type);
2371
2372   if (ID_INIT_P (method_name))
2373     method = lookup_java_constructor (self_type, method_signature);
2374   else
2375     method = lookup_java_method (self_type, method_name, method_signature);
2376
2377   /* We've found a method in a class other than the one in which it
2378      was wanted.  This can happen if, for instance, we're trying to
2379      compile invokespecial super.equals().  
2380      FIXME: This is a kludge.  Rather than nullifying the result, we
2381      should change lookup_java_method() so that it doesn't search the
2382      superclass chain when we're BC-compiling.  */
2383   if (! flag_verify_invocations
2384       && method
2385       && ! TYPE_ARRAY_P (self_type)
2386       && self_type != DECL_CONTEXT (method))
2387     method = NULL_TREE;
2388
2389   /* We've found a method in an interface, but this isn't an interface
2390      call.  */
2391   if (opcode != OPCODE_invokeinterface
2392       && method
2393       && (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method)))))
2394     method = NULL_TREE;
2395
2396   /* We've found a non-interface method but we are making an
2397      interface call.  This can happen if the interface overrides a
2398      method in Object.  */
2399   if (! flag_verify_invocations
2400       && opcode == OPCODE_invokeinterface
2401       && method
2402       && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
2403     method = NULL_TREE;
2404
2405   if (method == NULL_TREE)
2406     {
2407       if (flag_verify_invocations || ! flag_indirect_dispatch)
2408         {
2409           error ("class '%s' has no method named '%s' matching signature '%s'",
2410                  self_name,
2411                  IDENTIFIER_POINTER (method_name),
2412                  IDENTIFIER_POINTER (method_signature));
2413         }
2414       else
2415         {
2416           int flags = ACC_PUBLIC;
2417           if (opcode == OPCODE_invokestatic)
2418             flags |= ACC_STATIC;
2419           if (opcode == OPCODE_invokeinterface)
2420             {
2421               flags |= ACC_INTERFACE | ACC_ABSTRACT;
2422               CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
2423             }
2424           method = add_method (self_type, flags, method_name,
2425                                method_signature);
2426           DECL_ARTIFICIAL (method) = 1;
2427           METHOD_DUMMY (method) = 1;
2428           layout_class_method (self_type, NULL,
2429                                method, NULL);
2430         }
2431     }
2432
2433   /* Invoke static can't invoke static/abstract method */
2434   if (method != NULL_TREE)
2435     {
2436       if (opcode == OPCODE_invokestatic)
2437         {
2438           if (!METHOD_STATIC (method))
2439             {
2440               error ("invokestatic on non static method");
2441               method = NULL_TREE;
2442             }
2443           else if (METHOD_ABSTRACT (method))
2444             {
2445               error ("invokestatic on abstract method");
2446               method = NULL_TREE;
2447             }
2448         }
2449       else
2450         {
2451           if (METHOD_STATIC (method))
2452             {
2453               error ("invoke[non-static] on static method");
2454               method = NULL_TREE;
2455             }
2456         }
2457     }
2458
2459   if (method == NULL_TREE)
2460     {
2461       /* If we got here, we emitted an error message above.  So we
2462          just pop the arguments, push a properly-typed zero, and
2463          continue.  */
2464       method_type = get_type_from_signature (method_signature);
2465       pop_arguments (TYPE_ARG_TYPES (method_type));
2466       if (opcode != OPCODE_invokestatic) 
2467         pop_type (self_type);
2468       method_type = promote_type (TREE_TYPE (method_type));
2469       push_value (convert (method_type, integer_zero_node));
2470       return;
2471     }
2472
2473   method_type = TREE_TYPE (method);
2474   arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2475   flush_quick_stack ();
2476
2477   maybe_rewrite_invocation (&method, &arg_list, &method_signature);
2478
2479   func = NULL_TREE;
2480   if (opcode == OPCODE_invokestatic)
2481     func = build_known_method_ref (method, method_type, self_type,
2482                                    method_signature, arg_list);
2483   else if (opcode == OPCODE_invokespecial
2484            || (opcode == OPCODE_invokevirtual
2485                && (METHOD_PRIVATE (method)
2486                    || METHOD_FINAL (method) 
2487                    || CLASS_FINAL (TYPE_NAME (self_type)))))
2488     {
2489       /* If the object for the method call is null, we throw an
2490          exception.  We don't do this if the object is the current
2491          method's `this'.  In other cases we just rely on an
2492          optimization pass to eliminate redundant checks.  FIXME:
2493          Unfortunately there doesn't seem to be a way to determine
2494          what the current method is right now.
2495          We do omit the check if we're calling <init>.  */
2496       /* We use a SAVE_EXPR here to make sure we only evaluate
2497          the new `self' expression once.  */
2498       tree save_arg = save_expr (TREE_VALUE (arg_list));
2499       TREE_VALUE (arg_list) = save_arg;
2500       check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2501       func = build_known_method_ref (method, method_type, self_type,
2502                                      method_signature, arg_list);
2503     }
2504   else
2505     {
2506       tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 
2507                                          arg_list);
2508       if (opcode == OPCODE_invokevirtual)
2509         func = build_invokevirtual (dtable, method);
2510       else
2511         func = build_invokeinterface (dtable, method);
2512     }
2513       
2514   if (TREE_CODE (func) == ADDR_EXPR)
2515     TREE_TYPE (func) = build_pointer_type (method_type);
2516   else
2517     func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2518
2519   call = build3 (CALL_EXPR, TREE_TYPE (method_type),
2520                  func, arg_list, NULL_TREE);
2521   TREE_SIDE_EFFECTS (call) = 1;
2522   call = check_for_builtin (method, call);
2523
2524   if (check != NULL_TREE)
2525     {
2526       call = build2 (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2527       TREE_SIDE_EFFECTS (call) = 1;
2528     }
2529
2530   if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2531     java_add_stmt (call);
2532   else
2533     {
2534       push_value (call);
2535       flush_quick_stack ();
2536     }
2537 }
2538
2539 /* Create a stub which will be put into the vtable but which will call
2540    a JNI function.  */
2541
2542 tree
2543 build_jni_stub (tree method)
2544 {
2545   tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2546   tree jni_func_type, tem;
2547   tree env_var, res_var = NULL_TREE, block;
2548   tree method_args, res_type;
2549   tree meth_var;
2550   tree bind;
2551
2552   int args_size = 0;
2553
2554   tree klass = DECL_CONTEXT (method);
2555   int from_class = ! CLASS_FROM_SOURCE_P (klass);
2556   klass = build_class_ref (klass);
2557
2558   gcc_assert (METHOD_NATIVE (method) && flag_jni);
2559
2560   DECL_ARTIFICIAL (method) = 1;
2561   DECL_EXTERNAL (method) = 0;
2562
2563   env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2564   DECL_CONTEXT (env_var) = method;
2565
2566   if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2567     {
2568       res_var = build_decl (VAR_DECL, get_identifier ("res"),
2569                             TREE_TYPE (TREE_TYPE (method)));
2570       DECL_CONTEXT (res_var) = method;
2571       TREE_CHAIN (env_var) = res_var;
2572     }
2573
2574   meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2575   TREE_STATIC (meth_var) = 1;
2576   TREE_PUBLIC (meth_var) = 0;
2577   DECL_EXTERNAL (meth_var) = 0;
2578   DECL_CONTEXT (meth_var) = method;
2579   DECL_ARTIFICIAL (meth_var) = 1;
2580   DECL_INITIAL (meth_var) = null_pointer_node;
2581   TREE_USED (meth_var) = 1;
2582   chainon (env_var, meth_var);
2583   build_result_decl (method);
2584
2585   /* One strange way that the front ends are different is that they
2586      store arguments differently.  */
2587   if (from_class)
2588     method_args = DECL_ARGUMENTS (method);
2589   else
2590     method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2591   block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
2592   TREE_SIDE_EFFECTS (block) = 1;
2593   /* When compiling from source we don't set the type of the block,
2594      because that will prevent patch_return from ever being run.  */
2595   if (from_class)
2596     TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2597
2598   /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
2599   body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
2600                  build3 (CALL_EXPR, ptr_type_node,
2601                          build_address_of (soft_getjnienvnewframe_node),
2602                          build_tree_list (NULL_TREE, klass),
2603                          NULL_TREE));
2604   CAN_COMPLETE_NORMALLY (body) = 1;
2605
2606   /* All the arguments to this method become arguments to the
2607      underlying JNI function.  If we had to wrap object arguments in a
2608      special way, we would do that here.  */
2609   args = NULL_TREE;
2610   for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2611     {
2612       int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tem)));
2613 #ifdef PARM_BOUNDARY
2614       arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
2615                   * PARM_BOUNDARY);
2616 #endif
2617       args_size += (arg_bits / BITS_PER_UNIT);
2618
2619       args = tree_cons (NULL_TREE, tem, args);
2620     }
2621   args = nreverse (args);
2622   arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2623
2624   /* For a static method the second argument is the class.  For a
2625      non-static method the second argument is `this'; that is already
2626      available in the argument list.  */
2627   if (METHOD_STATIC (method))
2628     {
2629       args_size += int_size_in_bytes (TREE_TYPE (klass));
2630       args = tree_cons (NULL_TREE, klass, args);
2631       arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2632     }
2633
2634   /* The JNIEnv structure is the first argument to the JNI function.  */
2635   args_size += int_size_in_bytes (TREE_TYPE (env_var));
2636   args = tree_cons (NULL_TREE, env_var, args);
2637   arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2638
2639   /* We call _Jv_LookupJNIMethod to find the actual underlying
2640      function pointer.  _Jv_LookupJNIMethod will throw the appropriate
2641      exception if this function is not found at runtime.  */
2642   tem = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, args_size));
2643   method_sig = build_java_signature (TREE_TYPE (method));
2644   lookup_arg = tree_cons (NULL_TREE,
2645                           build_utf8_ref (unmangle_classname
2646                                           (IDENTIFIER_POINTER (method_sig),
2647                                            IDENTIFIER_LENGTH (method_sig))), 
2648                           tem);
2649   tem = DECL_NAME (method);
2650   lookup_arg
2651     = tree_cons (NULL_TREE, klass,
2652                  tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2653   
2654   tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
2655
2656 #ifdef MODIFY_JNI_METHOD_CALL
2657   tem = MODIFY_JNI_METHOD_CALL (tem);
2658 #endif
2659
2660   jni_func_type = build_pointer_type (tem);
2661
2662   jnifunc = build3 (COND_EXPR, ptr_type_node,
2663                     meth_var, meth_var,
2664                     build2 (MODIFY_EXPR, ptr_type_node, meth_var,
2665                             build3 (CALL_EXPR, ptr_type_node,
2666                                     build_address_of
2667                                       (soft_lookupjnimethod_node),
2668                                     lookup_arg, NULL_TREE)));
2669
2670   /* Now we make the actual JNI call via the resulting function
2671      pointer.    */
2672   call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2673                  build1 (NOP_EXPR, jni_func_type, jnifunc),
2674                  args, NULL_TREE);
2675
2676   /* If the JNI call returned a result, capture it here.  If we had to
2677      unwrap JNI object results, we would do that here.  */
2678   if (res_var != NULL_TREE)
2679     {
2680       /* If the call returns an object, it may return a JNI weak
2681          reference, in which case we must unwrap it.  */
2682       if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method))))
2683         call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2684                        build_address_of (soft_unwrapjni_node),
2685                        build_tree_list (NULL_TREE, call),
2686                        NULL_TREE);
2687       call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2688                      res_var, call);
2689     }
2690
2691   TREE_SIDE_EFFECTS (call) = 1;
2692   CAN_COMPLETE_NORMALLY (call) = 1;
2693
2694   body = build2 (COMPOUND_EXPR, void_type_node, body, call);
2695   TREE_SIDE_EFFECTS (body) = 1;
2696
2697   /* Now free the environment we allocated.  */
2698   call = build3 (CALL_EXPR, ptr_type_node,
2699                  build_address_of (soft_jnipopsystemframe_node),
2700                  build_tree_list (NULL_TREE, env_var),
2701                  NULL_TREE);
2702   TREE_SIDE_EFFECTS (call) = 1;
2703   CAN_COMPLETE_NORMALLY (call) = 1;
2704   body = build2 (COMPOUND_EXPR, void_type_node, body, call);
2705   TREE_SIDE_EFFECTS (body) = 1;
2706
2707   /* Finally, do the return.  */
2708   res_type = void_type_node;
2709   if (res_var != NULL_TREE)
2710     {
2711       tree drt;
2712       gcc_assert (DECL_RESULT (method));
2713       /* Make sure we copy the result variable to the actual
2714          result.  We use the type of the DECL_RESULT because it
2715          might be different from the return type of the function:
2716          it might be promoted.  */
2717       drt = TREE_TYPE (DECL_RESULT (method));
2718       if (drt != TREE_TYPE (res_var))
2719         res_var = build1 (CONVERT_EXPR, drt, res_var);
2720       res_var = build2 (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2721       TREE_SIDE_EFFECTS (res_var) = 1;
2722     }
2723
2724   body = build2 (COMPOUND_EXPR, void_type_node, body,
2725                  build1 (RETURN_EXPR, res_type, res_var));
2726   TREE_SIDE_EFFECTS (body) = 1;
2727   
2728   bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), 
2729                  body, block);
2730   return bind;
2731 }
2732
2733 /* Expand an operation to extract from or store into a field.
2734    IS_STATIC is 1 iff the field is static.
2735    IS_PUTTING is 1 for putting into a field;  0 for getting from the field.
2736    FIELD_REF_INDEX is an index into the constant pool.  */
2737
2738 static void
2739 expand_java_field_op (int is_static, int is_putting, int field_ref_index)
2740 {
2741   tree self_type
2742     = get_class_constant (current_jcf,
2743                           COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2744                           field_ref_index));
2745   const char *self_name
2746     = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2747   tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2748   tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 
2749                                                   field_ref_index);
2750   tree field_type = get_type_from_signature (field_signature);
2751   tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2752   tree field_ref;
2753   int is_error = 0;
2754   tree original_self_type = self_type;
2755   tree field_decl;
2756   
2757   if (! CLASS_LOADED_P (self_type))
2758     load_class (self_type, 1);  
2759   field_decl = lookup_field (&self_type, field_name);
2760   if (field_decl == error_mark_node)
2761     {
2762       is_error = 1;
2763     }
2764   else if (field_decl == NULL_TREE)
2765     {
2766       if (! flag_verify_invocations)
2767         {
2768           int flags = ACC_PUBLIC;
2769           if (is_static)
2770             flags |= ACC_STATIC;
2771           self_type = original_self_type;
2772           field_decl = add_field (original_self_type, field_name,
2773                                   field_type, flags); 
2774           DECL_ARTIFICIAL (field_decl) = 1;
2775           DECL_IGNORED_P (field_decl) = 1;
2776         }
2777       else
2778         {      
2779           error ("missing field '%s' in '%s'",
2780                  IDENTIFIER_POINTER (field_name), self_name);
2781           is_error = 1;
2782       }
2783     }
2784   else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2785     {
2786       error ("mismatching signature for field '%s' in '%s'",
2787              IDENTIFIER_POINTER (field_name), self_name);
2788       is_error = 1;
2789     }
2790   field_ref = is_static ? NULL_TREE : pop_value (self_type);
2791   if (is_error)
2792     {
2793       if (! is_putting)
2794         push_value (convert (field_type, integer_zero_node));
2795       flush_quick_stack ();
2796       return;
2797     }
2798
2799   field_ref = build_field_ref (field_ref, self_type, field_name);
2800   if (is_static
2801       && ! flag_indirect_dispatch)
2802     field_ref = build_class_init (self_type, field_ref);
2803   if (is_putting)
2804     {
2805       flush_quick_stack ();
2806       if (FIELD_FINAL (field_decl))
2807         {
2808           if (DECL_CONTEXT (field_decl) != current_class)
2809             error ("assignment to final field %q+D not in field's class",
2810                    field_decl);
2811           else if (FIELD_STATIC (field_decl))
2812             {
2813               if (!DECL_CLINIT_P (current_function_decl))
2814                 warning (0, "assignment to final static field %q+D not in "
2815                          "class initializer",
2816                          field_decl);
2817             }
2818           else
2819             {
2820               tree cfndecl_name = DECL_NAME (current_function_decl);
2821               if (! DECL_CONSTRUCTOR_P (current_function_decl)
2822                   && !ID_FINIT_P (cfndecl_name))
2823                 warning (0, "assignment to final field %q+D not in constructor",
2824                          field_decl);
2825             }
2826         }
2827       java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (field_ref),
2828                              field_ref, new_value));
2829     }
2830   else
2831     push_value (field_ref);
2832 }
2833
2834 void
2835 load_type_state (tree label)
2836 {
2837   int i;
2838   tree vec = LABEL_TYPE_STATE (label);
2839   int cur_length = TREE_VEC_LENGTH (vec);
2840   stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2841   for (i = 0; i < cur_length; i++)
2842     type_map [i] = TREE_VEC_ELT (vec, i);
2843 }
2844
2845 /* Go over METHOD's bytecode and note instruction starts in
2846    instruction_bits[].  */
2847
2848 void
2849 note_instructions (JCF *jcf, tree method)
2850 {
2851   int PC; 
2852   unsigned char* byte_ops;
2853   long length = DECL_CODE_LENGTH (method);
2854
2855   int saw_index;
2856   jint INT_temp;
2857
2858 #undef RET /* Defined by config/i386/i386.h */
2859 #undef PTR
2860 #define BCODE byte_ops
2861 #define BYTE_type_node byte_type_node
2862 #define SHORT_type_node short_type_node
2863 #define INT_type_node int_type_node
2864 #define LONG_type_node long_type_node
2865 #define CHAR_type_node char_type_node
2866 #define PTR_type_node ptr_type_node
2867 #define FLOAT_type_node float_type_node
2868 #define DOUBLE_type_node double_type_node
2869 #define VOID_type_node void_type_node
2870 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2871 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2872 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2873 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2874
2875 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2876
2877   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2878   byte_ops = jcf->read_ptr;
2879   instruction_bits = xrealloc (instruction_bits, length + 1);
2880   memset (instruction_bits, 0, length + 1);
2881
2882   /* This pass figures out which PC can be the targets of jumps. */
2883   for (PC = 0; PC < length;)
2884     {
2885       int oldpc = PC; /* PC at instruction start. */
2886       instruction_bits [PC] |=  BCODE_INSTRUCTION_START;
2887       switch (byte_ops[PC++])
2888         {
2889 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2890         case OPCODE: \
2891           PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2892           break;
2893
2894 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2895
2896 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2897 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2898 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2899 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2900 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2901 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2902 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2903 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2904
2905 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2906   PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2907 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2908   ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2909 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2910 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2911 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2912 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2913
2914 /* two forms of wide instructions */
2915 #define PRE_SPECIAL_WIDE(IGNORE) \
2916   { \
2917     int modified_opcode = IMMEDIATE_u1; \
2918     if (modified_opcode == OPCODE_iinc) \
2919       { \
2920         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2921         (void) IMMEDIATE_s2;    /* constbyte1 and constbyte2 */ \
2922       } \
2923     else \
2924       { \
2925         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2926       } \
2927   }
2928
2929 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2930
2931 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2932
2933 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2934 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2935           PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2936 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2937 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2938 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2939 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2940 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2941 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2942 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2943
2944 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2945 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2946 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2947   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2948   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2949 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2950   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2951   NOTE_LABEL (PC); \
2952   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2953
2954 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE)  (void)(OPERAND_VALUE)
2955
2956 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2957   PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2958
2959 #define PRE_LOOKUP_SWITCH                                               \
2960   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4;    \
2961     NOTE_LABEL (default_offset+oldpc);                                  \
2962     if (npairs >= 0)                                                    \
2963       while (--npairs >= 0) {                                           \
2964        jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4;                      \
2965        jint offset = IMMEDIATE_s4;                                      \
2966        NOTE_LABEL (offset+oldpc); }                                     \
2967   }
2968
2969 #define PRE_TABLE_SWITCH                                \
2970   { jint default_offset = IMMEDIATE_s4;                 \
2971     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4;  \
2972     NOTE_LABEL (default_offset+oldpc);                  \
2973     if (low <= high)                                    \
2974      while (low++ <= high) {                            \
2975        jint offset = IMMEDIATE_s4;                      \
2976        NOTE_LABEL (offset+oldpc); }                     \
2977   }
2978
2979 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2980 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2981 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2982   (void)(IMMEDIATE_u2); \
2983   PC += 2 * IS_INTERFACE /* for invokeinterface */;
2984
2985 #include "javaop.def"
2986 #undef JAVAOP
2987         }
2988     } /* for */
2989 }
2990
2991 void
2992 expand_byte_code (JCF *jcf, tree method)
2993 {
2994   int PC;
2995   int i;
2996   const unsigned char *linenumber_pointer;
2997   int dead_code_index = -1;
2998   unsigned char* byte_ops;
2999   long length = DECL_CODE_LENGTH (method);
3000
3001   stack_pointer = 0;
3002   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
3003   byte_ops = jcf->read_ptr;
3004
3005   /* We make an initial pass of the line number table, to note
3006      which instructions have associated line number entries. */
3007   linenumber_pointer = linenumber_table;
3008   for (i = 0; i < linenumber_count; i++)
3009     {
3010       int pc = GET_u2 (linenumber_pointer);
3011       linenumber_pointer += 4;
3012       if (pc >= length)
3013         warning (0, "invalid PC in line number table");
3014       else
3015         {
3016           if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
3017             instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
3018           instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
3019         }
3020     }  
3021
3022   if (! verify_jvm_instructions_new (jcf, byte_ops, length))
3023     return;
3024
3025   promote_arguments ();
3026
3027   /* Translate bytecodes.  */
3028   linenumber_pointer = linenumber_table;
3029   for (PC = 0; PC < length;)
3030     {
3031       if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
3032         {
3033           tree label = lookup_label (PC);
3034           flush_quick_stack ();
3035           if ((instruction_bits [PC] & BCODE_TARGET) != 0)
3036             java_add_stmt (build1 (LABEL_EXPR, void_type_node, label));
3037           if (LABEL_VERIFIED (label) || PC == 0)
3038             load_type_state (label);
3039         }
3040
3041       if (! (instruction_bits [PC] & BCODE_VERIFIED))
3042         {
3043           if (dead_code_index == -1)
3044             {
3045               /* This is the start of a region of unreachable bytecodes.
3046                  They still need to be processed in order for EH ranges
3047                  to get handled correctly.  However, we can simply
3048                  replace these bytecodes with nops.  */
3049               dead_code_index = PC;
3050             }
3051           
3052           /* Turn this bytecode into a nop.  */
3053           byte_ops[PC] = 0x0;
3054         }
3055        else
3056         {
3057           if (dead_code_index != -1)
3058             {
3059               /* We've just reached the end of a region of dead code.  */
3060               if (extra_warnings)
3061                 warning (0, "unreachable bytecode from %d to before %d",
3062                          dead_code_index, PC);
3063               dead_code_index = -1;
3064             }
3065         }
3066
3067       /* Handle possible line number entry for this PC.
3068
3069          This code handles out-of-order and multiple linenumbers per PC,
3070          but is optimized for the case of line numbers increasing
3071          monotonically with PC. */
3072       if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
3073         {
3074           if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
3075               || GET_u2 (linenumber_pointer) != PC)
3076             linenumber_pointer = linenumber_table;
3077           while (linenumber_pointer < linenumber_table + linenumber_count * 4)
3078             {
3079               int pc = GET_u2 (linenumber_pointer);
3080               linenumber_pointer += 4;
3081               if (pc == PC)
3082                 {
3083                   int line = GET_u2 (linenumber_pointer - 2);
3084 #ifdef USE_MAPPED_LOCATION
3085                   input_location = linemap_line_start (&line_table, line, 1);
3086 #else
3087                   input_location.line = line;
3088 #endif
3089                   if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
3090                     break;
3091                 }
3092             }
3093         }
3094       maybe_pushlevels (PC);
3095       PC = process_jvm_instruction (PC, byte_ops, length);
3096       maybe_poplevels (PC);
3097     } /* for */
3098   
3099   if (dead_code_index != -1)
3100     {
3101       /* We've just reached the end of a region of dead code.  */
3102       if (extra_warnings)
3103         warning (0, "unreachable bytecode from %d to the end of the method", 
3104                  dead_code_index);
3105     }
3106 }
3107
3108 static void
3109 java_push_constant_from_pool (JCF *jcf, int index)
3110 {
3111   tree c;
3112   if (JPOOL_TAG (jcf, index) == CONSTANT_String)
3113     {
3114       tree name;
3115       name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
3116       index = alloc_name_constant (CONSTANT_String, name);
3117       c = build_ref_from_constant_pool (index);
3118       c = convert (promote_type (string_type_node), c);
3119     }
3120   else if (JPOOL_TAG (jcf, index) == CONSTANT_Class
3121            || JPOOL_TAG (jcf, index) == CONSTANT_ResolvedClass)
3122     {
3123       tree record = get_class_constant (jcf, index);
3124       c = build_class_ref (record);
3125     }
3126   else
3127     c = get_constant (jcf, index);
3128   push_value (c);
3129
3130
3131 int
3132 process_jvm_instruction (int PC, const unsigned char* byte_ops,
3133                          long length ATTRIBUTE_UNUSED)
3134
3135   const char *opname; /* Temporary ??? */
3136   int oldpc = PC; /* PC at instruction start. */
3137
3138   /* If the instruction is at the beginning of an exception handler,
3139      replace the top of the stack with the thrown object reference.  */
3140   if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
3141     {
3142       /* Note that the verifier will not emit a type map at all for
3143          dead exception handlers.  In this case we just ignore the
3144          situation.  */
3145       if ((instruction_bits[PC] & BCODE_VERIFIED) != 0)
3146         {
3147           tree type = pop_type (promote_type (throwable_type_node));
3148           push_value (build_exception_object_ref (type));
3149         }
3150     }
3151
3152   switch (byte_ops[PC++])
3153     {
3154 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
3155     case OPCODE: \
3156       opname = #OPNAME; \
3157       OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
3158       break;
3159
3160 #define RET(OPERAND_TYPE, OPERAND_VALUE)                                \
3161   {                                                                     \
3162     int saw_index = 0;                                                  \
3163     int index     = OPERAND_VALUE;                                      \
3164     build_java_ret                                                      \
3165       (find_local_variable (index, return_address_type_node, oldpc));   \
3166   }
3167
3168 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
3169   {                                                 \
3170     /* OPERAND_VALUE may have side-effects on PC */ \
3171     int opvalue = OPERAND_VALUE;                    \
3172     build_java_jsr (oldpc + opvalue, PC);           \
3173   }
3174
3175 /* Push a constant onto the stack. */
3176 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
3177   { int saw_index = 0;  int ival = (OPERAND_VALUE); \
3178     if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
3179     else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
3180
3181 /* internal macro added for use by the WIDE case */
3182 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
3183   expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
3184
3185 /* Push local variable onto the opcode stack. */
3186 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
3187   { \
3188     /* have to do this since OPERAND_VALUE may have side-effects */ \
3189     int opvalue = OPERAND_VALUE; \
3190     LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3191   }
3192
3193 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
3194   expand_java_return (OPERAND_TYPE##_type_node)
3195
3196 #define REM_EXPR TRUNC_MOD_EXPR
3197 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
3198   expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
3199
3200 #define FIELD(IS_STATIC, IS_PUT) \
3201   expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
3202
3203 #define TEST(OPERAND_TYPE, CONDITION) \
3204   expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3205
3206 #define COND(OPERAND_TYPE, CONDITION) \
3207   expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3208
3209 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
3210   BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
3211
3212 #define BRANCH_GOTO(OPERAND_VALUE) \
3213   expand_java_goto (oldpc + OPERAND_VALUE)
3214
3215 #define BRANCH_CALL(OPERAND_VALUE) \
3216   expand_java_call (oldpc + OPERAND_VALUE, oldpc)
3217
3218 #if 0
3219 #define BRANCH_RETURN(OPERAND_VALUE) \
3220   { \
3221     tree type = OPERAND_TYPE##_type_node; \
3222     tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3223     expand_java_ret (value); \
3224   }
3225 #endif
3226
3227 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3228           fprintf (stderr, "%3d: %s ", oldpc, opname); \
3229           fprintf (stderr, "(not implemented)\n")
3230 #define NOT_IMPL1(OPERAND_VALUE) \
3231           fprintf (stderr, "%3d: %s ", oldpc, opname); \
3232           fprintf (stderr, "(not implemented)\n")
3233
3234 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3235
3236 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3237
3238 #define STACK_POP(COUNT) java_stack_pop (COUNT)
3239
3240 #define STACK_SWAP(COUNT) java_stack_swap()
3241
3242 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3243 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3244 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3245
3246 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3247   PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3248
3249 #define LOOKUP_SWITCH \
3250   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
3251     tree selector = pop_value (INT_type_node); \
3252     tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3253     while (--npairs >= 0) \
3254       { \
3255         jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3256         expand_java_add_case (switch_expr, match, oldpc + offset); \
3257       } \
3258   }
3259
3260 #define TABLE_SWITCH \
3261   { jint default_offset = IMMEDIATE_s4; \
3262     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3263     tree selector = pop_value (INT_type_node); \
3264     tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3265     for (; low <= high; low++) \
3266       { \
3267         jint offset = IMMEDIATE_s4; \
3268         expand_java_add_case (switch_expr, low, oldpc + offset); \
3269       } \
3270   }
3271
3272 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3273   { int opcode = byte_ops[PC-1]; \
3274     int method_ref_index = IMMEDIATE_u2; \
3275     int nargs; \
3276     if (IS_INTERFACE) { nargs = IMMEDIATE_u1;  (void) IMMEDIATE_u1; } \
3277     else nargs = -1; \
3278     expand_invoke (opcode, method_ref_index, nargs); \
3279   }
3280
3281 /* Handle new, checkcast, instanceof */
3282 #define OBJECT(TYPE, OP) \
3283   expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3284
3285 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3286
3287 #define ARRAY_LOAD(OPERAND_TYPE)                        \
3288   {                                                     \
3289     expand_java_arrayload( OPERAND_TYPE##_type_node );  \
3290   }
3291
3292 #define ARRAY_STORE(OPERAND_TYPE)                       \
3293   {                                                     \
3294     expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3295   }
3296
3297 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3298 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3299 #define ARRAY_NEW_PTR()                                                 \
3300     push_value (build_anewarray (get_class_constant (current_jcf,       \
3301                                                      IMMEDIATE_u2),     \
3302                                  pop_value (int_type_node)));
3303 #define ARRAY_NEW_NUM()                         \
3304   {                                             \
3305     int atype = IMMEDIATE_u1;                   \
3306     push_value (build_newarray (atype, pop_value (int_type_node)));\
3307   }
3308 #define ARRAY_NEW_MULTI()                                       \
3309   {                                                             \
3310     tree class = get_class_constant (current_jcf, IMMEDIATE_u2 );       \
3311     int  ndims = IMMEDIATE_u1;                                  \
3312     expand_java_multianewarray( class, ndims );                 \
3313   }
3314
3315 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3316   push_value (fold_build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3317                            pop_value (OPERAND_TYPE##_type_node)));
3318
3319 #define CONVERT2(FROM_TYPE, TO_TYPE)                                     \
3320   {                                                                      \
3321     push_value (build1 (NOP_EXPR, int_type_node,                         \
3322                         (convert (TO_TYPE##_type_node,                   \
3323                                   pop_value (FROM_TYPE##_type_node))))); \
3324   }
3325
3326 #define CONVERT(FROM_TYPE, TO_TYPE)                             \
3327   {                                                             \
3328     push_value (convert (TO_TYPE##_type_node,                   \
3329                          pop_value (FROM_TYPE##_type_node)));   \
3330   }
3331
3332 /* internal macro added for use by the WIDE case 
3333    Added TREE_TYPE (decl) assignment, apbianco  */
3334 #define STORE_INTERNAL(OPTYPE, OPVALUE)                         \
3335   {                                                             \
3336     tree decl, value;                                           \
3337     int index = OPVALUE;                                        \
3338     tree type = OPTYPE;                                         \
3339     value = pop_value (type);                                   \
3340     type = TREE_TYPE (value);                                   \
3341     decl = find_local_variable (index, type, oldpc);            \
3342     set_local_type (index, type);                               \
3343     java_add_stmt (build2 (MODIFY_EXPR, type, decl, value));    \
3344     update_aliases (decl, index, PC);                           \
3345   }
3346
3347 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3348   { \
3349     /* have to do this since OPERAND_VALUE may have side-effects */ \
3350     int opvalue = OPERAND_VALUE; \
3351     STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3352   }
3353
3354 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3355   SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3356
3357 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3358 #define SPECIAL_EXIT(IGNORED)  MONITOR_OPERATION (soft_monitorexit_node)
3359
3360 #define MONITOR_OPERATION(call)                 \
3361   {                                             \
3362     tree o = pop_value (ptr_type_node);         \
3363     tree c;                                     \
3364     flush_quick_stack ();                       \
3365     c = build_java_monitor (call, o);           \
3366     TREE_SIDE_EFFECTS (c) = 1;                  \
3367     java_add_stmt (c);                          \
3368   }
3369
3370 #define SPECIAL_IINC(IGNORED) \
3371   { \
3372     unsigned int local_var_index = IMMEDIATE_u1; \
3373     int ival = IMMEDIATE_s1; \
3374     expand_iinc(local_var_index, ival, oldpc); \
3375   }
3376
3377 #define SPECIAL_WIDE(IGNORED) \
3378   { \
3379     int modified_opcode = IMMEDIATE_u1; \
3380     unsigned int local_var_index = IMMEDIATE_u2; \
3381     switch (modified_opcode) \
3382       { \
3383       case OPCODE_iinc: \
3384         { \
3385           int ival = IMMEDIATE_s2; \
3386           expand_iinc (local_var_index, ival, oldpc); \
3387           break; \
3388         } \
3389       case OPCODE_iload: \
3390       case OPCODE_lload: \
3391       case OPCODE_fload: \
3392       case OPCODE_dload: \
3393       case OPCODE_aload: \
3394         { \
3395           /* duplicate code from LOAD macro */ \
3396           LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3397           break; \
3398         } \
3399       case OPCODE_istore: \
3400       case OPCODE_lstore: \
3401       case OPCODE_fstore: \
3402       case OPCODE_dstore: \
3403       case OPCODE_astore: \
3404         { \
3405           STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3406           break; \
3407         } \
3408       default: \
3409         error ("unrecogized wide sub-instruction"); \
3410       } \
3411   }
3412
3413 #define SPECIAL_THROW(IGNORED) \
3414   build_java_athrow (pop_value (throwable_type_node))
3415
3416 #define SPECIAL_BREAK NOT_IMPL1
3417 #define IMPL          NOT_IMPL
3418
3419 #include "javaop.def"
3420 #undef JAVAOP
3421    default:
3422     fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3423   }
3424   return PC;
3425 }
3426
3427 /* Return the opcode at PC in the code section pointed to by
3428    CODE_OFFSET.  */
3429
3430 static unsigned char
3431 peek_opcode_at_pc (JCF *jcf, int code_offset, int pc)
3432 {
3433   unsigned char opcode;
3434   long absolute_offset = (long)JCF_TELL (jcf);
3435
3436   JCF_SEEK (jcf, code_offset);
3437   opcode = jcf->read_ptr [pc];
3438   JCF_SEEK (jcf, absolute_offset);
3439   return opcode;
3440 }
3441
3442 /* Some bytecode compilers are emitting accurate LocalVariableTable
3443    attributes. Here's an example:
3444    
3445      PC   <t>store_<n>
3446      PC+1 ...
3447      
3448      Attribute "LocalVariableTable"
3449      slot #<n>: ... (PC: PC+1 length: L)
3450    
3451    This is accurate because the local in slot <n> really exists after
3452    the opcode at PC is executed, hence from PC+1 to PC+1+L.
3453
3454    This procedure recognizes this situation and extends the live range
3455    of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3456    length of the store instruction.)
3457
3458    This function is used by `give_name_to_locals' so that a local's
3459    DECL features a DECL_LOCAL_START_PC such that the first related
3460    store operation will use DECL as a destination, not an unrelated
3461    temporary created for the occasion.
3462
3463    This function uses a global (instruction_bits) `note_instructions' should
3464    have allocated and filled properly.  */
3465
3466 int
3467 maybe_adjust_start_pc (struct JCF *jcf, int code_offset,
3468                        int start_pc, int slot)
3469 {
3470   int first, index, opcode;
3471   int pc, insn_pc;
3472   int wide_found = 0;
3473
3474   if (!start_pc)
3475     return start_pc;
3476
3477   first = index = -1;
3478
3479   /* Find last previous instruction and remember it */
3480   for (pc = start_pc-1; pc; pc--) 
3481     if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3482       break;
3483   insn_pc = pc;
3484
3485   /* Retrieve the instruction, handle `wide'. */  
3486   opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3487   if (opcode == OPCODE_wide)
3488     {
3489       wide_found = 1;
3490       opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3491     }
3492
3493   switch (opcode)
3494     {
3495     case OPCODE_astore_0:
3496     case OPCODE_astore_1:
3497     case OPCODE_astore_2:
3498     case OPCODE_astore_3:
3499       first = OPCODE_astore_0;
3500       break;
3501
3502     case OPCODE_istore_0:
3503     case OPCODE_istore_1:
3504     case OPCODE_istore_2:
3505     case OPCODE_istore_3:
3506       first = OPCODE_istore_0;
3507       break;
3508       
3509     case OPCODE_lstore_0:
3510     case OPCODE_lstore_1:
3511     case OPCODE_lstore_2:
3512     case OPCODE_lstore_3:
3513       first = OPCODE_lstore_0;
3514       break;
3515
3516     case OPCODE_fstore_0:
3517     case OPCODE_fstore_1:
3518     case OPCODE_fstore_2:
3519     case OPCODE_fstore_3:
3520       first = OPCODE_fstore_0;
3521       break;
3522
3523     case OPCODE_dstore_0:
3524     case OPCODE_dstore_1:
3525     case OPCODE_dstore_2:
3526     case OPCODE_dstore_3:
3527       first = OPCODE_dstore_0;
3528       break;
3529
3530     case OPCODE_astore:
3531     case OPCODE_istore:
3532     case OPCODE_lstore:
3533     case OPCODE_fstore:
3534     case OPCODE_dstore:
3535       index = peek_opcode_at_pc (jcf, code_offset, pc);
3536       if (wide_found)
3537         {
3538           int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3539           index = (other << 8) + index;
3540         }
3541       break;
3542     }
3543
3544   /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3545      means we have a <t>store. */
3546   if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3547     start_pc = insn_pc;
3548
3549   return start_pc;
3550 }
3551
3552 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3553    order, as specified by Java Language Specification.
3554
3555    The problem is that while expand_expr will evaluate its sub-operands in
3556    left-to-right order, for variables it will just return an rtx (i.e.
3557    an lvalue) for the variable (rather than an rvalue).  So it is possible
3558    that a later sub-operand will change the register, and when the
3559    actual operation is done, it will use the new value, when it should
3560    have used the original value.
3561
3562    We fix this by using save_expr.  This forces the sub-operand to be
3563    copied into a fresh virtual register,
3564
3565    For method invocation, we modify the arguments so that a
3566    left-to-right order evaluation is performed. Saved expressions
3567    will, in CALL_EXPR order, be reused when the call will be expanded.
3568
3569    We also promote outgoing args if needed.  */
3570
3571 tree
3572 force_evaluation_order (tree node)
3573 {
3574   if (flag_syntax_only)
3575     return node;
3576   if (TREE_CODE (node) == CALL_EXPR
3577       || TREE_CODE (node) == NEW_CLASS_EXPR
3578       || (TREE_CODE (node) == COMPOUND_EXPR
3579           && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3580           && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR)) 
3581     {
3582       tree arg, cmp;
3583
3584       arg = node;
3585       
3586       /* Position arg properly, account for wrapped around ctors. */
3587       if (TREE_CODE (node) == COMPOUND_EXPR)
3588         arg = TREE_OPERAND (node, 0);
3589       
3590       arg = TREE_OPERAND (arg, 1);
3591       
3592       /* An empty argument list is ok, just ignore it.  */
3593       if (!arg)
3594         return node;
3595
3596       /* Not having a list of arguments here is an error. */ 
3597       gcc_assert (TREE_CODE (arg) == TREE_LIST);
3598
3599       /* This reverses the evaluation order. This is a desired effect. */
3600       for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3601         {
3602           /* Promote types smaller than integer.  This is required by
3603              some ABIs.  */
3604           tree type = TREE_TYPE (TREE_VALUE (arg));
3605           tree saved;
3606           if (targetm.calls.promote_prototypes (type)
3607               && INTEGRAL_TYPE_P (type)
3608               && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
3609                                       TYPE_SIZE (integer_type_node)))
3610             TREE_VALUE (arg) = fold_convert (integer_type_node, TREE_VALUE (arg));
3611
3612           saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3613           cmp = (cmp == NULL_TREE ? saved :
3614                  build2 (COMPOUND_EXPR, void_type_node, cmp, saved));
3615           TREE_VALUE (arg) = saved;
3616         }
3617       
3618       if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3619         TREE_SIDE_EFFECTS (cmp) = 1;
3620
3621       if (cmp)
3622         {
3623           cmp = build2 (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
3624           if (TREE_TYPE (cmp) != void_type_node)
3625             cmp = save_expr (cmp);
3626           CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3627           TREE_SIDE_EFFECTS (cmp) = 1;
3628           node = cmp;
3629         }
3630     }
3631   return node;
3632 }
3633
3634 /* EXPR_WITH_FILE_LOCATION are used to keep track of the exact
3635    location where an expression or an identifier were encountered. It
3636    is necessary for languages where the frontend parser will handle
3637    recursively more than one file (Java is one of them).  */
3638
3639 tree
3640 build_expr_wfl (tree node,
3641 #ifdef USE_MAPPED_LOCATION
3642                 source_location location
3643 #else
3644                 const char *file, int line, int col
3645 #endif
3646 )
3647 {
3648   tree wfl;
3649
3650 #ifdef USE_MAPPED_LOCATION
3651   wfl = make_node (EXPR_WITH_FILE_LOCATION);
3652   SET_EXPR_LOCATION (wfl, location);
3653 #else
3654   static const char *last_file = 0;
3655   static tree last_filenode = NULL_TREE;
3656
3657   wfl = make_node (EXPR_WITH_FILE_LOCATION);
3658
3659   EXPR_WFL_SET_LINECOL (wfl, line, col);
3660   if (file != last_file)
3661     {
3662       last_file = file;
3663       last_filenode = file ? get_identifier (file) : NULL_TREE;
3664     }
3665   EXPR_WFL_FILENAME_NODE (wfl) = last_filenode;
3666 #endif
3667   EXPR_WFL_NODE (wfl) = node;
3668   if (node)
3669     {
3670       if (!TYPE_P (node))
3671         TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
3672       TREE_TYPE (wfl) = TREE_TYPE (node);
3673     }
3674
3675   return wfl;
3676 }
3677
3678 #ifdef USE_MAPPED_LOCATION
3679 tree
3680 expr_add_location (tree node, source_location location, bool statement)
3681 {
3682   tree wfl;
3683 #if 0
3684   /* FIXME. This optimization causes failures in code that expects an
3685      EXPR_WITH_FILE_LOCATION.  E.g. in resolve_qualified_expression_name. */
3686   if (node && ! (statement && flag_emit_class_files))
3687     {
3688       source_location node_loc = EXPR_LOCATION (node);
3689       if (node_loc == location || location == UNKNOWN_LOCATION)
3690         return node;
3691       if (node_loc == UNKNOWN_LOCATION
3692           && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
3693         {
3694           SET_EXPR_LOCATION (node, location);
3695           return node;
3696         }
3697     }
3698 #endif
3699   wfl = make_node (EXPR_WITH_FILE_LOCATION);
3700   SET_EXPR_LOCATION (wfl, location);
3701   EXPR_WFL_NODE (wfl) = node;
3702   if (statement && debug_info_level != DINFO_LEVEL_NONE)
3703     EXPR_WFL_EMIT_LINE_NOTE (wfl) = 1;
3704   if (node)
3705     {
3706       if (!TYPE_P (node))
3707         TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
3708       TREE_TYPE (wfl) = TREE_TYPE (node);
3709     }
3710
3711   return wfl;
3712 }
3713 #endif
3714
3715 /* Build a node to represent empty statements and blocks. */
3716
3717 tree
3718 build_java_empty_stmt (void)
3719 {
3720   tree t = build_empty_stmt ();
3721   CAN_COMPLETE_NORMALLY (t) = 1;
3722   return t;
3723 }
3724
3725 /* Promote all args of integral type before generating any code.  */
3726
3727 static void
3728 promote_arguments (void)
3729 {
3730   int i;
3731   tree arg;
3732   for (arg = DECL_ARGUMENTS (current_function_decl), i = 0;
3733        arg != NULL_TREE;  arg = TREE_CHAIN (arg), i++)
3734     {
3735       tree arg_type = TREE_TYPE (arg);
3736       if (INTEGRAL_TYPE_P (arg_type)
3737           && TYPE_PRECISION (arg_type) < 32)
3738         {
3739           tree copy = find_local_variable (i, integer_type_node, -1);
3740           java_add_stmt (build2 (MODIFY_EXPR, integer_type_node,
3741                                  copy,
3742                                  fold_convert (integer_type_node, arg)));
3743         }
3744       if (TYPE_IS_WIDE (arg_type))
3745         i++;
3746     }
3747 }
3748
3749 #include "gt-java-expr.h"