OSDN Git Service

* expr.c (get_symbol_table_index): Add spaces in expression.
[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,
2293                         VEC(method_entry,gc) **symbol_table)
2294 {
2295   method_entry *e;
2296   unsigned i;
2297
2298   for (i = 0; VEC_iterate (method_entry, *symbol_table, i, e); i++)
2299     if (t == e->method && special == e->special)
2300       goto done;
2301
2302   e = VEC_safe_push (method_entry, gc, *symbol_table, NULL);
2303   e->method = t;
2304   e->special = special;
2305
2306  done:
2307   return i + 1;
2308 }
2309
2310 tree 
2311 build_invokevirtual (tree dtable, tree method, tree special)
2312 {
2313   tree func;
2314   tree nativecode_ptr_ptr_type_node
2315     = build_pointer_type (nativecode_ptr_type_node);
2316   tree method_index;
2317   tree otable_index;
2318
2319   if (flag_indirect_dispatch)
2320     {
2321       gcc_assert (! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))));
2322
2323       otable_index 
2324         = build_int_cst (NULL_TREE, get_symbol_table_index 
2325                          (method, special,
2326                           &TYPE_OTABLE_METHODS (output_class)));
2327       method_index = build4 (ARRAY_REF, integer_type_node, 
2328                              TYPE_OTABLE_DECL (output_class), 
2329                              otable_index, NULL_TREE, NULL_TREE);
2330     }
2331   else
2332     {
2333       /* We fetch the DECL_VINDEX field directly here, rather than
2334          using get_method_index().  DECL_VINDEX is the true offset
2335          from the vtable base to a method, regrdless of any extra
2336          words inserted at the start of the vtable.  */
2337       method_index = DECL_VINDEX (method);
2338       method_index = size_binop (MULT_EXPR, method_index,
2339                                  TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
2340       if (TARGET_VTABLE_USES_DESCRIPTORS)
2341         method_index = size_binop (MULT_EXPR, method_index,
2342                                    size_int (TARGET_VTABLE_USES_DESCRIPTORS));
2343     }
2344
2345   func = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dtable), dtable,
2346                       convert (sizetype, method_index));
2347
2348   if (TARGET_VTABLE_USES_DESCRIPTORS)
2349     func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
2350   else
2351     {
2352       func = fold_convert (nativecode_ptr_ptr_type_node, func);
2353       func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
2354     }
2355
2356   return func;
2357 }
2358
2359 static GTY(()) tree class_ident;
2360 tree
2361 build_invokeinterface (tree dtable, tree method)
2362 {
2363   tree interface;
2364   tree idx;
2365
2366   /* We expand invokeinterface here.  */
2367             
2368   if (class_ident == NULL_TREE)
2369     class_ident = get_identifier ("class");
2370
2371   dtable = build_java_indirect_ref (dtable_type, dtable,
2372                                     flag_check_references);
2373   dtable = build3 (COMPONENT_REF, class_ptr_type, dtable,
2374                    lookup_field (&dtable_type, class_ident), NULL_TREE);
2375
2376   interface = DECL_CONTEXT (method);
2377   gcc_assert (CLASS_INTERFACE (TYPE_NAME (interface)));
2378   layout_class_methods (interface);
2379   
2380   if (flag_indirect_dispatch)
2381     {
2382       int itable_index 
2383         = 2 * (get_symbol_table_index 
2384                (method, NULL_TREE, &TYPE_ITABLE_METHODS (output_class)));
2385       interface 
2386         = build4 (ARRAY_REF, 
2387                  TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
2388                  TYPE_ITABLE_DECL (output_class), 
2389                   build_int_cst (NULL_TREE, itable_index-1),
2390                   NULL_TREE, NULL_TREE);
2391       idx 
2392         = build4 (ARRAY_REF, 
2393                  TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
2394                  TYPE_ITABLE_DECL (output_class), 
2395                   build_int_cst (NULL_TREE, itable_index),
2396                   NULL_TREE, NULL_TREE);
2397       interface = convert (class_ptr_type, interface);
2398       idx = convert (integer_type_node, idx);
2399     }
2400   else
2401     {
2402       idx = build_int_cst (NULL_TREE, 
2403                            get_interface_method_index (method, interface));
2404       interface = build_class_ref (interface);
2405     }
2406                                                           
2407   return build_call_nary (ptr_type_node, 
2408                           build_address_of (soft_lookupinterfacemethod_node),
2409                           3, dtable, interface, idx);
2410 }
2411   
2412 /* Expand one of the invoke_* opcodes.
2413    OPCODE is the specific opcode.
2414    METHOD_REF_INDEX is an index into the constant pool.
2415    NARGS is the number of arguments, or -1 if not specified. */
2416
2417 static void
2418 expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
2419 {
2420   tree method_signature
2421     = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
2422   tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool,
2423                                          method_ref_index);
2424   tree self_type
2425     = get_class_constant (current_jcf,
2426                           COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool,
2427                           method_ref_index));
2428   const char *const self_name
2429     = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2430   tree call, func, method, method_type;
2431   VEC(tree,gc) *arg_list;
2432   tree check = NULL_TREE;
2433
2434   tree special = NULL_TREE;
2435
2436   if (! CLASS_LOADED_P (self_type))
2437     {
2438       load_class (self_type, 1);
2439       safe_layout_class (self_type);
2440       if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2441         fatal_error ("failed to find class '%s'", self_name);
2442     }
2443   layout_class_methods (self_type);
2444
2445   if (ID_INIT_P (method_name))
2446     method = lookup_java_constructor (self_type, method_signature);
2447   else
2448     method = lookup_java_method (self_type, method_name, method_signature);
2449
2450   /* We've found a method in a class other than the one in which it
2451      was wanted.  This can happen if, for instance, we're trying to
2452      compile invokespecial super.equals().  
2453      FIXME: This is a kludge.  Rather than nullifying the result, we
2454      should change lookup_java_method() so that it doesn't search the
2455      superclass chain when we're BC-compiling.  */
2456   if (! flag_verify_invocations
2457       && method
2458       && ! TYPE_ARRAY_P (self_type)
2459       && self_type != DECL_CONTEXT (method))
2460     method = NULL_TREE;
2461
2462   /* We've found a method in an interface, but this isn't an interface
2463      call.  */
2464   if (opcode != OPCODE_invokeinterface
2465       && method
2466       && (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method)))))
2467     method = NULL_TREE;
2468
2469   /* We've found a non-interface method but we are making an
2470      interface call.  This can happen if the interface overrides a
2471      method in Object.  */
2472   if (! flag_verify_invocations
2473       && opcode == OPCODE_invokeinterface
2474       && method
2475       && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
2476     method = NULL_TREE;
2477
2478   if (method == NULL_TREE)
2479     {
2480       if (flag_verify_invocations || ! flag_indirect_dispatch)
2481         {
2482           error ("class '%s' has no method named '%s' matching signature '%s'",
2483                  self_name,
2484                  IDENTIFIER_POINTER (method_name),
2485                  IDENTIFIER_POINTER (method_signature));
2486         }
2487       else
2488         {
2489           int flags = ACC_PUBLIC;
2490           if (opcode == OPCODE_invokestatic)
2491             flags |= ACC_STATIC;
2492           if (opcode == OPCODE_invokeinterface)
2493             {
2494               flags |= ACC_INTERFACE | ACC_ABSTRACT;
2495               CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
2496             }
2497           method = add_method (self_type, flags, method_name,
2498                                method_signature);
2499           DECL_ARTIFICIAL (method) = 1;
2500           METHOD_DUMMY (method) = 1;
2501           layout_class_method (self_type, NULL,
2502                                method, NULL);
2503         }
2504     }
2505
2506   /* Invoke static can't invoke static/abstract method */
2507   if (method != NULL_TREE)
2508     {
2509       if (opcode == OPCODE_invokestatic)
2510         {
2511           if (!METHOD_STATIC (method))
2512             {
2513               error ("invokestatic on non static method");
2514               method = NULL_TREE;
2515             }
2516           else if (METHOD_ABSTRACT (method))
2517             {
2518               error ("invokestatic on abstract method");
2519               method = NULL_TREE;
2520             }
2521         }
2522       else
2523         {
2524           if (METHOD_STATIC (method))
2525             {
2526               error ("invoke[non-static] on static method");
2527               method = NULL_TREE;
2528             }
2529         }
2530     }
2531
2532   if (method == NULL_TREE)
2533     {
2534       /* If we got here, we emitted an error message above.  So we
2535          just pop the arguments, push a properly-typed zero, and
2536          continue.  */
2537       method_type = get_type_from_signature (method_signature);
2538       pop_arguments (method_type);
2539       if (opcode != OPCODE_invokestatic) 
2540         pop_type (self_type);
2541       method_type = promote_type (TREE_TYPE (method_type));
2542       push_value (convert (method_type, integer_zero_node));
2543       return;
2544     }
2545
2546   method_type = TREE_TYPE (method);
2547   arg_list = pop_arguments (method_type);
2548   flush_quick_stack ();
2549
2550   maybe_rewrite_invocation (&method, &arg_list, &method_signature,
2551                             &special);
2552
2553   func = NULL_TREE;
2554   if (opcode == OPCODE_invokestatic)
2555     func = build_known_method_ref (method, method_type, self_type,
2556                                    method_signature, arg_list, special);
2557   else if (opcode == OPCODE_invokespecial
2558            || (opcode == OPCODE_invokevirtual
2559                && (METHOD_PRIVATE (method)
2560                    || METHOD_FINAL (method) 
2561                    || CLASS_FINAL (TYPE_NAME (self_type)))))
2562     {
2563       /* If the object for the method call is null, we throw an
2564          exception.  We don't do this if the object is the current
2565          method's `this'.  In other cases we just rely on an
2566          optimization pass to eliminate redundant checks.  FIXME:
2567          Unfortunately there doesn't seem to be a way to determine
2568          what the current method is right now.
2569          We do omit the check if we're calling <init>.  */
2570       /* We use a SAVE_EXPR here to make sure we only evaluate
2571          the new `self' expression once.  */
2572       tree save_arg = save_expr (VEC_index (tree, arg_list, 0));
2573       VEC_replace (tree, arg_list, 0, save_arg);
2574       check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2575       func = build_known_method_ref (method, method_type, self_type,
2576                                      method_signature, arg_list, special);
2577     }
2578   else
2579     {
2580       tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 
2581                                          arg_list);
2582       if (opcode == OPCODE_invokevirtual)
2583         func = build_invokevirtual (dtable, method, special);
2584       else
2585         func = build_invokeinterface (dtable, method);
2586     }
2587       
2588   if (TREE_CODE (func) == ADDR_EXPR)
2589     TREE_TYPE (func) = build_pointer_type (method_type);
2590   else
2591     func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2592
2593   call = build_call_vec (TREE_TYPE (method_type), func, arg_list);
2594   TREE_SIDE_EFFECTS (call) = 1;
2595   call = check_for_builtin (method, call);
2596
2597   if (check != NULL_TREE)
2598     {
2599       call = build2 (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2600       TREE_SIDE_EFFECTS (call) = 1;
2601     }
2602
2603   if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2604     java_add_stmt (call);
2605   else
2606     {
2607       push_value (call);
2608       flush_quick_stack ();
2609     }
2610 }
2611
2612 /* Create a stub which will be put into the vtable but which will call
2613    a JNI function.  */
2614
2615 tree
2616 build_jni_stub (tree method)
2617 {
2618   tree jnifunc, call, body, method_sig, arg_types;
2619   tree jniarg0, jniarg1, jniarg2, jniarg3;
2620   tree jni_func_type, tem;
2621   tree env_var, res_var = NULL_TREE, block;
2622   tree method_args;
2623   tree meth_var;
2624   tree bind;
2625   VEC(tree,gc) *args = NULL;
2626   int args_size = 0;
2627
2628   tree klass = DECL_CONTEXT (method);
2629   klass = build_class_ref (klass);
2630
2631   gcc_assert (METHOD_NATIVE (method) && flag_jni);
2632
2633   DECL_ARTIFICIAL (method) = 1;
2634   DECL_EXTERNAL (method) = 0;
2635
2636   env_var = build_decl (input_location,
2637                         VAR_DECL, get_identifier ("env"), ptr_type_node);
2638   DECL_CONTEXT (env_var) = method;
2639
2640   if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2641     {
2642       res_var = build_decl (input_location, VAR_DECL, get_identifier ("res"),
2643                             TREE_TYPE (TREE_TYPE (method)));
2644       DECL_CONTEXT (res_var) = method;
2645       TREE_CHAIN (env_var) = res_var;
2646     }
2647
2648   method_args = DECL_ARGUMENTS (method);
2649   block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
2650   TREE_SIDE_EFFECTS (block) = 1;
2651   TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2652
2653   /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
2654   body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
2655                  build_call_nary (ptr_type_node,
2656                                   build_address_of (soft_getjnienvnewframe_node),
2657                                   1, klass));
2658
2659   /* The JNIEnv structure is the first argument to the JNI function.  */
2660   args_size += int_size_in_bytes (TREE_TYPE (env_var));
2661   VEC_safe_push (tree, gc, args, env_var);
2662
2663   /* For a static method the second argument is the class.  For a
2664      non-static method the second argument is `this'; that is already
2665      available in the argument list.  */
2666   if (METHOD_STATIC (method))
2667     {
2668       args_size += int_size_in_bytes (TREE_TYPE (klass));
2669       VEC_safe_push (tree, gc, args, klass);
2670     }
2671
2672   /* All the arguments to this method become arguments to the
2673      underlying JNI function.  If we had to wrap object arguments in a
2674      special way, we would do that here.  */
2675   for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2676     {
2677       int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tem)));
2678 #ifdef PARM_BOUNDARY
2679       arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
2680                   * PARM_BOUNDARY);
2681 #endif
2682       args_size += (arg_bits / BITS_PER_UNIT);
2683
2684       VEC_safe_push (tree, gc, args, tem);
2685     }
2686   arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2687
2688   /* Argument types for static methods and the JNIEnv structure.
2689      FIXME: Write and use build_function_type_vec to avoid this.  */
2690   if (METHOD_STATIC (method))
2691     arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2692   arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2693
2694   /* We call _Jv_LookupJNIMethod to find the actual underlying
2695      function pointer.  _Jv_LookupJNIMethod will throw the appropriate
2696      exception if this function is not found at runtime.  */
2697   method_sig = build_java_signature (TREE_TYPE (method));
2698   jniarg0 = klass;
2699   jniarg1 = build_utf8_ref (DECL_NAME (method));
2700   jniarg2 = build_utf8_ref (unmangle_classname
2701                             (IDENTIFIER_POINTER (method_sig),
2702                              IDENTIFIER_LENGTH (method_sig)));
2703   jniarg3 = build_int_cst (NULL_TREE, args_size);
2704
2705   tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
2706
2707 #ifdef MODIFY_JNI_METHOD_CALL
2708   tem = MODIFY_JNI_METHOD_CALL (tem);
2709 #endif
2710
2711   jni_func_type = build_pointer_type (tem);
2712
2713   /* Use the actual function type, rather than a generic pointer type,
2714      such that this decl keeps the actual pointer type from being
2715      garbage-collected.  If it is, we end up using canonical types
2716      with different uids for equivalent function types, and this in
2717      turn causes utf8 identifiers and output order to vary.  */
2718   meth_var = build_decl (input_location,
2719                          VAR_DECL, get_identifier ("meth"), jni_func_type);
2720   TREE_STATIC (meth_var) = 1;
2721   TREE_PUBLIC (meth_var) = 0;
2722   DECL_EXTERNAL (meth_var) = 0;
2723   DECL_CONTEXT (meth_var) = method;
2724   DECL_ARTIFICIAL (meth_var) = 1;
2725   DECL_INITIAL (meth_var) = null_pointer_node;
2726   TREE_USED (meth_var) = 1;
2727   chainon (env_var, meth_var);
2728   build_result_decl (method);
2729
2730   jnifunc = build3 (COND_EXPR, jni_func_type,
2731                     build2 (NE_EXPR, boolean_type_node,
2732                             meth_var, build_int_cst (TREE_TYPE (meth_var), 0)),
2733                     meth_var,
2734                     build2 (MODIFY_EXPR, jni_func_type, meth_var,
2735                             build1
2736                             (NOP_EXPR, jni_func_type,
2737                              build_call_nary (ptr_type_node,
2738                                               build_address_of
2739                                               (soft_lookupjnimethod_node),
2740                                               4,
2741                                               jniarg0, jniarg1,
2742                                               jniarg2, jniarg3))));
2743
2744   /* Now we make the actual JNI call via the resulting function
2745      pointer.    */
2746   call = build_call_vec (TREE_TYPE (TREE_TYPE (method)), jnifunc, args);
2747
2748   /* If the JNI call returned a result, capture it here.  If we had to
2749      unwrap JNI object results, we would do that here.  */
2750   if (res_var != NULL_TREE)
2751     {
2752       /* If the call returns an object, it may return a JNI weak
2753          reference, in which case we must unwrap it.  */
2754       if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method))))
2755         call = build_call_nary (TREE_TYPE (TREE_TYPE (method)),
2756                                 build_address_of (soft_unwrapjni_node),
2757                                 1, call);
2758       call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2759                      res_var, call);
2760     }
2761
2762   TREE_SIDE_EFFECTS (call) = 1;
2763
2764   body = build2 (COMPOUND_EXPR, void_type_node, body, call);
2765   TREE_SIDE_EFFECTS (body) = 1;
2766
2767   /* Now free the environment we allocated.  */
2768   call = build_call_nary (ptr_type_node,
2769                           build_address_of (soft_jnipopsystemframe_node),
2770                           1, env_var);
2771   TREE_SIDE_EFFECTS (call) = 1;
2772   body = build2 (COMPOUND_EXPR, void_type_node, body, call);
2773   TREE_SIDE_EFFECTS (body) = 1;
2774
2775   /* Finally, do the return.  */
2776   if (res_var != NULL_TREE)
2777     {
2778       tree drt;
2779       gcc_assert (DECL_RESULT (method));
2780       /* Make sure we copy the result variable to the actual
2781          result.  We use the type of the DECL_RESULT because it
2782          might be different from the return type of the function:
2783          it might be promoted.  */
2784       drt = TREE_TYPE (DECL_RESULT (method));
2785       if (drt != TREE_TYPE (res_var))
2786         res_var = build1 (CONVERT_EXPR, drt, res_var);
2787       res_var = build2 (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2788       TREE_SIDE_EFFECTS (res_var) = 1;
2789     }
2790
2791   body = build2 (COMPOUND_EXPR, void_type_node, body,
2792                  build1 (RETURN_EXPR, void_type_node, res_var));
2793   TREE_SIDE_EFFECTS (body) = 1;
2794   
2795   /* Prepend class initialization for static methods reachable from
2796      other classes.  */
2797   if (METHOD_STATIC (method)
2798       && (! METHOD_PRIVATE (method)
2799           || INNER_CLASS_P (DECL_CONTEXT (method))))
2800     {
2801       tree init = build_call_expr (soft_initclass_node, 1, 
2802                                    klass);
2803       body = build2 (COMPOUND_EXPR, void_type_node, init, body);
2804       TREE_SIDE_EFFECTS (body) = 1;
2805     }
2806
2807   bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), 
2808                  body, block);
2809   return bind;
2810 }
2811
2812
2813 /* Given lvalue EXP, return a volatile expression that references the
2814    same object.  */
2815
2816 tree
2817 java_modify_addr_for_volatile (tree exp)
2818 {
2819   tree exp_type = TREE_TYPE (exp);
2820   tree v_type 
2821     = build_qualified_type (exp_type,
2822                             TYPE_QUALS (exp_type) | TYPE_QUAL_VOLATILE);
2823   tree addr = build_fold_addr_expr (exp);
2824   v_type = build_pointer_type (v_type);
2825   addr = fold_convert (v_type, addr);
2826   exp = build_fold_indirect_ref (addr);
2827   return exp;
2828 }
2829
2830
2831 /* Expand an operation to extract from or store into a field.
2832    IS_STATIC is 1 iff the field is static.
2833    IS_PUTTING is 1 for putting into a field;  0 for getting from the field.
2834    FIELD_REF_INDEX is an index into the constant pool.  */
2835
2836 static void
2837 expand_java_field_op (int is_static, int is_putting, int field_ref_index)
2838 {
2839   tree self_type
2840     = get_class_constant (current_jcf,
2841                           COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2842                           field_ref_index));
2843   const char *self_name
2844     = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2845   tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2846   tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 
2847                                                   field_ref_index);
2848   tree field_type = get_type_from_signature (field_signature);
2849   tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2850   tree field_ref;
2851   int is_error = 0;
2852   tree original_self_type = self_type;
2853   tree field_decl;
2854   tree modify_expr;
2855   
2856   if (! CLASS_LOADED_P (self_type))
2857     load_class (self_type, 1);  
2858   field_decl = lookup_field (&self_type, field_name);
2859   if (field_decl == error_mark_node)
2860     {
2861       is_error = 1;
2862     }
2863   else if (field_decl == NULL_TREE)
2864     {
2865       if (! flag_verify_invocations)
2866         {
2867           int flags = ACC_PUBLIC;
2868           if (is_static)
2869             flags |= ACC_STATIC;
2870           self_type = original_self_type;
2871           field_decl = add_field (original_self_type, field_name,
2872                                   field_type, flags); 
2873           DECL_ARTIFICIAL (field_decl) = 1;
2874           DECL_IGNORED_P (field_decl) = 1;
2875 #if 0
2876           /* FIXME: We should be pessimistic about volatility.  We
2877              don't know one way or another, but this is safe.
2878              However, doing this has bad effects on code quality.  We
2879              need to look at better ways to do this.  */
2880           TREE_THIS_VOLATILE (field_decl) = 1;
2881 #endif
2882         }
2883       else
2884         {      
2885           error ("missing field '%s' in '%s'",
2886                  IDENTIFIER_POINTER (field_name), self_name);
2887           is_error = 1;
2888       }
2889     }
2890   else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2891     {
2892       error ("mismatching signature for field '%s' in '%s'",
2893              IDENTIFIER_POINTER (field_name), self_name);
2894       is_error = 1;
2895     }
2896   field_ref = is_static ? NULL_TREE : pop_value (self_type);
2897   if (is_error)
2898     {
2899       if (! is_putting)
2900         push_value (convert (field_type, integer_zero_node));
2901       flush_quick_stack ();
2902       return;
2903     }
2904
2905   field_ref = build_field_ref (field_ref, self_type, field_name);
2906   if (is_static
2907       && ! flag_indirect_dispatch)
2908     {
2909       tree context = DECL_CONTEXT (field_ref);
2910       if (context != self_type && CLASS_INTERFACE (TYPE_NAME (context)))
2911         field_ref = build_class_init (context, field_ref);
2912       else
2913         field_ref = build_class_init (self_type, field_ref);
2914     }
2915   if (is_putting)
2916     {
2917       flush_quick_stack ();
2918       if (FIELD_FINAL (field_decl))
2919         {
2920           if (DECL_CONTEXT (field_decl) != current_class)
2921             error ("assignment to final field %q+D not in field's class",
2922                    field_decl);
2923           /* We used to check for assignments to final fields not
2924              occurring in the class initializer or in a constructor
2925              here.  However, this constraint doesn't seem to be
2926              enforced by the JVM.  */
2927         }      
2928
2929       if (TREE_THIS_VOLATILE (field_decl))
2930         field_ref = java_modify_addr_for_volatile (field_ref);
2931
2932       modify_expr = build2 (MODIFY_EXPR, TREE_TYPE (field_ref),
2933                             field_ref, new_value);
2934
2935       if (TREE_THIS_VOLATILE (field_decl))
2936         java_add_stmt
2937           (build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0));
2938           
2939       java_add_stmt (modify_expr);
2940     }
2941   else
2942     {
2943       tree temp = build_decl (input_location,
2944                               VAR_DECL, NULL_TREE, TREE_TYPE (field_ref));
2945       java_add_local_var (temp);
2946
2947       if (TREE_THIS_VOLATILE (field_decl))
2948         field_ref = java_modify_addr_for_volatile (field_ref);
2949
2950       modify_expr 
2951         = build2 (MODIFY_EXPR, TREE_TYPE (field_ref), temp, field_ref);
2952       java_add_stmt (modify_expr);
2953
2954       if (TREE_THIS_VOLATILE (field_decl))
2955         java_add_stmt 
2956           (build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0));
2957
2958       push_value (temp);
2959     }      
2960   TREE_THIS_VOLATILE (field_ref) = TREE_THIS_VOLATILE (field_decl);
2961 }
2962
2963 static void
2964 load_type_state (int pc)
2965 {
2966   int i;
2967   tree vec = VEC_index (tree, type_states, pc);
2968   int cur_length = TREE_VEC_LENGTH (vec);
2969   stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2970   for (i = 0; i < cur_length; i++)
2971     type_map [i] = TREE_VEC_ELT (vec, i);
2972 }
2973
2974 /* Go over METHOD's bytecode and note instruction starts in
2975    instruction_bits[].  */
2976
2977 void
2978 note_instructions (JCF *jcf, tree method)
2979 {
2980   int PC; 
2981   unsigned char* byte_ops;
2982   long length = DECL_CODE_LENGTH (method);
2983
2984   int saw_index;
2985   jint INT_temp;
2986
2987 #undef RET /* Defined by config/i386/i386.h */
2988 #undef PTR
2989 #define BCODE byte_ops
2990 #define BYTE_type_node byte_type_node
2991 #define SHORT_type_node short_type_node
2992 #define INT_type_node int_type_node
2993 #define LONG_type_node long_type_node
2994 #define CHAR_type_node char_type_node
2995 #define PTR_type_node ptr_type_node
2996 #define FLOAT_type_node float_type_node
2997 #define DOUBLE_type_node double_type_node
2998 #define VOID_type_node void_type_node
2999 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
3000 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
3001 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
3002 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
3003
3004 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
3005
3006   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
3007   byte_ops = jcf->read_ptr;
3008   instruction_bits = XRESIZEVAR (char, instruction_bits, length + 1);
3009   memset (instruction_bits, 0, length + 1);
3010   type_states = VEC_alloc (tree, gc, length + 1);
3011   VEC_safe_grow_cleared (tree, gc, type_states, length + 1);
3012
3013   /* This pass figures out which PC can be the targets of jumps. */
3014   for (PC = 0; PC < length;)
3015     {
3016       int oldpc = PC; /* PC at instruction start. */
3017       instruction_bits [PC] |=  BCODE_INSTRUCTION_START;
3018       switch (byte_ops[PC++])
3019         {
3020 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
3021         case OPCODE: \
3022           PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
3023           break;
3024
3025 #define NOTE_LABEL(PC) note_label(oldpc, PC)
3026
3027 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
3028 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
3029 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
3030 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
3031 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
3032 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
3033 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
3034 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
3035
3036 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3037   PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3038 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
3039   ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
3040 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
3041 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
3042 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
3043 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
3044
3045 /* two forms of wide instructions */
3046 #define PRE_SPECIAL_WIDE(IGNORE) \
3047   { \
3048     int modified_opcode = IMMEDIATE_u1; \
3049     if (modified_opcode == OPCODE_iinc) \
3050       { \
3051         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
3052         (void) IMMEDIATE_s2;    /* constbyte1 and constbyte2 */ \
3053       } \
3054     else \
3055       { \
3056         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
3057       } \
3058   }
3059
3060 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
3061
3062 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
3063
3064 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
3065 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
3066           PRE_ARRAY_##SUBOP(OPERAND_TYPE)
3067 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
3068 #define PRE_ARRAY_STORE(TYPE) /* nothing */
3069 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
3070 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
3071 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
3072 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
3073 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
3074
3075 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
3076 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
3077 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
3078   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
3079   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
3080 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
3081   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
3082   NOTE_LABEL (PC); \
3083   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
3084
3085 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE)  (void)(OPERAND_VALUE)
3086
3087 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3088   PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
3089
3090 #define PRE_LOOKUP_SWITCH                                               \
3091   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4;    \
3092     NOTE_LABEL (default_offset+oldpc);                                  \
3093     if (npairs >= 0)                                                    \
3094       while (--npairs >= 0) {                                           \
3095        jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4;                      \
3096        jint offset = IMMEDIATE_s4;                                      \
3097        NOTE_LABEL (offset+oldpc); }                                     \
3098   }
3099
3100 #define PRE_TABLE_SWITCH                                \
3101   { jint default_offset = IMMEDIATE_s4;                 \
3102     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4;  \
3103     NOTE_LABEL (default_offset+oldpc);                  \
3104     if (low <= high)                                    \
3105      while (low++ <= high) {                            \
3106        jint offset = IMMEDIATE_s4;                      \
3107        NOTE_LABEL (offset+oldpc); }                     \
3108   }
3109
3110 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
3111 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
3112 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3113   (void)(IMMEDIATE_u2); \
3114   PC += 2 * IS_INTERFACE /* for invokeinterface */;
3115
3116 #include "javaop.def"
3117 #undef JAVAOP
3118         }
3119     } /* for */
3120 }
3121
3122 void
3123 expand_byte_code (JCF *jcf, tree method)
3124 {
3125   int PC;
3126   int i;
3127   const unsigned char *linenumber_pointer;
3128   int dead_code_index = -1;
3129   unsigned char* byte_ops;
3130   long length = DECL_CODE_LENGTH (method);
3131   location_t max_location = input_location;
3132
3133   stack_pointer = 0;
3134   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
3135   byte_ops = jcf->read_ptr;
3136
3137   /* We make an initial pass of the line number table, to note
3138      which instructions have associated line number entries. */
3139   linenumber_pointer = linenumber_table;
3140   for (i = 0; i < linenumber_count; i++)
3141     {
3142       int pc = GET_u2 (linenumber_pointer);
3143       linenumber_pointer += 4;
3144       if (pc >= length)
3145         warning (0, "invalid PC in line number table");
3146       else
3147         {
3148           if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
3149             instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
3150           instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
3151         }
3152     }  
3153
3154   if (! verify_jvm_instructions_new (jcf, byte_ops, length))
3155     return;
3156
3157   promote_arguments ();
3158   cache_this_class_ref (method);
3159   cache_cpool_data_ref ();
3160
3161   /* Translate bytecodes.  */
3162   linenumber_pointer = linenumber_table;
3163   for (PC = 0; PC < length;)
3164     {
3165       if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
3166         {
3167           tree label = lookup_label (PC);
3168           flush_quick_stack ();
3169           if ((instruction_bits [PC] & BCODE_TARGET) != 0)
3170             java_add_stmt (build1 (LABEL_EXPR, void_type_node, label));
3171           if ((instruction_bits[PC] & BCODE_VERIFIED) != 0)
3172             load_type_state (PC);
3173         }
3174
3175       if (! (instruction_bits [PC] & BCODE_VERIFIED))
3176         {
3177           if (dead_code_index == -1)
3178             {
3179               /* This is the start of a region of unreachable bytecodes.
3180                  They still need to be processed in order for EH ranges
3181                  to get handled correctly.  However, we can simply
3182                  replace these bytecodes with nops.  */
3183               dead_code_index = PC;
3184             }
3185           
3186           /* Turn this bytecode into a nop.  */
3187           byte_ops[PC] = 0x0;
3188         }
3189        else
3190         {
3191           if (dead_code_index != -1)
3192             {
3193               /* We've just reached the end of a region of dead code.  */
3194               if (extra_warnings)
3195                 warning (0, "unreachable bytecode from %d to before %d",
3196                          dead_code_index, PC);
3197               dead_code_index = -1;
3198             }
3199         }
3200
3201       /* Handle possible line number entry for this PC.
3202
3203          This code handles out-of-order and multiple linenumbers per PC,
3204          but is optimized for the case of line numbers increasing
3205          monotonically with PC. */
3206       if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
3207         {
3208           if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
3209               || GET_u2 (linenumber_pointer) != PC)
3210             linenumber_pointer = linenumber_table;
3211           while (linenumber_pointer < linenumber_table + linenumber_count * 4)
3212             {
3213               int pc = GET_u2 (linenumber_pointer);
3214               linenumber_pointer += 4;
3215               if (pc == PC)
3216                 {
3217                   int line = GET_u2 (linenumber_pointer - 2);
3218                   input_location = linemap_line_start (line_table, line, 1);
3219                   if (input_location > max_location)
3220                     max_location = input_location;
3221                   if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
3222                     break;
3223                 }
3224             }
3225         }
3226       maybe_pushlevels (PC);
3227       PC = process_jvm_instruction (PC, byte_ops, length);
3228       maybe_poplevels (PC);
3229     } /* for */
3230
3231   uncache_this_class_ref (method);
3232
3233   if (dead_code_index != -1)
3234     {
3235       /* We've just reached the end of a region of dead code.  */
3236       if (extra_warnings)
3237         warning (0, "unreachable bytecode from %d to the end of the method", 
3238                  dead_code_index);
3239     }
3240
3241   DECL_FUNCTION_LAST_LINE (method) = max_location;
3242 }
3243
3244 static void
3245 java_push_constant_from_pool (JCF *jcf, int index)
3246 {
3247   tree c;
3248   if (JPOOL_TAG (jcf, index) == CONSTANT_String)
3249     {
3250       tree name;
3251       name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
3252       index = alloc_name_constant (CONSTANT_String, name);
3253       c = build_ref_from_constant_pool (index);
3254       c = convert (promote_type (string_type_node), c);
3255     }
3256   else if (JPOOL_TAG (jcf, index) == CONSTANT_Class
3257            || JPOOL_TAG (jcf, index) == CONSTANT_ResolvedClass)
3258     {
3259       tree record = get_class_constant (jcf, index);
3260       c = build_class_ref (record);
3261     }
3262   else
3263     c = get_constant (jcf, index);
3264   push_value (c);
3265
3266
3267 int
3268 process_jvm_instruction (int PC, const unsigned char* byte_ops,
3269                          long length ATTRIBUTE_UNUSED)
3270
3271   const char *opname; /* Temporary ??? */
3272   int oldpc = PC; /* PC at instruction start. */
3273
3274   /* If the instruction is at the beginning of an exception handler,
3275      replace the top of the stack with the thrown object reference.  */
3276   if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
3277     {
3278       /* Note that the verifier will not emit a type map at all for
3279          dead exception handlers.  In this case we just ignore the
3280          situation.  */
3281       if ((instruction_bits[PC] & BCODE_VERIFIED) != 0)
3282         {
3283           tree type = pop_type (promote_type (throwable_type_node));
3284           push_value (build_exception_object_ref (type));
3285         }
3286     }
3287
3288   switch (byte_ops[PC++])
3289     {
3290 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
3291     case OPCODE: \
3292       opname = #OPNAME; \
3293       OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
3294       break;
3295
3296 #define RET(OPERAND_TYPE, OPERAND_VALUE)                                \
3297   {                                                                     \
3298     int saw_index = 0;                                                  \
3299     int index     = OPERAND_VALUE;                                      \
3300     (void) saw_index; /* Avoid set but not used warning.  */            \
3301     build_java_ret                                                      \
3302       (find_local_variable (index, return_address_type_node, oldpc));   \
3303   }
3304
3305 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
3306   {                                                 \
3307     /* OPERAND_VALUE may have side-effects on PC */ \
3308     int opvalue = OPERAND_VALUE;                    \
3309     build_java_jsr (oldpc + opvalue, PC);           \
3310   }
3311
3312 /* Push a constant onto the stack. */
3313 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
3314   { int saw_index = 0;  int ival = (OPERAND_VALUE); \
3315     if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
3316     else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
3317
3318 /* internal macro added for use by the WIDE case */
3319 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
3320   expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
3321
3322 /* Push local variable onto the opcode stack. */
3323 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
3324   { \
3325     /* have to do this since OPERAND_VALUE may have side-effects */ \
3326     int opvalue = OPERAND_VALUE; \
3327     LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3328   }
3329
3330 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
3331   expand_java_return (OPERAND_TYPE##_type_node)
3332
3333 #define REM_EXPR TRUNC_MOD_EXPR
3334 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
3335   expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
3336
3337 #define FIELD(IS_STATIC, IS_PUT) \
3338   expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
3339
3340 #define TEST(OPERAND_TYPE, CONDITION) \
3341   expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3342
3343 #define COND(OPERAND_TYPE, CONDITION) \
3344   expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3345
3346 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
3347   BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
3348
3349 #define BRANCH_GOTO(OPERAND_VALUE) \
3350   expand_java_goto (oldpc + OPERAND_VALUE)
3351
3352 #define BRANCH_CALL(OPERAND_VALUE) \
3353   expand_java_call (oldpc + OPERAND_VALUE, oldpc)
3354
3355 #if 0
3356 #define BRANCH_RETURN(OPERAND_VALUE) \
3357   { \
3358     tree type = OPERAND_TYPE##_type_node; \
3359     tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3360     expand_java_ret (value); \
3361   }
3362 #endif
3363
3364 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3365           fprintf (stderr, "%3d: %s ", oldpc, opname); \
3366           fprintf (stderr, "(not implemented)\n")
3367 #define NOT_IMPL1(OPERAND_VALUE) \
3368           fprintf (stderr, "%3d: %s ", oldpc, opname); \
3369           fprintf (stderr, "(not implemented)\n")
3370
3371 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3372
3373 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3374
3375 #define STACK_POP(COUNT) java_stack_pop (COUNT)
3376
3377 #define STACK_SWAP(COUNT) java_stack_swap()
3378
3379 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3380 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3381 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3382
3383 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3384   PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3385
3386 #define LOOKUP_SWITCH \
3387   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
3388     tree selector = pop_value (INT_type_node); \
3389     tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3390     while (--npairs >= 0) \
3391       { \
3392         jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3393         expand_java_add_case (switch_expr, match, oldpc + offset); \
3394       } \
3395   }
3396
3397 #define TABLE_SWITCH \
3398   { jint default_offset = IMMEDIATE_s4; \
3399     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3400     tree selector = pop_value (INT_type_node); \
3401     tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3402     for (; low <= high; low++) \
3403       { \
3404         jint offset = IMMEDIATE_s4; \
3405         expand_java_add_case (switch_expr, low, oldpc + offset); \
3406       } \
3407   }
3408
3409 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3410   { int opcode = byte_ops[PC-1]; \
3411     int method_ref_index = IMMEDIATE_u2; \
3412     int nargs; \
3413     if (IS_INTERFACE) { nargs = IMMEDIATE_u1;  (void) IMMEDIATE_u1; } \
3414     else nargs = -1; \
3415     expand_invoke (opcode, method_ref_index, nargs); \
3416   }
3417
3418 /* Handle new, checkcast, instanceof */
3419 #define OBJECT(TYPE, OP) \
3420   expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3421
3422 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3423
3424 #define ARRAY_LOAD(OPERAND_TYPE)                        \
3425   {                                                     \
3426     expand_java_arrayload( OPERAND_TYPE##_type_node );  \
3427   }
3428
3429 #define ARRAY_STORE(OPERAND_TYPE)                       \
3430   {                                                     \
3431     expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3432   }
3433
3434 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3435 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3436 #define ARRAY_NEW_PTR()                                                 \
3437     push_value (build_anewarray (get_class_constant (current_jcf,       \
3438                                                      IMMEDIATE_u2),     \
3439                                  pop_value (int_type_node)));
3440 #define ARRAY_NEW_NUM()                         \
3441   {                                             \
3442     int atype = IMMEDIATE_u1;                   \
3443     push_value (build_newarray (atype, pop_value (int_type_node)));\
3444   }
3445 #define ARRAY_NEW_MULTI()                                       \
3446   {                                                             \
3447     tree klass = get_class_constant (current_jcf, IMMEDIATE_u2 );       \
3448     int  ndims = IMMEDIATE_u1;                                  \
3449     expand_java_multianewarray( klass, ndims );                 \
3450   }
3451
3452 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3453   push_value (fold_build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3454                            pop_value (OPERAND_TYPE##_type_node)));
3455
3456 #define CONVERT2(FROM_TYPE, TO_TYPE)                                     \
3457   {                                                                      \
3458     push_value (build1 (NOP_EXPR, int_type_node,                         \
3459                         (convert (TO_TYPE##_type_node,                   \
3460                                   pop_value (FROM_TYPE##_type_node))))); \
3461   }
3462
3463 #define CONVERT(FROM_TYPE, TO_TYPE)                             \
3464   {                                                             \
3465     push_value (convert (TO_TYPE##_type_node,                   \
3466                          pop_value (FROM_TYPE##_type_node)));   \
3467   }
3468
3469 /* internal macro added for use by the WIDE case 
3470    Added TREE_TYPE (decl) assignment, apbianco  */
3471 #define STORE_INTERNAL(OPTYPE, OPVALUE)                         \
3472   {                                                             \
3473     tree decl, value;                                           \
3474     int index = OPVALUE;                                        \
3475     tree type = OPTYPE;                                         \
3476     value = pop_value (type);                                   \
3477     type = TREE_TYPE (value);                                   \
3478     decl = find_local_variable (index, type, oldpc);            \
3479     set_local_type (index, type);                               \
3480     java_add_stmt (build2 (MODIFY_EXPR, type, decl, value));    \
3481   }
3482
3483 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3484   { \
3485     /* have to do this since OPERAND_VALUE may have side-effects */ \
3486     int opvalue = OPERAND_VALUE; \
3487     STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3488   }
3489
3490 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3491   SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3492
3493 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3494 #define SPECIAL_EXIT(IGNORED)  MONITOR_OPERATION (soft_monitorexit_node)
3495
3496 #define MONITOR_OPERATION(call)                 \
3497   {                                             \
3498     tree o = pop_value (ptr_type_node);         \
3499     tree c;                                     \
3500     flush_quick_stack ();                       \
3501     c = build_java_monitor (call, o);           \
3502     TREE_SIDE_EFFECTS (c) = 1;                  \
3503     java_add_stmt (c);                          \
3504   }
3505
3506 #define SPECIAL_IINC(IGNORED) \
3507   { \
3508     unsigned int local_var_index = IMMEDIATE_u1; \
3509     int ival = IMMEDIATE_s1; \
3510     expand_iinc(local_var_index, ival, oldpc); \
3511   }
3512
3513 #define SPECIAL_WIDE(IGNORED) \
3514   { \
3515     int modified_opcode = IMMEDIATE_u1; \
3516     unsigned int local_var_index = IMMEDIATE_u2; \
3517     switch (modified_opcode) \
3518       { \
3519       case OPCODE_iinc: \
3520         { \
3521           int ival = IMMEDIATE_s2; \
3522           expand_iinc (local_var_index, ival, oldpc); \
3523           break; \
3524         } \
3525       case OPCODE_iload: \
3526       case OPCODE_lload: \
3527       case OPCODE_fload: \
3528       case OPCODE_dload: \
3529       case OPCODE_aload: \
3530         { \
3531           /* duplicate code from LOAD macro */ \
3532           LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3533           break; \
3534         } \
3535       case OPCODE_istore: \
3536       case OPCODE_lstore: \
3537       case OPCODE_fstore: \
3538       case OPCODE_dstore: \
3539       case OPCODE_astore: \
3540         { \
3541           STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3542           break; \
3543         } \
3544       default: \
3545         error ("unrecogized wide sub-instruction"); \
3546       } \
3547   }
3548
3549 #define SPECIAL_THROW(IGNORED) \
3550   build_java_athrow (pop_value (throwable_type_node))
3551
3552 #define SPECIAL_BREAK NOT_IMPL1
3553 #define IMPL          NOT_IMPL
3554
3555 #include "javaop.def"
3556 #undef JAVAOP
3557    default:
3558     fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3559   }
3560   return PC;
3561 }
3562
3563 /* Return the opcode at PC in the code section pointed to by
3564    CODE_OFFSET.  */
3565
3566 static unsigned char
3567 peek_opcode_at_pc (JCF *jcf, int code_offset, int pc)
3568 {
3569   unsigned char opcode;
3570   long absolute_offset = (long)JCF_TELL (jcf);
3571
3572   JCF_SEEK (jcf, code_offset);
3573   opcode = jcf->read_ptr [pc];
3574   JCF_SEEK (jcf, absolute_offset);
3575   return opcode;
3576 }
3577
3578 /* Some bytecode compilers are emitting accurate LocalVariableTable
3579    attributes. Here's an example:
3580    
3581      PC   <t>store_<n>
3582      PC+1 ...
3583      
3584      Attribute "LocalVariableTable"
3585      slot #<n>: ... (PC: PC+1 length: L)
3586    
3587    This is accurate because the local in slot <n> really exists after
3588    the opcode at PC is executed, hence from PC+1 to PC+1+L.
3589
3590    This procedure recognizes this situation and extends the live range
3591    of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3592    length of the store instruction.)
3593
3594    This function is used by `give_name_to_locals' so that a local's
3595    DECL features a DECL_LOCAL_START_PC such that the first related
3596    store operation will use DECL as a destination, not an unrelated
3597    temporary created for the occasion.
3598
3599    This function uses a global (instruction_bits) `note_instructions' should
3600    have allocated and filled properly.  */
3601
3602 int
3603 maybe_adjust_start_pc (struct JCF *jcf, int code_offset,
3604                        int start_pc, int slot)
3605 {
3606   int first, index, opcode;
3607   int pc, insn_pc;
3608   int wide_found = 0;
3609
3610   if (!start_pc)
3611     return start_pc;
3612
3613   first = index = -1;
3614
3615   /* Find last previous instruction and remember it */
3616   for (pc = start_pc-1; pc; pc--) 
3617     if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3618       break;
3619   insn_pc = pc;
3620
3621   /* Retrieve the instruction, handle `wide'. */  
3622   opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3623   if (opcode == OPCODE_wide)
3624     {
3625       wide_found = 1;
3626       opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3627     }
3628
3629   switch (opcode)
3630     {
3631     case OPCODE_astore_0:
3632     case OPCODE_astore_1:
3633     case OPCODE_astore_2:
3634     case OPCODE_astore_3:
3635       first = OPCODE_astore_0;
3636       break;
3637
3638     case OPCODE_istore_0:
3639     case OPCODE_istore_1:
3640     case OPCODE_istore_2:
3641     case OPCODE_istore_3:
3642       first = OPCODE_istore_0;
3643       break;
3644       
3645     case OPCODE_lstore_0:
3646     case OPCODE_lstore_1:
3647     case OPCODE_lstore_2:
3648     case OPCODE_lstore_3:
3649       first = OPCODE_lstore_0;
3650       break;
3651
3652     case OPCODE_fstore_0:
3653     case OPCODE_fstore_1:
3654     case OPCODE_fstore_2:
3655     case OPCODE_fstore_3:
3656       first = OPCODE_fstore_0;
3657       break;
3658
3659     case OPCODE_dstore_0:
3660     case OPCODE_dstore_1:
3661     case OPCODE_dstore_2:
3662     case OPCODE_dstore_3:
3663       first = OPCODE_dstore_0;
3664       break;
3665
3666     case OPCODE_astore:
3667     case OPCODE_istore:
3668     case OPCODE_lstore:
3669     case OPCODE_fstore:
3670     case OPCODE_dstore:
3671       index = peek_opcode_at_pc (jcf, code_offset, pc);
3672       if (wide_found)
3673         {
3674           int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3675           index = (other << 8) + index;
3676         }
3677       break;
3678     }
3679
3680   /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3681      means we have a <t>store. */
3682   if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3683     start_pc = insn_pc;
3684
3685   return start_pc;
3686 }
3687
3688 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3689    order, as specified by Java Language Specification.
3690
3691    The problem is that while expand_expr will evaluate its sub-operands in
3692    left-to-right order, for variables it will just return an rtx (i.e.
3693    an lvalue) for the variable (rather than an rvalue).  So it is possible
3694    that a later sub-operand will change the register, and when the
3695    actual operation is done, it will use the new value, when it should
3696    have used the original value.
3697
3698    We fix this by using save_expr.  This forces the sub-operand to be
3699    copied into a fresh virtual register,
3700
3701    For method invocation, we modify the arguments so that a
3702    left-to-right order evaluation is performed. Saved expressions
3703    will, in CALL_EXPR order, be reused when the call will be expanded.
3704
3705    We also promote outgoing args if needed.  */
3706
3707 tree
3708 force_evaluation_order (tree node)
3709 {
3710   if (flag_syntax_only)
3711     return node;
3712   if (TREE_CODE (node) == CALL_EXPR
3713       || (TREE_CODE (node) == COMPOUND_EXPR
3714           && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3715           && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR)) 
3716     {
3717       tree call, cmp;
3718       int i, nargs;
3719
3720       /* Account for wrapped around ctors.  */
3721       if (TREE_CODE (node) == COMPOUND_EXPR)
3722         call = TREE_OPERAND (node, 0);
3723       else
3724         call = node;
3725
3726       nargs = call_expr_nargs (call);
3727
3728       /* This reverses the evaluation order. This is a desired effect. */
3729       for (i = 0, cmp = NULL_TREE; i < nargs; i++)
3730         {
3731           tree arg = CALL_EXPR_ARG (call, i);
3732           /* Promote types smaller than integer.  This is required by
3733              some ABIs.  */
3734           tree type = TREE_TYPE (arg);
3735           tree saved;
3736           if (targetm.calls.promote_prototypes (type)
3737               && INTEGRAL_TYPE_P (type)
3738               && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
3739                                       TYPE_SIZE (integer_type_node)))
3740             arg = fold_convert (integer_type_node, arg);
3741
3742           saved = save_expr (force_evaluation_order (arg));
3743           cmp = (cmp == NULL_TREE ? saved :
3744                  build2 (COMPOUND_EXPR, void_type_node, cmp, saved));
3745
3746           CALL_EXPR_ARG (call, i) = saved;
3747         }
3748       
3749       if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3750         TREE_SIDE_EFFECTS (cmp) = 1;
3751
3752       if (cmp)
3753         {
3754           cmp = build2 (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
3755           if (TREE_TYPE (cmp) != void_type_node)
3756             cmp = save_expr (cmp);
3757           TREE_SIDE_EFFECTS (cmp) = 1;
3758           node = cmp;
3759         }
3760     }
3761   return node;
3762 }
3763
3764 /* Build a node to represent empty statements and blocks. */
3765
3766 tree
3767 build_java_empty_stmt (void)
3768 {
3769   tree t = build_empty_stmt (input_location);
3770   return t;
3771 }
3772
3773 /* Promote all args of integral type before generating any code.  */
3774
3775 static void
3776 promote_arguments (void)
3777 {
3778   int i;
3779   tree arg;
3780   for (arg = DECL_ARGUMENTS (current_function_decl), i = 0;
3781        arg != NULL_TREE;  arg = TREE_CHAIN (arg), i++)
3782     {
3783       tree arg_type = TREE_TYPE (arg);
3784       if (INTEGRAL_TYPE_P (arg_type)
3785           && TYPE_PRECISION (arg_type) < 32)
3786         {
3787           tree copy = find_local_variable (i, integer_type_node, -1);
3788           java_add_stmt (build2 (MODIFY_EXPR, integer_type_node,
3789                                  copy,
3790                                  fold_convert (integer_type_node, arg)));
3791         }
3792       if (TYPE_IS_WIDE (arg_type))
3793         i++;
3794     }
3795 }
3796
3797 /* Create a local variable that points to the constant pool.  */
3798
3799 static void
3800 cache_cpool_data_ref (void)
3801 {
3802   if (optimize)
3803     {
3804       tree cpool;
3805       tree d = build_constant_data_ref (flag_indirect_classes);
3806       tree cpool_ptr = build_decl (input_location, VAR_DECL, NULL_TREE, 
3807                                    build_pointer_type (TREE_TYPE (d)));
3808       java_add_local_var (cpool_ptr);
3809       TREE_CONSTANT (cpool_ptr) = 1;
3810
3811       java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (cpool_ptr), 
3812                              cpool_ptr, build_address_of (d)));
3813       cpool = build1 (INDIRECT_REF, TREE_TYPE (d), cpool_ptr);
3814       TREE_THIS_NOTRAP (cpool) = 1;
3815       TYPE_CPOOL_DATA_REF (output_class) = cpool;
3816     }
3817 }
3818
3819 #include "gt-java-expr.h"