OSDN Git Service

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