2002-03-31 Segher Boessenkool <segher@koffie.nl>
[official-gcc.git] / gcc / java / expr.c
blob11748238fd751c37e29ee790d32d4d464413109b
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
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"
47 static void flush_quick_stack (void);
48 static void push_value (tree);
49 static tree pop_value (tree);
50 static void java_stack_swap (void);
51 static void java_stack_dup (int, int);
52 static void build_java_athrow (tree);
53 static void build_java_jsr (int, int);
54 static void build_java_ret (tree);
55 static void expand_java_multianewarray (tree, int);
56 static void expand_java_arraystore (tree);
57 static void expand_java_arrayload (tree);
58 static void expand_java_array_length (void);
59 static tree build_java_monitor (tree, tree);
60 static void expand_java_pushc (int, tree);
61 static void expand_java_return (tree);
62 static void expand_load_internal (int, tree, int);
63 static void expand_java_NEW (tree);
64 static void expand_java_INSTANCEOF (tree);
65 static void expand_java_CHECKCAST (tree);
66 static void expand_iinc (unsigned int, int, int);
67 static void expand_java_binop (tree, enum tree_code);
68 static void note_label (int, int);
69 static void expand_compare (enum tree_code, tree, tree, int);
70 static void expand_test (enum tree_code, tree, int);
71 static void expand_cond (enum tree_code, tree, int);
72 static void expand_java_goto (int);
73 #if 0
74 static void expand_java_call (int, int);
75 static void expand_java_ret (tree);
76 #endif
77 static tree pop_arguments (tree);
78 static void expand_invoke (int, int, int);
79 static void expand_java_field_op (int, int, int);
80 static void java_push_constant_from_pool (struct JCF *, int);
81 static void java_stack_pop (int);
82 static tree build_java_throw_out_of_bounds_exception (tree);
83 static tree build_java_check_indexed_type (tree, tree);
84 static tree case_identity (tree, tree);
85 static unsigned char peek_opcode_at_pc (struct JCF *, int, int);
86 static int emit_init_test_initialization (void **entry, void * ptr);
87 static int get_offset_table_index (tree);
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 parellel. 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 case FFS_EXPR:
179 /* These don't change whether an object is nonzero or zero. */
180 return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
182 case COND_EXPR:
183 /* Distribute the conversion into the arms of a COND_EXPR. */
184 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
185 java_truthvalue_conversion (TREE_OPERAND (expr, 1)),
186 java_truthvalue_conversion (TREE_OPERAND (expr, 2))));
188 case NOP_EXPR:
189 /* If this is widening the argument, we can ignore it. */
190 if (TYPE_PRECISION (TREE_TYPE (expr))
191 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
192 return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
193 /* fall through to default */
195 default:
196 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
200 /* Save any stack slots that happen to be in the quick_stack into their
201 home virtual register slots.
203 The copy order is from low stack index to high, to support the invariant
204 that the expression for a slot may contain decls for stack slots with
205 higher (or the same) index, but not lower. */
207 static void
208 flush_quick_stack (void)
210 int stack_index = stack_pointer;
211 register tree prev, cur, next;
213 /* First reverse the quick_stack, and count the number of slots it has. */
214 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
216 next = TREE_CHAIN (cur);
217 TREE_CHAIN (cur) = prev;
218 prev = cur;
219 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
221 quick_stack = prev;
223 while (quick_stack != NULL_TREE)
225 tree decl;
226 tree node = quick_stack, type;
227 quick_stack = TREE_CHAIN (node);
228 TREE_CHAIN (node) = tree_list_free_list;
229 tree_list_free_list = node;
230 node = TREE_VALUE (node);
231 type = TREE_TYPE (node);
233 decl = find_stack_slot (stack_index, type);
234 if (decl != node)
235 expand_assignment (decl, node, 0, 0);
236 stack_index += 1 + TYPE_IS_WIDE (type);
240 /* Push TYPE on the type stack.
241 Return true on success, 0 on overflow. */
244 push_type_0 (tree type)
246 int n_words;
247 type = promote_type (type);
248 n_words = 1 + TYPE_IS_WIDE (type);
249 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
250 return 0;
251 stack_type_map[stack_pointer++] = type;
252 n_words--;
253 while (--n_words >= 0)
254 stack_type_map[stack_pointer++] = TYPE_SECOND;
255 return 1;
258 void
259 push_type (tree type)
261 if (! push_type_0 (type))
262 abort ();
265 static void
266 push_value (tree value)
268 tree type = TREE_TYPE (value);
269 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
271 type = promote_type (type);
272 value = convert (type, value);
274 push_type (type);
275 if (tree_list_free_list == NULL_TREE)
276 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
277 else
279 tree node = tree_list_free_list;
280 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
281 TREE_VALUE (node) = value;
282 TREE_CHAIN (node) = quick_stack;
283 quick_stack = node;
287 /* Pop a type from the type stack.
288 TYPE is the expected type. Return the actual type, which must be
289 convertible to TYPE.
290 On an error, *MESSAGEP is set to a freshly malloc'd error message. */
292 tree
293 pop_type_0 (tree type, char **messagep)
295 int n_words;
296 tree t;
297 *messagep = NULL;
298 if (TREE_CODE (type) == RECORD_TYPE)
299 type = promote_type (type);
300 n_words = 1 + TYPE_IS_WIDE (type);
301 if (stack_pointer < n_words)
303 *messagep = xstrdup ("stack underflow");
304 return type;
306 while (--n_words > 0)
308 if (stack_type_map[--stack_pointer] != void_type_node)
310 *messagep = xstrdup ("Invalid multi-word value on type stack");
311 return type;
314 t = stack_type_map[--stack_pointer];
315 if (type == NULL_TREE || t == type)
316 return t;
317 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
318 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
319 return t;
320 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
322 if (type == ptr_type_node || type == object_ptr_type_node)
323 return t;
324 else if (t == ptr_type_node) /* Special case for null reference. */
325 return type;
326 else if (can_widen_reference_to (t, type))
327 return t;
328 /* This is a kludge, but matches what Sun's verifier does.
329 It can be tricked, but is safe as long as type errors
330 (i.e. interface method calls) are caught at run-time. */
331 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
332 return object_ptr_type_node;
335 /* lang_printable_name uses a static buffer, so we must save the result
336 from calling it the first time. */
338 char *temp = xstrdup (lang_printable_name (type, 0));
339 *messagep = concat ("expected type '", temp,
340 "' but stack contains '", lang_printable_name (t, 0),
341 "'", NULL);
342 free (temp);
344 return type;
347 /* Pop a type from the type stack.
348 TYPE is the expected type. Return the actual type, which must be
349 convertible to TYPE, otherwise call error. */
351 tree
352 pop_type (tree type)
354 char *message = NULL;
355 type = pop_type_0 (type, &message);
356 if (message != NULL)
358 error ("%s", message);
359 free (message);
361 return type;
364 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
365 Handles array types and interfaces. */
368 can_widen_reference_to (tree source_type, tree target_type)
370 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
371 return 1;
373 /* Get rid of pointers */
374 if (TREE_CODE (source_type) == POINTER_TYPE)
375 source_type = TREE_TYPE (source_type);
376 if (TREE_CODE (target_type) == POINTER_TYPE)
377 target_type = TREE_TYPE (target_type);
379 if (source_type == target_type)
380 return 1;
381 else
383 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
385 HOST_WIDE_INT source_length, target_length;
386 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
388 /* An array implements Cloneable and Serializable. */
389 tree name = DECL_NAME (TYPE_NAME (target_type));
390 return (name == java_lang_cloneable_identifier_node
391 || name == java_io_serializable_identifier_node);
393 target_length = java_array_type_length (target_type);
394 if (target_length >= 0)
396 source_length = java_array_type_length (source_type);
397 if (source_length != target_length)
398 return 0;
400 source_type = TYPE_ARRAY_ELEMENT (source_type);
401 target_type = TYPE_ARRAY_ELEMENT (target_type);
402 if (source_type == target_type)
403 return 1;
404 if (TREE_CODE (source_type) != POINTER_TYPE
405 || TREE_CODE (target_type) != POINTER_TYPE)
406 return 0;
407 return can_widen_reference_to (source_type, target_type);
409 else
411 int source_depth = class_depth (source_type);
412 int target_depth = class_depth (target_type);
414 /* class_depth can return a negative depth if an error occurred */
415 if (source_depth < 0 || target_depth < 0)
416 return 0;
418 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
420 /* target_type is OK if source_type or source_type ancestors
421 implement target_type. We handle multiple sub-interfaces */
423 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
424 int n = TREE_VEC_LENGTH (basetype_vec), i;
425 for (i=0 ; i < n; i++)
426 if (can_widen_reference_to
427 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
428 target_type))
429 return 1;
430 if (n == 0)
431 return 0;
434 for ( ; source_depth > target_depth; source_depth--)
436 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
438 return source_type == target_type;
443 static tree
444 pop_value (tree type)
446 type = pop_type (type);
447 if (quick_stack)
449 tree node = quick_stack;
450 quick_stack = TREE_CHAIN (quick_stack);
451 TREE_CHAIN (node) = tree_list_free_list;
452 tree_list_free_list = node;
453 node = TREE_VALUE (node);
454 return node;
456 else
457 return find_stack_slot (stack_pointer, promote_type (type));
461 /* Pop and discrad the top COUNT stack slots. */
463 static void
464 java_stack_pop (int count)
466 while (count > 0)
468 tree type, val;
470 if (stack_pointer == 0)
471 abort ();
473 type = stack_type_map[stack_pointer - 1];
474 if (type == TYPE_SECOND)
476 count--;
477 if (stack_pointer == 1 || count <= 0)
478 abort ();
480 type = stack_type_map[stack_pointer - 2];
482 val = pop_value (type);
483 count--;
487 /* Implement the 'swap' operator (to swap two top stack slots). */
489 static void
490 java_stack_swap (void)
492 tree type1, type2;
493 rtx temp;
494 tree decl1, decl2;
496 if (stack_pointer < 2
497 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
498 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
499 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
500 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
501 /* Bad stack swap. */
502 abort ();
504 flush_quick_stack ();
505 decl1 = find_stack_slot (stack_pointer - 1, type1);
506 decl2 = find_stack_slot (stack_pointer - 2, type2);
507 temp = copy_to_reg (DECL_RTL (decl1));
508 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
509 emit_move_insn (DECL_RTL (decl2), 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 tree cond;
700 expr = save_expr (expr);
701 cond = build (COND_EXPR, void_type_node,
702 build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
703 build (CALL_EXPR, void_type_node,
704 build_address_of (soft_nullpointer_node),
705 NULL_TREE, NULL_TREE),
706 empty_stmt_node);
707 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
710 return expr;
713 /* Reference an object: just like an INDIRECT_REF, but with checking. */
715 tree
716 build_java_indirect_ref (tree type, tree expr, int check)
718 return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
721 /* Implement array indexing (either as l-value or r-value).
722 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
723 Optionally performs bounds checking and/or test to NULL.
724 At this point, ARRAY should have been verified as an array. */
726 tree
727 build_java_arrayaccess (tree array, tree type, tree index)
729 tree node, throw = NULL_TREE;
730 tree data_field;
731 tree ref;
732 tree array_type = TREE_TYPE (TREE_TYPE (array));
734 if (flag_bounds_check)
736 /* Generate:
737 * (unsigned jint) INDEX >= (unsigned jint) LEN
738 * && throw ArrayIndexOutOfBoundsException.
739 * Note this is equivalent to and more efficient than:
740 * INDEX < 0 || INDEX >= LEN && throw ... */
741 tree test;
742 tree len = build_java_array_length_access (array);
743 TREE_TYPE (len) = unsigned_int_type_node;
744 test = fold (build (GE_EXPR, boolean_type_node,
745 convert (unsigned_int_type_node, index),
746 len));
747 if (! integer_zerop (test))
749 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
750 build_java_throw_out_of_bounds_exception (index));
751 /* allows expansion within COMPOUND */
752 TREE_SIDE_EFFECTS( throw ) = 1;
756 /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
757 to have the bounds check evaluated first. */
758 if (throw != NULL_TREE)
759 index = build (COMPOUND_EXPR, int_type_node, throw, index);
761 data_field = lookup_field (&array_type, get_identifier ("data"));
763 ref = build (COMPONENT_REF, TREE_TYPE (data_field),
764 build_java_indirect_ref (array_type, array,
765 flag_check_references),
766 data_field);
768 node = build (ARRAY_REF, type, ref, index);
769 return node;
772 /* Generate code to throw an ArrayStoreException if OBJECT is not assignable
773 (at runtime) to an element of ARRAY. A NOP_EXPR is returned if it can
774 determine that no check is required. */
776 tree
777 build_java_arraystore_check (tree array, tree object)
779 tree check, element_type, source;
780 tree array_type_p = TREE_TYPE (array);
781 tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));
783 if (! is_array_type_p (array_type_p))
784 abort ();
786 /* Get the TYPE_DECL for ARRAY's element type. */
787 element_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
789 if (TREE_CODE (element_type) != TYPE_DECL
790 || TREE_CODE (object_type) != TYPE_DECL)
791 abort ();
793 if (!flag_store_check)
794 return build1 (NOP_EXPR, array_type_p, array);
796 /* No check is needed if the element type is final or is itself an array.
797 Also check that element_type matches object_type, since in the bytecode
798 compilation case element_type may be the actual element type of the array
799 rather than its declared type. */
800 if (element_type == object_type
801 && (TYPE_ARRAY_P (TREE_TYPE (element_type))
802 || CLASS_FINAL (element_type)))
803 return build1 (NOP_EXPR, array_type_p, array);
805 /* OBJECT might be wrapped by a SAVE_EXPR. */
806 if (TREE_CODE (object) == SAVE_EXPR)
807 source = TREE_OPERAND (object, 0);
808 else
809 source = object;
811 /* Avoid the check if OBJECT was just loaded from the same array. */
812 if (TREE_CODE (source) == ARRAY_REF)
814 tree target;
815 source = TREE_OPERAND (source, 0); /* COMPONENT_REF. */
816 source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
817 source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
818 if (TREE_CODE (source) == SAVE_EXPR)
819 source = TREE_OPERAND (source, 0);
821 target = array;
822 if (TREE_CODE (target) == SAVE_EXPR)
823 target = TREE_OPERAND (target, 0);
825 if (source == target)
826 return build1 (NOP_EXPR, array_type_p, array);
829 /* Build an invocation of _Jv_CheckArrayStore */
830 check = build (CALL_EXPR, void_type_node,
831 build_address_of (soft_checkarraystore_node),
832 tree_cons (NULL_TREE, array,
833 build_tree_list (NULL_TREE, object)),
834 NULL_TREE);
835 TREE_SIDE_EFFECTS (check) = 1;
837 return check;
840 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
841 ARRAY_NODE. This function is used to retrieve something less vague than
842 a pointer type when indexing the first dimension of something like [[<t>.
843 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
844 return unchanged.
845 As a side effect, it also makes sure that ARRAY_NODE is an array. */
847 static tree
848 build_java_check_indexed_type (tree array_node, tree indexed_type)
850 tree elt_type;
852 if (!is_array_type_p (TREE_TYPE (array_node)))
853 abort ();
855 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
857 if (indexed_type == ptr_type_node )
858 return promote_type (elt_type);
860 /* BYTE/BOOLEAN store and load are used for both type */
861 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
862 return boolean_type_node;
864 if (indexed_type != elt_type )
865 abort ();
866 else
867 return indexed_type;
870 /* newarray triggers a call to _Jv_NewPrimArray. This function should be
871 called with an integer code (the type of array to create), and the length
872 of the array to create. */
874 tree
875 build_newarray (int atype_value, tree length)
877 tree type_arg;
879 tree prim_type = decode_newarray_type (atype_value);
880 tree type
881 = build_java_array_type (prim_type,
882 host_integerp (length, 0) == INTEGER_CST
883 ? tree_low_cst (length, 0) : -1);
885 /* If compiling to native, pass a reference to the primitive type class
886 and save the runtime some work. However, the bytecode generator
887 expects to find the type_code int here. */
888 if (flag_emit_class_files)
889 type_arg = build_int_2 (atype_value, 0);
890 else
891 type_arg = build_class_ref (prim_type);
893 return build (CALL_EXPR, promote_type (type),
894 build_address_of (soft_newarray_node),
895 tree_cons (NULL_TREE,
896 type_arg,
897 build_tree_list (NULL_TREE, length)),
898 NULL_TREE);
901 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
902 of the dimension. */
904 tree
905 build_anewarray (tree class_type, tree length)
907 tree type
908 = build_java_array_type (class_type,
909 host_integerp (length, 0)
910 ? tree_low_cst (length, 0) : -1);
912 return build (CALL_EXPR, promote_type (type),
913 build_address_of (soft_anewarray_node),
914 tree_cons (NULL_TREE, length,
915 tree_cons (NULL_TREE, build_class_ref (class_type),
916 build_tree_list (NULL_TREE,
917 null_pointer_node))),
918 NULL_TREE);
921 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
923 tree
924 build_new_array (tree type, tree length)
926 if (JPRIMITIVE_TYPE_P (type))
927 return build_newarray (encode_newarray_type (type), length);
928 else
929 return build_anewarray (TREE_TYPE (type), length);
932 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
933 class pointer, a number of dimensions and the matching number of
934 dimensions. The argument list is NULL terminated. */
936 static void
937 expand_java_multianewarray (tree class_type, int ndim)
939 int i;
940 tree args = build_tree_list( NULL_TREE, null_pointer_node );
942 for( i = 0; i < ndim; i++ )
943 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
945 push_value (build (CALL_EXPR,
946 promote_type (class_type),
947 build_address_of (soft_multianewarray_node),
948 tree_cons (NULL_TREE, build_class_ref (class_type),
949 tree_cons (NULL_TREE,
950 build_int_2 (ndim, 0), args )),
951 NULL_TREE));
954 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
955 ARRAY is an array type. May expand some bound checking and NULL
956 pointer checking. RHS_TYPE_NODE we are going to store. In the case
957 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
958 INT. In those cases, we make the conversion.
960 if ARRAy is a reference type, the assignment is checked at run-time
961 to make sure that the RHS can be assigned to the array element
962 type. It is not necessary to generate this code if ARRAY is final. */
964 static void
965 expand_java_arraystore (tree rhs_type_node)
967 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
968 && TYPE_PRECISION (rhs_type_node) <= 32) ?
969 int_type_node : rhs_type_node);
970 tree index = pop_value (int_type_node);
971 tree array = pop_value (ptr_type_node);
973 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
975 flush_quick_stack ();
977 index = save_expr (index);
978 array = save_expr (array);
980 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
982 tree check = build_java_arraystore_check (array, rhs_node);
983 expand_expr_stmt (check);
986 expand_assignment (build_java_arrayaccess (array,
987 rhs_type_node,
988 index),
989 rhs_node, 0, 0);
992 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
993 sure that LHS is an array type. May expand some bound checking and NULL
994 pointer checking.
995 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
996 BOOLEAN/SHORT, we push a promoted type back to the stack.
999 static void
1000 expand_java_arrayload (tree lhs_type_node )
1002 tree load_node;
1003 tree index_node = pop_value (int_type_node);
1004 tree array_node = pop_value (ptr_type_node);
1006 index_node = save_expr (index_node);
1007 array_node = save_expr (array_node);
1009 if (TREE_TYPE (array_node) == ptr_type_node)
1010 /* The only way we could get a node of type ptr_type_node at this
1011 point is `aconst_null; arraylength' or something equivalent, so
1012 unconditionally throw NullPointerException. */
1013 load_node = build (CALL_EXPR, lhs_type_node,
1014 build_address_of (soft_nullpointer_node),
1015 NULL_TREE, NULL_TREE);
1016 else
1018 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
1019 load_node = build_java_arrayaccess (array_node,
1020 lhs_type_node,
1021 index_node);
1023 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1024 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
1025 push_value (load_node);
1028 /* Expands .length. Makes sure that we deal with and array and may expand
1029 a NULL check on the array object. */
1031 static void
1032 expand_java_array_length (void)
1034 tree array = pop_value (ptr_type_node);
1035 tree length = build_java_array_length_access (array);
1037 push_value (length);
1040 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1041 either soft_monitorenter_node or soft_monitorexit_node. */
1043 static tree
1044 build_java_monitor (tree call, tree object)
1046 return (build (CALL_EXPR,
1047 void_type_node,
1048 build_address_of (call),
1049 build_tree_list (NULL_TREE, object),
1050 NULL_TREE));
1053 /* Emit code for one of the PUSHC instructions. */
1055 static void
1056 expand_java_pushc (int ival, tree type)
1058 tree value;
1059 if (type == ptr_type_node && ival == 0)
1060 value = null_pointer_node;
1061 else if (type == int_type_node || type == long_type_node)
1063 value = build_int_2 (ival, ival < 0 ? -1 : 0);
1064 TREE_TYPE (value) = type;
1066 else if (type == float_type_node || type == double_type_node)
1068 REAL_VALUE_TYPE x;
1069 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1070 value = build_real (type, x);
1072 else
1073 abort ();
1075 push_value (value);
1078 static void
1079 expand_java_return (tree type)
1081 if (type == void_type_node)
1082 expand_null_return ();
1083 else
1085 tree retval = pop_value (type);
1086 tree res = DECL_RESULT (current_function_decl);
1087 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1089 /* Handle the situation where the native integer type is smaller
1090 than the JVM integer. It can happen for many cross compilers.
1091 The whole if expression just goes away if INT_TYPE_SIZE < 32
1092 is false. */
1093 if (INT_TYPE_SIZE < 32
1094 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1095 < GET_MODE_SIZE (TYPE_MODE (type))))
1096 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1098 TREE_SIDE_EFFECTS (retval) = 1;
1099 expand_return (retval);
1103 static void
1104 expand_load_internal (int index, tree type, int pc)
1106 tree copy;
1107 tree var = find_local_variable (index, type, pc);
1109 /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1110 on the stack. If there is an assignment to this VAR_DECL between
1111 the stack push and the use, then the wrong code could be
1112 generated. To avoid this we create a new local and copy our
1113 value into it. Then we push this new local on the stack.
1114 Hopefully this all gets optimized out. */
1115 copy = build_decl (VAR_DECL, NULL_TREE, type);
1116 DECL_CONTEXT (copy) = current_function_decl;
1117 layout_decl (copy, 0);
1118 DECL_REGISTER (copy) = 1;
1119 expand_decl (copy);
1120 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
1121 DECL_INITIAL (copy) = var;
1122 expand_decl_init (copy);
1123 push_value (copy);
1126 tree
1127 build_address_of (tree value)
1129 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1132 bool class_has_finalize_method (tree type)
1134 tree super = CLASSTYPE_SUPER (type);
1136 if (super == NULL_TREE)
1137 return false; /* Every class with a real finalizer inherits */
1138 /* from java.lang.Object. */
1139 else
1140 return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1143 static void
1144 expand_java_NEW (tree type)
1146 tree alloc_node;
1148 alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1149 : alloc_no_finalizer_node);
1150 if (! CLASS_LOADED_P (type))
1151 load_class (type, 1);
1152 safe_layout_class (type);
1153 push_value (build (CALL_EXPR, promote_type (type),
1154 build_address_of (alloc_node),
1155 tree_cons (NULL_TREE, build_class_ref (type),
1156 build_tree_list (NULL_TREE,
1157 size_in_bytes (type))),
1158 NULL_TREE));
1161 /* This returns an expression which will extract the class of an
1162 object. */
1164 tree
1165 build_get_class (tree value)
1167 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1168 tree vtable_field = lookup_field (&object_type_node,
1169 get_identifier ("vtable"));
1170 return build (COMPONENT_REF, class_ptr_type,
1171 build1 (INDIRECT_REF, dtable_type,
1172 build (COMPONENT_REF, dtable_ptr_type,
1173 build_java_indirect_ref (object_type_node, value,
1174 flag_check_references),
1175 vtable_field)),
1176 class_field);
1179 /* This builds the tree representation of the `instanceof' operator.
1180 It tries various tricks to optimize this in cases where types are
1181 known. */
1183 tree
1184 build_instanceof (tree value, tree type)
1186 tree expr;
1187 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1188 tree valtype = TREE_TYPE (TREE_TYPE (value));
1189 tree valclass = TYPE_NAME (valtype);
1190 tree klass;
1192 /* When compiling from bytecode, we need to ensure that TYPE has
1193 been loaded. */
1194 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1196 load_class (type, 1);
1197 safe_layout_class (type);
1198 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1199 return error_mark_node;
1201 klass = TYPE_NAME (type);
1203 if (type == object_type_node || inherits_from_p (valtype, type))
1205 /* Anything except `null' is an instance of Object. Likewise,
1206 if the object is known to be an instance of the class, then
1207 we only need to check for `null'. */
1208 expr = build (NE_EXPR, itype, value, null_pointer_node);
1210 else if (! TYPE_ARRAY_P (type)
1211 && ! TYPE_ARRAY_P (valtype)
1212 && DECL_P (klass) && DECL_P (valclass)
1213 && ! CLASS_INTERFACE (valclass)
1214 && ! CLASS_INTERFACE (klass)
1215 && ! inherits_from_p (type, valtype)
1216 && (CLASS_FINAL (klass)
1217 || ! inherits_from_p (valtype, type)))
1219 /* The classes are from different branches of the derivation
1220 tree, so we immediately know the answer. */
1221 expr = boolean_false_node;
1223 else if (DECL_P (klass) && CLASS_FINAL (klass))
1225 tree save = save_expr (value);
1226 expr = build (COND_EXPR, itype,
1227 save,
1228 build (EQ_EXPR, itype,
1229 build_get_class (save),
1230 build_class_ref (type)),
1231 boolean_false_node);
1233 else
1235 expr = build (CALL_EXPR, itype,
1236 build_address_of (soft_instanceof_node),
1237 tree_cons (NULL_TREE, value,
1238 build_tree_list (NULL_TREE,
1239 build_class_ref (type))),
1240 NULL_TREE);
1242 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1243 return expr;
1246 static void
1247 expand_java_INSTANCEOF (tree type)
1249 tree value = pop_value (object_ptr_type_node);
1250 value = build_instanceof (value, type);
1251 push_value (value);
1254 static void
1255 expand_java_CHECKCAST (tree type)
1257 tree value = pop_value (ptr_type_node);
1258 value = build (CALL_EXPR, promote_type (type),
1259 build_address_of (soft_checkcast_node),
1260 tree_cons (NULL_TREE, build_class_ref (type),
1261 build_tree_list (NULL_TREE, value)),
1262 NULL_TREE);
1263 push_value (value);
1266 static void
1267 expand_iinc (unsigned int local_var_index, int ival, int pc)
1269 tree local_var, res;
1270 tree constant_value;
1272 flush_quick_stack ();
1273 local_var = find_local_variable (local_var_index, int_type_node, pc);
1274 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1275 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1276 expand_assignment (local_var, res, 0, 0);
1280 tree
1281 build_java_soft_divmod (enum tree_code op, tree type, tree op1, tree op2)
1283 tree call = NULL;
1284 tree arg1 = convert (type, op1);
1285 tree arg2 = convert (type, op2);
1287 if (type == int_type_node)
1289 switch (op)
1291 case TRUNC_DIV_EXPR:
1292 call = soft_idiv_node;
1293 break;
1294 case TRUNC_MOD_EXPR:
1295 call = soft_irem_node;
1296 break;
1297 default:
1298 break;
1301 else if (type == long_type_node)
1303 switch (op)
1305 case TRUNC_DIV_EXPR:
1306 call = soft_ldiv_node;
1307 break;
1308 case TRUNC_MOD_EXPR:
1309 call = soft_lrem_node;
1310 break;
1311 default:
1312 break;
1316 if (! call)
1317 abort ();
1319 call = build (CALL_EXPR, type,
1320 build_address_of (call),
1321 tree_cons (NULL_TREE, arg1,
1322 build_tree_list (NULL_TREE, arg2)),
1323 NULL_TREE);
1325 return call;
1328 tree
1329 build_java_binop (enum tree_code op, tree type, tree arg1, tree arg2)
1331 tree mask;
1332 switch (op)
1334 case URSHIFT_EXPR:
1336 tree u_type = java_unsigned_type (type);
1337 arg1 = convert (u_type, arg1);
1338 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1339 return convert (type, arg1);
1341 case LSHIFT_EXPR:
1342 case RSHIFT_EXPR:
1343 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1344 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1345 break;
1347 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1348 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1349 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1351 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1352 boolean_type_node, arg1, arg2));
1353 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1354 tree second_compare = fold (build (COND_EXPR, int_type_node,
1355 ifexp2, integer_zero_node,
1356 op == COMPARE_L_EXPR
1357 ? integer_minus_one_node
1358 : integer_one_node));
1359 return fold (build (COND_EXPR, int_type_node, ifexp1,
1360 op == COMPARE_L_EXPR ? integer_one_node
1361 : integer_minus_one_node,
1362 second_compare));
1364 case COMPARE_EXPR:
1365 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1367 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1368 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1369 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1370 ifexp2, integer_one_node,
1371 integer_zero_node));
1372 return fold (build (COND_EXPR, int_type_node,
1373 ifexp1, integer_minus_one_node, second_compare));
1375 case TRUNC_DIV_EXPR:
1376 case TRUNC_MOD_EXPR:
1377 if (TREE_CODE (type) == REAL_TYPE
1378 && op == TRUNC_MOD_EXPR)
1380 tree call;
1381 if (type != double_type_node)
1383 arg1 = convert (double_type_node, arg1);
1384 arg2 = convert (double_type_node, arg2);
1386 call = build (CALL_EXPR, double_type_node,
1387 build_address_of (soft_fmod_node),
1388 tree_cons (NULL_TREE, arg1,
1389 build_tree_list (NULL_TREE, arg2)),
1390 NULL_TREE);
1391 if (type != double_type_node)
1392 call = convert (type, call);
1393 return call;
1396 if (TREE_CODE (type) == INTEGER_TYPE
1397 && flag_use_divide_subroutine
1398 && ! flag_syntax_only)
1399 return build_java_soft_divmod (op, type, arg1, arg2);
1401 break;
1402 default: ;
1404 return fold (build (op, type, arg1, arg2));
1407 static void
1408 expand_java_binop (tree type, enum tree_code op)
1410 tree larg, rarg;
1411 tree ltype = type;
1412 tree rtype = type;
1413 switch (op)
1415 case LSHIFT_EXPR:
1416 case RSHIFT_EXPR:
1417 case URSHIFT_EXPR:
1418 rtype = int_type_node;
1419 rarg = pop_value (rtype);
1420 break;
1421 default:
1422 rarg = pop_value (rtype);
1424 larg = pop_value (ltype);
1425 push_value (build_java_binop (op, type, larg, rarg));
1428 /* Lookup the field named NAME in *TYPEP or its super classes.
1429 If not found, return NULL_TREE.
1430 (If the *TYPEP is not found, or if the field reference is
1431 ambiguous, return error_mark_node.)
1432 If found, return the FIELD_DECL, and set *TYPEP to the
1433 class containing the field. */
1435 tree
1436 lookup_field (tree *typep, tree name)
1438 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1440 load_class (*typep, 1);
1441 safe_layout_class (*typep);
1442 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1443 return error_mark_node;
1447 tree field, basetype_vec;
1448 tree save_field;
1449 int n, i;
1451 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1452 if (DECL_NAME (field) == name)
1453 return field;
1455 /* Process implemented interfaces. */
1456 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1457 n = TREE_VEC_LENGTH (basetype_vec);
1458 save_field = NULL_TREE;
1459 for (i = 0; i < n; i++)
1461 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1462 if ((field = lookup_field (&t, name)))
1464 if (save_field == field)
1465 continue;
1466 if (save_field == NULL_TREE)
1467 save_field = field;
1468 else
1470 tree i1 = DECL_CONTEXT (save_field);
1471 tree i2 = DECL_CONTEXT (field);
1472 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1473 IDENTIFIER_POINTER (name),
1474 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1475 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1476 return error_mark_node;
1481 if (save_field != NULL_TREE)
1482 return save_field;
1484 *typep = CLASSTYPE_SUPER (*typep);
1485 } while (*typep);
1486 return NULL_TREE;
1489 /* Look up the field named NAME in object SELF_VALUE,
1490 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1491 SELF_VALUE is NULL_TREE if looking for a static field. */
1493 tree
1494 build_field_ref (tree self_value, tree self_class, tree name)
1496 tree base_class = self_class;
1497 tree field_decl = lookup_field (&base_class, name);
1498 if (field_decl == NULL_TREE)
1500 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1501 return error_mark_node;
1503 if (self_value == NULL_TREE)
1505 return build_static_field_ref (field_decl);
1507 else
1509 int check = (flag_check_references
1510 && ! (DECL_P (self_value)
1511 && DECL_NAME (self_value) == this_identifier_node));
1513 tree base_type = promote_type (base_class);
1514 if (base_type != TREE_TYPE (self_value))
1515 self_value = fold (build1 (NOP_EXPR, base_type, self_value));
1516 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1517 self_value, check);
1518 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1519 self_value, field_decl));
1523 tree
1524 lookup_label (int pc)
1526 tree name;
1527 char buf[32];
1528 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1529 name = get_identifier (buf);
1530 if (IDENTIFIER_LOCAL_VALUE (name))
1531 return IDENTIFIER_LOCAL_VALUE (name);
1532 else
1534 /* The type of the address of a label is return_address_type_node. */
1535 tree decl = create_label_decl (name);
1536 LABEL_PC (decl) = pc;
1537 label_rtx (decl);
1538 return pushdecl (decl);
1542 /* Generate a unique name for the purpose of loops and switches
1543 labels, and try-catch-finally blocks label or temporary variables. */
1545 tree
1546 generate_name (void)
1548 static int l_number = 0;
1549 char buff [32];
1550 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1551 l_number++;
1552 return get_identifier (buff);
1555 tree
1556 create_label_decl (tree name)
1558 tree decl;
1559 decl = build_decl (LABEL_DECL, name,
1560 TREE_TYPE (return_address_type_node));
1561 DECL_CONTEXT (decl) = current_function_decl;
1562 DECL_IGNORED_P (decl) = 1;
1563 return decl;
1566 /* This maps a bytecode offset (PC) to various flags. */
1567 char *instruction_bits;
1569 static void
1570 note_label (int current_pc ATTRIBUTE_UNUSED, int target_pc)
1572 lookup_label (target_pc);
1573 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1576 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1577 where CONDITION is one of one the compare operators. */
1579 static void
1580 expand_compare (enum tree_code condition, tree value1, tree value2,
1581 int target_pc)
1583 tree target = lookup_label (target_pc);
1584 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1585 expand_start_cond (java_truthvalue_conversion (cond), 0);
1586 expand_goto (target);
1587 expand_end_cond ();
1590 /* Emit code for a TEST-type opcode. */
1592 static void
1593 expand_test (enum tree_code condition, tree type, int target_pc)
1595 tree value1, value2;
1596 flush_quick_stack ();
1597 value1 = pop_value (type);
1598 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1599 expand_compare (condition, value1, value2, target_pc);
1602 /* Emit code for a COND-type opcode. */
1604 static void
1605 expand_cond (enum tree_code condition, tree type, int target_pc)
1607 tree value1, value2;
1608 flush_quick_stack ();
1609 /* note: pop values in opposite order */
1610 value2 = pop_value (type);
1611 value1 = pop_value (type);
1612 /* Maybe should check value1 and value2 for type compatibility ??? */
1613 expand_compare (condition, value1, value2, target_pc);
1616 static void
1617 expand_java_goto (int target_pc)
1619 tree target_label = lookup_label (target_pc);
1620 flush_quick_stack ();
1621 expand_goto (target_label);
1624 #if 0
1625 static void
1626 expand_java_call (int target_pc, int return_address)
1627 int target_pc, return_address;
1629 tree target_label = lookup_label (target_pc);
1630 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1631 push_value (value);
1632 flush_quick_stack ();
1633 expand_goto (target_label);
1636 static void
1637 expand_java_ret (tree return_address ATTRIBUTE_UNUSED)
1639 warning ("ret instruction not implemented");
1640 #if 0
1641 tree target_label = lookup_label (target_pc);
1642 flush_quick_stack ();
1643 expand_goto (target_label);
1644 #endif
1646 #endif
1648 static tree
1649 pop_arguments (tree arg_types)
1651 if (arg_types == end_params_node)
1652 return NULL_TREE;
1653 if (TREE_CODE (arg_types) == TREE_LIST)
1655 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1656 tree type = TREE_VALUE (arg_types);
1657 tree arg = pop_value (type);
1658 if (PROMOTE_PROTOTYPES
1659 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1660 && INTEGRAL_TYPE_P (type))
1661 arg = convert (integer_type_node, arg);
1662 return tree_cons (NULL_TREE, arg, tail);
1664 abort ();
1667 /* Build an expression to initialize the class CLAS.
1668 if EXPR is non-NULL, returns an expression to first call the initializer
1669 (if it is needed) and then calls EXPR. */
1671 tree
1672 build_class_init (tree clas, tree expr)
1674 tree init;
1676 /* An optimization: if CLAS is a superclass of the class we're
1677 compiling, we don't need to initialize it. However, if CLAS is
1678 an interface, it won't necessarily be initialized, even if we
1679 implement it. */
1680 if ((! CLASS_INTERFACE (TYPE_NAME (clas))
1681 && inherits_from_p (current_class, clas))
1682 || current_class == clas)
1683 return expr;
1685 if (always_initialize_class_p)
1687 init = build (CALL_EXPR, void_type_node,
1688 build_address_of (soft_initclass_node),
1689 build_tree_list (NULL_TREE, build_class_ref (clas)),
1690 NULL_TREE);
1691 TREE_SIDE_EFFECTS (init) = 1;
1693 else
1695 tree *init_test_decl;
1696 init_test_decl = java_treetreehash_new
1697 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);
1699 if (*init_test_decl == NULL)
1701 /* Build a declaration and mark it as a flag used to track
1702 static class initializations. */
1703 *init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1704 boolean_type_node);
1705 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (*init_test_decl);
1706 LOCAL_CLASS_INITIALIZATION_FLAG (*init_test_decl) = 1;
1707 DECL_CONTEXT (*init_test_decl) = current_function_decl;
1708 DECL_FUNCTION_INIT_TEST_CLASS (*init_test_decl) = clas;
1709 /* Tell the check-init code to ignore this decl when not
1710 optimizing class initialization. */
1711 if (!STATIC_CLASS_INIT_OPT_P ())
1712 DECL_BIT_INDEX(*init_test_decl) = -1;
1715 init = build (CALL_EXPR, void_type_node,
1716 build_address_of (soft_initclass_node),
1717 build_tree_list (NULL_TREE, build_class_ref (clas)),
1718 NULL_TREE);
1719 TREE_SIDE_EFFECTS (init) = 1;
1720 init = build (COND_EXPR, void_type_node,
1721 build (EQ_EXPR, boolean_type_node,
1722 *init_test_decl, boolean_false_node),
1723 init, integer_zero_node);
1724 TREE_SIDE_EFFECTS (init) = 1;
1725 init = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1726 build (MODIFY_EXPR, boolean_type_node,
1727 *init_test_decl, boolean_true_node));
1728 TREE_SIDE_EFFECTS (init) = 1;
1731 if (expr != NULL_TREE)
1733 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1734 TREE_SIDE_EFFECTS (expr) = 1;
1735 return expr;
1737 return init;
1740 tree
1741 build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
1742 tree self_type, tree method_signature ATTRIBUTE_UNUSED,
1743 tree arg_list ATTRIBUTE_UNUSED)
1745 tree func;
1746 if (is_compiled_class (self_type))
1748 make_decl_rtl (method, NULL);
1749 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1751 else
1753 /* We don't know whether the method has been (statically) compiled.
1754 Compile this code to get a reference to the method's code:
1756 SELF_TYPE->methods[METHOD_INDEX].ncode
1760 int method_index = 0;
1761 tree meth, ref;
1763 /* The method might actually be declared in some superclass, so
1764 we have to use its class context, not the caller's notion of
1765 where the method is. */
1766 self_type = DECL_CONTEXT (method);
1767 ref = build_class_ref (self_type);
1768 ref = build1 (INDIRECT_REF, class_type_node, ref);
1769 if (ncode_ident == NULL_TREE)
1770 ncode_ident = get_identifier ("ncode");
1771 if (methods_ident == NULL_TREE)
1772 methods_ident = get_identifier ("methods");
1773 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1774 lookup_field (&class_type_node, methods_ident));
1775 for (meth = TYPE_METHODS (self_type);
1776 ; meth = TREE_CHAIN (meth))
1778 if (method == meth)
1779 break;
1780 if (meth == NULL_TREE)
1781 fatal_error ("method '%s' not found in class",
1782 IDENTIFIER_POINTER (DECL_NAME (method)));
1783 method_index++;
1785 method_index *= int_size_in_bytes (method_type_node);
1786 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1787 ref, build_int_2 (method_index, 0)));
1788 ref = build1 (INDIRECT_REF, method_type_node, ref);
1789 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1790 ref,
1791 lookup_field (&method_type_node, ncode_ident));
1793 return func;
1796 tree
1797 invoke_build_dtable (int is_invoke_interface, tree arg_list)
1799 tree dtable, objectref;
1801 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1803 /* If we're dealing with interfaces and if the objectref
1804 argument is an array then get the dispatch table of the class
1805 Object rather than the one from the objectref. */
1806 objectref = (is_invoke_interface
1807 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1808 object_type_node : TREE_VALUE (arg_list));
1810 if (dtable_ident == NULL_TREE)
1811 dtable_ident = get_identifier ("vtable");
1812 dtable = build_java_indirect_ref (object_type_node, objectref,
1813 flag_check_references);
1814 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1815 lookup_field (&object_type_node, dtable_ident));
1817 return dtable;
1820 /* Determine the index in the virtual offset table (otable) for a call to
1821 METHOD. If this method has not been seen before, it will be added to the
1822 otable_methods. If it has, the existing otable slot will be reused. */
1825 get_offset_table_index (tree method)
1827 int i = 1;
1828 tree method_list;
1830 if (otable_methods == NULL_TREE)
1832 otable_methods = build_tree_list (method, method);
1833 return 1;
1836 method_list = otable_methods;
1838 while (1)
1840 if (TREE_VALUE (method_list) == method)
1841 return i;
1842 i++;
1843 if (TREE_CHAIN (method_list) == NULL_TREE)
1844 break;
1845 else
1846 method_list = TREE_CHAIN (method_list);
1849 TREE_CHAIN (method_list) = build_tree_list (method, method);
1850 return i;
1853 tree
1854 build_invokevirtual (tree dtable, tree method)
1856 tree func;
1857 tree nativecode_ptr_ptr_type_node
1858 = build_pointer_type (nativecode_ptr_type_node);
1859 tree method_index;
1860 tree otable_index;
1862 if (flag_indirect_dispatch)
1864 otable_index = build_int_2 (get_offset_table_index (method), 0);
1865 method_index = build (ARRAY_REF, integer_type_node, otable_decl,
1866 otable_index);
1868 else
1870 method_index = convert (sizetype, DECL_VINDEX (method));
1872 if (TARGET_VTABLE_USES_DESCRIPTORS)
1873 /* Add one to skip bogus descriptor for class and GC descriptor. */
1874 method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
1875 else
1876 /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
1877 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1879 method_index = size_binop (MULT_EXPR, method_index,
1880 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1882 if (TARGET_VTABLE_USES_DESCRIPTORS)
1883 method_index = size_binop (MULT_EXPR, method_index,
1884 size_int (TARGET_VTABLE_USES_DESCRIPTORS));
1887 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1888 convert (nativecode_ptr_ptr_type_node, method_index)));
1890 if (TARGET_VTABLE_USES_DESCRIPTORS)
1891 func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
1892 else
1893 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1895 return func;
1898 static GTY(()) tree class_ident;
1899 tree
1900 build_invokeinterface (tree dtable, tree method)
1902 tree lookup_arg;
1903 tree interface;
1904 tree idx;
1905 tree meth;
1906 tree otable_index;
1907 int i;
1909 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1910 ensure that the selected method exists, is public and not
1911 abstract nor static. */
1913 if (class_ident == NULL_TREE)
1914 class_ident = get_identifier ("class");
1916 dtable = build_java_indirect_ref (dtable_type, dtable,
1917 flag_check_references);
1918 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1919 lookup_field (&dtable_type, class_ident));
1921 interface = DECL_CONTEXT (method);
1922 if (! CLASS_INTERFACE (TYPE_NAME (interface)))
1923 abort ();
1924 layout_class_methods (interface);
1926 if (flag_indirect_dispatch)
1928 otable_index = build_int_2 (get_offset_table_index (method), 0);
1929 idx = build (ARRAY_REF, integer_type_node, otable_decl, otable_index);
1931 else
1933 i = 1;
1934 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1936 if (meth == method)
1938 idx = build_int_2 (i, 0);
1939 break;
1941 if (meth == NULL_TREE)
1942 abort ();
1946 lookup_arg = tree_cons (NULL_TREE, dtable,
1947 tree_cons (NULL_TREE, build_class_ref (interface),
1948 build_tree_list (NULL_TREE, idx)));
1950 return build (CALL_EXPR, ptr_type_node,
1951 build_address_of (soft_lookupinterfacemethod_node),
1952 lookup_arg, NULL_TREE);
1955 /* Expand one of the invoke_* opcodes.
1956 OCPODE is the specific opcode.
1957 METHOD_REF_INDEX is an index into the constant pool.
1958 NARGS is the number of arguments, or -1 if not specified. */
1960 static void
1961 expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
1963 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1964 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1965 tree self_type = get_class_constant
1966 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1967 const char *const self_name
1968 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1969 tree call, func, method, arg_list, method_type;
1970 tree check = NULL_TREE;
1972 if (! CLASS_LOADED_P (self_type))
1974 load_class (self_type, 1);
1975 safe_layout_class (self_type);
1976 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1977 fatal_error ("failed to find class '%s'", self_name);
1979 layout_class_methods (self_type);
1981 if (ID_INIT_P (method_name))
1982 method = lookup_java_constructor (self_type, method_signature);
1983 else
1984 method = lookup_java_method (self_type, method_name, method_signature);
1985 if (method == NULL_TREE)
1987 error ("class '%s' has no method named '%s' matching signature '%s'",
1988 self_name,
1989 IDENTIFIER_POINTER (method_name),
1990 IDENTIFIER_POINTER (method_signature));
1992 /* Invoke static can't invoke static/abstract method */
1993 else if (opcode == OPCODE_invokestatic)
1995 if (!METHOD_STATIC (method))
1997 error ("invokestatic on non static method");
1998 method = NULL_TREE;
2000 else if (METHOD_ABSTRACT (method))
2002 error ("invokestatic on abstract method");
2003 method = NULL_TREE;
2006 else
2008 if (METHOD_STATIC (method))
2010 error ("invoke[non-static] on static method");
2011 method = NULL_TREE;
2015 if (method == NULL_TREE)
2017 method_type = get_type_from_signature (method_signature);
2018 pop_arguments (TYPE_ARG_TYPES (method_type));
2019 if (opcode != OPCODE_invokestatic)
2020 pop_type (self_type);
2021 method_type = promote_type (TREE_TYPE (method_type));
2022 push_value (convert (method_type, integer_zero_node));
2023 return;
2026 method_type = TREE_TYPE (method);
2027 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2028 flush_quick_stack ();
2030 func = NULL_TREE;
2031 if (opcode == OPCODE_invokestatic)
2032 func = build_known_method_ref (method, method_type, self_type,
2033 method_signature, arg_list);
2034 else if (opcode == OPCODE_invokespecial
2035 || (opcode == OPCODE_invokevirtual
2036 && (METHOD_PRIVATE (method)
2037 || METHOD_FINAL (method)
2038 || CLASS_FINAL (TYPE_NAME (self_type)))))
2040 /* If the object for the method call is null, we throw an
2041 exception. We don't do this if the object is the current
2042 method's `this'. In other cases we just rely on an
2043 optimization pass to eliminate redundant checks. FIXME:
2044 Unfortunately there doesn't seem to be a way to determine
2045 what the current method is right now.
2046 We do omit the check if we're calling <init>. */
2047 /* We use a SAVE_EXPR here to make sure we only evaluate
2048 the new `self' expression once. */
2049 tree save_arg = save_expr (TREE_VALUE (arg_list));
2050 TREE_VALUE (arg_list) = save_arg;
2051 check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2052 func = build_known_method_ref (method, method_type, self_type,
2053 method_signature, arg_list);
2055 else
2057 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
2058 arg_list);
2059 if (opcode == OPCODE_invokevirtual)
2060 func = build_invokevirtual (dtable, method);
2061 else
2062 func = build_invokeinterface (dtable, method);
2064 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2066 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
2067 TREE_SIDE_EFFECTS (call) = 1;
2068 call = check_for_builtin (method, call);
2070 if (check != NULL_TREE)
2072 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2073 TREE_SIDE_EFFECTS (call) = 1;
2076 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2077 expand_expr_stmt (call);
2078 else
2080 push_value (call);
2081 flush_quick_stack ();
2085 /* Create a stub which will be put into the vtable but which will call
2086 a JNI function. */
2088 tree
2089 build_jni_stub (tree method)
2091 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2092 tree jni_func_type, tem;
2093 tree env_var, res_var = NULL_TREE, block;
2094 tree method_args, res_type;
2095 tree meth_var;
2097 int args_size = 0;
2099 tree klass = DECL_CONTEXT (method);
2100 int from_class = ! CLASS_FROM_SOURCE_P (klass);
2101 klass = build_class_ref (klass);
2103 if (! METHOD_NATIVE (method) || ! flag_jni)
2104 abort ();
2106 DECL_ARTIFICIAL (method) = 1;
2107 DECL_EXTERNAL (method) = 0;
2109 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2110 DECL_CONTEXT (env_var) = method;
2112 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2114 res_var = build_decl (VAR_DECL, get_identifier ("res"),
2115 TREE_TYPE (TREE_TYPE (method)));
2116 DECL_CONTEXT (res_var) = method;
2117 TREE_CHAIN (env_var) = res_var;
2120 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2121 TREE_STATIC (meth_var) = 1;
2122 TREE_PUBLIC (meth_var) = 0;
2123 DECL_EXTERNAL (meth_var) = 0;
2124 DECL_CONTEXT (meth_var) = method;
2125 DECL_ARTIFICIAL (meth_var) = 1;
2126 DECL_INITIAL (meth_var) = null_pointer_node;
2127 TREE_USED (meth_var) = 1;
2128 chainon (env_var, meth_var);
2129 layout_decl (meth_var, 0);
2130 make_decl_rtl (meth_var, NULL);
2131 rest_of_decl_compilation (meth_var, NULL, 0, 0);
2133 /* One strange way that the front ends are different is that they
2134 store arguments differently. */
2135 if (from_class)
2136 method_args = DECL_ARGUMENTS (method);
2137 else
2138 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2139 block = build_block (env_var, NULL_TREE, NULL_TREE,
2140 method_args, NULL_TREE);
2141 TREE_SIDE_EFFECTS (block) = 1;
2142 /* When compiling from source we don't set the type of the block,
2143 because that will prevent patch_return from ever being run. */
2144 if (from_class)
2145 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2147 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2148 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2149 build (CALL_EXPR, ptr_type_node,
2150 build_address_of (soft_getjnienvnewframe_node),
2151 build_tree_list (NULL_TREE, klass),
2152 NULL_TREE));
2153 CAN_COMPLETE_NORMALLY (body) = 1;
2155 /* All the arguments to this method become arguments to the
2156 underlying JNI function. If we had to wrap object arguments in a
2157 special way, we would do that here. */
2158 args = NULL_TREE;
2159 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2161 int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (tem)));
2162 #ifdef PARM_BOUNDARY
2163 arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
2164 * PARM_BOUNDARY);
2165 #endif
2166 args_size += (arg_bits / BITS_PER_UNIT);
2168 args = tree_cons (NULL_TREE, tem, args);
2170 args = nreverse (args);
2171 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2173 /* For a static method the second argument is the class. For a
2174 non-static method the second argument is `this'; that is already
2175 available in the argument list. */
2176 if (METHOD_STATIC (method))
2178 args_size += int_size_in_bytes (TREE_TYPE (klass));
2179 args = tree_cons (NULL_TREE, klass, args);
2180 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2183 /* The JNIEnv structure is the first argument to the JNI function. */
2184 args_size += int_size_in_bytes (TREE_TYPE (env_var));
2185 args = tree_cons (NULL_TREE, env_var, args);
2186 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2188 /* We call _Jv_LookupJNIMethod to find the actual underlying
2189 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2190 exception if this function is not found at runtime. */
2191 tem = build_tree_list (NULL_TREE, build_int_2 (args_size, 0));
2192 method_sig = build_java_signature (TREE_TYPE (method));
2193 lookup_arg = tree_cons (NULL_TREE,
2194 build_utf8_ref (unmangle_classname
2195 (IDENTIFIER_POINTER (method_sig),
2196 IDENTIFIER_LENGTH (method_sig))),
2197 tem);
2198 tem = DECL_NAME (method);
2199 lookup_arg
2200 = tree_cons (NULL_TREE, klass,
2201 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2203 tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
2205 #ifdef MODIFY_JNI_METHOD_CALL
2206 tem = MODIFY_JNI_METHOD_CALL (tem);
2207 #endif
2209 jni_func_type = build_pointer_type (tem);
2211 jnifunc = build (COND_EXPR, ptr_type_node,
2212 meth_var, meth_var,
2213 build (MODIFY_EXPR, ptr_type_node,
2214 meth_var,
2215 build (CALL_EXPR, ptr_type_node,
2216 build_address_of (soft_lookupjnimethod_node),
2217 lookup_arg, NULL_TREE)));
2219 /* Now we make the actual JNI call via the resulting function
2220 pointer. */
2221 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2222 build1 (NOP_EXPR, jni_func_type, jnifunc),
2223 args, NULL_TREE);
2225 /* If the JNI call returned a result, capture it here. If we had to
2226 unwrap JNI object results, we would do that here. */
2227 if (res_var != NULL_TREE)
2228 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2229 res_var, call);
2231 TREE_SIDE_EFFECTS (call) = 1;
2232 CAN_COMPLETE_NORMALLY (call) = 1;
2234 body = build (COMPOUND_EXPR, void_type_node, body, call);
2235 TREE_SIDE_EFFECTS (body) = 1;
2237 /* Now free the environment we allocated. */
2238 call = build (CALL_EXPR, ptr_type_node,
2239 build_address_of (soft_jnipopsystemframe_node),
2240 build_tree_list (NULL_TREE, env_var),
2241 NULL_TREE);
2242 TREE_SIDE_EFFECTS (call) = 1;
2243 CAN_COMPLETE_NORMALLY (call) = 1;
2244 body = build (COMPOUND_EXPR, void_type_node, body, call);
2245 TREE_SIDE_EFFECTS (body) = 1;
2247 /* Finally, do the return. When compiling from source we rely on
2248 patch_return to patch the return value -- because DECL_RESULT is
2249 not set at the time this function is called. */
2250 if (from_class)
2252 res_type = void_type_node;
2253 if (res_var != NULL_TREE)
2255 tree drt;
2256 if (! DECL_RESULT (method))
2257 abort ();
2258 /* Make sure we copy the result variable to the actual
2259 result. We use the type of the DECL_RESULT because it
2260 might be different from the return type of the function:
2261 it might be promoted. */
2262 drt = TREE_TYPE (DECL_RESULT (method));
2263 if (drt != TREE_TYPE (res_var))
2264 res_var = build1 (CONVERT_EXPR, drt, res_var);
2265 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2266 TREE_SIDE_EFFECTS (res_var) = 1;
2269 else
2271 /* This is necessary to get patch_return to run. */
2272 res_type = NULL_TREE;
2274 body = build (COMPOUND_EXPR, void_type_node, body,
2275 build1 (RETURN_EXPR, res_type, res_var));
2276 TREE_SIDE_EFFECTS (body) = 1;
2278 BLOCK_EXPR_BODY (block) = body;
2279 return block;
2282 /* Expand an operation to extract from or store into a field.
2283 IS_STATIC is 1 iff the field is static.
2284 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2285 FIELD_REF_INDEX is an index into the constant pool. */
2287 static void
2288 expand_java_field_op (int is_static, int is_putting, int field_ref_index)
2290 tree self_type =
2291 get_class_constant (current_jcf,
2292 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2293 field_ref_index));
2294 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2295 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2296 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2297 field_ref_index);
2298 tree field_type = get_type_from_signature (field_signature);
2299 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2300 tree field_ref;
2301 int is_error = 0;
2302 tree field_decl = lookup_field (&self_type, field_name);
2303 if (field_decl == error_mark_node)
2305 is_error = 1;
2307 else if (field_decl == NULL_TREE)
2309 error ("missing field '%s' in '%s'",
2310 IDENTIFIER_POINTER (field_name), self_name);
2311 is_error = 1;
2313 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2315 error ("mismatching signature for field '%s' in '%s'",
2316 IDENTIFIER_POINTER (field_name), self_name);
2317 is_error = 1;
2319 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2320 if (is_error)
2322 if (! is_putting)
2323 push_value (convert (field_type, integer_zero_node));
2324 flush_quick_stack ();
2325 return;
2328 field_ref = build_field_ref (field_ref, self_type, field_name);
2329 if (is_static)
2330 field_ref = build_class_init (self_type, field_ref);
2331 if (is_putting)
2333 flush_quick_stack ();
2334 if (FIELD_FINAL (field_decl))
2336 if (DECL_CONTEXT (field_decl) != current_class)
2337 error_with_decl (field_decl,
2338 "assignment to final field `%s' not in field's class");
2339 else if (FIELD_STATIC (field_decl))
2341 if (!DECL_CLINIT_P (current_function_decl))
2342 warning_with_decl (field_decl,
2343 "assignment to final static field `%s' not in class initializer");
2345 else
2347 tree cfndecl_name = DECL_NAME (current_function_decl);
2348 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2349 && !ID_FINIT_P (cfndecl_name))
2350 warning_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2353 expand_assignment (field_ref, new_value, 0, 0);
2355 else
2356 push_value (field_ref);
2359 void
2360 load_type_state (tree label)
2362 int i;
2363 tree vec = LABEL_TYPE_STATE (label);
2364 int cur_length = TREE_VEC_LENGTH (vec);
2365 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2366 for (i = 0; i < cur_length; i++)
2367 type_map [i] = TREE_VEC_ELT (vec, i);
2370 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2371 dependent things, but they rely on gcc routines. This function is
2372 placed here because it uses things defined locally in parse.y. */
2374 static tree
2375 case_identity (tree t __attribute__ ((__unused__)), tree v)
2377 return v;
2380 /* Return the name of the vtable for an array of a given primitive
2381 type. */
2382 static tree
2383 get_primitive_array_vtable (tree elt)
2385 tree r;
2386 if (elt == boolean_type_node)
2387 r = boolean_array_vtable;
2388 else if (elt == byte_type_node)
2389 r = byte_array_vtable;
2390 else if (elt == char_type_node)
2391 r = char_array_vtable;
2392 else if (elt == short_type_node)
2393 r = short_array_vtable;
2394 else if (elt == int_type_node)
2395 r = int_array_vtable;
2396 else if (elt == long_type_node)
2397 r = long_array_vtable;
2398 else if (elt == float_type_node)
2399 r = float_array_vtable;
2400 else if (elt == double_type_node)
2401 r = double_array_vtable;
2402 else
2403 abort ();
2404 return build_address_of (r);
2407 struct rtx_def *
2408 java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
2409 int modifier /* Actually an enum expand_modifier. */)
2411 tree current;
2413 switch (TREE_CODE (exp))
2415 case NEW_ARRAY_INIT:
2417 rtx tmp;
2418 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2419 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2420 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2421 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2422 tree length = build_int_2 (ilength, 0);
2423 tree init = TREE_OPERAND (exp, 0);
2424 tree array_decl;
2426 /* See if we can generate the array statically. */
2427 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2428 && JPRIMITIVE_TYPE_P (element_type))
2430 tree temp, value, init_decl;
2431 struct rtx_def *r;
2432 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2433 PUSH_FIELD_VALUE (temp, "vtable",
2434 get_primitive_array_vtable (element_type));
2435 if (! flag_hash_synchronization)
2436 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2437 FINISH_RECORD_CONSTRUCTOR (temp);
2438 START_RECORD_CONSTRUCTOR (value, array_type);
2439 PUSH_SUPER_VALUE (value, temp);
2440 PUSH_FIELD_VALUE (value, "length", length);
2441 PUSH_FIELD_VALUE (value, "data", init);
2442 FINISH_RECORD_CONSTRUCTOR (value);
2444 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2445 pushdecl_top_level (init_decl);
2446 TREE_STATIC (init_decl) = 1;
2447 DECL_INITIAL (init_decl) = value;
2448 DECL_IGNORED_P (init_decl) = 1;
2449 TREE_READONLY (init_decl) = 1;
2450 /* Hash synchronization requires at least 64-bit alignment. */
2451 if (flag_hash_synchronization && POINTER_SIZE < 64)
2452 DECL_ALIGN (init_decl) = 64;
2453 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2454 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2455 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2456 r = expand_expr (init, target, tmode, modifier);
2457 return r;
2460 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2461 expand_decl (array_decl);
2462 tmp = expand_assignment (array_decl,
2463 build_new_array (element_type, length),
2464 1, 0);
2465 if (TREE_CONSTANT (init)
2466 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2468 tree init_decl;
2469 init_decl = build_decl (VAR_DECL, generate_name (),
2470 TREE_TYPE (init));
2471 pushdecl_top_level (init_decl);
2472 TREE_STATIC (init_decl) = 1;
2473 DECL_INITIAL (init_decl) = init;
2474 DECL_IGNORED_P (init_decl) = 1;
2475 TREE_READONLY (init_decl) = 1;
2476 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2477 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2478 init = init_decl;
2480 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2481 build_java_indirect_ref (array_type,
2482 array_decl, flag_check_references),
2483 data_fld), init, 0, 0);
2484 return tmp;
2486 case BLOCK:
2487 if (BLOCK_EXPR_BODY (exp))
2489 tree local;
2490 rtx last;
2491 tree body = BLOCK_EXPR_BODY (exp);
2492 /* Set to 1 or more when we found a static class
2493 initialization flag. */
2494 int found_class_initialization_flag = 0;
2496 pushlevel (2); /* 2 and above */
2497 expand_start_bindings (0);
2498 local = BLOCK_EXPR_DECLS (exp);
2499 while (local)
2501 tree next = TREE_CHAIN (local);
2502 found_class_initialization_flag +=
2503 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
2504 layout_decl (local, 0);
2505 expand_decl (pushdecl (local));
2506 local = next;
2509 /* Emit initialization code for test flags if we saw one. */
2510 if (! always_initialize_class_p
2511 && current_function_decl
2512 && found_class_initialization_flag)
2513 htab_traverse
2514 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
2515 emit_init_test_initialization, NULL);
2517 /* Avoid deep recursion for long block. */
2518 while (TREE_CODE (body) == COMPOUND_EXPR)
2520 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2521 emit_queue ();
2522 body = TREE_OPERAND (body, 1);
2524 last = expand_expr (body, NULL_RTX, VOIDmode, 0);
2525 emit_queue ();
2526 expand_end_bindings (getdecls (), 1, 0);
2527 poplevel (1, 1, 0);
2528 return last;
2530 return const0_rtx;
2532 case CASE_EXPR:
2534 tree duplicate;
2535 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2536 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2537 &duplicate) == 2)
2539 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2540 parse_error_context
2541 (wfl_operator, "Duplicate case label: `%s'",
2542 print_int_node (TREE_OPERAND (exp, 0)));
2544 return const0_rtx;
2547 case DEFAULT_EXPR:
2548 pushcase (NULL_TREE, 0,
2549 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2550 return const0_rtx;
2552 case SWITCH_EXPR:
2553 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2554 expand_expr_stmt (TREE_OPERAND (exp, 1));
2555 expand_end_case (TREE_OPERAND (exp, 0));
2556 return const0_rtx;
2558 case TRY_EXPR:
2559 /* We expand a try[-catch] block */
2561 /* Expand the try block */
2562 expand_eh_region_start ();
2563 expand_expr_stmt (TREE_OPERAND (exp, 0));
2564 expand_start_all_catch ();
2566 /* Expand all catch clauses (EH handlers) */
2567 for (current = TREE_OPERAND (exp, 1); current;
2568 current = TREE_CHAIN (current))
2570 tree catch = TREE_OPERAND (current, 0);
2571 tree decl = BLOCK_EXPR_DECLS (catch);
2572 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2574 expand_start_catch (type);
2575 expand_expr_stmt (TREE_OPERAND (current, 0));
2576 expand_end_catch ();
2578 expand_end_all_catch ();
2579 return const0_rtx;
2581 case JAVA_EXC_OBJ_EXPR:
2582 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2583 target, tmode, modifier);
2585 case LABEL_EXPR:
2586 /* Used only by expanded inline functions. */
2587 expand_label (TREE_OPERAND (exp, 0));
2588 return const0_rtx;
2590 default:
2591 internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
2595 /* Go over METHOD's bytecode and note instruction starts in
2596 instruction_bits[]. */
2598 void
2599 note_instructions (JCF *jcf, tree method)
2601 int PC;
2602 unsigned char* byte_ops;
2603 long length = DECL_CODE_LENGTH (method);
2605 int saw_index;
2606 jint INT_temp;
2608 #undef RET /* Defined by config/i386/i386.h */
2609 #undef PTR
2610 #define BCODE byte_ops
2611 #define BYTE_type_node byte_type_node
2612 #define SHORT_type_node short_type_node
2613 #define INT_type_node int_type_node
2614 #define LONG_type_node long_type_node
2615 #define CHAR_type_node char_type_node
2616 #define PTR_type_node ptr_type_node
2617 #define FLOAT_type_node float_type_node
2618 #define DOUBLE_type_node double_type_node
2619 #define VOID_type_node void_type_node
2620 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2621 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2622 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2623 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2625 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2627 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2628 byte_ops = jcf->read_ptr;
2629 instruction_bits = xrealloc (instruction_bits, length + 1);
2630 memset (instruction_bits, 0, length + 1);
2632 /* This pass figures out which PC can be the targets of jumps. */
2633 for (PC = 0; PC < length;)
2635 int oldpc = PC; /* PC at instruction start. */
2636 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2637 switch (byte_ops[PC++])
2639 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2640 case OPCODE: \
2641 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2642 break;
2644 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2646 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2647 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2648 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2649 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2650 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2651 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2652 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2653 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2655 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2656 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2657 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2658 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2659 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2660 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2661 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2662 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2664 /* two forms of wide instructions */
2665 #define PRE_SPECIAL_WIDE(IGNORE) \
2667 int modified_opcode = IMMEDIATE_u1; \
2668 if (modified_opcode == OPCODE_iinc) \
2670 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2671 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2673 else \
2675 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2679 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2681 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2683 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2684 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2685 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2686 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2687 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2688 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2689 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2690 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2691 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2692 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2694 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2695 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2696 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2697 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2698 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2699 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2700 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2701 NOTE_LABEL (PC); \
2702 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2704 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2706 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2707 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2709 #define PRE_LOOKUP_SWITCH \
2710 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2711 NOTE_LABEL (default_offset+oldpc); \
2712 if (npairs >= 0) \
2713 while (--npairs >= 0) { \
2714 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2715 jint offset = IMMEDIATE_s4; \
2716 NOTE_LABEL (offset+oldpc); } \
2719 #define PRE_TABLE_SWITCH \
2720 { jint default_offset = IMMEDIATE_s4; \
2721 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2722 NOTE_LABEL (default_offset+oldpc); \
2723 if (low <= high) \
2724 while (low++ <= high) { \
2725 jint offset = IMMEDIATE_s4; \
2726 NOTE_LABEL (offset+oldpc); } \
2729 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2730 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2731 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2732 (void)(IMMEDIATE_u2); \
2733 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2735 #include "javaop.def"
2736 #undef JAVAOP
2738 } /* for */
2741 void
2742 expand_byte_code (JCF *jcf, tree method)
2744 int PC;
2745 int i;
2746 const unsigned char *linenumber_pointer;
2747 int dead_code_index = -1;
2748 unsigned char* byte_ops;
2749 long length = DECL_CODE_LENGTH (method);
2751 stack_pointer = 0;
2752 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2753 byte_ops = jcf->read_ptr;
2755 /* We make an initial pass of the line number table, to note
2756 which instructions have associated line number entries. */
2757 linenumber_pointer = linenumber_table;
2758 for (i = 0; i < linenumber_count; i++)
2760 int pc = GET_u2 (linenumber_pointer);
2761 linenumber_pointer += 4;
2762 if (pc >= length)
2763 warning ("invalid PC in line number table");
2764 else
2766 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2767 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2768 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2772 if (! verify_jvm_instructions (jcf, byte_ops, length))
2773 return;
2775 /* Translate bytecodes to rtl instructions. */
2776 linenumber_pointer = linenumber_table;
2777 for (PC = 0; PC < length;)
2779 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2781 tree label = lookup_label (PC);
2782 flush_quick_stack ();
2783 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2784 expand_label (label);
2785 if (LABEL_VERIFIED (label) || PC == 0)
2786 load_type_state (label);
2789 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2791 if (dead_code_index == -1)
2793 /* This is the start of a region of unreachable bytecodes.
2794 They still need to be processed in order for EH ranges
2795 to get handled correctly. However, we can simply
2796 replace these bytecodes with nops. */
2797 dead_code_index = PC;
2800 /* Turn this bytecode into a nop. */
2801 byte_ops[PC] = 0x0;
2803 else
2805 if (dead_code_index != -1)
2807 /* We've just reached the end of a region of dead code. */
2808 warning ("unreachable bytecode from %d to before %d",
2809 dead_code_index, PC);
2810 dead_code_index = -1;
2814 /* Handle possible line number entry for this PC.
2816 This code handles out-of-order and multiple linenumbers per PC,
2817 but is optimized for the case of line numbers increasing
2818 monotonically with PC. */
2819 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2821 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2822 || GET_u2 (linenumber_pointer) != PC)
2823 linenumber_pointer = linenumber_table;
2824 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2826 int pc = GET_u2 (linenumber_pointer);
2827 linenumber_pointer += 4;
2828 if (pc == PC)
2830 lineno = GET_u2 (linenumber_pointer - 2);
2831 emit_line_note (input_filename, lineno);
2832 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2833 break;
2837 maybe_pushlevels (PC);
2838 PC = process_jvm_instruction (PC, byte_ops, length);
2839 maybe_poplevels (PC);
2840 } /* for */
2842 if (dead_code_index != -1)
2844 /* We've just reached the end of a region of dead code. */
2845 warning ("unreachable bytecode from %d to the end of the method",
2846 dead_code_index);
2850 static void
2851 java_push_constant_from_pool (JCF *jcf, int index)
2853 tree c;
2854 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2856 tree name;
2857 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2858 index = alloc_name_constant (CONSTANT_String, name);
2859 c = build_ref_from_constant_pool (index);
2860 TREE_TYPE (c) = promote_type (string_type_node);
2862 else
2863 c = get_constant (jcf, index);
2864 push_value (c);
2868 process_jvm_instruction (int PC, const unsigned char* byte_ops,
2869 long length ATTRIBUTE_UNUSED)
2871 const char *opname; /* Temporary ??? */
2872 int oldpc = PC; /* PC at instruction start. */
2874 /* If the instruction is at the beginning of a exception handler,
2875 replace the top of the stack with the thrown object reference */
2876 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2878 tree type = pop_type (ptr_type_node);
2879 push_value (build (JAVA_EXC_OBJ_EXPR, type));
2882 switch (byte_ops[PC++])
2884 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2885 case OPCODE: \
2886 opname = #OPNAME; \
2887 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2888 break;
2890 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2892 int saw_index = 0; \
2893 int index = OPERAND_VALUE; \
2894 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2897 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2899 /* OPERAND_VALUE may have side-effects on PC */ \
2900 int opvalue = OPERAND_VALUE; \
2901 build_java_jsr (oldpc + opvalue, PC); \
2904 /* Push a constant onto the stack. */
2905 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2906 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2907 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2908 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2910 /* internal macro added for use by the WIDE case */
2911 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2912 expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
2914 /* Push local variable onto the opcode stack. */
2915 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2917 /* have to do this since OPERAND_VALUE may have side-effects */ \
2918 int opvalue = OPERAND_VALUE; \
2919 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2922 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2923 expand_java_return (OPERAND_TYPE##_type_node)
2925 #define REM_EXPR TRUNC_MOD_EXPR
2926 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2927 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2929 #define FIELD(IS_STATIC, IS_PUT) \
2930 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2932 #define TEST(OPERAND_TYPE, CONDITION) \
2933 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2935 #define COND(OPERAND_TYPE, CONDITION) \
2936 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2938 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2939 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2941 #define BRANCH_GOTO(OPERAND_VALUE) \
2942 expand_java_goto (oldpc + OPERAND_VALUE)
2944 #define BRANCH_CALL(OPERAND_VALUE) \
2945 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2947 #if 0
2948 #define BRANCH_RETURN(OPERAND_VALUE) \
2950 tree type = OPERAND_TYPE##_type_node; \
2951 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2952 expand_java_ret (value); \
2954 #endif
2956 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2957 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2958 fprintf (stderr, "(not implemented)\n")
2959 #define NOT_IMPL1(OPERAND_VALUE) \
2960 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2961 fprintf (stderr, "(not implemented)\n")
2963 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2965 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2967 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2969 #define STACK_SWAP(COUNT) java_stack_swap()
2971 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2972 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2973 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2975 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2976 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2978 #define LOOKUP_SWITCH \
2979 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2980 tree selector = pop_value (INT_type_node); \
2981 tree duplicate, label; \
2982 tree type = TREE_TYPE (selector); \
2983 flush_quick_stack (); \
2984 expand_start_case (0, selector, type, "switch statement");\
2985 while (--npairs >= 0) \
2987 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2988 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2989 TREE_TYPE (value) = type; \
2990 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2991 pushcase (value, convert, label, &duplicate); \
2992 expand_java_goto (oldpc + offset); \
2994 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2995 pushcase (NULL_TREE, 0, label, &duplicate); \
2996 expand_java_goto (oldpc + default_offset); \
2997 expand_end_case (selector); \
3000 #define TABLE_SWITCH \
3001 { jint default_offset = IMMEDIATE_s4; \
3002 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3003 tree selector = pop_value (INT_type_node); \
3004 tree duplicate, label; \
3005 tree type = TREE_TYPE (selector); \
3006 flush_quick_stack (); \
3007 expand_start_case (0, selector, type, "switch statement");\
3008 for (; low <= high; low++) \
3010 jint offset = IMMEDIATE_s4; \
3011 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
3012 TREE_TYPE (value) = type; \
3013 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3014 pushcase (value, convert, label, &duplicate); \
3015 expand_java_goto (oldpc + offset); \
3017 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3018 pushcase (NULL_TREE, 0, label, &duplicate); \
3019 expand_java_goto (oldpc + default_offset); \
3020 expand_end_case (selector); \
3023 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3024 { int opcode = byte_ops[PC-1]; \
3025 int method_ref_index = IMMEDIATE_u2; \
3026 int nargs; \
3027 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
3028 else nargs = -1; \
3029 expand_invoke (opcode, method_ref_index, nargs); \
3032 /* Handle new, checkcast, instanceof */
3033 #define OBJECT(TYPE, OP) \
3034 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3036 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3038 #define ARRAY_LOAD(OPERAND_TYPE) \
3040 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
3043 #define ARRAY_STORE(OPERAND_TYPE) \
3045 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3048 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3049 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3050 #define ARRAY_NEW_PTR() \
3051 push_value (build_anewarray (get_class_constant (current_jcf, \
3052 IMMEDIATE_u2), \
3053 pop_value (int_type_node)));
3054 #define ARRAY_NEW_NUM() \
3056 int atype = IMMEDIATE_u1; \
3057 push_value (build_newarray (atype, pop_value (int_type_node)));\
3059 #define ARRAY_NEW_MULTI() \
3061 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
3062 int ndims = IMMEDIATE_u1; \
3063 expand_java_multianewarray( class, ndims ); \
3066 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3067 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3068 pop_value (OPERAND_TYPE##_type_node))));
3070 #define CONVERT2(FROM_TYPE, TO_TYPE) \
3072 push_value (build1 (NOP_EXPR, int_type_node, \
3073 (convert (TO_TYPE##_type_node, \
3074 pop_value (FROM_TYPE##_type_node))))); \
3077 #define CONVERT(FROM_TYPE, TO_TYPE) \
3079 push_value (convert (TO_TYPE##_type_node, \
3080 pop_value (FROM_TYPE##_type_node))); \
3083 /* internal macro added for use by the WIDE case
3084 Added TREE_TYPE (decl) assignment, apbianco */
3085 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
3087 tree decl, value; \
3088 int var = OPVALUE; \
3089 tree type = OPTYPE; \
3090 value = pop_value (type); \
3091 type = TREE_TYPE (value); \
3092 decl = find_local_variable (var, type, oldpc); \
3093 set_local_type (var, type ); \
3094 expand_assignment (decl, value, 0, 0); \
3097 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3099 /* have to do this since OPERAND_VALUE may have side-effects */ \
3100 int opvalue = OPERAND_VALUE; \
3101 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3104 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3105 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3107 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3108 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3110 #define MONITOR_OPERATION(call) \
3112 tree o = pop_value (ptr_type_node); \
3113 tree c; \
3114 flush_quick_stack (); \
3115 c = build_java_monitor (call, o); \
3116 TREE_SIDE_EFFECTS (c) = 1; \
3117 expand_expr_stmt (c); \
3120 #define SPECIAL_IINC(IGNORED) \
3122 unsigned int local_var_index = IMMEDIATE_u1; \
3123 int ival = IMMEDIATE_s1; \
3124 expand_iinc(local_var_index, ival, oldpc); \
3127 #define SPECIAL_WIDE(IGNORED) \
3129 int modified_opcode = IMMEDIATE_u1; \
3130 unsigned int local_var_index = IMMEDIATE_u2; \
3131 switch (modified_opcode) \
3133 case OPCODE_iinc: \
3135 int ival = IMMEDIATE_s2; \
3136 expand_iinc (local_var_index, ival, oldpc); \
3137 break; \
3139 case OPCODE_iload: \
3140 case OPCODE_lload: \
3141 case OPCODE_fload: \
3142 case OPCODE_dload: \
3143 case OPCODE_aload: \
3145 /* duplicate code from LOAD macro */ \
3146 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3147 break; \
3149 case OPCODE_istore: \
3150 case OPCODE_lstore: \
3151 case OPCODE_fstore: \
3152 case OPCODE_dstore: \
3153 case OPCODE_astore: \
3155 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3156 break; \
3158 default: \
3159 error ("unrecogized wide sub-instruction"); \
3163 #define SPECIAL_THROW(IGNORED) \
3164 build_java_athrow (pop_value (throwable_type_node))
3166 #define SPECIAL_BREAK NOT_IMPL1
3167 #define IMPL NOT_IMPL
3169 #include "javaop.def"
3170 #undef JAVAOP
3171 default:
3172 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3174 return PC;
3177 /* Return the opcode at PC in the code section pointed to by
3178 CODE_OFFSET. */
3180 static unsigned char
3181 peek_opcode_at_pc (JCF *jcf, int code_offset, int pc)
3183 unsigned char opcode;
3184 long absolute_offset = (long)JCF_TELL (jcf);
3186 JCF_SEEK (jcf, code_offset);
3187 opcode = jcf->read_ptr [pc];
3188 JCF_SEEK (jcf, absolute_offset);
3189 return opcode;
3192 /* Some bytecode compilers are emitting accurate LocalVariableTable
3193 attributes. Here's an example:
3195 PC <t>store_<n>
3196 PC+1 ...
3198 Attribute "LocalVariableTable"
3199 slot #<n>: ... (PC: PC+1 length: L)
3201 This is accurate because the local in slot <n> really exists after
3202 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3204 This procedure recognizes this situation and extends the live range
3205 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3206 length of the store instruction.)
3208 This function is used by `give_name_to_locals' so that a local's
3209 DECL features a DECL_LOCAL_START_PC such that the first related
3210 store operation will use DECL as a destination, not a unrelated
3211 temporary created for the occasion.
3213 This function uses a global (instruction_bits) `note_instructions' should
3214 have allocated and filled properly. */
3217 maybe_adjust_start_pc (struct JCF *jcf, int code_offset,
3218 int start_pc, int slot)
3220 int first, index, opcode;
3221 int pc, insn_pc;
3222 int wide_found = 0;
3224 if (!start_pc)
3225 return start_pc;
3227 first = index = -1;
3229 /* Find last previous instruction and remember it */
3230 for (pc = start_pc-1; pc; pc--)
3231 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3232 break;
3233 insn_pc = pc;
3235 /* Retrieve the instruction, handle `wide'. */
3236 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3237 if (opcode == OPCODE_wide)
3239 wide_found = 1;
3240 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3243 switch (opcode)
3245 case OPCODE_astore_0:
3246 case OPCODE_astore_1:
3247 case OPCODE_astore_2:
3248 case OPCODE_astore_3:
3249 first = OPCODE_astore_0;
3250 break;
3252 case OPCODE_istore_0:
3253 case OPCODE_istore_1:
3254 case OPCODE_istore_2:
3255 case OPCODE_istore_3:
3256 first = OPCODE_istore_0;
3257 break;
3259 case OPCODE_lstore_0:
3260 case OPCODE_lstore_1:
3261 case OPCODE_lstore_2:
3262 case OPCODE_lstore_3:
3263 first = OPCODE_lstore_0;
3264 break;
3266 case OPCODE_fstore_0:
3267 case OPCODE_fstore_1:
3268 case OPCODE_fstore_2:
3269 case OPCODE_fstore_3:
3270 first = OPCODE_fstore_0;
3271 break;
3273 case OPCODE_dstore_0:
3274 case OPCODE_dstore_1:
3275 case OPCODE_dstore_2:
3276 case OPCODE_dstore_3:
3277 first = OPCODE_dstore_0;
3278 break;
3280 case OPCODE_astore:
3281 case OPCODE_istore:
3282 case OPCODE_lstore:
3283 case OPCODE_fstore:
3284 case OPCODE_dstore:
3285 index = peek_opcode_at_pc (jcf, code_offset, pc);
3286 if (wide_found)
3288 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3289 index = (other << 8) + index;
3291 break;
3294 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3295 means we have a <t>store. */
3296 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3297 start_pc = insn_pc;
3299 return start_pc;
3302 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3303 order, as specified by Java Language Specification.
3305 The problem is that while expand_expr will evaluate its sub-operands in
3306 left-to-right order, for variables it will just return an rtx (i.e.
3307 an lvalue) for the variable (rather than an rvalue). So it is possible
3308 that a later sub-operand will change the register, and when the
3309 actual operation is done, it will use the new value, when it should
3310 have used the original value.
3312 We fix this by using save_expr. This forces the sub-operand to be
3313 copied into a fresh virtual register,
3315 For method invocation, we modify the arguments so that a
3316 left-to-right order evaluation is performed. Saved expressions
3317 will, in CALL_EXPR order, be reused when the call will be expanded.
3320 tree
3321 force_evaluation_order (tree node)
3323 if (flag_syntax_only)
3324 return node;
3325 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3327 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3328 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3330 else if (TREE_CODE (node) == CALL_EXPR
3331 || TREE_CODE (node) == NEW_CLASS_EXPR
3332 || (TREE_CODE (node) == COMPOUND_EXPR
3333 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3334 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3336 tree arg, cmp;
3338 if (!TREE_OPERAND (node, 1))
3339 return node;
3341 arg = node;
3343 /* Position arg properly, account for wrapped around ctors. */
3344 if (TREE_CODE (node) == COMPOUND_EXPR)
3345 arg = TREE_OPERAND (node, 0);
3347 arg = TREE_OPERAND (arg, 1);
3349 /* Not having a list of argument here is an error. */
3350 if (TREE_CODE (arg) != TREE_LIST)
3351 abort ();
3353 /* This reverses the evaluation order. This is a desired effect. */
3354 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3356 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3357 cmp = (cmp == NULL_TREE ? saved :
3358 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3359 TREE_VALUE (arg) = saved;
3362 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3363 TREE_SIDE_EFFECTS (cmp) = 1;
3365 if (cmp)
3367 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3368 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3369 TREE_SIDE_EFFECTS (cmp) = 1;
3370 node = cmp;
3373 return node;
3376 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
3377 method in order to emit initialization code for each test flag. */
3379 static int
3380 emit_init_test_initialization (void **entry, void *x ATTRIBUTE_UNUSED)
3382 struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
3383 tree klass = build_class_ref (ite->key);
3384 tree rhs;
3386 /* If the DECL_INITIAL of the test flag is set to true, it
3387 means that the class is already initialized the time it
3388 is in use. */
3389 if (DECL_INITIAL (ite->value) == boolean_true_node)
3390 rhs = boolean_true_node;
3391 /* Otherwise, we initialize the class init check variable by looking
3392 at the `state' field of the class to see if it is already
3393 initialized. This makes things a bit faster if the class is
3394 already initialized, which should be the common case. */
3395 else
3396 rhs = build (GE_EXPR, boolean_type_node,
3397 build (COMPONENT_REF, byte_type_node,
3398 build1 (INDIRECT_REF, class_type_node, klass),
3399 lookup_field (&class_type_node,
3400 get_identifier ("state"))),
3401 build_int_2 (JV_STATE_DONE, 0));
3403 expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
3404 ite->value, rhs));
3405 return true;
3408 #include "gt-java-expr.h"