* call.c: Fix comment formatting.
[official-gcc.git] / gcc / java / expr.c
blobd6a443dca9a82f3f62f33af1208cdc82b1aa99b7
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC 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 GNU CC 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 GNU CC; 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 "tree.h"
31 #include "real.h"
32 #include "rtl.h"
33 #include "flags.h"
34 #include "expr.h"
35 #include "java-tree.h"
36 #include "javaop.h"
37 #include "java-opcodes.h"
38 #include "jcf.h"
39 #include "java-except.h"
40 #include "parse.h"
41 #include "toplev.h"
42 #include "except.h"
43 #include "ggc.h"
45 static void flush_quick_stack PARAMS ((void));
46 static void push_value PARAMS ((tree));
47 static tree pop_value PARAMS ((tree));
48 static void java_stack_swap PARAMS ((void));
49 static void java_stack_dup PARAMS ((int, int));
50 static void build_java_athrow PARAMS ((tree));
51 static void build_java_jsr PARAMS ((int, int));
52 static void build_java_ret PARAMS ((tree));
53 static void expand_java_multianewarray PARAMS ((tree, int));
54 static void expand_java_arraystore PARAMS ((tree));
55 static void expand_java_arrayload PARAMS ((tree));
56 static void expand_java_array_length PARAMS ((void));
57 static tree build_java_monitor PARAMS ((tree, tree));
58 static void expand_java_pushc PARAMS ((int, tree));
59 static void expand_java_return PARAMS ((tree));
60 static void expand_load_internal PARAMS ((int, tree, int));
61 static void expand_java_NEW PARAMS ((tree));
62 static void expand_java_INSTANCEOF PARAMS ((tree));
63 static void expand_java_CHECKCAST PARAMS ((tree));
64 static void expand_iinc PARAMS ((unsigned int, int, int));
65 static void expand_java_binop PARAMS ((tree, enum tree_code));
66 static void note_label PARAMS ((int, int));
67 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
68 static void expand_test PARAMS ((enum tree_code, tree, int));
69 static void expand_cond PARAMS ((enum tree_code, tree, int));
70 static void expand_java_goto PARAMS ((int));
71 #if 0
72 static void expand_java_call PARAMS ((int, int));
73 static void expand_java_ret PARAMS ((tree));
74 #endif
75 static tree pop_arguments PARAMS ((tree));
76 static void expand_invoke PARAMS ((int, int, int));
77 static void expand_java_field_op PARAMS ((int, int, int));
78 static void java_push_constant_from_pool PARAMS ((struct JCF *, int));
79 static void java_stack_pop PARAMS ((int));
80 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
81 static tree build_java_check_indexed_type PARAMS ((tree, tree));
82 static tree case_identity PARAMS ((tree, tree));
83 static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int));
84 static int emit_init_test_initialization PARAMS ((void **entry,
85 void * ptr));
86 static int get_offset_table_index PARAMS ((tree));
88 static GTY(()) tree operand_type[59];
90 static GTY(()) tree methods_ident;
91 static GTY(()) tree ncode_ident;
92 tree dtable_ident = NULL_TREE;
94 /* Set to non-zero value in order to emit class initilization code
95 before static field references. */
96 int always_initialize_class_p;
98 /* We store the stack state in two places:
99 Within a basic block, we use the quick_stack, which is a
100 pushdown list (TREE_LISTs) of expression nodes.
101 This is the top part of the stack; below that we use find_stack_slot.
102 At the end of a basic block, the quick_stack must be flushed
103 to the stack slot array (as handled by find_stack_slot).
104 Using quick_stack generates better code (especially when
105 compiled without optimization), because we do not have to
106 explicitly store and load trees to temporary variables.
108 If a variable is on the quick stack, it means the value of variable
109 when the quick stack was last flushed. Conceptually, flush_quick_stack
110 saves all the the quick_stack elements in parellel. However, that is
111 complicated, so it actually saves them (i.e. copies each stack value
112 to is home virtual register) from low indexes. This allows a quick_stack
113 element at index i (counting from the bottom of stack the) to references
114 slot virtuals for register that are >= i, but not those that are deeper.
115 This convention makes most operations easier. For example iadd works
116 even when the stack contains (reg[0], reg[1]): It results in the
117 stack containing (reg[0]+reg[1]), which is OK. However, some stack
118 operations are more complicated. For example dup given a stack
119 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
120 the convention, since stack value 1 would refer to a register with
121 lower index (reg[0]), which flush_quick_stack does not safely handle.
122 So dup cannot just add an extra element to the quick_stack, but iadd can.
125 static GTY(()) tree quick_stack;
127 /* A free-list of unused permamnet TREE_LIST nodes. */
128 static GTY((deletable (""))) tree tree_list_free_list;
130 /* The stack pointer of the Java virtual machine.
131 This does include the size of the quick_stack. */
133 int stack_pointer;
135 const unsigned char *linenumber_table;
136 int linenumber_count;
138 void
139 init_expr_processing()
141 operand_type[21] = operand_type[54] = int_type_node;
142 operand_type[22] = operand_type[55] = long_type_node;
143 operand_type[23] = operand_type[56] = float_type_node;
144 operand_type[24] = operand_type[57] = double_type_node;
145 operand_type[25] = operand_type[58] = ptr_type_node;
148 tree
149 java_truthvalue_conversion (expr)
150 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 non-zero 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 ()
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 (type)
245 tree type;
247 int n_words;
248 type = promote_type (type);
249 n_words = 1 + TYPE_IS_WIDE (type);
250 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
251 return 0;
252 stack_type_map[stack_pointer++] = type;
253 n_words--;
254 while (--n_words >= 0)
255 stack_type_map[stack_pointer++] = TYPE_SECOND;
256 return 1;
259 void
260 push_type (type)
261 tree type;
263 if (! push_type_0 (type))
264 abort ();
267 static void
268 push_value (value)
269 tree value;
271 tree type = TREE_TYPE (value);
272 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
274 type = promote_type (type);
275 value = convert (type, value);
277 push_type (type);
278 if (tree_list_free_list == NULL_TREE)
279 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
280 else
282 tree node = tree_list_free_list;
283 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
284 TREE_VALUE (node) = value;
285 TREE_CHAIN (node) = quick_stack;
286 quick_stack = node;
290 /* Pop a type from the type stack.
291 TYPE is the expected type. Return the actual type, which must be
292 convertible to TYPE.
293 On an error, *MESSAGEP is set to a freshly malloc'd error message. */
295 tree
296 pop_type_0 (type, messagep)
297 tree type;
298 char **messagep;
300 int n_words;
301 tree t;
302 *messagep = NULL;
303 if (TREE_CODE (type) == RECORD_TYPE)
304 type = promote_type (type);
305 n_words = 1 + TYPE_IS_WIDE (type);
306 if (stack_pointer < n_words)
308 *messagep = xstrdup ("stack underflow");
309 return type;
311 while (--n_words > 0)
313 if (stack_type_map[--stack_pointer] != void_type_node)
315 *messagep = xstrdup ("Invalid multi-word value on type stack");
316 return type;
319 t = stack_type_map[--stack_pointer];
320 if (type == NULL_TREE || t == type)
321 return t;
322 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
323 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
324 return t;
325 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
327 if (type == ptr_type_node || type == object_ptr_type_node)
328 return t;
329 else if (t == ptr_type_node) /* Special case for null reference. */
330 return type;
331 else if (can_widen_reference_to (t, type))
332 return t;
333 /* This is a kludge, but matches what Sun's verifier does.
334 It can be tricked, but is safe as long as type errors
335 (i.e. interface method calls) are caught at run-time. */
336 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
337 return object_ptr_type_node;
340 /* lang_printable_name uses a static buffer, so we must save the result
341 from calling it the first time. */
343 char *temp = xstrdup (lang_printable_name (type, 0));
344 *messagep = concat ("expected type '", temp,
345 "' but stack contains '", lang_printable_name (t, 0),
346 "'", NULL);
347 free (temp);
349 return type;
352 /* Pop a type from the type stack.
353 TYPE is the expected type. Return the actual type, which must be
354 convertible to TYPE, otherwise call error. */
356 tree
357 pop_type (type)
358 tree type;
360 char *message = NULL;
361 type = pop_type_0 (type, &message);
362 if (message != NULL)
364 error ("%s", message);
365 free (message);
367 return type;
370 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
371 Handles array types and interfaces. */
374 can_widen_reference_to (source_type, target_type)
375 tree source_type, target_type;
377 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
378 return 1;
380 /* Get rid of pointers */
381 if (TREE_CODE (source_type) == POINTER_TYPE)
382 source_type = TREE_TYPE (source_type);
383 if (TREE_CODE (target_type) == POINTER_TYPE)
384 target_type = TREE_TYPE (target_type);
386 if (source_type == target_type)
387 return 1;
388 else
390 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
392 HOST_WIDE_INT source_length, target_length;
393 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
394 return 0;
395 target_length = java_array_type_length (target_type);
396 if (target_length >= 0)
398 source_length = java_array_type_length (source_type);
399 if (source_length != target_length)
400 return 0;
402 source_type = TYPE_ARRAY_ELEMENT (source_type);
403 target_type = TYPE_ARRAY_ELEMENT (target_type);
404 if (source_type == target_type)
405 return 1;
406 if (TREE_CODE (source_type) != POINTER_TYPE
407 || TREE_CODE (target_type) != POINTER_TYPE)
408 return 0;
409 return can_widen_reference_to (source_type, target_type);
411 else
413 int source_depth = class_depth (source_type);
414 int target_depth = class_depth (target_type);
416 /* class_depth can return a negative depth if an error occurred */
417 if (source_depth < 0 || target_depth < 0)
418 return 0;
420 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
422 /* target_type is OK if source_type or source_type ancestors
423 implement target_type. We handle multiple sub-interfaces */
425 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
426 int n = TREE_VEC_LENGTH (basetype_vec), i;
427 for (i=0 ; i < n; i++)
428 if (can_widen_reference_to
429 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
430 target_type))
431 return 1;
432 if (n == 0)
433 return 0;
436 for ( ; source_depth > target_depth; source_depth--)
438 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
440 return source_type == target_type;
445 static tree
446 pop_value (type)
447 tree type;
449 type = pop_type (type);
450 if (quick_stack)
452 tree node = quick_stack;
453 quick_stack = TREE_CHAIN (quick_stack);
454 TREE_CHAIN (node) = tree_list_free_list;
455 tree_list_free_list = node;
456 node = TREE_VALUE (node);
457 return node;
459 else
460 return find_stack_slot (stack_pointer, promote_type (type));
464 /* Pop and discrad the top COUNT stack slots. */
466 static void
467 java_stack_pop (count)
468 int count;
470 while (count > 0)
472 tree type, val;
474 if (stack_pointer == 0)
475 abort ();
477 type = stack_type_map[stack_pointer - 1];
478 if (type == TYPE_SECOND)
480 count--;
481 if (stack_pointer == 1 || count <= 0)
482 abort ();
484 type = stack_type_map[stack_pointer - 2];
486 val = pop_value (type);
487 count--;
491 /* Implement the 'swap' operator (to swap two top stack slots). */
493 static void
494 java_stack_swap ()
496 tree type1, type2;
497 rtx temp;
498 tree decl1, decl2;
500 if (stack_pointer < 2
501 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
502 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
503 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
504 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
505 /* Bad stack swap. */
506 abort ();
508 flush_quick_stack ();
509 decl1 = find_stack_slot (stack_pointer - 1, type1);
510 decl2 = find_stack_slot (stack_pointer - 2, type2);
511 temp = copy_to_reg (DECL_RTL (decl1));
512 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
513 emit_move_insn (DECL_RTL (decl2), temp);
514 stack_type_map[stack_pointer - 1] = type2;
515 stack_type_map[stack_pointer - 2] = type1;
518 static void
519 java_stack_dup (size, offset)
520 int size, offset;
522 int low_index = stack_pointer - size - offset;
523 int dst_index;
524 if (low_index < 0)
525 error ("stack underflow - dup* operation");
527 flush_quick_stack ();
529 stack_pointer += size;
530 dst_index = stack_pointer;
532 for (dst_index = stack_pointer; --dst_index >= low_index; )
534 tree type;
535 int src_index = dst_index - size;
536 if (src_index < low_index)
537 src_index = dst_index + size + offset;
538 type = stack_type_map [src_index];
539 if (type == TYPE_SECOND)
541 if (src_index <= low_index)
542 /* Dup operation splits 64-bit number. */
543 abort ();
545 stack_type_map[dst_index] = type;
546 src_index--; dst_index--;
547 type = stack_type_map[src_index];
548 if (! TYPE_IS_WIDE (type))
549 abort ();
551 else if (TYPE_IS_WIDE (type))
552 abort ();
554 if (src_index != dst_index)
556 tree src_decl = find_stack_slot (src_index, type);
557 tree dst_decl = find_stack_slot (dst_index, type);
558 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
559 stack_type_map[dst_index] = type;
564 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
565 value stack. */
567 static void
568 build_java_athrow (node)
569 tree node;
571 tree call;
573 call = build (CALL_EXPR,
574 void_type_node,
575 build_address_of (throw_node),
576 build_tree_list (NULL_TREE, node),
577 NULL_TREE);
578 TREE_SIDE_EFFECTS (call) = 1;
579 expand_expr_stmt (call);
580 java_stack_pop (stack_pointer);
583 /* Implementation for jsr/ret */
585 static void
586 build_java_jsr (target_pc, return_pc)
587 int target_pc, return_pc;
589 tree where = lookup_label (target_pc);
590 tree ret = lookup_label (return_pc);
591 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
592 push_value (ret_label);
593 flush_quick_stack ();
594 emit_jump (label_rtx (where));
595 expand_label (ret);
596 if (instruction_bits [return_pc] & BCODE_VERIFIED)
597 load_type_state (ret);
600 static void
601 build_java_ret (location)
602 tree location;
604 expand_computed_goto (location);
607 /* Implementation of operations on array: new, load, store, length */
609 tree
610 decode_newarray_type (atype)
611 int atype;
613 switch (atype)
615 case 4: return boolean_type_node;
616 case 5: return char_type_node;
617 case 6: return float_type_node;
618 case 7: return double_type_node;
619 case 8: return byte_type_node;
620 case 9: return short_type_node;
621 case 10: return int_type_node;
622 case 11: return long_type_node;
623 default: return NULL_TREE;
627 /* Map primitive type to the code used by OPCODE_newarray. */
630 encode_newarray_type (type)
631 tree type;
633 if (type == boolean_type_node)
634 return 4;
635 else if (type == char_type_node)
636 return 5;
637 else if (type == float_type_node)
638 return 6;
639 else if (type == double_type_node)
640 return 7;
641 else if (type == byte_type_node)
642 return 8;
643 else if (type == short_type_node)
644 return 9;
645 else if (type == int_type_node)
646 return 10;
647 else if (type == long_type_node)
648 return 11;
649 else
650 abort ();
653 /* Build a call to _Jv_ThrowBadArrayIndex(), the
654 ArrayIndexOfBoundsException exception handler. */
656 static tree
657 build_java_throw_out_of_bounds_exception (index)
658 tree index;
660 tree node = build (CALL_EXPR, int_type_node,
661 build_address_of (soft_badarrayindex_node),
662 build_tree_list (NULL_TREE, index), NULL_TREE);
663 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
664 return (node);
667 /* Return the length of an array. Doesn't perform any checking on the nature
668 or value of the array NODE. May be used to implement some bytecodes. */
670 tree
671 build_java_array_length_access (node)
672 tree node;
674 tree type = TREE_TYPE (node);
675 tree array_type = TREE_TYPE (type);
676 HOST_WIDE_INT length;
678 if (!is_array_type_p (type))
679 abort ();
681 length = java_array_type_length (type);
682 if (length >= 0)
683 return build_int_2 (length, 0);
685 node = build (COMPONENT_REF, int_type_node,
686 build_java_indirect_ref (array_type, node,
687 flag_check_references),
688 lookup_field (&array_type, get_identifier ("length")));
689 IS_ARRAY_LENGTH_ACCESS (node) = 1;
690 return node;
693 /* Optionally checks a reference against the NULL pointer. ARG1: the
694 expr, ARG2: we should check the reference. Don't generate extra
695 checks if we're not generating code. */
697 tree
698 java_check_reference (expr, check)
699 tree expr;
700 int check;
702 if (!flag_syntax_only && check)
704 tree cond;
705 expr = save_expr (expr);
706 cond = build (COND_EXPR, void_type_node,
707 build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
708 build (CALL_EXPR, void_type_node,
709 build_address_of (soft_nullpointer_node),
710 NULL_TREE, NULL_TREE),
711 empty_stmt_node);
712 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
715 return expr;
718 /* Reference an object: just like an INDIRECT_REF, but with checking. */
720 tree
721 build_java_indirect_ref (type, expr, check)
722 tree type;
723 tree expr;
724 int check;
726 return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
729 /* Implement array indexing (either as l-value or r-value).
730 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
731 Optionally performs bounds checking and/or test to NULL.
732 At this point, ARRAY should have been verified as an array. */
734 tree
735 build_java_arrayaccess (array, type, index)
736 tree array, type, index;
738 tree node, throw = NULL_TREE;
739 tree data_field;
740 tree ref;
741 tree array_type = TREE_TYPE (TREE_TYPE (array));
743 if (flag_bounds_check)
745 /* Generate:
746 * (unsigned jint) INDEX >= (unsigned jint) LEN
747 * && throw ArrayIndexOutOfBoundsException.
748 * Note this is equivalent to and more efficient than:
749 * INDEX < 0 || INDEX >= LEN && throw ... */
750 tree test;
751 tree len = build_java_array_length_access (array);
752 TREE_TYPE (len) = unsigned_int_type_node;
753 test = fold (build (GE_EXPR, boolean_type_node,
754 convert (unsigned_int_type_node, index),
755 len));
756 if (! integer_zerop (test))
758 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
759 build_java_throw_out_of_bounds_exception (index));
760 /* allows expansion within COMPOUND */
761 TREE_SIDE_EFFECTS( throw ) = 1;
765 /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
766 to have the bounds check evaluated first. */
767 if (throw != NULL_TREE)
768 index = build (COMPOUND_EXPR, int_type_node, throw, index);
770 data_field = lookup_field (&array_type, get_identifier ("data"));
772 ref = build (COMPONENT_REF, TREE_TYPE (data_field),
773 build_java_indirect_ref (array_type, array,
774 flag_check_references),
775 data_field);
777 node = build (ARRAY_REF, type, ref, index);
778 return node;
781 /* Generate code to throw an ArrayStoreException if OBJECT is not assignable
782 (at runtime) to an element of ARRAY. A NOP_EXPR is returned if it can
783 determine that no check is required. */
785 tree
786 build_java_arraystore_check (array, object)
787 tree array;
788 tree object;
790 tree check, element_type, source;
791 tree array_type_p = TREE_TYPE (array);
792 tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));
794 if (! is_array_type_p (array_type_p))
795 abort ();
797 /* Get the TYPE_DECL for ARRAY's element type. */
798 element_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
800 if (TREE_CODE (element_type) != TYPE_DECL
801 || TREE_CODE (object_type) != TYPE_DECL)
802 abort ();
804 if (!flag_store_check)
805 return build1 (NOP_EXPR, array_type_p, array);
807 /* No check is needed if the element type is final or is itself an array.
808 Also check that element_type matches object_type, since in the bytecode
809 compilation case element_type may be the actual element type of the arra
810 rather than its declared type. */
811 if (element_type == object_type
812 && (TYPE_ARRAY_P (TREE_TYPE (element_type))
813 || CLASS_FINAL (element_type)))
814 return build1 (NOP_EXPR, array_type_p, array);
816 /* OBJECT might be wrapped by a SAVE_EXPR. */
817 if (TREE_CODE (object) == SAVE_EXPR)
818 source = TREE_OPERAND (object, 0);
819 else
820 source = object;
822 /* Avoid the check if OBJECT was just loaded from the same array. */
823 if (TREE_CODE (source) == ARRAY_REF)
825 tree target;
826 source = TREE_OPERAND (source, 0); /* COMPONENT_REF. */
827 source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
828 source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
829 if (TREE_CODE (source) == SAVE_EXPR)
830 source = TREE_OPERAND (source, 0);
832 target = array;
833 if (TREE_CODE (target) == SAVE_EXPR)
834 target = TREE_OPERAND (target, 0);
836 if (source == target)
837 return build1 (NOP_EXPR, array_type_p, array);
840 /* Build an invocation of _Jv_CheckArrayStore */
841 check = build (CALL_EXPR, void_type_node,
842 build_address_of (soft_checkarraystore_node),
843 tree_cons (NULL_TREE, array,
844 build_tree_list (NULL_TREE, object)),
845 NULL_TREE);
846 TREE_SIDE_EFFECTS (check) = 1;
848 return check;
851 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
852 ARRAY_NODE. This function is used to retrieve something less vague than
853 a pointer type when indexing the first dimension of something like [[<t>.
854 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
855 return unchanged.
856 As a side effect, it also makes sure that ARRAY_NODE is an array. */
858 static tree
859 build_java_check_indexed_type (array_node, indexed_type)
860 tree array_node;
861 tree indexed_type;
863 tree elt_type;
865 if (!is_array_type_p (TREE_TYPE (array_node)))
866 abort ();
868 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
870 if (indexed_type == ptr_type_node )
871 return promote_type (elt_type);
873 /* BYTE/BOOLEAN store and load are used for both type */
874 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
875 return boolean_type_node;
877 if (indexed_type != elt_type )
878 abort ();
879 else
880 return indexed_type;
883 /* newarray triggers a call to _Jv_NewPrimArray. This function should be
884 called with an integer code (the type of array to create), and the length
885 of the array to create. */
887 tree
888 build_newarray (atype_value, length)
889 int atype_value;
890 tree length;
892 tree type_arg;
894 tree prim_type = decode_newarray_type (atype_value);
895 tree type
896 = build_java_array_type (prim_type,
897 host_integerp (length, 0) == INTEGER_CST
898 ? tree_low_cst (length, 0) : -1);
900 /* If compiling to native, pass a reference to the primitive type class
901 and save the runtime some work. However, the bytecode generator
902 expects to find the type_code int here. */
903 if (flag_emit_class_files)
904 type_arg = build_int_2 (atype_value, 0);
905 else
906 type_arg = build_class_ref (prim_type);
908 return build (CALL_EXPR, promote_type (type),
909 build_address_of (soft_newarray_node),
910 tree_cons (NULL_TREE,
911 type_arg,
912 build_tree_list (NULL_TREE, length)),
913 NULL_TREE);
916 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
917 of the dimension. */
919 tree
920 build_anewarray (class_type, length)
921 tree class_type;
922 tree length;
924 tree type
925 = build_java_array_type (class_type,
926 host_integerp (length, 0)
927 ? tree_low_cst (length, 0) : -1);
929 return build (CALL_EXPR, promote_type (type),
930 build_address_of (soft_anewarray_node),
931 tree_cons (NULL_TREE, length,
932 tree_cons (NULL_TREE, build_class_ref (class_type),
933 build_tree_list (NULL_TREE,
934 null_pointer_node))),
935 NULL_TREE);
938 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
940 tree
941 build_new_array (type, length)
942 tree type;
943 tree length;
945 if (JPRIMITIVE_TYPE_P (type))
946 return build_newarray (encode_newarray_type (type), length);
947 else
948 return build_anewarray (TREE_TYPE (type), length);
951 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
952 class pointer, a number of dimensions and the matching number of
953 dimensions. The argument list is NULL terminated. */
955 static void
956 expand_java_multianewarray (class_type, ndim)
957 tree class_type;
958 int ndim;
960 int i;
961 tree args = build_tree_list( NULL_TREE, null_pointer_node );
963 for( i = 0; i < ndim; i++ )
964 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
966 push_value (build (CALL_EXPR,
967 promote_type (class_type),
968 build_address_of (soft_multianewarray_node),
969 tree_cons (NULL_TREE, build_class_ref (class_type),
970 tree_cons (NULL_TREE,
971 build_int_2 (ndim, 0), args )),
972 NULL_TREE));
975 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
976 ARRAY is an array type. May expand some bound checking and NULL
977 pointer checking. RHS_TYPE_NODE we are going to store. In the case
978 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
979 INT. In those cases, we make the convertion.
981 if ARRAy is a reference type, the assignment is checked at run-time
982 to make sure that the RHS can be assigned to the array element
983 type. It is not necessary to generate this code if ARRAY is final. */
985 static void
986 expand_java_arraystore (rhs_type_node)
987 tree rhs_type_node;
989 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
990 && TYPE_PRECISION (rhs_type_node) <= 32) ?
991 int_type_node : rhs_type_node);
992 tree index = pop_value (int_type_node);
993 tree array = pop_value (ptr_type_node);
995 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
997 flush_quick_stack ();
999 index = save_expr (index);
1000 array = save_expr (array);
1002 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
1004 tree check = build_java_arraystore_check (array, rhs_node);
1005 expand_expr_stmt (check);
1008 expand_assignment (build_java_arrayaccess (array,
1009 rhs_type_node,
1010 index),
1011 rhs_node, 0, 0);
1014 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
1015 sure that LHS is an array type. May expand some bound checking and NULL
1016 pointer checking.
1017 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
1018 BOOLEAN/SHORT, we push a promoted type back to the stack.
1021 static void
1022 expand_java_arrayload (lhs_type_node )
1023 tree lhs_type_node;
1025 tree load_node;
1026 tree index_node = pop_value (int_type_node);
1027 tree array_node = pop_value (ptr_type_node);
1029 index_node = save_expr (index_node);
1030 array_node = save_expr (array_node);
1031 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
1033 load_node = build_java_arrayaccess (array_node,
1034 lhs_type_node,
1035 index_node);
1037 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1038 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
1039 push_value (load_node);
1042 /* Expands .length. Makes sure that we deal with and array and may expand
1043 a NULL check on the array object. */
1045 static void
1046 expand_java_array_length ()
1048 tree array = pop_value (ptr_type_node);
1049 tree length = build_java_array_length_access (array);
1051 push_value (length);
1054 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1055 either soft_monitorenter_node or soft_monitorexit_node. */
1057 static tree
1058 build_java_monitor (call, object)
1059 tree call;
1060 tree object;
1062 return (build (CALL_EXPR,
1063 void_type_node,
1064 build_address_of (call),
1065 build_tree_list (NULL_TREE, object),
1066 NULL_TREE));
1069 /* Emit code for one of the PUSHC instructions. */
1071 static void
1072 expand_java_pushc (ival, type)
1073 int ival;
1074 tree type;
1076 tree value;
1077 if (type == ptr_type_node && ival == 0)
1078 value = null_pointer_node;
1079 else if (type == int_type_node || type == long_type_node)
1081 value = build_int_2 (ival, ival < 0 ? -1 : 0);
1082 TREE_TYPE (value) = type;
1084 else if (type == float_type_node || type == double_type_node)
1086 REAL_VALUE_TYPE x;
1087 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1088 value = build_real (type, x);
1090 else
1091 abort ();
1093 push_value (value);
1096 static void
1097 expand_java_return (type)
1098 tree type;
1100 if (type == void_type_node)
1101 expand_null_return ();
1102 else
1104 tree retval = pop_value (type);
1105 tree res = DECL_RESULT (current_function_decl);
1106 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1108 /* Handle the situation where the native integer type is smaller
1109 than the JVM integer. It can happen for many cross compilers.
1110 The whole if expression just goes away if INT_TYPE_SIZE < 32
1111 is false. */
1112 if (INT_TYPE_SIZE < 32
1113 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1114 < GET_MODE_SIZE (TYPE_MODE (type))))
1115 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1117 TREE_SIDE_EFFECTS (retval) = 1;
1118 expand_return (retval);
1122 static void
1123 expand_load_internal (index, type, pc)
1124 int index;
1125 tree type;
1126 int pc;
1128 tree copy;
1129 tree var = find_local_variable (index, type, pc);
1131 /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1132 on the stack. If there is an assignment to this VAR_DECL between
1133 the stack push and the use, then the wrong code could be
1134 generated. To avoid this we create a new local and copy our
1135 value into it. Then we push this new local on the stack.
1136 Hopefully this all gets optimized out. */
1137 copy = build_decl (VAR_DECL, NULL_TREE, type);
1138 DECL_CONTEXT (copy) = current_function_decl;
1139 layout_decl (copy, 0);
1140 DECL_REGISTER (copy) = 1;
1141 expand_decl (copy);
1142 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
1143 DECL_INITIAL (copy) = var;
1144 expand_decl_init (copy);
1145 push_value (copy);
1148 tree
1149 build_address_of (value)
1150 tree value;
1152 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1155 bool class_has_finalize_method (type)
1156 tree type;
1158 tree super = CLASSTYPE_SUPER (type);
1160 if (super == NULL_TREE)
1161 return false; /* Every class with a real finalizer inherits */
1162 /* from java.lang.Object. */
1163 else
1164 return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1167 static void
1168 expand_java_NEW (type)
1169 tree type;
1171 tree alloc_node;
1173 alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1174 : alloc_no_finalizer_node);
1175 if (! CLASS_LOADED_P (type))
1176 load_class (type, 1);
1177 safe_layout_class (type);
1178 push_value (build (CALL_EXPR, promote_type (type),
1179 build_address_of (alloc_node),
1180 tree_cons (NULL_TREE, build_class_ref (type),
1181 build_tree_list (NULL_TREE,
1182 size_in_bytes (type))),
1183 NULL_TREE));
1186 /* This returns an expression which will extract the class of an
1187 object. */
1189 tree
1190 build_get_class (value)
1191 tree value;
1193 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1194 tree vtable_field = lookup_field (&object_type_node,
1195 get_identifier ("vtable"));
1196 return build (COMPONENT_REF, class_ptr_type,
1197 build1 (INDIRECT_REF, dtable_type,
1198 build (COMPONENT_REF, dtable_ptr_type,
1199 build_java_indirect_ref (object_type_node, value,
1200 flag_check_references),
1201 vtable_field)),
1202 class_field);
1205 /* This builds the tree representation of the `instanceof' operator.
1206 It tries various tricks to optimize this in cases where types are
1207 known. */
1209 tree
1210 build_instanceof (value, type)
1211 tree value, type;
1213 tree expr;
1214 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1215 tree valtype = TREE_TYPE (TREE_TYPE (value));
1216 tree valclass = TYPE_NAME (valtype);
1217 tree klass;
1219 /* When compiling from bytecode, we need to ensure that TYPE has
1220 been loaded. */
1221 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1223 load_class (type, 1);
1224 safe_layout_class (type);
1225 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1226 return error_mark_node;
1228 klass = TYPE_NAME (type);
1230 if (type == object_type_node || inherits_from_p (valtype, type))
1232 /* Anything except `null' is an instance of Object. Likewise,
1233 if the object is known to be an instance of the class, then
1234 we only need to check for `null'. */
1235 expr = build (COND_EXPR, itype,
1236 value,
1237 boolean_true_node, boolean_false_node);
1239 else if (! TYPE_ARRAY_P (type)
1240 && ! TYPE_ARRAY_P (valtype)
1241 && DECL_P (klass) && DECL_P (valclass)
1242 && ! CLASS_INTERFACE (valclass)
1243 && ! CLASS_INTERFACE (klass)
1244 && ! inherits_from_p (type, valtype)
1245 && (CLASS_FINAL (klass)
1246 || ! inherits_from_p (valtype, type)))
1248 /* The classes are from different branches of the derivation
1249 tree, so we immediately know the answer. */
1250 expr = boolean_false_node;
1252 else if (DECL_P (klass) && CLASS_FINAL (klass))
1254 tree save = save_expr (value);
1255 expr = build (COND_EXPR, itype,
1256 save,
1257 build (EQ_EXPR, itype,
1258 build_get_class (save),
1259 build_class_ref (type)),
1260 boolean_false_node);
1262 else
1264 expr = build (CALL_EXPR, itype,
1265 build_address_of (soft_instanceof_node),
1266 tree_cons (NULL_TREE, value,
1267 build_tree_list (NULL_TREE,
1268 build_class_ref (type))),
1269 NULL_TREE);
1271 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1272 return expr;
1275 static void
1276 expand_java_INSTANCEOF (type)
1277 tree type;
1279 tree value = pop_value (object_ptr_type_node);
1280 value = build_instanceof (value, type);
1281 push_value (value);
1284 static void
1285 expand_java_CHECKCAST (type)
1286 tree type;
1288 tree value = pop_value (ptr_type_node);
1289 value = build (CALL_EXPR, promote_type (type),
1290 build_address_of (soft_checkcast_node),
1291 tree_cons (NULL_TREE, build_class_ref (type),
1292 build_tree_list (NULL_TREE, value)),
1293 NULL_TREE);
1294 push_value (value);
1297 static void
1298 expand_iinc (local_var_index, ival, pc)
1299 unsigned int local_var_index;
1300 int ival;
1301 int pc;
1303 tree local_var, res;
1304 tree constant_value;
1306 flush_quick_stack ();
1307 local_var = find_local_variable (local_var_index, int_type_node, pc);
1308 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1309 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1310 expand_assignment (local_var, res, 0, 0);
1314 tree
1315 build_java_soft_divmod (op, type, op1, op2)
1316 enum tree_code op;
1317 tree type, op1, op2;
1319 tree call = NULL;
1320 tree arg1 = convert (type, op1);
1321 tree arg2 = convert (type, op2);
1323 if (type == int_type_node)
1325 switch (op)
1327 case TRUNC_DIV_EXPR:
1328 call = soft_idiv_node;
1329 break;
1330 case TRUNC_MOD_EXPR:
1331 call = soft_irem_node;
1332 break;
1333 default:
1334 break;
1337 else if (type == long_type_node)
1339 switch (op)
1341 case TRUNC_DIV_EXPR:
1342 call = soft_ldiv_node;
1343 break;
1344 case TRUNC_MOD_EXPR:
1345 call = soft_lrem_node;
1346 break;
1347 default:
1348 break;
1352 if (! call)
1353 abort ();
1355 call = build (CALL_EXPR, type,
1356 build_address_of (call),
1357 tree_cons (NULL_TREE, arg1,
1358 build_tree_list (NULL_TREE, arg2)),
1359 NULL_TREE);
1361 return call;
1364 tree
1365 build_java_binop (op, type, arg1, arg2)
1366 enum tree_code op;
1367 tree type, arg1, arg2;
1369 tree mask;
1370 switch (op)
1372 case URSHIFT_EXPR:
1374 tree u_type = java_unsigned_type (type);
1375 arg1 = convert (u_type, arg1);
1376 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1377 return convert (type, arg1);
1379 case LSHIFT_EXPR:
1380 case RSHIFT_EXPR:
1381 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1382 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1383 break;
1385 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1386 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1387 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1389 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1390 boolean_type_node, arg1, arg2));
1391 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1392 tree second_compare = fold (build (COND_EXPR, int_type_node,
1393 ifexp2, integer_zero_node,
1394 op == COMPARE_L_EXPR
1395 ? integer_minus_one_node
1396 : integer_one_node));
1397 return fold (build (COND_EXPR, int_type_node, ifexp1,
1398 op == COMPARE_L_EXPR ? integer_one_node
1399 : integer_minus_one_node,
1400 second_compare));
1402 case COMPARE_EXPR:
1403 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1405 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1406 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1407 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1408 ifexp2, integer_one_node,
1409 integer_zero_node));
1410 return fold (build (COND_EXPR, int_type_node,
1411 ifexp1, integer_minus_one_node, second_compare));
1413 case TRUNC_DIV_EXPR:
1414 case TRUNC_MOD_EXPR:
1415 if (TREE_CODE (type) == REAL_TYPE
1416 && op == TRUNC_MOD_EXPR)
1418 tree call;
1419 if (type != double_type_node)
1421 arg1 = convert (double_type_node, arg1);
1422 arg2 = convert (double_type_node, arg2);
1424 call = build (CALL_EXPR, double_type_node,
1425 build_address_of (soft_fmod_node),
1426 tree_cons (NULL_TREE, arg1,
1427 build_tree_list (NULL_TREE, arg2)),
1428 NULL_TREE);
1429 if (type != double_type_node)
1430 call = convert (type, call);
1431 return call;
1434 if (TREE_CODE (type) == INTEGER_TYPE
1435 && flag_use_divide_subroutine
1436 && ! flag_syntax_only)
1437 return build_java_soft_divmod (op, type, arg1, arg2);
1439 break;
1440 default: ;
1442 return fold (build (op, type, arg1, arg2));
1445 static void
1446 expand_java_binop (type, op)
1447 tree type; enum tree_code op;
1449 tree larg, rarg;
1450 tree ltype = type;
1451 tree rtype = type;
1452 switch (op)
1454 case LSHIFT_EXPR:
1455 case RSHIFT_EXPR:
1456 case URSHIFT_EXPR:
1457 rtype = int_type_node;
1458 rarg = pop_value (rtype);
1459 break;
1460 default:
1461 rarg = pop_value (rtype);
1463 larg = pop_value (ltype);
1464 push_value (build_java_binop (op, type, larg, rarg));
1467 /* Lookup the field named NAME in *TYPEP or its super classes.
1468 If not found, return NULL_TREE.
1469 (If the *TYPEP is not found, or if the field reference is
1470 ambiguous, return error_mark_node.)
1471 If found, return the FIELD_DECL, and set *TYPEP to the
1472 class containing the field. */
1474 tree
1475 lookup_field (typep, name)
1476 tree *typep;
1477 tree name;
1479 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1481 load_class (*typep, 1);
1482 safe_layout_class (*typep);
1483 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1484 return error_mark_node;
1488 tree field, basetype_vec;
1489 tree save_field;
1490 int n, i;
1492 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1493 if (DECL_NAME (field) == name)
1494 return field;
1496 /* Process implemented interfaces. */
1497 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1498 n = TREE_VEC_LENGTH (basetype_vec);
1499 save_field = NULL_TREE;
1500 for (i = 0; i < n; i++)
1502 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1503 if ((field = lookup_field (&t, name)))
1505 if (save_field == field)
1506 continue;
1507 if (save_field == NULL_TREE)
1508 save_field = field;
1509 else
1511 tree i1 = DECL_CONTEXT (save_field);
1512 tree i2 = DECL_CONTEXT (field);
1513 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1514 IDENTIFIER_POINTER (name),
1515 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1516 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1517 return error_mark_node;
1522 if (save_field != NULL_TREE)
1523 return save_field;
1525 *typep = CLASSTYPE_SUPER (*typep);
1526 } while (*typep);
1527 return NULL_TREE;
1530 /* Look up the field named NAME in object SELF_VALUE,
1531 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1532 SELF_VALUE is NULL_TREE if looking for a static field. */
1534 tree
1535 build_field_ref (self_value, self_class, name)
1536 tree self_value, self_class, name;
1538 tree base_class = self_class;
1539 tree field_decl = lookup_field (&base_class, name);
1540 if (field_decl == NULL_TREE)
1542 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1543 return error_mark_node;
1545 if (self_value == NULL_TREE)
1547 return build_static_field_ref (field_decl);
1549 else
1551 int check = (flag_check_references
1552 && ! (DECL_P (self_value)
1553 && DECL_NAME (self_value) == this_identifier_node));
1555 tree base_type = promote_type (base_class);
1556 if (base_type != TREE_TYPE (self_value))
1557 self_value = fold (build1 (NOP_EXPR, base_type, self_value));
1558 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1559 self_value, check);
1560 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1561 self_value, field_decl));
1565 tree
1566 lookup_label (pc)
1567 int pc;
1569 tree name;
1570 char buf[32];
1571 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1572 name = get_identifier (buf);
1573 if (IDENTIFIER_LOCAL_VALUE (name))
1574 return IDENTIFIER_LOCAL_VALUE (name);
1575 else
1577 /* The type of the address of a label is return_address_type_node. */
1578 tree decl = create_label_decl (name);
1579 LABEL_PC (decl) = pc;
1580 label_rtx (decl);
1581 return pushdecl (decl);
1585 /* Generate a unique name for the purpose of loops and switches
1586 labels, and try-catch-finally blocks label or temporary variables. */
1588 tree
1589 generate_name ()
1591 static int l_number = 0;
1592 char buff [32];
1593 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1594 l_number++;
1595 return get_identifier (buff);
1598 tree
1599 create_label_decl (name)
1600 tree name;
1602 tree decl;
1603 decl = build_decl (LABEL_DECL, name,
1604 TREE_TYPE (return_address_type_node));
1605 DECL_CONTEXT (decl) = current_function_decl;
1606 DECL_IGNORED_P (decl) = 1;
1607 return decl;
1610 /* This maps a bytecode offset (PC) to various flags. */
1611 char *instruction_bits;
1613 static void
1614 note_label (current_pc, target_pc)
1615 int current_pc ATTRIBUTE_UNUSED, target_pc;
1617 lookup_label (target_pc);
1618 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1621 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1622 where CONDITION is one of one the compare operators. */
1624 static void
1625 expand_compare (condition, value1, value2, target_pc)
1626 enum tree_code condition;
1627 tree value1, value2;
1628 int target_pc;
1630 tree target = lookup_label (target_pc);
1631 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1632 expand_start_cond (java_truthvalue_conversion (cond), 0);
1633 expand_goto (target);
1634 expand_end_cond ();
1637 /* Emit code for a TEST-type opcode. */
1639 static void
1640 expand_test (condition, type, target_pc)
1641 enum tree_code condition;
1642 tree type;
1643 int target_pc;
1645 tree value1, value2;
1646 flush_quick_stack ();
1647 value1 = pop_value (type);
1648 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1649 expand_compare (condition, value1, value2, target_pc);
1652 /* Emit code for a COND-type opcode. */
1654 static void
1655 expand_cond (condition, type, target_pc)
1656 enum tree_code condition;
1657 tree type;
1658 int target_pc;
1660 tree value1, value2;
1661 flush_quick_stack ();
1662 /* note: pop values in opposite order */
1663 value2 = pop_value (type);
1664 value1 = pop_value (type);
1665 /* Maybe should check value1 and value2 for type compatibility ??? */
1666 expand_compare (condition, value1, value2, target_pc);
1669 static void
1670 expand_java_goto (target_pc)
1671 int target_pc;
1673 tree target_label = lookup_label (target_pc);
1674 flush_quick_stack ();
1675 expand_goto (target_label);
1678 #if 0
1679 static void
1680 expand_java_call (target_pc, return_address)
1681 int target_pc, return_address;
1683 tree target_label = lookup_label (target_pc);
1684 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1685 push_value (value);
1686 flush_quick_stack ();
1687 expand_goto (target_label);
1690 static void
1691 expand_java_ret (return_address)
1692 tree return_address ATTRIBUTE_UNUSED;
1694 warning ("ret instruction not implemented");
1695 #if 0
1696 tree target_label = lookup_label (target_pc);
1697 flush_quick_stack ();
1698 expand_goto (target_label);
1699 #endif
1701 #endif
1703 static tree
1704 pop_arguments (arg_types)
1705 tree arg_types;
1707 if (arg_types == end_params_node)
1708 return NULL_TREE;
1709 if (TREE_CODE (arg_types) == TREE_LIST)
1711 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1712 tree type = TREE_VALUE (arg_types);
1713 tree arg = pop_value (type);
1714 if (PROMOTE_PROTOTYPES
1715 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1716 && INTEGRAL_TYPE_P (type))
1717 arg = convert (integer_type_node, arg);
1718 return tree_cons (NULL_TREE, arg, tail);
1720 abort ();
1723 /* Build an expression to initialize the class CLAS.
1724 if EXPR is non-NULL, returns an expression to first call the initializer
1725 (if it is needed) and then calls EXPR. */
1727 tree
1728 build_class_init (clas, expr)
1729 tree clas, expr;
1731 tree init;
1732 if (inherits_from_p (current_class, clas))
1733 return expr;
1735 if (always_initialize_class_p)
1737 init = build (CALL_EXPR, void_type_node,
1738 build_address_of (soft_initclass_node),
1739 build_tree_list (NULL_TREE, build_class_ref (clas)),
1740 NULL_TREE);
1741 TREE_SIDE_EFFECTS (init) = 1;
1743 else
1745 tree *init_test_decl;
1746 init_test_decl = java_treetreehash_new
1747 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);
1749 if (*init_test_decl == NULL)
1751 /* Build a declaration and mark it as a flag used to track
1752 static class initializations. */
1753 *init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1754 boolean_type_node);
1755 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (*init_test_decl);
1756 LOCAL_CLASS_INITIALIZATION_FLAG (*init_test_decl) = 1;
1757 DECL_CONTEXT (*init_test_decl) = current_function_decl;
1758 DECL_FUNCTION_INIT_TEST_CLASS (*init_test_decl) = clas;
1759 /* Tell the check-init code to ignore this decl when not
1760 optimizing class initialization. */
1761 if (!STATIC_CLASS_INIT_OPT_P ())
1762 DECL_BIT_INDEX(*init_test_decl) = -1;
1765 init = build (CALL_EXPR, void_type_node,
1766 build_address_of (soft_initclass_node),
1767 build_tree_list (NULL_TREE, build_class_ref (clas)),
1768 NULL_TREE);
1769 TREE_SIDE_EFFECTS (init) = 1;
1770 init = build (COND_EXPR, void_type_node,
1771 build (EQ_EXPR, boolean_type_node,
1772 *init_test_decl, boolean_false_node),
1773 init, integer_zero_node);
1774 TREE_SIDE_EFFECTS (init) = 1;
1775 init = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1776 build (MODIFY_EXPR, boolean_type_node,
1777 *init_test_decl, boolean_true_node));
1778 TREE_SIDE_EFFECTS (init) = 1;
1781 if (expr != NULL_TREE)
1783 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1784 TREE_SIDE_EFFECTS (expr) = 1;
1785 return expr;
1787 return init;
1790 tree
1791 build_known_method_ref (method, method_type, self_type,
1792 method_signature, arg_list)
1793 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1794 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1796 tree func;
1797 if (is_compiled_class (self_type))
1799 make_decl_rtl (method, NULL);
1800 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1802 else
1804 /* We don't know whether the method has been (statically) compiled.
1805 Compile this code to get a reference to the method's code:
1807 SELF_TYPE->methods[METHOD_INDEX].ncode
1809 This is guaranteed to work (assuming SELF_TYPE has
1810 been initialized), since if the method is not compiled yet,
1811 its ncode points to a trampoline that forces compilation. */
1813 int method_index = 0;
1814 tree meth;
1815 tree ref = build_class_ref (self_type);
1816 ref = build1 (INDIRECT_REF, class_type_node, ref);
1817 if (ncode_ident == NULL_TREE)
1818 ncode_ident = get_identifier ("ncode");
1819 if (methods_ident == NULL_TREE)
1820 methods_ident = get_identifier ("methods");
1821 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1822 lookup_field (&class_type_node, methods_ident));
1823 for (meth = TYPE_METHODS (self_type);
1824 ; meth = TREE_CHAIN (meth))
1826 if (method == meth)
1827 break;
1828 if (meth == NULL_TREE)
1829 fatal_error ("method '%s' not found in class",
1830 IDENTIFIER_POINTER (DECL_NAME (method)));
1831 method_index++;
1833 method_index *= int_size_in_bytes (method_type_node);
1834 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1835 ref, build_int_2 (method_index, 0)));
1836 ref = build1 (INDIRECT_REF, method_type_node, ref);
1837 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1838 ref,
1839 lookup_field (&method_type_node, ncode_ident));
1841 return func;
1844 tree
1845 invoke_build_dtable (is_invoke_interface, arg_list)
1846 int is_invoke_interface;
1847 tree arg_list;
1849 tree dtable, objectref;
1851 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1853 /* If we're dealing with interfaces and if the objectref
1854 argument is an array then get the dispatch table of the class
1855 Object rather than the one from the objectref. */
1856 objectref = (is_invoke_interface
1857 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1858 object_type_node : TREE_VALUE (arg_list));
1860 if (dtable_ident == NULL_TREE)
1861 dtable_ident = get_identifier ("vtable");
1862 dtable = build_java_indirect_ref (object_type_node, objectref,
1863 flag_check_references);
1864 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1865 lookup_field (&object_type_node, dtable_ident));
1867 return dtable;
1870 /* Determine the index in the virtual offset table (otable) for a call to
1871 METHOD. If this method has not been seen before, it will be added to the
1872 otable_methods. If it has, the existing otable slot will be reused. */
1875 get_offset_table_index (method)
1876 tree method;
1878 int i = 1;
1879 tree method_list;
1881 if (otable_methods == NULL_TREE)
1883 otable_methods = build_tree_list (method, method);
1884 return 1;
1887 method_list = otable_methods;
1889 while (1)
1891 if (TREE_VALUE (method_list) == method)
1892 return i;
1893 i++;
1894 if (TREE_CHAIN (method_list) == NULL_TREE)
1895 break;
1896 else
1897 method_list = TREE_CHAIN (method_list);
1900 TREE_CHAIN (method_list) = build_tree_list (method, method);
1901 return i;
1904 tree
1905 build_invokevirtual (dtable, method)
1906 tree dtable, method;
1908 tree func;
1909 tree nativecode_ptr_ptr_type_node
1910 = build_pointer_type (nativecode_ptr_type_node);
1911 tree method_index;
1912 tree otable_index;
1914 if (flag_indirect_dispatch)
1916 otable_index = build_int_2 (get_offset_table_index (method), 0);
1917 method_index = build (ARRAY_REF, integer_type_node, otable_decl,
1918 otable_index);
1920 else
1922 method_index = convert (sizetype, DECL_VINDEX (method));
1924 if (TARGET_VTABLE_USES_DESCRIPTORS)
1925 /* Add one to skip bogus descriptor for class and GC descriptor. */
1926 method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
1927 else
1928 /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
1929 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1931 method_index = size_binop (MULT_EXPR, method_index,
1932 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1934 if (TARGET_VTABLE_USES_DESCRIPTORS)
1935 method_index = size_binop (MULT_EXPR, method_index,
1936 size_int (TARGET_VTABLE_USES_DESCRIPTORS));
1939 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1940 convert (nativecode_ptr_ptr_type_node, method_index)));
1942 if (TARGET_VTABLE_USES_DESCRIPTORS)
1943 func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
1944 else
1945 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1947 return func;
1950 static GTY(()) tree class_ident;
1951 tree
1952 build_invokeinterface (dtable, method)
1953 tree dtable, method;
1955 tree lookup_arg;
1956 tree interface;
1957 tree idx;
1958 tree meth;
1959 tree otable_index;
1960 int i;
1962 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1963 ensure that the selected method exists, is public and not
1964 abstract nor static. */
1966 if (class_ident == NULL_TREE)
1968 class_ident = get_identifier ("class");
1971 dtable = build_java_indirect_ref (dtable_type, dtable, flag_check_references);
1972 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1973 lookup_field (&dtable_type, class_ident));
1975 interface = DECL_CONTEXT (method);
1976 layout_class_methods (interface);
1978 if (flag_indirect_dispatch)
1980 otable_index = build_int_2 (get_offset_table_index (method), 0);
1981 idx = build (ARRAY_REF, integer_type_node, otable_decl, otable_index);
1983 else
1985 i = 1;
1986 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1988 if (meth == method)
1990 idx = build_int_2 (i, 0);
1991 break;
1993 if (meth == NULL_TREE)
1994 abort ();
1998 lookup_arg = tree_cons (NULL_TREE, dtable,
1999 tree_cons (NULL_TREE, build_class_ref (interface),
2000 build_tree_list (NULL_TREE, idx)));
2002 return build (CALL_EXPR, ptr_type_node,
2003 build_address_of (soft_lookupinterfacemethod_node),
2004 lookup_arg, NULL_TREE);
2007 /* Expand one of the invoke_* opcodes.
2008 OCPODE is the specific opcode.
2009 METHOD_REF_INDEX is an index into the constant pool.
2010 NARGS is the number of arguments, or -1 if not specified. */
2012 static void
2013 expand_invoke (opcode, method_ref_index, nargs)
2014 int opcode;
2015 int method_ref_index;
2016 int nargs ATTRIBUTE_UNUSED;
2018 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
2019 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
2020 tree self_type = get_class_constant
2021 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
2022 const char *const self_name
2023 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2024 tree call, func, method, arg_list, method_type;
2025 tree check = NULL_TREE;
2027 if (! CLASS_LOADED_P (self_type))
2029 load_class (self_type, 1);
2030 safe_layout_class (self_type);
2031 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2032 fatal_error ("failed to find class '%s'", self_name);
2034 layout_class_methods (self_type);
2036 if (ID_INIT_P (method_name))
2037 method = lookup_java_constructor (self_type, method_signature);
2038 else
2039 method = lookup_java_method (self_type, method_name, method_signature);
2040 if (method == NULL_TREE)
2042 error ("class '%s' has no method named '%s' matching signature '%s'",
2043 self_name,
2044 IDENTIFIER_POINTER (method_name),
2045 IDENTIFIER_POINTER (method_signature));
2047 /* Invoke static can't invoke static/abstract method */
2048 else if (opcode == OPCODE_invokestatic)
2050 if (!METHOD_STATIC (method))
2052 error ("invokestatic on non static method");
2053 method = NULL_TREE;
2055 else if (METHOD_ABSTRACT (method))
2057 error ("invokestatic on abstract method");
2058 method = NULL_TREE;
2061 else
2063 if (METHOD_STATIC (method))
2065 error ("invoke[non-static] on static method");
2066 method = NULL_TREE;
2070 if (method == NULL_TREE)
2072 method_type = get_type_from_signature (method_signature);
2073 pop_arguments (TYPE_ARG_TYPES (method_type));
2074 if (opcode != OPCODE_invokestatic)
2075 pop_type (self_type);
2076 method_type = promote_type (TREE_TYPE (method_type));
2077 push_value (convert (method_type, integer_zero_node));
2078 return;
2081 method_type = TREE_TYPE (method);
2082 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2083 flush_quick_stack ();
2085 func = NULL_TREE;
2086 if (opcode == OPCODE_invokestatic)
2087 func = build_known_method_ref (method, method_type, self_type,
2088 method_signature, arg_list);
2089 else if (opcode == OPCODE_invokespecial
2090 || (opcode == OPCODE_invokevirtual
2091 && (METHOD_PRIVATE (method)
2092 || METHOD_FINAL (method)
2093 || CLASS_FINAL (TYPE_NAME (self_type)))))
2095 /* If the object for the method call is null, we throw an
2096 exception. We don't do this if the object is the current
2097 method's `this'. In other cases we just rely on an
2098 optimization pass to eliminate redundant checks. FIXME:
2099 Unfortunately there doesn't seem to be a way to determine
2100 what the current method is right now.
2101 We do omit the check if we're calling <init>. */
2102 /* We use a SAVE_EXPR here to make sure we only evaluate
2103 the new `self' expression once. */
2104 tree save_arg = save_expr (TREE_VALUE (arg_list));
2105 TREE_VALUE (arg_list) = save_arg;
2106 check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2107 func = build_known_method_ref (method, method_type, self_type,
2108 method_signature, arg_list);
2110 else
2112 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
2113 arg_list);
2114 if (opcode == OPCODE_invokevirtual)
2115 func = build_invokevirtual (dtable, method);
2116 else
2117 func = build_invokeinterface (dtable, method);
2119 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2121 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
2122 TREE_SIDE_EFFECTS (call) = 1;
2123 call = check_for_builtin (method, call);
2125 if (check != NULL_TREE)
2127 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2128 TREE_SIDE_EFFECTS (call) = 1;
2131 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2132 expand_expr_stmt (call);
2133 else
2135 push_value (call);
2136 flush_quick_stack ();
2140 /* Create a stub which will be put into the vtable but which will call
2141 a JNI function. */
2143 tree
2144 build_jni_stub (method)
2145 tree method;
2147 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2148 tree jni_func_type, tem;
2149 tree env_var, res_var = NULL_TREE, block;
2150 tree method_args, res_type;
2151 tree meth_var;
2153 tree klass = DECL_CONTEXT (method);
2154 int from_class = ! CLASS_FROM_SOURCE_P (klass);
2155 klass = build_class_ref (klass);
2157 if (! METHOD_NATIVE (method) || ! flag_jni)
2158 abort ();
2160 DECL_ARTIFICIAL (method) = 1;
2161 DECL_EXTERNAL (method) = 0;
2163 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2164 DECL_CONTEXT (env_var) = method;
2166 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2168 res_var = build_decl (VAR_DECL, get_identifier ("res"),
2169 TREE_TYPE (TREE_TYPE (method)));
2170 DECL_CONTEXT (res_var) = method;
2171 TREE_CHAIN (env_var) = res_var;
2174 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2175 TREE_STATIC (meth_var) = 1;
2176 TREE_PUBLIC (meth_var) = 0;
2177 DECL_EXTERNAL (meth_var) = 0;
2178 DECL_CONTEXT (meth_var) = method;
2179 DECL_ARTIFICIAL (meth_var) = 1;
2180 DECL_INITIAL (meth_var) = null_pointer_node;
2181 TREE_USED (meth_var) = 1;
2182 chainon (env_var, meth_var);
2183 layout_decl (meth_var, 0);
2184 make_decl_rtl (meth_var, NULL);
2185 rest_of_decl_compilation (meth_var, NULL, 0, 0);
2187 /* One strange way that the front ends are different is that they
2188 store arguments differently. */
2189 if (from_class)
2190 method_args = DECL_ARGUMENTS (method);
2191 else
2192 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2193 block = build_block (env_var, NULL_TREE, NULL_TREE,
2194 method_args, NULL_TREE);
2195 TREE_SIDE_EFFECTS (block) = 1;
2196 /* When compiling from source we don't set the type of the block,
2197 because that will prevent patch_return from ever being run. */
2198 if (from_class)
2199 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2201 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2202 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2203 build (CALL_EXPR, ptr_type_node,
2204 build_address_of (soft_getjnienvnewframe_node),
2205 build_tree_list (NULL_TREE, klass),
2206 NULL_TREE));
2207 CAN_COMPLETE_NORMALLY (body) = 1;
2209 /* All the arguments to this method become arguments to the
2210 underlying JNI function. If we had to wrap object arguments in a
2211 special way, we would do that here. */
2212 args = NULL_TREE;
2213 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2214 args = tree_cons (NULL_TREE, tem, args);
2215 args = nreverse (args);
2216 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2218 /* For a static method the second argument is the class. For a
2219 non-static method the second argument is `this'; that is already
2220 available in the argument list. */
2221 if (METHOD_STATIC (method))
2223 args = tree_cons (NULL_TREE, klass, args);
2224 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2227 /* The JNIEnv structure is the first argument to the JNI function. */
2228 args = tree_cons (NULL_TREE, env_var, args);
2229 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2231 /* We call _Jv_LookupJNIMethod to find the actual underlying
2232 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2233 exception if this function is not found at runtime. */
2234 method_sig = build_java_signature (TREE_TYPE (method));
2235 lookup_arg =
2236 build_tree_list (NULL_TREE,
2237 build_utf8_ref (unmangle_classname
2238 (IDENTIFIER_POINTER (method_sig),
2239 IDENTIFIER_LENGTH (method_sig))));
2240 tem = DECL_NAME (method);
2241 lookup_arg
2242 = tree_cons (NULL_TREE, klass,
2243 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2245 jni_func_type
2246 = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2247 arg_types));
2249 jnifunc = build (COND_EXPR, ptr_type_node,
2250 meth_var, meth_var,
2251 build (MODIFY_EXPR, ptr_type_node,
2252 meth_var,
2253 build (CALL_EXPR, ptr_type_node,
2254 build_address_of (soft_lookupjnimethod_node),
2255 lookup_arg, NULL_TREE)));
2257 /* Now we make the actual JNI call via the resulting function
2258 pointer. */
2259 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2260 build1 (NOP_EXPR, jni_func_type, jnifunc),
2261 args, NULL_TREE);
2263 /* If the JNI call returned a result, capture it here. If we had to
2264 unwrap JNI object results, we would do that here. */
2265 if (res_var != NULL_TREE)
2266 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2267 res_var, call);
2269 TREE_SIDE_EFFECTS (call) = 1;
2270 CAN_COMPLETE_NORMALLY (call) = 1;
2272 body = build (COMPOUND_EXPR, void_type_node, body, call);
2273 TREE_SIDE_EFFECTS (body) = 1;
2275 /* Now free the environment we allocated. */
2276 call = build (CALL_EXPR, ptr_type_node,
2277 build_address_of (soft_jnipopsystemframe_node),
2278 build_tree_list (NULL_TREE, env_var),
2279 NULL_TREE);
2280 TREE_SIDE_EFFECTS (call) = 1;
2281 CAN_COMPLETE_NORMALLY (call) = 1;
2282 body = build (COMPOUND_EXPR, void_type_node, body, call);
2283 TREE_SIDE_EFFECTS (body) = 1;
2285 /* Finally, do the return. When compiling from source we rely on
2286 patch_return to patch the return value -- because DECL_RESULT is
2287 not set at the time this function is called. */
2288 if (from_class)
2290 res_type = void_type_node;
2291 if (res_var != NULL_TREE)
2293 tree drt;
2294 if (! DECL_RESULT (method))
2295 abort ();
2296 /* Make sure we copy the result variable to the actual
2297 result. We use the type of the DECL_RESULT because it
2298 might be different from the return type of the function:
2299 it might be promoted. */
2300 drt = TREE_TYPE (DECL_RESULT (method));
2301 if (drt != TREE_TYPE (res_var))
2302 res_var = build1 (CONVERT_EXPR, drt, res_var);
2303 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2304 TREE_SIDE_EFFECTS (res_var) = 1;
2307 else
2309 /* This is necessary to get patch_return to run. */
2310 res_type = NULL_TREE;
2312 body = build (COMPOUND_EXPR, void_type_node, body,
2313 build1 (RETURN_EXPR, res_type, res_var));
2314 TREE_SIDE_EFFECTS (body) = 1;
2316 BLOCK_EXPR_BODY (block) = body;
2317 return block;
2320 /* Expand an operation to extract from or store into a field.
2321 IS_STATIC is 1 iff the field is static.
2322 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2323 FIELD_REF_INDEX is an index into the constant pool. */
2325 static void
2326 expand_java_field_op (is_static, is_putting, field_ref_index)
2327 int is_static;
2328 int is_putting;
2329 int field_ref_index;
2331 tree self_type =
2332 get_class_constant (current_jcf,
2333 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2334 field_ref_index));
2335 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2336 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2337 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2338 field_ref_index);
2339 tree field_type = get_type_from_signature (field_signature);
2340 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2341 tree field_ref;
2342 int is_error = 0;
2343 tree field_decl = lookup_field (&self_type, field_name);
2344 if (field_decl == error_mark_node)
2346 is_error = 1;
2348 else if (field_decl == NULL_TREE)
2350 error ("missing field '%s' in '%s'",
2351 IDENTIFIER_POINTER (field_name), self_name);
2352 is_error = 1;
2354 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2356 error ("mismatching signature for field '%s' in '%s'",
2357 IDENTIFIER_POINTER (field_name), self_name);
2358 is_error = 1;
2360 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2361 if (is_error)
2363 if (! is_putting)
2364 push_value (convert (field_type, integer_zero_node));
2365 flush_quick_stack ();
2366 return;
2369 field_ref = build_field_ref (field_ref, self_type, field_name);
2370 if (is_static)
2371 field_ref = build_class_init (self_type, field_ref);
2372 if (is_putting)
2374 flush_quick_stack ();
2375 if (FIELD_FINAL (field_decl))
2377 if (DECL_CONTEXT (field_decl) != current_class)
2378 error_with_decl (field_decl,
2379 "assignment to final field `%s' not in field's class");
2380 else if (FIELD_STATIC (field_decl))
2382 if (!DECL_CLINIT_P (current_function_decl))
2383 warning_with_decl (field_decl,
2384 "assignment to final static field `%s' not in class initializer");
2386 else
2388 tree cfndecl_name = DECL_NAME (current_function_decl);
2389 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2390 && !ID_FINIT_P (cfndecl_name))
2391 warning_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2394 expand_assignment (field_ref, new_value, 0, 0);
2396 else
2397 push_value (field_ref);
2400 void
2401 load_type_state (label)
2402 tree label;
2404 int i;
2405 tree vec = LABEL_TYPE_STATE (label);
2406 int cur_length = TREE_VEC_LENGTH (vec);
2407 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2408 for (i = 0; i < cur_length; i++)
2409 type_map [i] = TREE_VEC_ELT (vec, i);
2412 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2413 dependent things, but they rely on gcc routines. This function is
2414 placed here because it uses things defined locally in parse.y. */
2416 static tree
2417 case_identity (t, v)
2418 tree t __attribute__ ((__unused__));
2419 tree v;
2421 return v;
2424 /* Return the name of the vtable for an array of a given primitive
2425 type. */
2426 static tree
2427 get_primitive_array_vtable (tree elt)
2429 tree r;
2430 if (elt == boolean_type_node)
2431 r = boolean_array_vtable;
2432 else if (elt == byte_type_node)
2433 r = byte_array_vtable;
2434 else if (elt == char_type_node)
2435 r = char_array_vtable;
2436 else if (elt == short_type_node)
2437 r = short_array_vtable;
2438 else if (elt == int_type_node)
2439 r = int_array_vtable;
2440 else if (elt == long_type_node)
2441 r = long_array_vtable;
2442 else if (elt == float_type_node)
2443 r = float_array_vtable;
2444 else if (elt == double_type_node)
2445 r = double_array_vtable;
2446 else
2447 abort ();
2448 return build_address_of (r);
2451 struct rtx_def *
2452 java_expand_expr (exp, target, tmode, modifier)
2453 register tree exp;
2454 rtx target;
2455 enum machine_mode tmode;
2456 int modifier; /* Actually an enum expand_modifier. */
2458 tree current;
2460 switch (TREE_CODE (exp))
2462 case NEW_ARRAY_INIT:
2464 rtx tmp;
2465 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2466 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2467 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2468 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2469 tree length = build_int_2 (ilength, 0);
2470 tree init = TREE_OPERAND (exp, 0);
2471 tree array_decl;
2473 /* See if we can generate the array statically. */
2474 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2475 && JPRIMITIVE_TYPE_P (element_type))
2477 tree temp, value, init_decl;
2478 struct rtx_def *r;
2479 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2480 PUSH_FIELD_VALUE (temp, "vtable",
2481 get_primitive_array_vtable (element_type));
2482 if (! flag_hash_synchronization)
2483 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2484 FINISH_RECORD_CONSTRUCTOR (temp);
2485 START_RECORD_CONSTRUCTOR (value, array_type);
2486 PUSH_SUPER_VALUE (value, temp);
2487 PUSH_FIELD_VALUE (value, "length", length);
2488 PUSH_FIELD_VALUE (value, "data", init);
2489 FINISH_RECORD_CONSTRUCTOR (value);
2491 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2492 pushdecl_top_level (init_decl);
2493 TREE_STATIC (init_decl) = 1;
2494 DECL_INITIAL (init_decl) = value;
2495 DECL_IGNORED_P (init_decl) = 1;
2496 TREE_READONLY (init_decl) = 1;
2497 /* Hash synchronization requires at least 64-bit alignment. */
2498 if (flag_hash_synchronization && POINTER_SIZE < 64)
2499 DECL_ALIGN (init_decl) = 64;
2500 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2501 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2502 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2503 r = expand_expr (init, target, tmode, modifier);
2504 return r;
2507 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2508 expand_decl (array_decl);
2509 tmp = expand_assignment (array_decl,
2510 build_new_array (element_type, length),
2511 1, 0);
2512 if (TREE_CONSTANT (init)
2513 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2515 tree init_decl;
2516 init_decl = build_decl (VAR_DECL, generate_name (),
2517 TREE_TYPE (init));
2518 pushdecl_top_level (init_decl);
2519 TREE_STATIC (init_decl) = 1;
2520 DECL_INITIAL (init_decl) = init;
2521 DECL_IGNORED_P (init_decl) = 1;
2522 TREE_READONLY (init_decl) = 1;
2523 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2524 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2525 init = init_decl;
2527 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2528 build_java_indirect_ref (array_type,
2529 array_decl, flag_check_references),
2530 data_fld), init, 0, 0);
2531 return tmp;
2533 case BLOCK:
2534 if (BLOCK_EXPR_BODY (exp))
2536 tree local;
2537 rtx last;
2538 tree body = BLOCK_EXPR_BODY (exp);
2539 /* Set to 1 or more when we found a static class
2540 initialization flag. */
2541 int found_class_initialization_flag = 0;
2543 pushlevel (2); /* 2 and above */
2544 expand_start_bindings (0);
2545 local = BLOCK_EXPR_DECLS (exp);
2546 while (local)
2548 tree next = TREE_CHAIN (local);
2549 found_class_initialization_flag +=
2550 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
2551 layout_decl (local, 0);
2552 expand_decl (pushdecl (local));
2553 local = next;
2556 /* Emit initialization code for test flags if we saw one. */
2557 if (! always_initialize_class_p
2558 && current_function_decl
2559 && found_class_initialization_flag)
2560 htab_traverse
2561 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
2562 emit_init_test_initialization, NULL);
2564 /* Avoid deep recursion for long block. */
2565 while (TREE_CODE (body) == COMPOUND_EXPR)
2567 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2568 emit_queue ();
2569 body = TREE_OPERAND (body, 1);
2571 last = expand_expr (body, NULL_RTX, VOIDmode, 0);
2572 emit_queue ();
2573 expand_end_bindings (getdecls (), 1, 0);
2574 poplevel (1, 1, 0);
2575 return last;
2577 return const0_rtx;
2579 case CASE_EXPR:
2581 tree duplicate;
2582 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2583 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2584 &duplicate) == 2)
2586 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2587 parse_error_context
2588 (wfl_operator, "Duplicate case label: `%s'",
2589 print_int_node (TREE_OPERAND (exp, 0)));
2591 return const0_rtx;
2594 case DEFAULT_EXPR:
2595 pushcase (NULL_TREE, 0,
2596 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2597 return const0_rtx;
2599 case SWITCH_EXPR:
2600 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2601 expand_expr_stmt (TREE_OPERAND (exp, 1));
2602 expand_end_case (TREE_OPERAND (exp, 0));
2603 return const0_rtx;
2605 case TRY_EXPR:
2606 /* We expand a try[-catch] block */
2608 /* Expand the try block */
2609 expand_eh_region_start ();
2610 expand_expr_stmt (TREE_OPERAND (exp, 0));
2611 expand_start_all_catch ();
2613 /* Expand all catch clauses (EH handlers) */
2614 for (current = TREE_OPERAND (exp, 1); current;
2615 current = TREE_CHAIN (current))
2617 tree catch = TREE_OPERAND (current, 0);
2618 tree decl = BLOCK_EXPR_DECLS (catch);
2619 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2621 expand_start_catch (type);
2622 expand_expr_stmt (TREE_OPERAND (current, 0));
2623 expand_end_catch ();
2625 expand_end_all_catch ();
2626 return const0_rtx;
2628 case JAVA_EXC_OBJ_EXPR:
2629 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2630 target, tmode, modifier);
2632 case LABEL_EXPR:
2633 /* Used only by expanded inline functions. */
2634 expand_label (TREE_OPERAND (exp, 0));
2635 return const0_rtx;
2637 default:
2638 internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
2642 /* Go over METHOD's bytecode and note instruction starts in
2643 instruction_bits[]. */
2645 void
2646 note_instructions (jcf, method)
2647 JCF *jcf;
2648 tree method;
2650 int PC;
2651 unsigned char* byte_ops;
2652 long length = DECL_CODE_LENGTH (method);
2654 int saw_index;
2655 jint INT_temp;
2657 #undef RET /* Defined by config/i386/i386.h */
2658 #undef AND /* Causes problems with opcodes for iand and land. */
2659 #undef PTR
2660 #define BCODE byte_ops
2661 #define BYTE_type_node byte_type_node
2662 #define SHORT_type_node short_type_node
2663 #define INT_type_node int_type_node
2664 #define LONG_type_node long_type_node
2665 #define CHAR_type_node char_type_node
2666 #define PTR_type_node ptr_type_node
2667 #define FLOAT_type_node float_type_node
2668 #define DOUBLE_type_node double_type_node
2669 #define VOID_type_node void_type_node
2670 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2671 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2672 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2673 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2675 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2677 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2678 byte_ops = jcf->read_ptr;
2679 instruction_bits = xrealloc (instruction_bits, length + 1);
2680 memset (instruction_bits, 0, length + 1);
2682 /* This pass figures out which PC can be the targets of jumps. */
2683 for (PC = 0; PC < length;)
2685 int oldpc = PC; /* PC at instruction start. */
2686 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2687 switch (byte_ops[PC++])
2689 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2690 case OPCODE: \
2691 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2692 break;
2694 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2696 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2697 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2698 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2699 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2700 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2701 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2702 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2703 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2705 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2706 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2707 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2708 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2709 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2710 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2711 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2712 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2714 /* two forms of wide instructions */
2715 #define PRE_SPECIAL_WIDE(IGNORE) \
2717 int modified_opcode = IMMEDIATE_u1; \
2718 if (modified_opcode == OPCODE_iinc) \
2720 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2721 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2723 else \
2725 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2729 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2731 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2733 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2734 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2735 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2736 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2737 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2738 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2739 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2740 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2741 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2742 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2744 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2745 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2746 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2747 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2748 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2749 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2750 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2751 NOTE_LABEL (PC); \
2752 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2754 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2756 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2757 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2759 #define PRE_LOOKUP_SWITCH \
2760 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2761 NOTE_LABEL (default_offset+oldpc); \
2762 if (npairs >= 0) \
2763 while (--npairs >= 0) { \
2764 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2765 jint offset = IMMEDIATE_s4; \
2766 NOTE_LABEL (offset+oldpc); } \
2769 #define PRE_TABLE_SWITCH \
2770 { jint default_offset = IMMEDIATE_s4; \
2771 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2772 NOTE_LABEL (default_offset+oldpc); \
2773 if (low <= high) \
2774 while (low++ <= high) { \
2775 jint offset = IMMEDIATE_s4; \
2776 NOTE_LABEL (offset+oldpc); } \
2779 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2780 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2781 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2782 (void)(IMMEDIATE_u2); \
2783 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2785 #include "javaop.def"
2786 #undef JAVAOP
2788 } /* for */
2791 void
2792 expand_byte_code (jcf, method)
2793 JCF *jcf;
2794 tree method;
2796 int PC;
2797 int i;
2798 const unsigned char *linenumber_pointer;
2799 int dead_code_index = -1;
2800 unsigned char* byte_ops;
2801 long length = DECL_CODE_LENGTH (method);
2803 stack_pointer = 0;
2804 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2805 byte_ops = jcf->read_ptr;
2807 /* We make an initial pass of the line number table, to note
2808 which instructions have associated line number entries. */
2809 linenumber_pointer = linenumber_table;
2810 for (i = 0; i < linenumber_count; i++)
2812 int pc = GET_u2 (linenumber_pointer);
2813 linenumber_pointer += 4;
2814 if (pc >= length)
2815 warning ("invalid PC in line number table");
2816 else
2818 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2819 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2820 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2824 if (! verify_jvm_instructions (jcf, byte_ops, length))
2825 return;
2827 /* Translate bytecodes to rtl instructions. */
2828 linenumber_pointer = linenumber_table;
2829 for (PC = 0; PC < length;)
2831 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2833 tree label = lookup_label (PC);
2834 flush_quick_stack ();
2835 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2836 expand_label (label);
2837 if (LABEL_VERIFIED (label) || PC == 0)
2838 load_type_state (label);
2841 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2843 if (dead_code_index == -1)
2845 /* This is the start of a region of unreachable bytecodes.
2846 They still need to be processed in order for EH ranges
2847 to get handled correctly. However, we can simply
2848 replace these bytecodes with nops. */
2849 dead_code_index = PC;
2852 /* Turn this bytecode into a nop. */
2853 byte_ops[PC] = 0x0;
2855 else
2857 if (dead_code_index != -1)
2859 /* We've just reached the end of a region of dead code. */
2860 warning ("unreachable bytecode from %d to before %d",
2861 dead_code_index, PC);
2862 dead_code_index = -1;
2866 /* Handle possible line number entry for this PC.
2868 This code handles out-of-order and multiple linenumbers per PC,
2869 but is optimized for the case of line numbers increasing
2870 monotonically with PC. */
2871 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2873 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2874 || GET_u2 (linenumber_pointer) != PC)
2875 linenumber_pointer = linenumber_table;
2876 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2878 int pc = GET_u2 (linenumber_pointer);
2879 linenumber_pointer += 4;
2880 if (pc == PC)
2882 lineno = GET_u2 (linenumber_pointer - 2);
2883 emit_line_note (input_filename, lineno);
2884 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2885 break;
2889 maybe_pushlevels (PC);
2890 PC = process_jvm_instruction (PC, byte_ops, length);
2891 maybe_poplevels (PC);
2892 } /* for */
2894 if (dead_code_index != -1)
2896 /* We've just reached the end of a region of dead code. */
2897 warning ("unreachable bytecode from %d to the end of the method",
2898 dead_code_index);
2902 static void
2903 java_push_constant_from_pool (jcf, index)
2904 JCF *jcf;
2905 int index;
2907 tree c;
2908 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2910 tree name;
2911 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2912 index = alloc_name_constant (CONSTANT_String, name);
2913 c = build_ref_from_constant_pool (index);
2914 TREE_TYPE (c) = promote_type (string_type_node);
2916 else
2917 c = get_constant (jcf, index);
2918 push_value (c);
2922 process_jvm_instruction (PC, byte_ops, length)
2923 int PC;
2924 const unsigned char* byte_ops;
2925 long length ATTRIBUTE_UNUSED;
2927 const char *opname; /* Temporary ??? */
2928 int oldpc = PC; /* PC at instruction start. */
2930 /* If the instruction is at the beginning of a exception handler,
2931 replace the top of the stack with the thrown object reference */
2932 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2934 tree type = pop_type (ptr_type_node);
2935 push_value (build (JAVA_EXC_OBJ_EXPR, type));
2938 switch (byte_ops[PC++])
2940 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2941 case OPCODE: \
2942 opname = #OPNAME; \
2943 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2944 break;
2946 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2948 int saw_index = 0; \
2949 int index = OPERAND_VALUE; \
2950 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2953 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2955 /* OPERAND_VALUE may have side-effects on PC */ \
2956 int opvalue = OPERAND_VALUE; \
2957 build_java_jsr (oldpc + opvalue, PC); \
2960 /* Push a constant onto the stack. */
2961 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2962 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2963 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2964 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2966 /* internal macro added for use by the WIDE case */
2967 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2968 expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
2970 /* Push local variable onto the opcode stack. */
2971 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2973 /* have to do this since OPERAND_VALUE may have side-effects */ \
2974 int opvalue = OPERAND_VALUE; \
2975 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2978 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2979 expand_java_return (OPERAND_TYPE##_type_node)
2981 #define REM_EXPR TRUNC_MOD_EXPR
2982 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2983 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2985 #define FIELD(IS_STATIC, IS_PUT) \
2986 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2988 #define TEST(OPERAND_TYPE, CONDITION) \
2989 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2991 #define COND(OPERAND_TYPE, CONDITION) \
2992 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2994 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2995 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2997 #define BRANCH_GOTO(OPERAND_VALUE) \
2998 expand_java_goto (oldpc + OPERAND_VALUE)
3000 #define BRANCH_CALL(OPERAND_VALUE) \
3001 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
3003 #if 0
3004 #define BRANCH_RETURN(OPERAND_VALUE) \
3006 tree type = OPERAND_TYPE##_type_node; \
3007 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3008 expand_java_ret (value); \
3010 #endif
3012 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3013 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3014 fprintf (stderr, "(not implemented)\n")
3015 #define NOT_IMPL1(OPERAND_VALUE) \
3016 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3017 fprintf (stderr, "(not implemented)\n")
3019 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3021 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3023 #define STACK_POP(COUNT) java_stack_pop (COUNT)
3025 #define STACK_SWAP(COUNT) java_stack_swap()
3027 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3028 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3029 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3031 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3032 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3034 #define LOOKUP_SWITCH \
3035 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
3036 tree selector = pop_value (INT_type_node); \
3037 tree duplicate, label; \
3038 tree type = TREE_TYPE (selector); \
3039 flush_quick_stack (); \
3040 expand_start_case (0, selector, type, "switch statement");\
3041 while (--npairs >= 0) \
3043 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3044 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
3045 TREE_TYPE (value) = type; \
3046 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3047 pushcase (value, convert, label, &duplicate); \
3048 expand_java_goto (oldpc + offset); \
3050 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3051 pushcase (NULL_TREE, 0, label, &duplicate); \
3052 expand_java_goto (oldpc + default_offset); \
3053 expand_end_case (selector); \
3056 #define TABLE_SWITCH \
3057 { jint default_offset = IMMEDIATE_s4; \
3058 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3059 tree selector = pop_value (INT_type_node); \
3060 tree duplicate, label; \
3061 tree type = TREE_TYPE (selector); \
3062 flush_quick_stack (); \
3063 expand_start_case (0, selector, type, "switch statement");\
3064 for (; low <= high; low++) \
3066 jint offset = IMMEDIATE_s4; \
3067 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
3068 TREE_TYPE (value) = type; \
3069 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3070 pushcase (value, convert, label, &duplicate); \
3071 expand_java_goto (oldpc + offset); \
3073 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3074 pushcase (NULL_TREE, 0, label, &duplicate); \
3075 expand_java_goto (oldpc + default_offset); \
3076 expand_end_case (selector); \
3079 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3080 { int opcode = byte_ops[PC-1]; \
3081 int method_ref_index = IMMEDIATE_u2; \
3082 int nargs; \
3083 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
3084 else nargs = -1; \
3085 expand_invoke (opcode, method_ref_index, nargs); \
3088 /* Handle new, checkcast, instanceof */
3089 #define OBJECT(TYPE, OP) \
3090 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3092 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3094 #define ARRAY_LOAD(OPERAND_TYPE) \
3096 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
3099 #define ARRAY_STORE(OPERAND_TYPE) \
3101 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3104 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3105 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3106 #define ARRAY_NEW_PTR() \
3107 push_value (build_anewarray (get_class_constant (current_jcf, \
3108 IMMEDIATE_u2), \
3109 pop_value (int_type_node)));
3110 #define ARRAY_NEW_NUM() \
3112 int atype = IMMEDIATE_u1; \
3113 push_value (build_newarray (atype, pop_value (int_type_node)));\
3115 #define ARRAY_NEW_MULTI() \
3117 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
3118 int ndims = IMMEDIATE_u1; \
3119 expand_java_multianewarray( class, ndims ); \
3122 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3123 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3124 pop_value (OPERAND_TYPE##_type_node))));
3126 #define CONVERT2(FROM_TYPE, TO_TYPE) \
3128 push_value (build1 (NOP_EXPR, int_type_node, \
3129 (convert (TO_TYPE##_type_node, \
3130 pop_value (FROM_TYPE##_type_node))))); \
3133 #define CONVERT(FROM_TYPE, TO_TYPE) \
3135 push_value (convert (TO_TYPE##_type_node, \
3136 pop_value (FROM_TYPE##_type_node))); \
3139 /* internal macro added for use by the WIDE case
3140 Added TREE_TYPE (decl) assignment, apbianco */
3141 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
3143 tree decl, value; \
3144 int var = OPVALUE; \
3145 tree type = OPTYPE; \
3146 value = pop_value (type); \
3147 type = TREE_TYPE (value); \
3148 decl = find_local_variable (var, type, oldpc); \
3149 set_local_type (var, type ); \
3150 expand_assignment (decl, value, 0, 0); \
3153 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3155 /* have to do this since OPERAND_VALUE may have side-effects */ \
3156 int opvalue = OPERAND_VALUE; \
3157 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3160 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3161 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3163 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3164 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3166 #define MONITOR_OPERATION(call) \
3168 tree o = pop_value (ptr_type_node); \
3169 tree c; \
3170 flush_quick_stack (); \
3171 c = build_java_monitor (call, o); \
3172 TREE_SIDE_EFFECTS (c) = 1; \
3173 expand_expr_stmt (c); \
3176 #define SPECIAL_IINC(IGNORED) \
3178 unsigned int local_var_index = IMMEDIATE_u1; \
3179 int ival = IMMEDIATE_s1; \
3180 expand_iinc(local_var_index, ival, oldpc); \
3183 #define SPECIAL_WIDE(IGNORED) \
3185 int modified_opcode = IMMEDIATE_u1; \
3186 unsigned int local_var_index = IMMEDIATE_u2; \
3187 switch (modified_opcode) \
3189 case OPCODE_iinc: \
3191 int ival = IMMEDIATE_s2; \
3192 expand_iinc (local_var_index, ival, oldpc); \
3193 break; \
3195 case OPCODE_iload: \
3196 case OPCODE_lload: \
3197 case OPCODE_fload: \
3198 case OPCODE_dload: \
3199 case OPCODE_aload: \
3201 /* duplicate code from LOAD macro */ \
3202 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3203 break; \
3205 case OPCODE_istore: \
3206 case OPCODE_lstore: \
3207 case OPCODE_fstore: \
3208 case OPCODE_dstore: \
3209 case OPCODE_astore: \
3211 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3212 break; \
3214 default: \
3215 error ("unrecogized wide sub-instruction"); \
3219 #define SPECIAL_THROW(IGNORED) \
3220 build_java_athrow (pop_value (throwable_type_node))
3222 #define SPECIAL_BREAK NOT_IMPL1
3223 #define IMPL NOT_IMPL
3225 #include "javaop.def"
3226 #undef JAVAOP
3227 default:
3228 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3230 return PC;
3233 /* Return the opcode at PC in the code section pointed to by
3234 CODE_OFFSET. */
3236 static unsigned char
3237 peek_opcode_at_pc (jcf, code_offset, pc)
3238 JCF *jcf;
3239 int code_offset, pc;
3241 unsigned char opcode;
3242 long absolute_offset = (long)JCF_TELL (jcf);
3244 JCF_SEEK (jcf, code_offset);
3245 opcode = jcf->read_ptr [pc];
3246 JCF_SEEK (jcf, absolute_offset);
3247 return opcode;
3250 /* Some bytecode compilers are emitting accurate LocalVariableTable
3251 attributes. Here's an example:
3253 PC <t>store_<n>
3254 PC+1 ...
3256 Attribute "LocalVariableTable"
3257 slot #<n>: ... (PC: PC+1 length: L)
3259 This is accurate because the local in slot <n> really exists after
3260 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3262 This procedure recognizes this situation and extends the live range
3263 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3264 length of the store instruction.)
3266 This function is used by `give_name_to_locals' so that a local's
3267 DECL features a DECL_LOCAL_START_PC such that the first related
3268 store operation will use DECL as a destination, not a unrelated
3269 temporary created for the occasion.
3271 This function uses a global (instruction_bits) `note_instructions' should
3272 have allocated and filled properly. */
3275 maybe_adjust_start_pc (jcf, code_offset, start_pc, slot)
3276 struct JCF *jcf;
3277 int code_offset, start_pc, slot;
3279 int first, index, opcode;
3280 int pc, insn_pc;
3281 int wide_found = 0;
3283 if (!start_pc)
3284 return start_pc;
3286 first = index = -1;
3288 /* Find last previous instruction and remember it */
3289 for (pc = start_pc-1; pc; pc--)
3290 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3291 break;
3292 insn_pc = pc;
3294 /* Retrieve the instruction, handle `wide'. */
3295 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3296 if (opcode == OPCODE_wide)
3298 wide_found = 1;
3299 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3302 switch (opcode)
3304 case OPCODE_astore_0:
3305 case OPCODE_astore_1:
3306 case OPCODE_astore_2:
3307 case OPCODE_astore_3:
3308 first = OPCODE_astore_0;
3309 break;
3311 case OPCODE_istore_0:
3312 case OPCODE_istore_1:
3313 case OPCODE_istore_2:
3314 case OPCODE_istore_3:
3315 first = OPCODE_istore_0;
3316 break;
3318 case OPCODE_lstore_0:
3319 case OPCODE_lstore_1:
3320 case OPCODE_lstore_2:
3321 case OPCODE_lstore_3:
3322 first = OPCODE_lstore_0;
3323 break;
3325 case OPCODE_fstore_0:
3326 case OPCODE_fstore_1:
3327 case OPCODE_fstore_2:
3328 case OPCODE_fstore_3:
3329 first = OPCODE_fstore_0;
3330 break;
3332 case OPCODE_dstore_0:
3333 case OPCODE_dstore_1:
3334 case OPCODE_dstore_2:
3335 case OPCODE_dstore_3:
3336 first = OPCODE_dstore_0;
3337 break;
3339 case OPCODE_astore:
3340 case OPCODE_istore:
3341 case OPCODE_lstore:
3342 case OPCODE_fstore:
3343 case OPCODE_dstore:
3344 index = peek_opcode_at_pc (jcf, code_offset, pc);
3345 if (wide_found)
3347 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3348 index = (other << 8) + index;
3350 break;
3353 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3354 means we have a <t>store. */
3355 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3356 start_pc = insn_pc;
3358 return start_pc;
3361 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3362 order, as specified by Java Language Specification.
3364 The problem is that while expand_expr will evaluate its sub-operands in
3365 left-to-right order, for variables it will just return an rtx (i.e.
3366 an lvalue) for the variable (rather than an rvalue). So it is possible
3367 that a later sub-operand will change the register, and when the
3368 actual operation is done, it will use the new value, when it should
3369 have used the original value.
3371 We fix this by using save_expr. This forces the sub-operand to be
3372 copied into a fresh virtual register,
3374 For method invocation, we modify the arguments so that a
3375 left-to-right order evaluation is performed. Saved expressions
3376 will, in CALL_EXPR order, be reused when the call will be expanded.
3379 tree
3380 force_evaluation_order (node)
3381 tree node;
3383 if (flag_syntax_only)
3384 return node;
3385 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3387 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3388 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3390 else if (TREE_CODE (node) == CALL_EXPR
3391 || TREE_CODE (node) == NEW_CLASS_EXPR
3392 || (TREE_CODE (node) == COMPOUND_EXPR
3393 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3394 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3396 tree arg, cmp;
3398 if (!TREE_OPERAND (node, 1))
3399 return node;
3401 arg = node;
3403 /* Position arg properly, account for wrapped around ctors. */
3404 if (TREE_CODE (node) == COMPOUND_EXPR)
3405 arg = TREE_OPERAND (node, 0);
3407 arg = TREE_OPERAND (arg, 1);
3409 /* Not having a list of argument here is an error. */
3410 if (TREE_CODE (arg) != TREE_LIST)
3411 abort ();
3413 /* This reverses the evaluation order. This is a desired effect. */
3414 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3416 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3417 cmp = (cmp == NULL_TREE ? saved :
3418 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3419 TREE_VALUE (arg) = saved;
3422 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3423 TREE_SIDE_EFFECTS (cmp) = 1;
3425 if (cmp)
3427 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3428 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3429 TREE_SIDE_EFFECTS (cmp) = 1;
3430 node = cmp;
3433 return node;
3436 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
3437 method in order to emit initialization code for each test flag. */
3439 static int
3440 emit_init_test_initialization (entry, x)
3441 void * * entry;
3442 void * x ATTRIBUTE_UNUSED;
3444 struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
3445 tree klass = build_class_ref (ite->key);
3446 tree rhs;
3448 /* If the DECL_INITIAL of the test flag is set to true, it
3449 means that the class is already initialized the time it
3450 is in use. */
3451 if (DECL_INITIAL (ite->value) == boolean_true_node)
3452 rhs = boolean_true_node;
3453 /* Otherwise, we initialize the class init check variable by looking
3454 at the `state' field of the class to see if it is already
3455 initialized. This makes things a bit faster if the class is
3456 already initialized, which should be the common case. */
3457 else
3458 rhs = build (GE_EXPR, boolean_type_node,
3459 build (COMPONENT_REF, byte_type_node,
3460 build1 (INDIRECT_REF, class_type_node, klass),
3461 lookup_field (&class_type_node,
3462 get_identifier ("state"))),
3463 build_int_2 (JV_STATE_DONE, 0));
3465 expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
3466 ite->value, rhs));
3467 return true;
3470 #include "gt-java-expr.h"