OSDN Git Service

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