* cp-demangle.c (__cxa_demangle): Pass DMGL_PARAMS to d_demangle.
[official-gcc.git] / gcc / java / expr.c
bloba4356eb3e4841f631be43320849478015356d10c
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 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
28 #include "config.h"
29 #include "system.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "tree.h"
33 #include "real.h"
34 #include "rtl.h"
35 #include "flags.h"
36 #include "expr.h"
37 #include "java-tree.h"
38 #include "javaop.h"
39 #include "java-opcodes.h"
40 #include "jcf.h"
41 #include "java-except.h"
42 #include "parse.h"
43 #include "toplev.h"
44 #include "except.h"
45 #include "ggc.h"
46 #include "target.h"
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 #if 0
75 static void expand_java_call (int, int);
76 static void expand_java_ret (tree);
77 #endif
78 static tree pop_arguments (tree);
79 static void expand_invoke (int, int, int);
80 static void expand_java_field_op (int, int, int);
81 static void java_push_constant_from_pool (struct JCF *, int);
82 static void java_stack_pop (int);
83 static tree build_java_throw_out_of_bounds_exception (tree);
84 static tree build_java_check_indexed_type (tree, tree);
85 static tree case_identity (tree, tree);
86 static unsigned char peek_opcode_at_pc (struct JCF *, int, int);
87 static int emit_init_test_initialization (void **entry, void * ptr);
89 static GTY(()) tree operand_type[59];
91 static GTY(()) tree methods_ident;
92 static GTY(()) tree ncode_ident;
93 tree dtable_ident = NULL_TREE;
95 /* Set to nonzero value in order to emit class initialization code
96 before static field references. */
97 int always_initialize_class_p;
99 /* We store the stack state in two places:
100 Within a basic block, we use the quick_stack, which is a
101 pushdown list (TREE_LISTs) of expression nodes.
102 This is the top part of the stack; below that we use find_stack_slot.
103 At the end of a basic block, the quick_stack must be flushed
104 to the stack slot array (as handled by find_stack_slot).
105 Using quick_stack generates better code (especially when
106 compiled without optimization), because we do not have to
107 explicitly store and load trees to temporary variables.
109 If a variable is on the quick stack, it means the value of variable
110 when the quick stack was last flushed. Conceptually, flush_quick_stack
111 saves all the the quick_stack elements in parallel. However, that is
112 complicated, so it actually saves them (i.e. copies each stack value
113 to is home virtual register) from low indexes. This allows a quick_stack
114 element at index i (counting from the bottom of stack the) to references
115 slot virtuals for register that are >= i, but not those that are deeper.
116 This convention makes most operations easier. For example iadd works
117 even when the stack contains (reg[0], reg[1]): It results in the
118 stack containing (reg[0]+reg[1]), which is OK. However, some stack
119 operations are more complicated. For example dup given a stack
120 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
121 the convention, since stack value 1 would refer to a register with
122 lower index (reg[0]), which flush_quick_stack does not safely handle.
123 So dup cannot just add an extra element to the quick_stack, but iadd can.
126 static GTY(()) tree quick_stack;
128 /* A free-list of unused permanent TREE_LIST nodes. */
129 static GTY((deletable (""))) tree tree_list_free_list;
131 /* The stack pointer of the Java virtual machine.
132 This does include the size of the quick_stack. */
134 int stack_pointer;
136 const unsigned char *linenumber_table;
137 int linenumber_count;
139 void
140 init_expr_processing (void)
142 operand_type[21] = operand_type[54] = int_type_node;
143 operand_type[22] = operand_type[55] = long_type_node;
144 operand_type[23] = operand_type[56] = float_type_node;
145 operand_type[24] = operand_type[57] = double_type_node;
146 operand_type[25] = operand_type[58] = ptr_type_node;
149 tree
150 java_truthvalue_conversion (tree expr)
152 /* It is simpler and generates better code to have only TRUTH_*_EXPR
153 or comparison expressions as truth values at this level.
155 This function should normally be identity for Java. */
157 switch (TREE_CODE (expr))
159 case EQ_EXPR:
160 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
161 case TRUTH_ANDIF_EXPR:
162 case TRUTH_ORIF_EXPR:
163 case TRUTH_AND_EXPR:
164 case TRUTH_OR_EXPR:
165 case ERROR_MARK:
166 return expr;
168 case INTEGER_CST:
169 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
171 case REAL_CST:
172 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
174 /* are these legal? XXX JH */
175 case NEGATE_EXPR:
176 case ABS_EXPR:
177 case FLOAT_EXPR:
178 /* These don't change whether an object is nonzero or zero. */
179 return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
181 case COND_EXPR:
182 /* Distribute the conversion into the arms of a COND_EXPR. */
183 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
184 java_truthvalue_conversion (TREE_OPERAND (expr, 1)),
185 java_truthvalue_conversion (TREE_OPERAND (expr, 2))));
187 case NOP_EXPR:
188 /* If this is widening the argument, we can ignore it. */
189 if (TYPE_PRECISION (TREE_TYPE (expr))
190 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
191 return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
192 /* fall through to default */
194 default:
195 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
199 /* Save any stack slots that happen to be in the quick_stack into their
200 home virtual register slots.
202 The copy order is from low stack index to high, to support the invariant
203 that the expression for a slot may contain decls for stack slots with
204 higher (or the same) index, but not lower. */
206 static void
207 flush_quick_stack (void)
209 int stack_index = stack_pointer;
210 tree prev, cur, next;
212 /* First reverse the quick_stack, and count the number of slots it has. */
213 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
215 next = TREE_CHAIN (cur);
216 TREE_CHAIN (cur) = prev;
217 prev = cur;
218 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
220 quick_stack = prev;
222 while (quick_stack != NULL_TREE)
224 tree decl;
225 tree node = quick_stack, type;
226 quick_stack = TREE_CHAIN (node);
227 TREE_CHAIN (node) = tree_list_free_list;
228 tree_list_free_list = node;
229 node = TREE_VALUE (node);
230 type = TREE_TYPE (node);
232 decl = find_stack_slot (stack_index, type);
233 if (decl != node)
234 expand_assignment (decl, node, 0);
235 stack_index += 1 + TYPE_IS_WIDE (type);
239 /* Push TYPE on the type stack.
240 Return true on success, 0 on overflow. */
243 push_type_0 (tree type)
245 int n_words;
246 type = promote_type (type);
247 n_words = 1 + TYPE_IS_WIDE (type);
248 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
249 return 0;
250 stack_type_map[stack_pointer++] = type;
251 n_words--;
252 while (--n_words >= 0)
253 stack_type_map[stack_pointer++] = TYPE_SECOND;
254 return 1;
257 void
258 push_type (tree type)
260 if (! push_type_0 (type))
261 abort ();
264 static void
265 push_value (tree value)
267 tree type = TREE_TYPE (value);
268 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
270 type = promote_type (type);
271 value = convert (type, value);
273 push_type (type);
274 if (tree_list_free_list == NULL_TREE)
275 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
276 else
278 tree node = tree_list_free_list;
279 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
280 TREE_VALUE (node) = value;
281 TREE_CHAIN (node) = quick_stack;
282 quick_stack = node;
286 /* Pop a type from the type stack.
287 TYPE is the expected type. Return the actual type, which must be
288 convertible to TYPE.
289 On an error, *MESSAGEP is set to a freshly malloc'd error message. */
291 tree
292 pop_type_0 (tree type, char **messagep)
294 int n_words;
295 tree t;
296 *messagep = NULL;
297 if (TREE_CODE (type) == RECORD_TYPE)
298 type = promote_type (type);
299 n_words = 1 + TYPE_IS_WIDE (type);
300 if (stack_pointer < n_words)
302 *messagep = xstrdup ("stack underflow");
303 return type;
305 while (--n_words > 0)
307 if (stack_type_map[--stack_pointer] != void_type_node)
309 *messagep = xstrdup ("Invalid multi-word value on type stack");
310 return type;
313 t = stack_type_map[--stack_pointer];
314 if (type == NULL_TREE || t == type)
315 return t;
316 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
317 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
318 return t;
319 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
321 if (type == ptr_type_node || type == object_ptr_type_node)
322 return t;
323 else if (t == ptr_type_node) /* Special case for null reference. */
324 return type;
325 else if (can_widen_reference_to (t, type))
326 return t;
327 /* This is a kludge, but matches what Sun's verifier does.
328 It can be tricked, but is safe as long as type errors
329 (i.e. interface method calls) are caught at run-time. */
330 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
331 return object_ptr_type_node;
334 /* lang_printable_name uses a static buffer, so we must save the result
335 from calling it the first time. */
337 char *temp = xstrdup (lang_printable_name (type, 0));
338 *messagep = concat ("expected type '", temp,
339 "' but stack contains '", lang_printable_name (t, 0),
340 "'", NULL);
341 free (temp);
343 return type;
346 /* Pop a type from the type stack.
347 TYPE is the expected type. Return the actual type, which must be
348 convertible to TYPE, otherwise call error. */
350 tree
351 pop_type (tree type)
353 char *message = NULL;
354 type = pop_type_0 (type, &message);
355 if (message != NULL)
357 error ("%s", message);
358 free (message);
360 return type;
363 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
364 Handles array types and interfaces. */
367 can_widen_reference_to (tree source_type, tree target_type)
369 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
370 return 1;
372 /* Get rid of pointers */
373 if (TREE_CODE (source_type) == POINTER_TYPE)
374 source_type = TREE_TYPE (source_type);
375 if (TREE_CODE (target_type) == POINTER_TYPE)
376 target_type = TREE_TYPE (target_type);
378 if (source_type == target_type)
379 return 1;
380 else
382 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
384 HOST_WIDE_INT source_length, target_length;
385 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
387 /* An array implements Cloneable and Serializable. */
388 tree name = DECL_NAME (TYPE_NAME (target_type));
389 return (name == java_lang_cloneable_identifier_node
390 || name == java_io_serializable_identifier_node);
392 target_length = java_array_type_length (target_type);
393 if (target_length >= 0)
395 source_length = java_array_type_length (source_type);
396 if (source_length != target_length)
397 return 0;
399 source_type = TYPE_ARRAY_ELEMENT (source_type);
400 target_type = TYPE_ARRAY_ELEMENT (target_type);
401 if (source_type == target_type)
402 return 1;
403 if (TREE_CODE (source_type) != POINTER_TYPE
404 || TREE_CODE (target_type) != POINTER_TYPE)
405 return 0;
406 return can_widen_reference_to (source_type, target_type);
408 else
410 int source_depth = class_depth (source_type);
411 int target_depth = class_depth (target_type);
413 /* class_depth can return a negative depth if an error occurred */
414 if (source_depth < 0 || target_depth < 0)
415 return 0;
417 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
419 /* target_type is OK if source_type or source_type ancestors
420 implement target_type. We handle multiple sub-interfaces */
422 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
423 int n = TREE_VEC_LENGTH (basetype_vec), i;
424 for (i=0 ; i < n; i++)
425 if (can_widen_reference_to
426 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
427 target_type))
428 return 1;
429 if (n == 0)
430 return 0;
433 for ( ; source_depth > target_depth; source_depth--)
435 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
437 return source_type == target_type;
442 static tree
443 pop_value (tree type)
445 type = pop_type (type);
446 if (quick_stack)
448 tree node = quick_stack;
449 quick_stack = TREE_CHAIN (quick_stack);
450 TREE_CHAIN (node) = tree_list_free_list;
451 tree_list_free_list = node;
452 node = TREE_VALUE (node);
453 return node;
455 else
456 return find_stack_slot (stack_pointer, promote_type (type));
460 /* Pop and discard the top COUNT stack slots. */
462 static void
463 java_stack_pop (int count)
465 while (count > 0)
467 tree type, val;
469 if (stack_pointer == 0)
470 abort ();
472 type = stack_type_map[stack_pointer - 1];
473 if (type == TYPE_SECOND)
475 count--;
476 if (stack_pointer == 1 || count <= 0)
477 abort ();
479 type = stack_type_map[stack_pointer - 2];
481 val = pop_value (type);
482 count--;
486 /* Implement the 'swap' operator (to swap two top stack slots). */
488 static void
489 java_stack_swap (void)
491 tree type1, type2;
492 rtx temp;
493 tree decl1, decl2;
495 if (stack_pointer < 2
496 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
497 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
498 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
499 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
500 /* Bad stack swap. */
501 abort ();
503 flush_quick_stack ();
504 decl1 = find_stack_slot (stack_pointer - 1, type1);
505 decl2 = find_stack_slot (stack_pointer - 2, type2);
506 temp = copy_to_reg (DECL_RTL (decl1));
507 emit_move_insn (DECL_RTL (find_stack_slot (stack_pointer - 1, type2)),
508 DECL_RTL (decl2));
509 emit_move_insn (DECL_RTL (find_stack_slot (stack_pointer - 2, type1)), temp);
510 stack_type_map[stack_pointer - 1] = type2;
511 stack_type_map[stack_pointer - 2] = type1;
514 static void
515 java_stack_dup (int size, int offset)
517 int low_index = stack_pointer - size - offset;
518 int dst_index;
519 if (low_index < 0)
520 error ("stack underflow - dup* operation");
522 flush_quick_stack ();
524 stack_pointer += size;
525 dst_index = stack_pointer;
527 for (dst_index = stack_pointer; --dst_index >= low_index; )
529 tree type;
530 int src_index = dst_index - size;
531 if (src_index < low_index)
532 src_index = dst_index + size + offset;
533 type = stack_type_map [src_index];
534 if (type == TYPE_SECOND)
536 if (src_index <= low_index)
537 /* Dup operation splits 64-bit number. */
538 abort ();
540 stack_type_map[dst_index] = type;
541 src_index--; dst_index--;
542 type = stack_type_map[src_index];
543 if (! TYPE_IS_WIDE (type))
544 abort ();
546 else if (TYPE_IS_WIDE (type))
547 abort ();
549 if (src_index != dst_index)
551 tree src_decl = find_stack_slot (src_index, type);
552 tree dst_decl = find_stack_slot (dst_index, type);
553 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
554 stack_type_map[dst_index] = type;
559 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
560 value stack. */
562 static void
563 build_java_athrow (tree node)
565 tree call;
567 call = build (CALL_EXPR,
568 void_type_node,
569 build_address_of (throw_node),
570 build_tree_list (NULL_TREE, node),
571 NULL_TREE);
572 TREE_SIDE_EFFECTS (call) = 1;
573 expand_expr_stmt (call);
574 java_stack_pop (stack_pointer);
577 /* Implementation for jsr/ret */
579 static void
580 build_java_jsr (int target_pc, int return_pc)
582 tree where = lookup_label (target_pc);
583 tree ret = lookup_label (return_pc);
584 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
585 push_value (ret_label);
586 flush_quick_stack ();
587 emit_jump (label_rtx (where));
588 expand_label (ret);
589 if (instruction_bits [return_pc] & BCODE_VERIFIED)
590 load_type_state (ret);
593 static void
594 build_java_ret (tree location)
596 expand_computed_goto (location);
599 /* Implementation of operations on array: new, load, store, length */
601 tree
602 decode_newarray_type (int atype)
604 switch (atype)
606 case 4: return boolean_type_node;
607 case 5: return char_type_node;
608 case 6: return float_type_node;
609 case 7: return double_type_node;
610 case 8: return byte_type_node;
611 case 9: return short_type_node;
612 case 10: return int_type_node;
613 case 11: return long_type_node;
614 default: return NULL_TREE;
618 /* Map primitive type to the code used by OPCODE_newarray. */
621 encode_newarray_type (tree type)
623 if (type == boolean_type_node)
624 return 4;
625 else if (type == char_type_node)
626 return 5;
627 else if (type == float_type_node)
628 return 6;
629 else if (type == double_type_node)
630 return 7;
631 else if (type == byte_type_node)
632 return 8;
633 else if (type == short_type_node)
634 return 9;
635 else if (type == int_type_node)
636 return 10;
637 else if (type == long_type_node)
638 return 11;
639 else
640 abort ();
643 /* Build a call to _Jv_ThrowBadArrayIndex(), the
644 ArrayIndexOfBoundsException exception handler. */
646 static tree
647 build_java_throw_out_of_bounds_exception (tree index)
649 tree node = build (CALL_EXPR, int_type_node,
650 build_address_of (soft_badarrayindex_node),
651 build_tree_list (NULL_TREE, index), NULL_TREE);
652 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
653 return (node);
656 /* Return the length of an array. Doesn't perform any checking on the nature
657 or value of the array NODE. May be used to implement some bytecodes. */
659 tree
660 build_java_array_length_access (tree node)
662 tree type = TREE_TYPE (node);
663 tree array_type = TREE_TYPE (type);
664 HOST_WIDE_INT length;
666 /* JVM spec: If the arrayref is null, the arraylength instruction
667 throws a NullPointerException. The only way we could get a node
668 of type ptr_type_node at this point is `aconst_null; arraylength'
669 or something equivalent. */
670 if (type == ptr_type_node)
671 return build (CALL_EXPR, int_type_node,
672 build_address_of (soft_nullpointer_node),
673 NULL_TREE, NULL_TREE);
675 if (!is_array_type_p (type))
676 abort ();
678 length = java_array_type_length (type);
679 if (length >= 0)
680 return build_int_2 (length, 0);
682 node = build (COMPONENT_REF, int_type_node,
683 build_java_indirect_ref (array_type, node,
684 flag_check_references),
685 lookup_field (&array_type, get_identifier ("length")));
686 IS_ARRAY_LENGTH_ACCESS (node) = 1;
687 return node;
690 /* Optionally checks a reference against the NULL pointer. ARG1: the
691 expr, ARG2: we should check the reference. Don't generate extra
692 checks if we're not generating code. */
694 tree
695 java_check_reference (tree expr, int check)
697 if (!flag_syntax_only && check)
699 expr = save_expr (expr);
700 expr = build (COND_EXPR, TREE_TYPE (expr),
701 build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
702 build (CALL_EXPR, void_type_node,
703 build_address_of (soft_nullpointer_node),
704 NULL_TREE, NULL_TREE),
705 expr);
708 return expr;
711 /* Reference an object: just like an INDIRECT_REF, but with checking. */
713 tree
714 build_java_indirect_ref (tree type, tree expr, int check)
716 return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
719 /* Implement array indexing (either as l-value or r-value).
720 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
721 Optionally performs bounds checking and/or test to NULL.
722 At this point, ARRAY should have been verified as an array. */
724 tree
725 build_java_arrayaccess (tree array, tree type, tree index)
727 tree node, throw = NULL_TREE;
728 tree data_field;
729 tree ref;
730 tree array_type = TREE_TYPE (TREE_TYPE (array));
732 if (flag_bounds_check)
734 /* Generate:
735 * (unsigned jint) INDEX >= (unsigned jint) LEN
736 * && throw ArrayIndexOutOfBoundsException.
737 * Note this is equivalent to and more efficient than:
738 * INDEX < 0 || INDEX >= LEN && throw ... */
739 tree test;
740 tree len = build_java_array_length_access (array);
741 TREE_TYPE (len) = unsigned_int_type_node;
742 test = fold (build (GE_EXPR, boolean_type_node,
743 convert (unsigned_int_type_node, index),
744 len));
745 if (! integer_zerop (test))
747 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
748 build_java_throw_out_of_bounds_exception (index));
749 /* allows expansion within COMPOUND */
750 TREE_SIDE_EFFECTS( throw ) = 1;
754 /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
755 to have the bounds check evaluated first. */
756 if (throw != NULL_TREE)
757 index = build (COMPOUND_EXPR, int_type_node, throw, index);
759 data_field = lookup_field (&array_type, get_identifier ("data"));
761 ref = build (COMPONENT_REF, TREE_TYPE (data_field),
762 build_java_indirect_ref (array_type, array,
763 flag_check_references),
764 data_field);
766 node = build (ARRAY_REF, type, ref, index);
767 return node;
770 /* Generate code to throw an ArrayStoreException if OBJECT is not assignable
771 (at runtime) to an element of ARRAY. A NOP_EXPR is returned if it can
772 determine that no check is required. */
774 tree
775 build_java_arraystore_check (tree array, tree object)
777 tree check, element_type, source;
778 tree array_type_p = TREE_TYPE (array);
779 tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));
781 if (! is_array_type_p (array_type_p))
782 abort ();
784 /* Get the TYPE_DECL for ARRAY's element type. */
785 element_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
787 if (TREE_CODE (element_type) != TYPE_DECL
788 || TREE_CODE (object_type) != TYPE_DECL)
789 abort ();
791 if (!flag_store_check)
792 return build1 (NOP_EXPR, array_type_p, array);
794 /* No check is needed if the element type is final or is itself an array.
795 Also check that element_type matches object_type, since in the bytecode
796 compilation case element_type may be the actual element type of the array
797 rather than its declared type. */
798 if (element_type == object_type
799 && (TYPE_ARRAY_P (TREE_TYPE (element_type))
800 || CLASS_FINAL (element_type)))
801 return build1 (NOP_EXPR, array_type_p, array);
803 /* OBJECT might be wrapped by a SAVE_EXPR. */
804 if (TREE_CODE (object) == SAVE_EXPR)
805 source = TREE_OPERAND (object, 0);
806 else
807 source = object;
809 /* Avoid the check if OBJECT was just loaded from the same array. */
810 if (TREE_CODE (source) == ARRAY_REF)
812 tree target;
813 source = TREE_OPERAND (source, 0); /* COMPONENT_REF. */
814 source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
815 source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
816 if (TREE_CODE (source) == SAVE_EXPR)
817 source = TREE_OPERAND (source, 0);
819 target = array;
820 if (TREE_CODE (target) == SAVE_EXPR)
821 target = TREE_OPERAND (target, 0);
823 if (source == target)
824 return build1 (NOP_EXPR, array_type_p, array);
827 /* Build an invocation of _Jv_CheckArrayStore */
828 check = build (CALL_EXPR, void_type_node,
829 build_address_of (soft_checkarraystore_node),
830 tree_cons (NULL_TREE, array,
831 build_tree_list (NULL_TREE, object)),
832 NULL_TREE);
833 TREE_SIDE_EFFECTS (check) = 1;
835 return check;
838 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
839 ARRAY_NODE. This function is used to retrieve something less vague than
840 a pointer type when indexing the first dimension of something like [[<t>.
841 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
842 return unchanged.
843 As a side effect, it also makes sure that ARRAY_NODE is an array. */
845 static tree
846 build_java_check_indexed_type (tree array_node, tree indexed_type)
848 tree elt_type;
850 if (!is_array_type_p (TREE_TYPE (array_node)))
851 abort ();
853 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
855 if (indexed_type == ptr_type_node )
856 return promote_type (elt_type);
858 /* BYTE/BOOLEAN store and load are used for both type */
859 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
860 return boolean_type_node;
862 if (indexed_type != elt_type )
863 abort ();
864 else
865 return indexed_type;
868 /* newarray triggers a call to _Jv_NewPrimArray. This function should be
869 called with an integer code (the type of array to create), and the length
870 of the array to create. */
872 tree
873 build_newarray (int atype_value, tree length)
875 tree type_arg;
877 tree prim_type = decode_newarray_type (atype_value);
878 tree type
879 = build_java_array_type (prim_type,
880 host_integerp (length, 0) == INTEGER_CST
881 ? tree_low_cst (length, 0) : -1);
883 /* If compiling to native, pass a reference to the primitive type class
884 and save the runtime some work. However, the bytecode generator
885 expects to find the type_code int here. */
886 if (flag_emit_class_files)
887 type_arg = build_int_2 (atype_value, 0);
888 else
889 type_arg = build_class_ref (prim_type);
891 return build (CALL_EXPR, promote_type (type),
892 build_address_of (soft_newarray_node),
893 tree_cons (NULL_TREE,
894 type_arg,
895 build_tree_list (NULL_TREE, length)),
896 NULL_TREE);
899 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
900 of the dimension. */
902 tree
903 build_anewarray (tree class_type, tree length)
905 tree type
906 = build_java_array_type (class_type,
907 host_integerp (length, 0)
908 ? tree_low_cst (length, 0) : -1);
910 return build (CALL_EXPR, promote_type (type),
911 build_address_of (soft_anewarray_node),
912 tree_cons (NULL_TREE, length,
913 tree_cons (NULL_TREE, build_class_ref (class_type),
914 build_tree_list (NULL_TREE,
915 null_pointer_node))),
916 NULL_TREE);
919 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
921 tree
922 build_new_array (tree type, tree length)
924 if (JPRIMITIVE_TYPE_P (type))
925 return build_newarray (encode_newarray_type (type), length);
926 else
927 return build_anewarray (TREE_TYPE (type), length);
930 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
931 class pointer, a number of dimensions and the matching number of
932 dimensions. The argument list is NULL terminated. */
934 static void
935 expand_java_multianewarray (tree class_type, int ndim)
937 int i;
938 tree args = build_tree_list( NULL_TREE, null_pointer_node );
940 for( i = 0; i < ndim; i++ )
941 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
943 push_value (build (CALL_EXPR,
944 promote_type (class_type),
945 build_address_of (soft_multianewarray_node),
946 tree_cons (NULL_TREE, build_class_ref (class_type),
947 tree_cons (NULL_TREE,
948 build_int_2 (ndim, 0), args )),
949 NULL_TREE));
952 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
953 ARRAY is an array type. May expand some bound checking and NULL
954 pointer checking. RHS_TYPE_NODE we are going to store. In the case
955 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
956 INT. In those cases, we make the conversion.
958 if ARRAy is a reference type, the assignment is checked at run-time
959 to make sure that the RHS can be assigned to the array element
960 type. It is not necessary to generate this code if ARRAY is final. */
962 static void
963 expand_java_arraystore (tree rhs_type_node)
965 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
966 && TYPE_PRECISION (rhs_type_node) <= 32) ?
967 int_type_node : rhs_type_node);
968 tree index = pop_value (int_type_node);
969 tree array = pop_value (ptr_type_node);
971 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
973 flush_quick_stack ();
975 index = save_expr (index);
976 array = save_expr (array);
978 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
980 tree check = build_java_arraystore_check (array, rhs_node);
981 expand_expr_stmt (check);
984 expand_assignment (build_java_arrayaccess (array,
985 rhs_type_node,
986 index),
987 rhs_node, 0);
990 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
991 sure that LHS is an array type. May expand some bound checking and NULL
992 pointer checking.
993 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
994 BOOLEAN/SHORT, we push a promoted type back to the stack.
997 static void
998 expand_java_arrayload (tree lhs_type_node )
1000 tree load_node;
1001 tree index_node = pop_value (int_type_node);
1002 tree array_node = pop_value (ptr_type_node);
1004 index_node = save_expr (index_node);
1005 array_node = save_expr (array_node);
1007 if (TREE_TYPE (array_node) == ptr_type_node)
1008 /* The only way we could get a node of type ptr_type_node at this
1009 point is `aconst_null; arraylength' or something equivalent, so
1010 unconditionally throw NullPointerException. */
1011 load_node = build (CALL_EXPR, lhs_type_node,
1012 build_address_of (soft_nullpointer_node),
1013 NULL_TREE, NULL_TREE);
1014 else
1016 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
1017 load_node = build_java_arrayaccess (array_node,
1018 lhs_type_node,
1019 index_node);
1021 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1022 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
1023 push_value (load_node);
1026 /* Expands .length. Makes sure that we deal with and array and may expand
1027 a NULL check on the array object. */
1029 static void
1030 expand_java_array_length (void)
1032 tree array = pop_value (ptr_type_node);
1033 tree length = build_java_array_length_access (array);
1035 push_value (length);
1038 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1039 either soft_monitorenter_node or soft_monitorexit_node. */
1041 static tree
1042 build_java_monitor (tree call, tree object)
1044 return (build (CALL_EXPR,
1045 void_type_node,
1046 build_address_of (call),
1047 build_tree_list (NULL_TREE, object),
1048 NULL_TREE));
1051 /* Emit code for one of the PUSHC instructions. */
1053 static void
1054 expand_java_pushc (int ival, tree type)
1056 tree value;
1057 if (type == ptr_type_node && ival == 0)
1058 value = null_pointer_node;
1059 else if (type == int_type_node || type == long_type_node)
1061 value = build_int_2 (ival, ival < 0 ? -1 : 0);
1062 TREE_TYPE (value) = type;
1064 else if (type == float_type_node || type == double_type_node)
1066 REAL_VALUE_TYPE x;
1067 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1068 value = build_real (type, x);
1070 else
1071 abort ();
1073 push_value (value);
1076 static void
1077 expand_java_return (tree type)
1079 if (type == void_type_node)
1080 expand_null_return ();
1081 else
1083 tree retval = pop_value (type);
1084 tree res = DECL_RESULT (current_function_decl);
1085 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1087 /* Handle the situation where the native integer type is smaller
1088 than the JVM integer. It can happen for many cross compilers.
1089 The whole if expression just goes away if INT_TYPE_SIZE < 32
1090 is false. */
1091 if (INT_TYPE_SIZE < 32
1092 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1093 < GET_MODE_SIZE (TYPE_MODE (type))))
1094 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1096 TREE_SIDE_EFFECTS (retval) = 1;
1097 expand_return (retval);
1101 static void
1102 expand_load_internal (int index, tree type, int pc)
1104 tree copy;
1105 tree var = find_local_variable (index, type, pc);
1107 /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1108 on the stack. If there is an assignment to this VAR_DECL between
1109 the stack push and the use, then the wrong code could be
1110 generated. To avoid this we create a new local and copy our
1111 value into it. Then we push this new local on the stack.
1112 Hopefully this all gets optimized out. */
1113 copy = build_decl (VAR_DECL, NULL_TREE, type);
1114 DECL_CONTEXT (copy) = current_function_decl;
1115 layout_decl (copy, 0);
1116 DECL_REGISTER (copy) = 1;
1117 expand_decl (copy);
1118 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
1119 DECL_INITIAL (copy) = var;
1120 expand_decl_init (copy);
1121 push_value (copy);
1124 tree
1125 build_address_of (tree value)
1127 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1130 bool class_has_finalize_method (tree type)
1132 tree super = CLASSTYPE_SUPER (type);
1134 if (super == NULL_TREE)
1135 return false; /* Every class with a real finalizer inherits */
1136 /* from java.lang.Object. */
1137 else
1138 return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1141 static void
1142 expand_java_NEW (tree type)
1144 tree alloc_node;
1146 alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1147 : alloc_no_finalizer_node);
1148 if (! CLASS_LOADED_P (type))
1149 load_class (type, 1);
1150 safe_layout_class (type);
1151 push_value (build (CALL_EXPR, promote_type (type),
1152 build_address_of (alloc_node),
1153 tree_cons (NULL_TREE, build_class_ref (type),
1154 build_tree_list (NULL_TREE,
1155 size_in_bytes (type))),
1156 NULL_TREE));
1159 /* This returns an expression which will extract the class of an
1160 object. */
1162 tree
1163 build_get_class (tree value)
1165 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1166 tree vtable_field = lookup_field (&object_type_node,
1167 get_identifier ("vtable"));
1168 return build (COMPONENT_REF, class_ptr_type,
1169 build1 (INDIRECT_REF, dtable_type,
1170 build (COMPONENT_REF, dtable_ptr_type,
1171 build_java_indirect_ref (object_type_node, value,
1172 flag_check_references),
1173 vtable_field)),
1174 class_field);
1177 /* This builds the tree representation of the `instanceof' operator.
1178 It tries various tricks to optimize this in cases where types are
1179 known. */
1181 tree
1182 build_instanceof (tree value, tree type)
1184 tree expr;
1185 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1186 tree valtype = TREE_TYPE (TREE_TYPE (value));
1187 tree valclass = TYPE_NAME (valtype);
1188 tree klass;
1190 /* When compiling from bytecode, we need to ensure that TYPE has
1191 been loaded. */
1192 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1194 load_class (type, 1);
1195 safe_layout_class (type);
1196 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1197 return error_mark_node;
1199 klass = TYPE_NAME (type);
1201 if (type == object_type_node || inherits_from_p (valtype, type))
1203 /* Anything except `null' is an instance of Object. Likewise,
1204 if the object is known to be an instance of the class, then
1205 we only need to check for `null'. */
1206 expr = build (NE_EXPR, itype, value, null_pointer_node);
1208 else if (! TYPE_ARRAY_P (type)
1209 && ! TYPE_ARRAY_P (valtype)
1210 && DECL_P (klass) && DECL_P (valclass)
1211 && ! CLASS_INTERFACE (valclass)
1212 && ! CLASS_INTERFACE (klass)
1213 && ! inherits_from_p (type, valtype)
1214 && (CLASS_FINAL (klass)
1215 || ! inherits_from_p (valtype, type)))
1217 /* The classes are from different branches of the derivation
1218 tree, so we immediately know the answer. */
1219 expr = boolean_false_node;
1221 else if (DECL_P (klass) && CLASS_FINAL (klass))
1223 tree save = save_expr (value);
1224 expr = build (COND_EXPR, itype,
1225 save,
1226 build (EQ_EXPR, itype,
1227 build_get_class (save),
1228 build_class_ref (type)),
1229 boolean_false_node);
1231 else
1233 expr = build (CALL_EXPR, itype,
1234 build_address_of (soft_instanceof_node),
1235 tree_cons (NULL_TREE, value,
1236 build_tree_list (NULL_TREE,
1237 build_class_ref (type))),
1238 NULL_TREE);
1240 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1241 return expr;
1244 static void
1245 expand_java_INSTANCEOF (tree type)
1247 tree value = pop_value (object_ptr_type_node);
1248 value = build_instanceof (value, type);
1249 push_value (value);
1252 static void
1253 expand_java_CHECKCAST (tree type)
1255 tree value = pop_value (ptr_type_node);
1256 value = build (CALL_EXPR, promote_type (type),
1257 build_address_of (soft_checkcast_node),
1258 tree_cons (NULL_TREE, build_class_ref (type),
1259 build_tree_list (NULL_TREE, value)),
1260 NULL_TREE);
1261 push_value (value);
1264 static void
1265 expand_iinc (unsigned int local_var_index, int ival, int pc)
1267 tree local_var, res;
1268 tree constant_value;
1270 flush_quick_stack ();
1271 local_var = find_local_variable (local_var_index, int_type_node, pc);
1272 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1273 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1274 expand_assignment (local_var, res, 0);
1278 tree
1279 build_java_soft_divmod (enum tree_code op, tree type, tree op1, tree op2)
1281 tree call = NULL;
1282 tree arg1 = convert (type, op1);
1283 tree arg2 = convert (type, op2);
1285 if (type == int_type_node)
1287 switch (op)
1289 case TRUNC_DIV_EXPR:
1290 call = soft_idiv_node;
1291 break;
1292 case TRUNC_MOD_EXPR:
1293 call = soft_irem_node;
1294 break;
1295 default:
1296 break;
1299 else if (type == long_type_node)
1301 switch (op)
1303 case TRUNC_DIV_EXPR:
1304 call = soft_ldiv_node;
1305 break;
1306 case TRUNC_MOD_EXPR:
1307 call = soft_lrem_node;
1308 break;
1309 default:
1310 break;
1314 if (! call)
1315 abort ();
1317 call = build (CALL_EXPR, type,
1318 build_address_of (call),
1319 tree_cons (NULL_TREE, arg1,
1320 build_tree_list (NULL_TREE, arg2)),
1321 NULL_TREE);
1323 return call;
1326 tree
1327 build_java_binop (enum tree_code op, tree type, tree arg1, tree arg2)
1329 tree mask;
1330 switch (op)
1332 case URSHIFT_EXPR:
1334 tree u_type = java_unsigned_type (type);
1335 arg1 = convert (u_type, arg1);
1336 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1337 return convert (type, arg1);
1339 case LSHIFT_EXPR:
1340 case RSHIFT_EXPR:
1341 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1342 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1343 break;
1345 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1346 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1347 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1349 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1350 boolean_type_node, arg1, arg2));
1351 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1352 tree second_compare = fold (build (COND_EXPR, int_type_node,
1353 ifexp2, integer_zero_node,
1354 op == COMPARE_L_EXPR
1355 ? integer_minus_one_node
1356 : integer_one_node));
1357 return fold (build (COND_EXPR, int_type_node, ifexp1,
1358 op == COMPARE_L_EXPR ? integer_one_node
1359 : integer_minus_one_node,
1360 second_compare));
1362 case COMPARE_EXPR:
1363 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1365 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1366 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1367 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1368 ifexp2, integer_one_node,
1369 integer_zero_node));
1370 return fold (build (COND_EXPR, int_type_node,
1371 ifexp1, integer_minus_one_node, second_compare));
1373 case TRUNC_DIV_EXPR:
1374 case TRUNC_MOD_EXPR:
1375 if (TREE_CODE (type) == REAL_TYPE
1376 && op == TRUNC_MOD_EXPR)
1378 tree call;
1379 if (type != double_type_node)
1381 arg1 = convert (double_type_node, arg1);
1382 arg2 = convert (double_type_node, arg2);
1384 call = build (CALL_EXPR, double_type_node,
1385 build_address_of (soft_fmod_node),
1386 tree_cons (NULL_TREE, arg1,
1387 build_tree_list (NULL_TREE, arg2)),
1388 NULL_TREE);
1389 if (type != double_type_node)
1390 call = convert (type, call);
1391 return call;
1394 if (TREE_CODE (type) == INTEGER_TYPE
1395 && flag_use_divide_subroutine
1396 && ! flag_syntax_only)
1397 return build_java_soft_divmod (op, type, arg1, arg2);
1399 break;
1400 default: ;
1402 return fold (build (op, type, arg1, arg2));
1405 static void
1406 expand_java_binop (tree type, enum tree_code op)
1408 tree larg, rarg;
1409 tree ltype = type;
1410 tree rtype = type;
1411 switch (op)
1413 case LSHIFT_EXPR:
1414 case RSHIFT_EXPR:
1415 case URSHIFT_EXPR:
1416 rtype = int_type_node;
1417 rarg = pop_value (rtype);
1418 break;
1419 default:
1420 rarg = pop_value (rtype);
1422 larg = pop_value (ltype);
1423 push_value (build_java_binop (op, type, larg, rarg));
1426 /* Lookup the field named NAME in *TYPEP or its super classes.
1427 If not found, return NULL_TREE.
1428 (If the *TYPEP is not found, or if the field reference is
1429 ambiguous, return error_mark_node.)
1430 If found, return the FIELD_DECL, and set *TYPEP to the
1431 class containing the field. */
1433 tree
1434 lookup_field (tree *typep, tree name)
1436 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1438 load_class (*typep, 1);
1439 safe_layout_class (*typep);
1440 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1441 return error_mark_node;
1445 tree field, basetype_vec;
1446 tree save_field;
1447 int n, i;
1449 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1450 if (DECL_NAME (field) == name)
1451 return field;
1453 /* Process implemented interfaces. */
1454 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1455 n = TREE_VEC_LENGTH (basetype_vec);
1456 save_field = NULL_TREE;
1457 for (i = 0; i < n; i++)
1459 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1460 if ((field = lookup_field (&t, name)))
1462 if (save_field == field)
1463 continue;
1464 if (save_field == NULL_TREE)
1465 save_field = field;
1466 else
1468 tree i1 = DECL_CONTEXT (save_field);
1469 tree i2 = DECL_CONTEXT (field);
1470 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1471 IDENTIFIER_POINTER (name),
1472 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1473 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1474 return error_mark_node;
1479 if (save_field != NULL_TREE)
1480 return save_field;
1482 *typep = CLASSTYPE_SUPER (*typep);
1483 } while (*typep);
1484 return NULL_TREE;
1487 /* Look up the field named NAME in object SELF_VALUE,
1488 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1489 SELF_VALUE is NULL_TREE if looking for a static field. */
1491 tree
1492 build_field_ref (tree self_value, tree self_class, tree name)
1494 tree base_class = self_class;
1495 tree field_decl = lookup_field (&base_class, name);
1496 if (field_decl == NULL_TREE)
1498 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1499 return error_mark_node;
1501 if (self_value == NULL_TREE)
1503 return build_static_field_ref (field_decl);
1505 else
1507 int check = (flag_check_references
1508 && ! (DECL_P (self_value)
1509 && DECL_NAME (self_value) == this_identifier_node));
1511 tree base_type = promote_type (base_class);
1512 if (base_type != TREE_TYPE (self_value))
1513 self_value = fold (build1 (NOP_EXPR, base_type, self_value));
1514 if (flag_indirect_dispatch
1515 && output_class != self_class)
1516 /* FIXME: output_class != self_class is not exactly the right
1517 test. What we really want to know is whether self_class is
1518 in the same translation unit as output_class. If it is,
1519 we can make a direct reference. */
1521 tree otable_index =
1522 build_int_2 (get_symbol_table_index
1523 (field_decl, &TYPE_OTABLE_METHODS (output_class)), 0);
1524 tree field_offset =
1525 build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class),
1526 otable_index);
1527 tree address;
1528 field_offset = fold (convert (sizetype, field_offset));
1529 address
1530 = fold (build (PLUS_EXPR,
1531 build_pointer_type (TREE_TYPE (field_decl)),
1532 self_value, field_offset));
1533 return fold (build1 (INDIRECT_REF, TREE_TYPE (field_decl), address));
1536 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1537 self_value, check);
1538 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1539 self_value, field_decl));
1543 tree
1544 lookup_label (int pc)
1546 tree name;
1547 char buf[32];
1548 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1549 name = get_identifier (buf);
1550 if (IDENTIFIER_LOCAL_VALUE (name))
1551 return IDENTIFIER_LOCAL_VALUE (name);
1552 else
1554 /* The type of the address of a label is return_address_type_node. */
1555 tree decl = create_label_decl (name);
1556 LABEL_PC (decl) = pc;
1557 label_rtx (decl);
1558 return pushdecl (decl);
1562 /* Generate a unique name for the purpose of loops and switches
1563 labels, and try-catch-finally blocks label or temporary variables. */
1565 tree
1566 generate_name (void)
1568 static int l_number = 0;
1569 char buff [32];
1570 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1571 l_number++;
1572 return get_identifier (buff);
1575 tree
1576 create_label_decl (tree name)
1578 tree decl;
1579 decl = build_decl (LABEL_DECL, name,
1580 TREE_TYPE (return_address_type_node));
1581 DECL_CONTEXT (decl) = current_function_decl;
1582 DECL_IGNORED_P (decl) = 1;
1583 return decl;
1586 /* This maps a bytecode offset (PC) to various flags. */
1587 char *instruction_bits;
1589 static void
1590 note_label (int current_pc ATTRIBUTE_UNUSED, int target_pc)
1592 lookup_label (target_pc);
1593 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1596 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1597 where CONDITION is one of one the compare operators. */
1599 static void
1600 expand_compare (enum tree_code condition, tree value1, tree value2,
1601 int target_pc)
1603 tree target = lookup_label (target_pc);
1604 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1605 expand_start_cond (java_truthvalue_conversion (cond), 0);
1606 expand_goto (target);
1607 expand_end_cond ();
1610 /* Emit code for a TEST-type opcode. */
1612 static void
1613 expand_test (enum tree_code condition, tree type, int target_pc)
1615 tree value1, value2;
1616 flush_quick_stack ();
1617 value1 = pop_value (type);
1618 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1619 expand_compare (condition, value1, value2, target_pc);
1622 /* Emit code for a COND-type opcode. */
1624 static void
1625 expand_cond (enum tree_code condition, tree type, int target_pc)
1627 tree value1, value2;
1628 flush_quick_stack ();
1629 /* note: pop values in opposite order */
1630 value2 = pop_value (type);
1631 value1 = pop_value (type);
1632 /* Maybe should check value1 and value2 for type compatibility ??? */
1633 expand_compare (condition, value1, value2, target_pc);
1636 static void
1637 expand_java_goto (int target_pc)
1639 tree target_label = lookup_label (target_pc);
1640 flush_quick_stack ();
1641 expand_goto (target_label);
1644 #if 0
1645 static void
1646 expand_java_call (int target_pc, int return_address)
1647 int target_pc, return_address;
1649 tree target_label = lookup_label (target_pc);
1650 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1651 push_value (value);
1652 flush_quick_stack ();
1653 expand_goto (target_label);
1656 static void
1657 expand_java_ret (tree return_address ATTRIBUTE_UNUSED)
1659 warning ("ret instruction not implemented");
1660 #if 0
1661 tree target_label = lookup_label (target_pc);
1662 flush_quick_stack ();
1663 expand_goto (target_label);
1664 #endif
1666 #endif
1668 static tree
1669 pop_arguments (tree arg_types)
1671 if (arg_types == end_params_node)
1672 return NULL_TREE;
1673 if (TREE_CODE (arg_types) == TREE_LIST)
1675 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1676 tree type = TREE_VALUE (arg_types);
1677 tree arg = pop_value (type);
1678 if (targetm.calls.promote_prototypes (type)
1679 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1680 && INTEGRAL_TYPE_P (type))
1681 arg = convert (integer_type_node, arg);
1682 return tree_cons (NULL_TREE, arg, tail);
1684 abort ();
1687 /* Build an expression to initialize the class CLAS.
1688 if EXPR is non-NULL, returns an expression to first call the initializer
1689 (if it is needed) and then calls EXPR. */
1691 tree
1692 build_class_init (tree clas, tree expr)
1694 tree init;
1696 /* An optimization: if CLAS is a superclass of the class we're
1697 compiling, we don't need to initialize it. However, if CLAS is
1698 an interface, it won't necessarily be initialized, even if we
1699 implement it. */
1700 if ((! CLASS_INTERFACE (TYPE_NAME (clas))
1701 && inherits_from_p (current_class, clas))
1702 || current_class == clas)
1703 return expr;
1705 if (always_initialize_class_p)
1707 init = build (CALL_EXPR, void_type_node,
1708 build_address_of (soft_initclass_node),
1709 build_tree_list (NULL_TREE, build_class_ref (clas)),
1710 NULL_TREE);
1711 TREE_SIDE_EFFECTS (init) = 1;
1713 else
1715 tree *init_test_decl;
1716 init_test_decl = java_treetreehash_new
1717 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);
1719 if (*init_test_decl == NULL)
1721 /* Build a declaration and mark it as a flag used to track
1722 static class initializations. */
1723 *init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1724 boolean_type_node);
1725 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (*init_test_decl);
1726 LOCAL_CLASS_INITIALIZATION_FLAG (*init_test_decl) = 1;
1727 DECL_CONTEXT (*init_test_decl) = current_function_decl;
1728 DECL_FUNCTION_INIT_TEST_CLASS (*init_test_decl) = clas;
1729 /* Tell the check-init code to ignore this decl when not
1730 optimizing class initialization. */
1731 if (!STATIC_CLASS_INIT_OPT_P ())
1732 DECL_BIT_INDEX(*init_test_decl) = -1;
1733 /* Don't emit any symbolic debugging info for this decl. */
1734 DECL_IGNORED_P (*init_test_decl) = 1;
1737 init = build (CALL_EXPR, void_type_node,
1738 build_address_of (soft_initclass_node),
1739 build_tree_list (NULL_TREE, build_class_ref (clas)),
1740 NULL_TREE);
1741 TREE_SIDE_EFFECTS (init) = 1;
1742 init = build (COND_EXPR, void_type_node,
1743 build (EQ_EXPR, boolean_type_node,
1744 *init_test_decl, boolean_false_node),
1745 init, integer_zero_node);
1746 TREE_SIDE_EFFECTS (init) = 1;
1747 init = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1748 build (MODIFY_EXPR, boolean_type_node,
1749 *init_test_decl, boolean_true_node));
1750 TREE_SIDE_EFFECTS (init) = 1;
1753 if (expr != NULL_TREE)
1755 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1756 TREE_SIDE_EFFECTS (expr) = 1;
1757 return expr;
1759 return init;
1762 tree
1763 build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
1764 tree self_type, tree method_signature ATTRIBUTE_UNUSED,
1765 tree arg_list ATTRIBUTE_UNUSED)
1767 tree func;
1768 if (is_compiled_class (self_type))
1770 if (!flag_indirect_dispatch
1771 || (!TREE_PUBLIC (method) && DECL_CONTEXT (method)))
1773 make_decl_rtl (method, NULL);
1774 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1776 else
1778 tree table_index =
1779 build_int_2 (get_symbol_table_index
1780 (method, &TYPE_ATABLE_METHODS (output_class)), 0);
1781 func =
1782 build (ARRAY_REF, method_ptr_type_node,
1783 TYPE_ATABLE_DECL (output_class), table_index);
1786 else
1788 /* We don't know whether the method has been (statically) compiled.
1789 Compile this code to get a reference to the method's code:
1791 SELF_TYPE->methods[METHOD_INDEX].ncode
1795 int method_index = 0;
1796 tree meth, ref;
1798 /* The method might actually be declared in some superclass, so
1799 we have to use its class context, not the caller's notion of
1800 where the method is. */
1801 self_type = DECL_CONTEXT (method);
1802 ref = build_class_ref (self_type);
1803 ref = build1 (INDIRECT_REF, class_type_node, ref);
1804 if (ncode_ident == NULL_TREE)
1805 ncode_ident = get_identifier ("ncode");
1806 if (methods_ident == NULL_TREE)
1807 methods_ident = get_identifier ("methods");
1808 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1809 lookup_field (&class_type_node, methods_ident));
1810 for (meth = TYPE_METHODS (self_type);
1811 ; meth = TREE_CHAIN (meth))
1813 if (method == meth)
1814 break;
1815 if (meth == NULL_TREE)
1816 fatal_error ("method '%s' not found in class",
1817 IDENTIFIER_POINTER (DECL_NAME (method)));
1818 method_index++;
1820 method_index *= int_size_in_bytes (method_type_node);
1821 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1822 ref, build_int_2 (method_index, 0)));
1823 ref = build1 (INDIRECT_REF, method_type_node, ref);
1824 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1825 ref,
1826 lookup_field (&method_type_node, ncode_ident));
1828 return func;
1831 tree
1832 invoke_build_dtable (int is_invoke_interface, tree arg_list)
1834 tree dtable, objectref;
1836 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1838 /* If we're dealing with interfaces and if the objectref
1839 argument is an array then get the dispatch table of the class
1840 Object rather than the one from the objectref. */
1841 objectref = (is_invoke_interface
1842 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1843 object_type_node : TREE_VALUE (arg_list));
1845 if (dtable_ident == NULL_TREE)
1846 dtable_ident = get_identifier ("vtable");
1847 dtable = build_java_indirect_ref (object_type_node, objectref,
1848 flag_check_references);
1849 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1850 lookup_field (&object_type_node, dtable_ident));
1852 return dtable;
1855 /* Determine the index in SYMBOL_TABLE for a reference to the decl
1856 T. If this decl has not been seen before, it will be added to the
1857 otable_methods. If it has, the existing table slot will be
1858 reused. */
1861 get_symbol_table_index (tree t, tree *symbol_table)
1863 int i = 1;
1864 tree method_list;
1866 if (*symbol_table == NULL_TREE)
1868 *symbol_table = build_tree_list (t, t);
1869 return 1;
1872 method_list = *symbol_table;
1874 while (1)
1876 tree value = TREE_VALUE (method_list);
1877 if (value == t)
1878 return i;
1879 i++;
1880 if (TREE_CHAIN (method_list) == NULL_TREE)
1881 break;
1882 else
1883 method_list = TREE_CHAIN (method_list);
1886 TREE_CHAIN (method_list) = build_tree_list (t, t);
1887 return i;
1890 tree
1891 build_invokevirtual (tree dtable, tree method)
1893 tree func;
1894 tree nativecode_ptr_ptr_type_node
1895 = build_pointer_type (nativecode_ptr_type_node);
1896 tree method_index;
1897 tree otable_index;
1899 if (flag_indirect_dispatch)
1901 otable_index
1902 = build_int_2 (get_symbol_table_index
1903 (method, &TYPE_OTABLE_METHODS (output_class)), 0);
1904 method_index = build (ARRAY_REF, integer_type_node,
1905 TYPE_OTABLE_DECL (output_class),
1906 otable_index);
1908 else
1910 method_index = convert (sizetype, DECL_VINDEX (method));
1912 if (TARGET_VTABLE_USES_DESCRIPTORS)
1913 /* Add one to skip bogus descriptor for class and GC descriptor. */
1914 method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
1915 else
1916 /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
1917 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1919 method_index = size_binop (MULT_EXPR, method_index,
1920 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1922 if (TARGET_VTABLE_USES_DESCRIPTORS)
1923 method_index = size_binop (MULT_EXPR, method_index,
1924 size_int (TARGET_VTABLE_USES_DESCRIPTORS));
1927 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1928 convert (nativecode_ptr_ptr_type_node, method_index)));
1930 if (TARGET_VTABLE_USES_DESCRIPTORS)
1931 func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
1932 else
1933 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1935 return func;
1938 static GTY(()) tree class_ident;
1939 tree
1940 build_invokeinterface (tree dtable, tree method)
1942 tree lookup_arg;
1943 tree interface;
1944 tree idx;
1945 tree meth;
1946 tree otable_index;
1947 int i;
1949 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1950 ensure that the selected method exists, is public and not
1951 abstract nor static. */
1953 if (class_ident == NULL_TREE)
1954 class_ident = get_identifier ("class");
1956 dtable = build_java_indirect_ref (dtable_type, dtable,
1957 flag_check_references);
1958 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1959 lookup_field (&dtable_type, class_ident));
1961 interface = DECL_CONTEXT (method);
1962 if (! CLASS_INTERFACE (TYPE_NAME (interface)))
1963 abort ();
1964 layout_class_methods (interface);
1966 if (flag_indirect_dispatch)
1968 otable_index =
1969 build_int_2 (get_symbol_table_index
1970 (method, &TYPE_OTABLE_METHODS (output_class)), 0);
1971 idx =
1972 build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class),
1973 otable_index);
1975 else
1977 i = 1;
1978 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1980 if (meth == method)
1982 idx = build_int_2 (i, 0);
1983 break;
1985 if (meth == NULL_TREE)
1986 abort ();
1990 lookup_arg = tree_cons (NULL_TREE, dtable,
1991 tree_cons (NULL_TREE, build_class_ref (interface),
1992 build_tree_list (NULL_TREE, idx)));
1994 return build (CALL_EXPR, ptr_type_node,
1995 build_address_of (soft_lookupinterfacemethod_node),
1996 lookup_arg, NULL_TREE);
1999 /* Expand one of the invoke_* opcodes.
2000 OCPODE is the specific opcode.
2001 METHOD_REF_INDEX is an index into the constant pool.
2002 NARGS is the number of arguments, or -1 if not specified. */
2004 static void
2005 expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
2007 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
2008 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
2009 tree self_type = get_class_constant
2010 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
2011 const char *const self_name
2012 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2013 tree call, func, method, arg_list, method_type;
2014 tree check = NULL_TREE;
2016 if (! CLASS_LOADED_P (self_type))
2018 load_class (self_type, 1);
2019 safe_layout_class (self_type);
2020 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2021 fatal_error ("failed to find class '%s'", self_name);
2023 layout_class_methods (self_type);
2025 if (ID_INIT_P (method_name))
2026 method = lookup_java_constructor (self_type, method_signature);
2027 else
2028 method = lookup_java_method (self_type, method_name, method_signature);
2029 if (method == NULL_TREE)
2031 error ("class '%s' has no method named '%s' matching signature '%s'",
2032 self_name,
2033 IDENTIFIER_POINTER (method_name),
2034 IDENTIFIER_POINTER (method_signature));
2036 /* Invoke static can't invoke static/abstract method */
2037 else if (opcode == OPCODE_invokestatic)
2039 if (!METHOD_STATIC (method))
2041 error ("invokestatic on non static method");
2042 method = NULL_TREE;
2044 else if (METHOD_ABSTRACT (method))
2046 error ("invokestatic on abstract method");
2047 method = NULL_TREE;
2050 else
2052 if (METHOD_STATIC (method))
2054 error ("invoke[non-static] on static method");
2055 method = NULL_TREE;
2059 if (method == NULL_TREE)
2061 method_type = get_type_from_signature (method_signature);
2062 pop_arguments (TYPE_ARG_TYPES (method_type));
2063 if (opcode != OPCODE_invokestatic)
2064 pop_type (self_type);
2065 method_type = promote_type (TREE_TYPE (method_type));
2066 push_value (convert (method_type, integer_zero_node));
2067 return;
2070 method_type = TREE_TYPE (method);
2071 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2072 flush_quick_stack ();
2074 func = NULL_TREE;
2075 if (opcode == OPCODE_invokestatic)
2076 func = build_known_method_ref (method, method_type, self_type,
2077 method_signature, arg_list);
2078 else if (opcode == OPCODE_invokespecial
2079 || (opcode == OPCODE_invokevirtual
2080 && (METHOD_PRIVATE (method)
2081 || METHOD_FINAL (method)
2082 || CLASS_FINAL (TYPE_NAME (self_type)))))
2084 /* If the object for the method call is null, we throw an
2085 exception. We don't do this if the object is the current
2086 method's `this'. In other cases we just rely on an
2087 optimization pass to eliminate redundant checks. FIXME:
2088 Unfortunately there doesn't seem to be a way to determine
2089 what the current method is right now.
2090 We do omit the check if we're calling <init>. */
2091 /* We use a SAVE_EXPR here to make sure we only evaluate
2092 the new `self' expression once. */
2093 tree save_arg = save_expr (TREE_VALUE (arg_list));
2094 TREE_VALUE (arg_list) = save_arg;
2095 check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2096 func = build_known_method_ref (method, method_type, self_type,
2097 method_signature, arg_list);
2099 else
2101 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
2102 arg_list);
2103 if (opcode == OPCODE_invokevirtual)
2104 func = build_invokevirtual (dtable, method);
2105 else
2106 func = build_invokeinterface (dtable, method);
2108 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2110 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
2111 TREE_SIDE_EFFECTS (call) = 1;
2112 call = check_for_builtin (method, call);
2114 if (check != NULL_TREE)
2116 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2117 TREE_SIDE_EFFECTS (call) = 1;
2120 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2121 expand_expr_stmt (call);
2122 else
2124 push_value (call);
2125 flush_quick_stack ();
2129 /* Create a stub which will be put into the vtable but which will call
2130 a JNI function. */
2132 tree
2133 build_jni_stub (tree method)
2135 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2136 tree jni_func_type, tem;
2137 tree env_var, res_var = NULL_TREE, block;
2138 tree method_args, res_type;
2139 tree meth_var;
2141 int args_size = 0;
2143 tree klass = DECL_CONTEXT (method);
2144 int from_class = ! CLASS_FROM_SOURCE_P (klass);
2145 klass = build_class_ref (klass);
2147 if (! METHOD_NATIVE (method) || ! flag_jni)
2148 abort ();
2150 DECL_ARTIFICIAL (method) = 1;
2151 DECL_EXTERNAL (method) = 0;
2153 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2154 DECL_CONTEXT (env_var) = method;
2156 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2158 res_var = build_decl (VAR_DECL, get_identifier ("res"),
2159 TREE_TYPE (TREE_TYPE (method)));
2160 DECL_CONTEXT (res_var) = method;
2161 TREE_CHAIN (env_var) = res_var;
2164 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2165 TREE_STATIC (meth_var) = 1;
2166 TREE_PUBLIC (meth_var) = 0;
2167 DECL_EXTERNAL (meth_var) = 0;
2168 DECL_CONTEXT (meth_var) = method;
2169 DECL_ARTIFICIAL (meth_var) = 1;
2170 DECL_INITIAL (meth_var) = null_pointer_node;
2171 TREE_USED (meth_var) = 1;
2172 chainon (env_var, meth_var);
2173 layout_decl (meth_var, 0);
2174 make_decl_rtl (meth_var, NULL);
2175 rest_of_decl_compilation (meth_var, NULL, 0, 0);
2177 /* One strange way that the front ends are different is that they
2178 store arguments differently. */
2179 if (from_class)
2180 method_args = DECL_ARGUMENTS (method);
2181 else
2182 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2183 block = build_block (env_var, NULL_TREE, NULL_TREE,
2184 method_args, NULL_TREE);
2185 TREE_SIDE_EFFECTS (block) = 1;
2186 /* When compiling from source we don't set the type of the block,
2187 because that will prevent patch_return from ever being run. */
2188 if (from_class)
2189 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2191 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2192 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2193 build (CALL_EXPR, ptr_type_node,
2194 build_address_of (soft_getjnienvnewframe_node),
2195 build_tree_list (NULL_TREE, klass),
2196 NULL_TREE));
2197 CAN_COMPLETE_NORMALLY (body) = 1;
2199 /* All the arguments to this method become arguments to the
2200 underlying JNI function. If we had to wrap object arguments in a
2201 special way, we would do that here. */
2202 args = NULL_TREE;
2203 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2205 int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (tem)));
2206 #ifdef PARM_BOUNDARY
2207 arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
2208 * PARM_BOUNDARY);
2209 #endif
2210 args_size += (arg_bits / BITS_PER_UNIT);
2212 args = tree_cons (NULL_TREE, tem, args);
2214 args = nreverse (args);
2215 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2217 /* For a static method the second argument is the class. For a
2218 non-static method the second argument is `this'; that is already
2219 available in the argument list. */
2220 if (METHOD_STATIC (method))
2222 args_size += int_size_in_bytes (TREE_TYPE (klass));
2223 args = tree_cons (NULL_TREE, klass, args);
2224 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2227 /* The JNIEnv structure is the first argument to the JNI function. */
2228 args_size += int_size_in_bytes (TREE_TYPE (env_var));
2229 args = tree_cons (NULL_TREE, env_var, args);
2230 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2232 /* We call _Jv_LookupJNIMethod to find the actual underlying
2233 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2234 exception if this function is not found at runtime. */
2235 tem = build_tree_list (NULL_TREE, build_int_2 (args_size, 0));
2236 method_sig = build_java_signature (TREE_TYPE (method));
2237 lookup_arg = tree_cons (NULL_TREE,
2238 build_utf8_ref (unmangle_classname
2239 (IDENTIFIER_POINTER (method_sig),
2240 IDENTIFIER_LENGTH (method_sig))),
2241 tem);
2242 tem = DECL_NAME (method);
2243 lookup_arg
2244 = tree_cons (NULL_TREE, klass,
2245 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2247 tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
2249 #ifdef MODIFY_JNI_METHOD_CALL
2250 tem = MODIFY_JNI_METHOD_CALL (tem);
2251 #endif
2253 jni_func_type = build_pointer_type (tem);
2255 jnifunc = build (COND_EXPR, ptr_type_node,
2256 meth_var, meth_var,
2257 build (MODIFY_EXPR, ptr_type_node,
2258 meth_var,
2259 build (CALL_EXPR, ptr_type_node,
2260 build_address_of (soft_lookupjnimethod_node),
2261 lookup_arg, NULL_TREE)));
2263 /* Now we make the actual JNI call via the resulting function
2264 pointer. */
2265 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2266 build1 (NOP_EXPR, jni_func_type, jnifunc),
2267 args, NULL_TREE);
2269 /* If the JNI call returned a result, capture it here. If we had to
2270 unwrap JNI object results, we would do that here. */
2271 if (res_var != NULL_TREE)
2272 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2273 res_var, call);
2275 TREE_SIDE_EFFECTS (call) = 1;
2276 CAN_COMPLETE_NORMALLY (call) = 1;
2278 body = build (COMPOUND_EXPR, void_type_node, body, call);
2279 TREE_SIDE_EFFECTS (body) = 1;
2281 /* Now free the environment we allocated. */
2282 call = build (CALL_EXPR, ptr_type_node,
2283 build_address_of (soft_jnipopsystemframe_node),
2284 build_tree_list (NULL_TREE, env_var),
2285 NULL_TREE);
2286 TREE_SIDE_EFFECTS (call) = 1;
2287 CAN_COMPLETE_NORMALLY (call) = 1;
2288 body = build (COMPOUND_EXPR, void_type_node, body, call);
2289 TREE_SIDE_EFFECTS (body) = 1;
2291 /* Finally, do the return. When compiling from source we rely on
2292 patch_return to patch the return value -- because DECL_RESULT is
2293 not set at the time this function is called. */
2294 if (from_class)
2296 res_type = void_type_node;
2297 if (res_var != NULL_TREE)
2299 tree drt;
2300 if (! DECL_RESULT (method))
2301 abort ();
2302 /* Make sure we copy the result variable to the actual
2303 result. We use the type of the DECL_RESULT because it
2304 might be different from the return type of the function:
2305 it might be promoted. */
2306 drt = TREE_TYPE (DECL_RESULT (method));
2307 if (drt != TREE_TYPE (res_var))
2308 res_var = build1 (CONVERT_EXPR, drt, res_var);
2309 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2310 TREE_SIDE_EFFECTS (res_var) = 1;
2313 else
2315 /* This is necessary to get patch_return to run. */
2316 res_type = NULL_TREE;
2318 body = build (COMPOUND_EXPR, void_type_node, body,
2319 build1 (RETURN_EXPR, res_type, res_var));
2320 TREE_SIDE_EFFECTS (body) = 1;
2322 BLOCK_EXPR_BODY (block) = body;
2323 return block;
2326 /* Expand an operation to extract from or store into a field.
2327 IS_STATIC is 1 iff the field is static.
2328 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2329 FIELD_REF_INDEX is an index into the constant pool. */
2331 static void
2332 expand_java_field_op (int is_static, int is_putting, int field_ref_index)
2334 tree self_type =
2335 get_class_constant (current_jcf,
2336 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2337 field_ref_index));
2338 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2339 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2340 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2341 field_ref_index);
2342 tree field_type = get_type_from_signature (field_signature);
2343 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2344 tree field_ref;
2345 int is_error = 0;
2346 tree field_decl = lookup_field (&self_type, field_name);
2347 if (field_decl == error_mark_node)
2349 is_error = 1;
2351 else if (field_decl == NULL_TREE)
2353 error ("missing field '%s' in '%s'",
2354 IDENTIFIER_POINTER (field_name), self_name);
2355 is_error = 1;
2357 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2359 error ("mismatching signature for field '%s' in '%s'",
2360 IDENTIFIER_POINTER (field_name), self_name);
2361 is_error = 1;
2363 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2364 if (is_error)
2366 if (! is_putting)
2367 push_value (convert (field_type, integer_zero_node));
2368 flush_quick_stack ();
2369 return;
2372 field_ref = build_field_ref (field_ref, self_type, field_name);
2373 if (is_static)
2374 field_ref = build_class_init (self_type, field_ref);
2375 if (is_putting)
2377 flush_quick_stack ();
2378 if (FIELD_FINAL (field_decl))
2380 if (DECL_CONTEXT (field_decl) != current_class)
2381 error ("%Jassignment to final field '%D' not in field's class",
2382 field_decl, field_decl);
2383 else if (FIELD_STATIC (field_decl))
2385 if (!DECL_CLINIT_P (current_function_decl))
2386 warning ("%Jassignment to final static field `%D' not in "
2387 "class initializer", field_decl, field_decl);
2389 else
2391 tree cfndecl_name = DECL_NAME (current_function_decl);
2392 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2393 && !ID_FINIT_P (cfndecl_name))
2394 warning ("%Jassignment to final field '%D' not in constructor",
2395 field_decl, field_decl);
2398 expand_assignment (field_ref, new_value, 0);
2400 else
2401 push_value (field_ref);
2404 void
2405 load_type_state (tree label)
2407 int i;
2408 tree vec = LABEL_TYPE_STATE (label);
2409 int cur_length = TREE_VEC_LENGTH (vec);
2410 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2411 for (i = 0; i < cur_length; i++)
2412 type_map [i] = TREE_VEC_ELT (vec, i);
2415 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2416 dependent things, but they rely on gcc routines. This function is
2417 placed here because it uses things defined locally in parse.y. */
2419 static tree
2420 case_identity (tree t __attribute__ ((__unused__)), tree v)
2422 return v;
2425 /* Return the name of the vtable for an array of a given primitive
2426 type. */
2427 static tree
2428 get_primitive_array_vtable (tree elt)
2430 tree r;
2431 if (elt == boolean_type_node)
2432 r = boolean_array_vtable;
2433 else if (elt == byte_type_node)
2434 r = byte_array_vtable;
2435 else if (elt == char_type_node)
2436 r = char_array_vtable;
2437 else if (elt == short_type_node)
2438 r = short_array_vtable;
2439 else if (elt == int_type_node)
2440 r = int_array_vtable;
2441 else if (elt == long_type_node)
2442 r = long_array_vtable;
2443 else if (elt == float_type_node)
2444 r = float_array_vtable;
2445 else if (elt == double_type_node)
2446 r = double_array_vtable;
2447 else
2448 abort ();
2449 return build_address_of (r);
2452 struct rtx_def *
2453 java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
2454 int modifier /* Actually an enum expand_modifier. */,
2455 rtx *alt_rtl ATTRIBUTE_UNUSED)
2457 tree current;
2459 switch (TREE_CODE (exp))
2461 case NEW_ARRAY_INIT:
2463 rtx tmp;
2464 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2465 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2466 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2467 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2468 tree length = build_int_2 (ilength, 0);
2469 tree init = TREE_OPERAND (exp, 0);
2470 tree array_decl;
2472 /* See if we can generate the array statically. */
2473 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2474 && JPRIMITIVE_TYPE_P (element_type))
2476 tree temp, value, init_decl;
2477 struct rtx_def *r;
2478 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2479 PUSH_FIELD_VALUE (temp, "vtable",
2480 get_primitive_array_vtable (element_type));
2481 if (! flag_hash_synchronization)
2482 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2483 FINISH_RECORD_CONSTRUCTOR (temp);
2484 START_RECORD_CONSTRUCTOR (value, array_type);
2485 PUSH_SUPER_VALUE (value, temp);
2486 PUSH_FIELD_VALUE (value, "length", length);
2487 PUSH_FIELD_VALUE (value, "data", init);
2488 FINISH_RECORD_CONSTRUCTOR (value);
2490 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2491 pushdecl_top_level (init_decl);
2492 TREE_STATIC (init_decl) = 1;
2493 DECL_INITIAL (init_decl) = value;
2494 DECL_IGNORED_P (init_decl) = 1;
2495 TREE_READONLY (init_decl) = 1;
2496 /* Hash synchronization requires at least 64-bit alignment. */
2497 if (flag_hash_synchronization && POINTER_SIZE < 64)
2498 DECL_ALIGN (init_decl) = 64;
2499 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2500 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2501 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2502 r = expand_expr (init, target, tmode, modifier);
2503 return r;
2506 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2507 expand_decl (array_decl);
2508 tmp = expand_assignment (array_decl,
2509 build_new_array (element_type, length),
2511 if (TREE_CONSTANT (init)
2512 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2514 tree init_decl;
2515 init_decl = build_decl (VAR_DECL, generate_name (),
2516 TREE_TYPE (init));
2517 pushdecl_top_level (init_decl);
2518 TREE_STATIC (init_decl) = 1;
2519 DECL_INITIAL (init_decl) = init;
2520 DECL_IGNORED_P (init_decl) = 1;
2521 TREE_READONLY (init_decl) = 1;
2522 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2523 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2524 init = init_decl;
2526 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2527 build_java_indirect_ref (array_type,
2528 array_decl, flag_check_references),
2529 data_fld), init, 0);
2530 return tmp;
2532 case BLOCK:
2533 if (BLOCK_EXPR_BODY (exp))
2535 tree local;
2536 rtx last;
2537 tree body = BLOCK_EXPR_BODY (exp);
2538 /* Set to 1 or more when we found a static class
2539 initialization flag. */
2540 int found_class_initialization_flag = 0;
2542 pushlevel (2); /* 2 and above */
2543 expand_start_bindings (0);
2544 local = BLOCK_EXPR_DECLS (exp);
2545 while (local)
2547 tree next = TREE_CHAIN (local);
2548 found_class_initialization_flag +=
2549 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
2550 layout_decl (local, 0);
2551 expand_decl (pushdecl (local));
2552 local = next;
2555 /* Emit initialization code for test flags if we saw one. */
2556 if (! always_initialize_class_p
2557 && current_function_decl
2558 && found_class_initialization_flag)
2559 htab_traverse
2560 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
2561 emit_init_test_initialization, NULL);
2563 /* Avoid deep recursion for long block. */
2564 while (TREE_CODE (body) == COMPOUND_EXPR)
2566 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2567 emit_queue ();
2568 body = TREE_OPERAND (body, 1);
2570 last = expand_expr (body, NULL_RTX, VOIDmode, 0);
2571 emit_queue ();
2572 expand_end_bindings (getdecls (), 1, 0);
2573 poplevel (1, 1, 0);
2574 return last;
2576 return const0_rtx;
2578 case CASE_EXPR:
2580 tree duplicate;
2581 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2582 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2583 &duplicate) == 2)
2585 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2586 parse_error_context
2587 (wfl_operator, "Duplicate case label: `%s'",
2588 print_int_node (TREE_OPERAND (exp, 0)));
2590 return const0_rtx;
2593 case DEFAULT_EXPR:
2594 pushcase (NULL_TREE, 0,
2595 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2596 return const0_rtx;
2598 case SWITCH_EXPR:
2599 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2600 expand_expr_stmt (TREE_OPERAND (exp, 1));
2601 expand_end_case (TREE_OPERAND (exp, 0));
2602 return const0_rtx;
2604 case TRY_EXPR:
2605 /* We expand a try[-catch] block */
2607 /* Expand the try block */
2608 expand_eh_region_start ();
2609 expand_expr_stmt (TREE_OPERAND (exp, 0));
2610 expand_start_all_catch ();
2612 /* Expand all catch clauses (EH handlers) */
2613 for (current = TREE_OPERAND (exp, 1); current;
2614 current = TREE_CHAIN (current))
2616 tree catch = TREE_OPERAND (current, 0);
2617 tree decl = BLOCK_EXPR_DECLS (catch);
2618 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2620 expand_start_catch (prepare_eh_table_type (type));
2621 expand_expr_stmt (TREE_OPERAND (current, 0));
2622 expand_end_catch ();
2624 expand_end_all_catch ();
2625 return const0_rtx;
2627 case JAVA_EXC_OBJ_EXPR:
2628 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2629 target, tmode, modifier);
2631 case LABEL_EXPR:
2632 /* Used only by expanded inline functions. */
2633 expand_label (TREE_OPERAND (exp, 0));
2634 return const0_rtx;
2636 default:
2637 internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
2641 /* Go over METHOD's bytecode and note instruction starts in
2642 instruction_bits[]. */
2644 void
2645 note_instructions (JCF *jcf, tree method)
2647 int PC;
2648 unsigned char* byte_ops;
2649 long length = DECL_CODE_LENGTH (method);
2651 int saw_index;
2652 jint INT_temp;
2654 #undef RET /* Defined by config/i386/i386.h */
2655 #undef PTR
2656 #define BCODE byte_ops
2657 #define BYTE_type_node byte_type_node
2658 #define SHORT_type_node short_type_node
2659 #define INT_type_node int_type_node
2660 #define LONG_type_node long_type_node
2661 #define CHAR_type_node char_type_node
2662 #define PTR_type_node ptr_type_node
2663 #define FLOAT_type_node float_type_node
2664 #define DOUBLE_type_node double_type_node
2665 #define VOID_type_node void_type_node
2666 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2667 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2668 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2669 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2671 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2673 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2674 byte_ops = jcf->read_ptr;
2675 instruction_bits = xrealloc (instruction_bits, length + 1);
2676 memset (instruction_bits, 0, length + 1);
2678 /* This pass figures out which PC can be the targets of jumps. */
2679 for (PC = 0; PC < length;)
2681 int oldpc = PC; /* PC at instruction start. */
2682 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2683 switch (byte_ops[PC++])
2685 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2686 case OPCODE: \
2687 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2688 break;
2690 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2692 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2693 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2694 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2695 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2696 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2697 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2698 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2699 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2701 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2702 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2703 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2704 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2705 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2706 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2707 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2708 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2710 /* two forms of wide instructions */
2711 #define PRE_SPECIAL_WIDE(IGNORE) \
2713 int modified_opcode = IMMEDIATE_u1; \
2714 if (modified_opcode == OPCODE_iinc) \
2716 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2717 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2719 else \
2721 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2725 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2727 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2729 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2730 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2731 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2732 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2733 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2734 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2735 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2736 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2737 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2738 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2740 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2741 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2742 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2743 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2744 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2745 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2746 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2747 NOTE_LABEL (PC); \
2748 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2750 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2752 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2753 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2755 #define PRE_LOOKUP_SWITCH \
2756 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2757 NOTE_LABEL (default_offset+oldpc); \
2758 if (npairs >= 0) \
2759 while (--npairs >= 0) { \
2760 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2761 jint offset = IMMEDIATE_s4; \
2762 NOTE_LABEL (offset+oldpc); } \
2765 #define PRE_TABLE_SWITCH \
2766 { jint default_offset = IMMEDIATE_s4; \
2767 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2768 NOTE_LABEL (default_offset+oldpc); \
2769 if (low <= high) \
2770 while (low++ <= high) { \
2771 jint offset = IMMEDIATE_s4; \
2772 NOTE_LABEL (offset+oldpc); } \
2775 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2776 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2777 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2778 (void)(IMMEDIATE_u2); \
2779 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2781 #include "javaop.def"
2782 #undef JAVAOP
2784 } /* for */
2787 void
2788 expand_byte_code (JCF *jcf, tree method)
2790 int PC;
2791 int i;
2792 const unsigned char *linenumber_pointer;
2793 int dead_code_index = -1;
2794 unsigned char* byte_ops;
2795 long length = DECL_CODE_LENGTH (method);
2797 stack_pointer = 0;
2798 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2799 byte_ops = jcf->read_ptr;
2801 /* We make an initial pass of the line number table, to note
2802 which instructions have associated line number entries. */
2803 linenumber_pointer = linenumber_table;
2804 for (i = 0; i < linenumber_count; i++)
2806 int pc = GET_u2 (linenumber_pointer);
2807 linenumber_pointer += 4;
2808 if (pc >= length)
2809 warning ("invalid PC in line number table");
2810 else
2812 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2813 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2814 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2818 if (! verify_jvm_instructions (jcf, byte_ops, length))
2819 return;
2821 /* Translate bytecodes to rtl instructions. */
2822 linenumber_pointer = linenumber_table;
2823 for (PC = 0; PC < length;)
2825 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2827 tree label = lookup_label (PC);
2828 flush_quick_stack ();
2829 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2830 expand_label (label);
2831 if (LABEL_VERIFIED (label) || PC == 0)
2832 load_type_state (label);
2835 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2837 if (dead_code_index == -1)
2839 /* This is the start of a region of unreachable bytecodes.
2840 They still need to be processed in order for EH ranges
2841 to get handled correctly. However, we can simply
2842 replace these bytecodes with nops. */
2843 dead_code_index = PC;
2846 /* Turn this bytecode into a nop. */
2847 byte_ops[PC] = 0x0;
2849 else
2851 if (dead_code_index != -1)
2853 /* We've just reached the end of a region of dead code. */
2854 if (extra_warnings)
2855 warning ("unreachable bytecode from %d to before %d",
2856 dead_code_index, PC);
2857 dead_code_index = -1;
2861 /* Handle possible line number entry for this PC.
2863 This code handles out-of-order and multiple linenumbers per PC,
2864 but is optimized for the case of line numbers increasing
2865 monotonically with PC. */
2866 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2868 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2869 || GET_u2 (linenumber_pointer) != PC)
2870 linenumber_pointer = linenumber_table;
2871 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2873 int pc = GET_u2 (linenumber_pointer);
2874 linenumber_pointer += 4;
2875 if (pc == PC)
2877 input_line = GET_u2 (linenumber_pointer - 2);
2878 emit_line_note (input_location);
2879 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2880 break;
2884 maybe_pushlevels (PC);
2885 PC = process_jvm_instruction (PC, byte_ops, length);
2886 maybe_poplevels (PC);
2887 } /* for */
2889 if (dead_code_index != -1)
2891 /* We've just reached the end of a region of dead code. */
2892 if (extra_warnings)
2893 warning ("unreachable bytecode from %d to the end of the method",
2894 dead_code_index);
2898 static void
2899 java_push_constant_from_pool (JCF *jcf, int index)
2901 tree c;
2902 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2904 tree name;
2905 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2906 index = alloc_name_constant (CONSTANT_String, name);
2907 c = build_ref_from_constant_pool (index);
2908 TREE_TYPE (c) = promote_type (string_type_node);
2910 else
2911 c = get_constant (jcf, index);
2912 push_value (c);
2916 process_jvm_instruction (int PC, const unsigned char* byte_ops,
2917 long length ATTRIBUTE_UNUSED)
2919 const char *opname; /* Temporary ??? */
2920 int oldpc = PC; /* PC at instruction start. */
2922 /* If the instruction is at the beginning of a exception handler,
2923 replace the top of the stack with the thrown object reference */
2924 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2926 tree type = pop_type (ptr_type_node);
2927 push_value (build (JAVA_EXC_OBJ_EXPR, type));
2930 switch (byte_ops[PC++])
2932 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2933 case OPCODE: \
2934 opname = #OPNAME; \
2935 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2936 break;
2938 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2940 int saw_index = 0; \
2941 int index = OPERAND_VALUE; \
2942 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2945 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2947 /* OPERAND_VALUE may have side-effects on PC */ \
2948 int opvalue = OPERAND_VALUE; \
2949 build_java_jsr (oldpc + opvalue, PC); \
2952 /* Push a constant onto the stack. */
2953 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2954 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2955 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2956 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2958 /* internal macro added for use by the WIDE case */
2959 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2960 expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
2962 /* Push local variable onto the opcode stack. */
2963 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2965 /* have to do this since OPERAND_VALUE may have side-effects */ \
2966 int opvalue = OPERAND_VALUE; \
2967 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2970 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2971 expand_java_return (OPERAND_TYPE##_type_node)
2973 #define REM_EXPR TRUNC_MOD_EXPR
2974 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2975 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2977 #define FIELD(IS_STATIC, IS_PUT) \
2978 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2980 #define TEST(OPERAND_TYPE, CONDITION) \
2981 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2983 #define COND(OPERAND_TYPE, CONDITION) \
2984 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2986 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2987 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2989 #define BRANCH_GOTO(OPERAND_VALUE) \
2990 expand_java_goto (oldpc + OPERAND_VALUE)
2992 #define BRANCH_CALL(OPERAND_VALUE) \
2993 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2995 #if 0
2996 #define BRANCH_RETURN(OPERAND_VALUE) \
2998 tree type = OPERAND_TYPE##_type_node; \
2999 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3000 expand_java_ret (value); \
3002 #endif
3004 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3005 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3006 fprintf (stderr, "(not implemented)\n")
3007 #define NOT_IMPL1(OPERAND_VALUE) \
3008 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3009 fprintf (stderr, "(not implemented)\n")
3011 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3013 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3015 #define STACK_POP(COUNT) java_stack_pop (COUNT)
3017 #define STACK_SWAP(COUNT) java_stack_swap()
3019 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3020 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3021 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3023 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3024 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3026 #define LOOKUP_SWITCH \
3027 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
3028 tree selector = pop_value (INT_type_node); \
3029 tree duplicate, label; \
3030 tree type = TREE_TYPE (selector); \
3031 flush_quick_stack (); \
3032 expand_start_case (0, selector, type, "switch statement");\
3033 while (--npairs >= 0) \
3035 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3036 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
3037 TREE_TYPE (value) = type; \
3038 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3039 pushcase (value, convert, label, &duplicate); \
3040 expand_java_goto (oldpc + offset); \
3042 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3043 pushcase (NULL_TREE, 0, label, &duplicate); \
3044 expand_java_goto (oldpc + default_offset); \
3045 expand_end_case (selector); \
3048 #define TABLE_SWITCH \
3049 { jint default_offset = IMMEDIATE_s4; \
3050 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3051 tree selector = pop_value (INT_type_node); \
3052 tree duplicate, label; \
3053 tree type = TREE_TYPE (selector); \
3054 flush_quick_stack (); \
3055 expand_start_case (0, selector, type, "switch statement");\
3056 for (; low <= high; low++) \
3058 jint offset = IMMEDIATE_s4; \
3059 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
3060 TREE_TYPE (value) = type; \
3061 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3062 pushcase (value, convert, label, &duplicate); \
3063 expand_java_goto (oldpc + offset); \
3065 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3066 pushcase (NULL_TREE, 0, label, &duplicate); \
3067 expand_java_goto (oldpc + default_offset); \
3068 expand_end_case (selector); \
3071 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3072 { int opcode = byte_ops[PC-1]; \
3073 int method_ref_index = IMMEDIATE_u2; \
3074 int nargs; \
3075 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
3076 else nargs = -1; \
3077 expand_invoke (opcode, method_ref_index, nargs); \
3080 /* Handle new, checkcast, instanceof */
3081 #define OBJECT(TYPE, OP) \
3082 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3084 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3086 #define ARRAY_LOAD(OPERAND_TYPE) \
3088 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
3091 #define ARRAY_STORE(OPERAND_TYPE) \
3093 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3096 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3097 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3098 #define ARRAY_NEW_PTR() \
3099 push_value (build_anewarray (get_class_constant (current_jcf, \
3100 IMMEDIATE_u2), \
3101 pop_value (int_type_node)));
3102 #define ARRAY_NEW_NUM() \
3104 int atype = IMMEDIATE_u1; \
3105 push_value (build_newarray (atype, pop_value (int_type_node)));\
3107 #define ARRAY_NEW_MULTI() \
3109 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
3110 int ndims = IMMEDIATE_u1; \
3111 expand_java_multianewarray( class, ndims ); \
3114 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3115 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3116 pop_value (OPERAND_TYPE##_type_node))));
3118 #define CONVERT2(FROM_TYPE, TO_TYPE) \
3120 push_value (build1 (NOP_EXPR, int_type_node, \
3121 (convert (TO_TYPE##_type_node, \
3122 pop_value (FROM_TYPE##_type_node))))); \
3125 #define CONVERT(FROM_TYPE, TO_TYPE) \
3127 push_value (convert (TO_TYPE##_type_node, \
3128 pop_value (FROM_TYPE##_type_node))); \
3131 /* internal macro added for use by the WIDE case
3132 Added TREE_TYPE (decl) assignment, apbianco */
3133 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
3135 tree decl, value; \
3136 int var = OPVALUE; \
3137 tree type = OPTYPE; \
3138 value = pop_value (type); \
3139 type = TREE_TYPE (value); \
3140 decl = find_local_variable (var, type, oldpc); \
3141 set_local_type (var, type ); \
3142 expand_assignment (decl, value, 0); \
3145 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3147 /* have to do this since OPERAND_VALUE may have side-effects */ \
3148 int opvalue = OPERAND_VALUE; \
3149 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3152 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3153 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3155 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3156 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3158 #define MONITOR_OPERATION(call) \
3160 tree o = pop_value (ptr_type_node); \
3161 tree c; \
3162 flush_quick_stack (); \
3163 c = build_java_monitor (call, o); \
3164 TREE_SIDE_EFFECTS (c) = 1; \
3165 expand_expr_stmt (c); \
3168 #define SPECIAL_IINC(IGNORED) \
3170 unsigned int local_var_index = IMMEDIATE_u1; \
3171 int ival = IMMEDIATE_s1; \
3172 expand_iinc(local_var_index, ival, oldpc); \
3175 #define SPECIAL_WIDE(IGNORED) \
3177 int modified_opcode = IMMEDIATE_u1; \
3178 unsigned int local_var_index = IMMEDIATE_u2; \
3179 switch (modified_opcode) \
3181 case OPCODE_iinc: \
3183 int ival = IMMEDIATE_s2; \
3184 expand_iinc (local_var_index, ival, oldpc); \
3185 break; \
3187 case OPCODE_iload: \
3188 case OPCODE_lload: \
3189 case OPCODE_fload: \
3190 case OPCODE_dload: \
3191 case OPCODE_aload: \
3193 /* duplicate code from LOAD macro */ \
3194 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3195 break; \
3197 case OPCODE_istore: \
3198 case OPCODE_lstore: \
3199 case OPCODE_fstore: \
3200 case OPCODE_dstore: \
3201 case OPCODE_astore: \
3203 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3204 break; \
3206 default: \
3207 error ("unrecogized wide sub-instruction"); \
3211 #define SPECIAL_THROW(IGNORED) \
3212 build_java_athrow (pop_value (throwable_type_node))
3214 #define SPECIAL_BREAK NOT_IMPL1
3215 #define IMPL NOT_IMPL
3217 #include "javaop.def"
3218 #undef JAVAOP
3219 default:
3220 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3222 return PC;
3225 /* Return the opcode at PC in the code section pointed to by
3226 CODE_OFFSET. */
3228 static unsigned char
3229 peek_opcode_at_pc (JCF *jcf, int code_offset, int pc)
3231 unsigned char opcode;
3232 long absolute_offset = (long)JCF_TELL (jcf);
3234 JCF_SEEK (jcf, code_offset);
3235 opcode = jcf->read_ptr [pc];
3236 JCF_SEEK (jcf, absolute_offset);
3237 return opcode;
3240 /* Some bytecode compilers are emitting accurate LocalVariableTable
3241 attributes. Here's an example:
3243 PC <t>store_<n>
3244 PC+1 ...
3246 Attribute "LocalVariableTable"
3247 slot #<n>: ... (PC: PC+1 length: L)
3249 This is accurate because the local in slot <n> really exists after
3250 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3252 This procedure recognizes this situation and extends the live range
3253 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3254 length of the store instruction.)
3256 This function is used by `give_name_to_locals' so that a local's
3257 DECL features a DECL_LOCAL_START_PC such that the first related
3258 store operation will use DECL as a destination, not a unrelated
3259 temporary created for the occasion.
3261 This function uses a global (instruction_bits) `note_instructions' should
3262 have allocated and filled properly. */
3265 maybe_adjust_start_pc (struct JCF *jcf, int code_offset,
3266 int start_pc, int slot)
3268 int first, index, opcode;
3269 int pc, insn_pc;
3270 int wide_found = 0;
3272 if (!start_pc)
3273 return start_pc;
3275 first = index = -1;
3277 /* Find last previous instruction and remember it */
3278 for (pc = start_pc-1; pc; pc--)
3279 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3280 break;
3281 insn_pc = pc;
3283 /* Retrieve the instruction, handle `wide'. */
3284 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3285 if (opcode == OPCODE_wide)
3287 wide_found = 1;
3288 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3291 switch (opcode)
3293 case OPCODE_astore_0:
3294 case OPCODE_astore_1:
3295 case OPCODE_astore_2:
3296 case OPCODE_astore_3:
3297 first = OPCODE_astore_0;
3298 break;
3300 case OPCODE_istore_0:
3301 case OPCODE_istore_1:
3302 case OPCODE_istore_2:
3303 case OPCODE_istore_3:
3304 first = OPCODE_istore_0;
3305 break;
3307 case OPCODE_lstore_0:
3308 case OPCODE_lstore_1:
3309 case OPCODE_lstore_2:
3310 case OPCODE_lstore_3:
3311 first = OPCODE_lstore_0;
3312 break;
3314 case OPCODE_fstore_0:
3315 case OPCODE_fstore_1:
3316 case OPCODE_fstore_2:
3317 case OPCODE_fstore_3:
3318 first = OPCODE_fstore_0;
3319 break;
3321 case OPCODE_dstore_0:
3322 case OPCODE_dstore_1:
3323 case OPCODE_dstore_2:
3324 case OPCODE_dstore_3:
3325 first = OPCODE_dstore_0;
3326 break;
3328 case OPCODE_astore:
3329 case OPCODE_istore:
3330 case OPCODE_lstore:
3331 case OPCODE_fstore:
3332 case OPCODE_dstore:
3333 index = peek_opcode_at_pc (jcf, code_offset, pc);
3334 if (wide_found)
3336 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3337 index = (other << 8) + index;
3339 break;
3342 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3343 means we have a <t>store. */
3344 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3345 start_pc = insn_pc;
3347 return start_pc;
3350 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3351 order, as specified by Java Language Specification.
3353 The problem is that while expand_expr will evaluate its sub-operands in
3354 left-to-right order, for variables it will just return an rtx (i.e.
3355 an lvalue) for the variable (rather than an rvalue). So it is possible
3356 that a later sub-operand will change the register, and when the
3357 actual operation is done, it will use the new value, when it should
3358 have used the original value.
3360 We fix this by using save_expr. This forces the sub-operand to be
3361 copied into a fresh virtual register,
3363 For method invocation, we modify the arguments so that a
3364 left-to-right order evaluation is performed. Saved expressions
3365 will, in CALL_EXPR order, be reused when the call will be expanded.
3368 tree
3369 force_evaluation_order (tree node)
3371 if (flag_syntax_only)
3372 return node;
3373 if (TREE_CODE (node) == CALL_EXPR
3374 || TREE_CODE (node) == NEW_CLASS_EXPR
3375 || (TREE_CODE (node) == COMPOUND_EXPR
3376 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3377 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3379 tree arg, cmp;
3381 if (!TREE_OPERAND (node, 1))
3382 return node;
3384 arg = node;
3386 /* Position arg properly, account for wrapped around ctors. */
3387 if (TREE_CODE (node) == COMPOUND_EXPR)
3388 arg = TREE_OPERAND (node, 0);
3390 arg = TREE_OPERAND (arg, 1);
3392 /* Not having a list of argument here is an error. */
3393 if (TREE_CODE (arg) != TREE_LIST)
3394 abort ();
3396 /* This reverses the evaluation order. This is a desired effect. */
3397 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3399 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3400 cmp = (cmp == NULL_TREE ? saved :
3401 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3402 TREE_VALUE (arg) = saved;
3405 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3406 TREE_SIDE_EFFECTS (cmp) = 1;
3408 if (cmp)
3410 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3411 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3412 TREE_SIDE_EFFECTS (cmp) = 1;
3413 node = cmp;
3416 return node;
3419 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
3420 method in order to emit initialization code for each test flag. */
3422 static int
3423 emit_init_test_initialization (void **entry, void *x ATTRIBUTE_UNUSED)
3425 struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
3426 tree klass = build_class_ref (ite->key);
3427 tree rhs;
3429 /* If the DECL_INITIAL of the test flag is set to true, it
3430 means that the class is already initialized the time it
3431 is in use. */
3432 if (DECL_INITIAL (ite->value) == boolean_true_node)
3433 rhs = boolean_true_node;
3434 /* Otherwise, we initialize the class init check variable by looking
3435 at the `state' field of the class to see if it is already
3436 initialized. This makes things a bit faster if the class is
3437 already initialized, which should be the common case. */
3438 else
3439 rhs = build (GE_EXPR, boolean_type_node,
3440 build (COMPONENT_REF, byte_type_node,
3441 build1 (INDIRECT_REF, class_type_node, klass),
3442 lookup_field (&class_type_node,
3443 get_identifier ("state"))),
3444 build_int_2 (JV_STATE_DONE, 0));
3446 expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
3447 ite->value, rhs));
3448 return true;
3451 #include "gt-java-expr.h"