1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
34 #include "java-tree.h"
36 #include "java-opcodes.h"
38 #include "java-except.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 ((tree, tree));
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_java_NEW PARAMS ((tree));
61 static void expand_java_INSTANCEOF PARAMS ((tree));
62 static void expand_java_CHECKCAST PARAMS ((tree));
63 static void expand_iinc PARAMS ((unsigned int, int, int));
64 static void expand_java_binop PARAMS ((tree, enum tree_code));
65 static void note_label PARAMS ((int, int));
66 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
67 static void expand_test PARAMS ((enum tree_code, tree, int));
68 static void expand_cond PARAMS ((enum tree_code, tree, int));
69 static void expand_java_goto PARAMS ((int));
71 static void expand_java_call PARAMS ((int, int));
72 static void expand_java_ret PARAMS ((tree));
74 static tree pop_arguments PARAMS ((tree));
75 static void expand_invoke PARAMS ((int, int, int));
76 static void expand_java_field_op PARAMS ((int, int, int));
77 static void java_push_constant_from_pool PARAMS ((struct JCF *, int));
78 static void java_stack_pop PARAMS ((int));
79 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
80 static tree build_java_check_indexed_type PARAMS ((tree, tree));
81 static tree java_array_data_offset PARAMS ((tree));
82 static tree case_identity PARAMS ((tree, tree));
84 static tree operand_type[59];
85 extern struct obstack permanent_obstack;
87 static tree methods_ident = NULL_TREE;
88 static tree ncode_ident = NULL_TREE;
89 tree dtable_ident = NULL_TREE;
91 /* Set to non-zero value in order to emit class initilization code
92 before static field references. */
93 int always_initialize_class_p;
96 init_expr_processing()
98 operand_type[21] = operand_type[54] = int_type_node;
99 operand_type[22] = operand_type[55] = long_type_node;
100 operand_type[23] = operand_type[56] = float_type_node;
101 operand_type[24] = operand_type[57] = double_type_node;
102 operand_type[25] = operand_type[58] = ptr_type_node;
103 ggc_add_tree_root (operand_type, 59);
104 ggc_add_tree_root (&methods_ident, 1);
105 ggc_add_tree_root (&ncode_ident, 1);
108 /* We store the stack state in two places:
109 Within a basic block, we use the quick_stack, which is a
110 pushdown list (TREE_LISTs) of expression nodes.
111 This is the top part of the stack; below that we use find_stack_slot.
112 At the end of a basic block, the quick_stack must be flushed
113 to the stack slot array (as handled by find_stack_slot).
114 Using quick_stack generates better code (especially when
115 compiled without optimization), because we do not have to
116 explicitly store and load trees to temporary variables.
118 If a variable is on the quick stack, it means the value of variable
119 when the quick stack was last flushed. Conceptually, flush_quick_stack
120 saves all the the quick_stack elements in parellel. However, that is
121 complicated, so it actually saves them (i.e. copies each stack value
122 to is home virtual register) from low indexes. This allows a quick_stack
123 element at index i (counting from the bottom of stack the) to references
124 slot virtuals for register that are >= i, but not those that are deeper.
125 This convention makes most operations easier. For example iadd works
126 even when the stack contains (reg[0], reg[1]): It results in the
127 stack containing (reg[0]+reg[1]), which is OK. However, some stack
128 operations are more complicated. For example dup given a stack
129 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
130 the convention, since stack value 1 would refer to a register with
131 lower index (reg[0]), which flush_quick_stack does not safely handle.
132 So dup cannot just add an extra element to the quick_stack, but iadd can.
135 tree quick_stack = NULL_TREE;
137 /* A free-list of unused permamnet TREE_LIST nodes. */
138 tree tree_list_free_list = NULL_TREE;
140 /* The stack pointer of the Java virtual machine.
141 This does include the size of the quick_stack. */
145 const unsigned char *linenumber_table;
146 int linenumber_count;
149 truthvalue_conversion (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))
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:
169 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
172 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
174 /* are these legal? XXX JH */
179 /* These don't change whether an object is non-zero or zero. */
180 return truthvalue_conversion (TREE_OPERAND (expr, 0));
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 truthvalue_conversion (TREE_OPERAND (expr, 1)),
186 truthvalue_conversion (TREE_OPERAND (expr, 2))));
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 truthvalue_conversion (TREE_OPERAND (expr, 0));
193 /* fall through to default */
196 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
200 #ifdef JAVA_USE_HANDLES
201 /* Given a pointer to a handle, get a pointer to an object. */
207 tree field, handle_type;
208 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
209 handle_type = TREE_TYPE (expr);
210 field = TYPE_FIELDS (handle_type);
211 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
216 /* Save any stack slots that happen to be in the quick_stack into their
217 home virtual register slots.
219 The copy order is from low stack index to high, to support the invariant
220 that the expression for a slot may contain decls for stack slots with
221 higher (or the same) index, but not lower. */
226 int stack_index = stack_pointer;
227 register tree prev, cur, next;
229 /* First reverse the quick_stack, and count the number of slots it has. */
230 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
232 next = TREE_CHAIN (cur);
233 TREE_CHAIN (cur) = prev;
235 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
239 while (quick_stack != NULL_TREE)
242 tree node = quick_stack, type;
243 quick_stack = TREE_CHAIN (node);
244 TREE_CHAIN (node) = tree_list_free_list;
245 tree_list_free_list = node;
246 node = TREE_VALUE (node);
247 type = TREE_TYPE (node);
249 decl = find_stack_slot (stack_index, type);
251 expand_assignment (decl, node, 0, 0);
252 stack_index += 1 + TYPE_IS_WIDE (type);
261 type = promote_type (type);
262 n_words = 1 + TYPE_IS_WIDE (type);
263 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
264 fatal ("stack overflow");
265 stack_type_map[stack_pointer++] = type;
267 while (--n_words >= 0)
268 stack_type_map[stack_pointer++] = TYPE_SECOND;
275 tree type = TREE_TYPE (value);
276 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
278 type = promote_type (type);
279 value = convert (type, value);
282 if (tree_list_free_list == NULL_TREE)
283 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
286 tree node = tree_list_free_list;
287 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
288 TREE_VALUE (node) = value;
289 TREE_CHAIN (node) = quick_stack;
294 /* Pop a type from the type stack.
295 TYPE is the expected type. Return the actual type, which must be
296 convertible to TYPE, otherwise NULL_TREE is returned. */
304 if (TREE_CODE (type) == RECORD_TYPE)
305 type = promote_type (type);
306 n_words = 1 + TYPE_IS_WIDE (type);
307 if (stack_pointer < n_words)
308 fatal ("stack underflow");
309 while (--n_words > 0)
311 if (stack_type_map[--stack_pointer] != void_type_node)
312 fatal ("Invalid multi-word value on type stack");
314 t = stack_type_map[--stack_pointer];
315 if (type == NULL_TREE || t == type)
317 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
318 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
320 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
322 if (type == ptr_type_node || type == object_ptr_type_node)
324 else if (t == ptr_type_node) /* Special case for null reference. */
326 else if (can_widen_reference_to (t, type))
328 /* This is a kludge, but matches what Sun's verifier does.
329 It can be tricked, but is safe as long as type errors
330 (i.e. interface method calls) are caught at run-time. */
331 /* FIXME: this is worse than a kludge, probably. */
332 return object_ptr_type_node;
337 /* Pop a type from the type stack.
338 TYPE is the expected type. Return the actual type, which must be
339 convertible to TYPE, otherwise call error. */
345 tree t = pop_type_0 (type);
348 error ("unexpected type on stack");
352 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
353 Handles array types and interfaces. */
356 can_widen_reference_to (source_type, target_type)
357 tree source_type, target_type;
359 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
362 /* Get rid of pointers */
363 if (TREE_CODE (source_type) == POINTER_TYPE)
364 source_type = TREE_TYPE (source_type);
365 if (TREE_CODE (target_type) == POINTER_TYPE)
366 target_type = TREE_TYPE (target_type);
368 if (source_type == target_type)
372 source_type = HANDLE_TO_CLASS_TYPE (source_type);
373 target_type = HANDLE_TO_CLASS_TYPE (target_type);
374 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
376 HOST_WIDE_INT source_length, target_length;
377 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
379 target_length = java_array_type_length (target_type);
380 if (target_length >= 0)
382 source_length = java_array_type_length (source_type);
383 if (source_length != target_length)
386 source_type = TYPE_ARRAY_ELEMENT (source_type);
387 target_type = TYPE_ARRAY_ELEMENT (target_type);
388 if (source_type == target_type)
390 if (TREE_CODE (source_type) != POINTER_TYPE
391 || TREE_CODE (target_type) != POINTER_TYPE)
393 return can_widen_reference_to (source_type, target_type);
397 int source_depth = class_depth (source_type);
398 int target_depth = class_depth (target_type);
400 /* class_depth can return a negative depth if an error occurred */
401 if (source_depth < 0 || target_depth < 0)
404 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
406 /* target_type is OK if source_type or source_type ancestors
407 implement target_type. We handle multiple sub-interfaces */
409 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
410 int n = TREE_VEC_LENGTH (basetype_vec), i;
411 for (i=0 ; i < n; i++)
412 if (can_widen_reference_to
413 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
420 for ( ; source_depth > target_depth; source_depth--)
422 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
424 return source_type == target_type;
433 type = pop_type (type);
436 tree node = quick_stack;
437 quick_stack = TREE_CHAIN (quick_stack);
438 TREE_CHAIN (node) = tree_list_free_list;
439 tree_list_free_list = node;
440 node = TREE_VALUE (node);
444 return find_stack_slot (stack_pointer, promote_type (type));
448 /* Pop and discrad the top COUNT stack slots. */
451 java_stack_pop (count)
457 if (stack_pointer == 0)
458 fatal ("stack underflow");
459 type = stack_type_map[stack_pointer - 1];
460 if (type == TYPE_SECOND)
463 if (stack_pointer == 1 || count <= 0)
464 fatal ("stack underflow");
465 type = stack_type_map[stack_pointer - 2];
467 val = pop_value (type);
472 /* Implement the 'swap' operator (to swap two top stack slots). */
481 if (stack_pointer < 2
482 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
483 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
484 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
485 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
486 fatal ("bad stack swap");
488 flush_quick_stack ();
489 decl1 = find_stack_slot (stack_pointer - 1, type1);
490 decl2 = find_stack_slot (stack_pointer - 2, type2);
491 temp = copy_to_reg (DECL_RTL (decl1));
492 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
493 emit_move_insn (DECL_RTL (decl2), temp);
494 stack_type_map[stack_pointer - 1] = type2;
495 stack_type_map[stack_pointer - 2] = type1;
499 java_stack_dup (size, offset)
502 int low_index = stack_pointer - size - offset;
505 error ("stack underflow - dup* operation");
507 flush_quick_stack ();
509 stack_pointer += size;
510 dst_index = stack_pointer;
512 for (dst_index = stack_pointer; --dst_index >= low_index; )
515 int src_index = dst_index - size;
516 if (src_index < low_index)
517 src_index = dst_index + size + offset;
518 type = stack_type_map [src_index];
519 if (type == TYPE_SECOND)
521 if (src_index <= low_index)
522 fatal ("dup operation splits 64-bit number");
523 stack_type_map[dst_index] = type;
524 src_index--; dst_index--;
525 type = stack_type_map[src_index];
526 if (! TYPE_IS_WIDE (type))
527 fatal ("internal error - dup operation");
529 else if (TYPE_IS_WIDE (type))
530 fatal ("internal error - dup operation");
531 if (src_index != dst_index)
533 tree src_decl = find_stack_slot (src_index, type);
534 tree dst_decl = find_stack_slot (dst_index, type);
535 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
536 stack_type_map[dst_index] = type;
541 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
545 build_java_athrow (node)
550 call = build (CALL_EXPR,
552 build_address_of (throw_node[exceptions_via_longjmp ? 1 : 0]),
553 build_tree_list (NULL_TREE, node),
555 TREE_SIDE_EFFECTS (call) = 1;
556 expand_expr_stmt (call);
557 java_stack_pop (stack_pointer);
560 /* Implementation for jsr/ret */
563 build_java_jsr (where, ret)
567 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
568 push_value (ret_label);
569 flush_quick_stack ();
570 emit_jump (label_rtx (where));
575 build_java_ret (location)
578 expand_computed_goto (location);
581 /* Implementation of operations on array: new, load, store, length */
583 /* Array core info access macros */
585 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
586 byte_position (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))
589 decode_newarray_type (atype)
594 case 4: return boolean_type_node;
595 case 5: return char_type_node;
596 case 6: return float_type_node;
597 case 7: return double_type_node;
598 case 8: return byte_type_node;
599 case 9: return short_type_node;
600 case 10: return int_type_node;
601 case 11: return long_type_node;
602 default: return NULL_TREE;
606 /* Map primitive type to the code used by OPCODE_newarray. */
609 encode_newarray_type (type)
612 if (type == boolean_type_node)
614 else if (type == char_type_node)
616 else if (type == float_type_node)
618 else if (type == double_type_node)
620 else if (type == byte_type_node)
622 else if (type == short_type_node)
624 else if (type == int_type_node)
626 else if (type == long_type_node)
629 fatal ("Can't compute type code - patch_newarray");
632 /* Build a call to _Jv_ThrowBadArrayIndex(), the
633 ArrayIndexOfBoundsException exception handler. */
636 build_java_throw_out_of_bounds_exception (index)
639 tree node = build (CALL_EXPR, int_type_node,
640 build_address_of (soft_badarrayindex_node),
641 build_tree_list (NULL_TREE, index), NULL_TREE);
642 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
646 /* Return the length of an array. Doesn't perform any checking on the nature
647 or value of the array NODE. May be used to implement some bytecodes. */
650 build_java_array_length_access (node)
653 tree type = TREE_TYPE (node);
654 HOST_WIDE_INT length;
655 if (!is_array_type_p (type))
656 fatal ("array length on a non-array reference");
657 length = java_array_type_length (type);
659 return build_int_2 (length, 0);
660 return fold (build1 (INDIRECT_REF,
662 fold (build (PLUS_EXPR, ptr_type_node,
664 JAVA_ARRAY_LENGTH_OFFSET(node)))));
667 /* Optionally checks an array against the NULL pointer, eventually throwing a
668 NullPointerException. It could replace signal handling, but tied to NULL.
669 ARG1: the pointer to check, ARG2: the expression to use if
670 the pointer is non-null and ARG3 the type that should be returned. */
673 build_java_arraynull_check (node, expr, type)
674 tree node ATTRIBUTE_UNUSED;
676 tree type ATTRIBUTE_UNUSED;
679 static int java_array_access_throws_null_exception = 0;
681 if (java_array_access_throws_null_exception)
682 return (build (COND_EXPR,
684 build (EQ_EXPR, int_type_node, node, null_pointer_node),
685 build_java_athrow (node), expr ));
692 java_array_data_offset (array)
695 tree array_type = TREE_TYPE (TREE_TYPE (array));
696 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
698 if (data_fld == NULL_TREE)
699 return size_in_bytes (array_type);
701 return byte_position (data_fld);
704 /* Implement array indexing (either as l-value or r-value).
705 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
706 Optionally performs bounds checking and/or test to NULL.
707 At this point, ARRAY should have been verified as an array. */
710 build_java_arrayaccess (array, type, index)
711 tree array, type, index;
713 tree arith, node, throw = NULL_TREE;
715 arith = fold (build (PLUS_EXPR, int_type_node,
716 java_array_data_offset (array),
717 fold (build (MULT_EXPR, int_type_node,
718 index, size_in_bytes(type)))));
720 if (flag_bounds_check)
723 * (unsigned jint) INDEX >= (unsigned jint) LEN
724 * && throw ArrayIndexOutOfBoundsException.
725 * Note this is equivalent to and more efficient than:
726 * INDEX < 0 || INDEX >= LEN && throw ... */
728 tree len = build_java_array_length_access (array);
729 TREE_TYPE (len) = unsigned_int_type_node;
730 test = fold (build (GE_EXPR, boolean_type_node,
731 convert (unsigned_int_type_node, index),
733 if (! integer_zerop (test))
735 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
736 build_java_throw_out_of_bounds_exception (index));
737 /* allows expansion within COMPOUND */
738 TREE_SIDE_EFFECTS( throw ) = 1;
742 node = build1 (INDIRECT_REF, type,
743 fold (build (PLUS_EXPR, ptr_type_node,
745 (throw ? build (COMPOUND_EXPR, int_type_node,
749 return (fold (build_java_arraynull_check (array, node, type)));
752 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
753 ARRAY_NODE. This function is used to retrieve something less vague than
754 a pointer type when indexing the first dimension of something like [[<t>.
755 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
757 As a side effect, it also makes sure that ARRAY_NODE is an array. */
760 build_java_check_indexed_type (array_node, indexed_type)
766 if (!is_array_type_p (TREE_TYPE (array_node)))
767 fatal ("array indexing on a non-array reference");
769 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
771 if (indexed_type == ptr_type_node )
772 return promote_type (elt_type);
774 /* BYTE/BOOLEAN store and load are used for both type */
775 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
776 return boolean_type_node;
778 if (indexed_type != elt_type )
779 fatal ("type array element mismatch");
784 /* newarray triggers a call to _Jv_NewArray. This function should be called
785 with an integer code (the type of array to create) and get from the stack
786 the size of the dimmension. */
789 build_newarray (atype_value, length)
794 = build_java_array_type (decode_newarray_type (atype_value),
795 host_integerp (length, 0) == INTEGER_CST
796 ? tree_low_cst (length, 0) : -1);
798 return build (CALL_EXPR, promote_type (type),
799 build_address_of (soft_newarray_node),
800 tree_cons (NULL_TREE,
801 build_int_2 (atype_value, 0),
802 build_tree_list (NULL_TREE, length)),
806 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
810 build_anewarray (class_type, length)
815 = build_java_array_type (class_type,
816 host_integerp (length, 0)
817 ? tree_low_cst (length, 0) : -1);
819 return build (CALL_EXPR, promote_type (type),
820 build_address_of (soft_anewarray_node),
821 tree_cons (NULL_TREE, length,
822 tree_cons (NULL_TREE, build_class_ref (class_type),
823 build_tree_list (NULL_TREE,
824 null_pointer_node))),
828 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
831 build_new_array (type, length)
835 if (JPRIMITIVE_TYPE_P (type))
836 return build_newarray (encode_newarray_type (type), length);
838 return build_anewarray (TREE_TYPE (type), length);
841 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
842 class pointer, a number of dimensions and the matching number of
843 dimensions. The argument list is NULL terminated. */
846 expand_java_multianewarray (class_type, ndim)
851 tree args = build_tree_list( NULL_TREE, null_pointer_node );
853 for( i = 0; i < ndim; i++ )
854 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
856 push_value (build (CALL_EXPR,
857 promote_type (class_type),
858 build_address_of (soft_multianewarray_node),
859 tree_cons (NULL_TREE, build_class_ref (class_type),
860 tree_cons (NULL_TREE,
861 build_int_2 (ndim, 0), args )),
865 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
866 ARRAY is an array type. May expand some bound checking and NULL
867 pointer checking. RHS_TYPE_NODE we are going to store. In the case
868 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
869 INT. In those cases, we make the convertion.
871 if ARRAy is a reference type, the assignment is checked at run-time
872 to make sure that the RHS can be assigned to the array element
873 type. It is not necessary to generate this code if ARRAY is final. */
876 expand_java_arraystore (rhs_type_node)
879 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
880 && TYPE_PRECISION (rhs_type_node) <= 32) ?
881 int_type_node : rhs_type_node);
882 tree index = pop_value (int_type_node);
883 tree array = pop_value (ptr_type_node);
885 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
887 flush_quick_stack ();
889 index = save_expr (index);
890 array = save_expr (array);
892 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
894 tree check = build (CALL_EXPR, void_type_node,
895 build_address_of (soft_checkarraystore_node),
896 tree_cons (NULL_TREE, array,
897 build_tree_list (NULL_TREE, rhs_node)),
899 TREE_SIDE_EFFECTS (check) = 1;
900 expand_expr_stmt (check);
903 expand_assignment (build_java_arrayaccess (array,
909 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
910 sure that LHS is an array type. May expand some bound checking and NULL
912 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
913 BOOLEAN/SHORT, we push a promoted type back to the stack.
917 expand_java_arrayload (lhs_type_node )
921 tree index_node = pop_value (int_type_node);
922 tree array_node = pop_value (ptr_type_node);
924 index_node = save_expr (index_node);
925 array_node = save_expr (array_node);
926 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
928 load_node = build_java_arrayaccess (array_node,
932 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
933 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
934 push_value (load_node);
937 /* Expands .length. Makes sure that we deal with and array and may expand
938 a NULL check on the array object. */
941 expand_java_array_length ()
943 tree array = pop_value (ptr_type_node);
944 tree length = build_java_array_length_access (array);
946 push_value (build_java_arraynull_check (array, length, int_type_node));
949 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
950 either soft_monitorenter_node or soft_monitorexit_node. */
953 build_java_monitor (call, object)
957 return (build (CALL_EXPR,
959 build_address_of (call),
960 build_tree_list (NULL_TREE, object),
964 /* Emit code for one of the PUSHC instructions. */
967 expand_java_pushc (ival, type)
972 if (type == ptr_type_node && ival == 0)
973 value = null_pointer_node;
974 else if (type == int_type_node || type == long_type_node)
976 value = build_int_2 (ival, ival < 0 ? -1 : 0);
977 TREE_TYPE (value) = type;
979 else if (type == float_type_node || type == double_type_node)
982 #ifdef REAL_ARITHMETIC
983 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
987 value = build_real (type, x);
990 fatal ("internal error in expand_java_pushc");
995 expand_java_return (type)
998 if (type == void_type_node)
999 expand_null_return ();
1002 tree retval = pop_value (type);
1003 tree res = DECL_RESULT (current_function_decl);
1004 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1006 /* Handle the situation where the native integer type is smaller
1007 than the JVM integer. It can happen for many cross compilers.
1008 The whole if expression just goes away if INT_TYPE_SIZE < 32
1010 if (INT_TYPE_SIZE < 32
1011 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1012 < GET_MODE_SIZE (TYPE_MODE (type))))
1013 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1015 TREE_SIDE_EFFECTS (retval) = 1;
1016 expand_return (retval);
1021 build_address_of (value)
1024 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1028 expand_java_NEW (type)
1031 if (! CLASS_LOADED_P (type))
1032 load_class (type, 1);
1033 safe_layout_class (type);
1034 push_value (build (CALL_EXPR, promote_type (type),
1035 build_address_of (alloc_object_node),
1036 tree_cons (NULL_TREE, build_class_ref (type),
1037 build_tree_list (NULL_TREE,
1038 size_in_bytes (type))),
1042 /* This returns an expression which will extract the class of an
1046 build_get_class (value)
1049 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1050 tree vtable_field = lookup_field (&object_type_node,
1051 get_identifier ("vtable"));
1052 return build (COMPONENT_REF, class_ptr_type,
1053 build1 (INDIRECT_REF, dtable_type,
1054 build (COMPONENT_REF, dtable_ptr_type,
1055 build1 (INDIRECT_REF, object_type_node, value),
1060 /* This builds the tree representation of the `instanceof' operator.
1061 It tries various tricks to optimize this in cases where types are
1065 build_instanceof (value, type)
1069 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1070 tree valtype = TREE_TYPE (TREE_TYPE (value));
1071 tree valclass = TYPE_NAME (valtype);
1074 /* When compiling from bytecode, we need to ensure that TYPE has
1076 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1078 load_class (type, 1);
1079 safe_layout_class (type);
1080 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1081 return error_mark_node;
1083 klass = TYPE_NAME (type);
1085 if (type == object_type_node || inherits_from_p (valtype, type))
1087 /* Anything except `null' is an instance of Object. Likewise,
1088 if the object is known to be an instance of the class, then
1089 we only need to check for `null'. */
1090 expr = build (COND_EXPR, itype,
1092 boolean_true_node, boolean_false_node);
1094 else if (DECL_P (klass) && DECL_P (valclass)
1095 && ! CLASS_INTERFACE (valclass)
1096 && ! CLASS_INTERFACE (klass)
1097 && ! inherits_from_p (type, valtype)
1098 && (CLASS_FINAL (klass)
1099 || ! inherits_from_p (valtype, type)))
1101 /* The classes are from different branches of the derivation
1102 tree, so we immediately know the answer. */
1103 expr = boolean_false_node;
1105 else if (DECL_P (klass) && CLASS_FINAL (klass))
1107 tree save = save_expr (value);
1108 expr = build (COND_EXPR, itype,
1110 build (EQ_EXPR, itype,
1111 build_get_class (save),
1112 build_class_ref (type)),
1113 boolean_false_node);
1117 expr = build (CALL_EXPR, itype,
1118 build_address_of (soft_instanceof_node),
1119 tree_cons (NULL_TREE, value,
1120 build_tree_list (NULL_TREE,
1121 build_class_ref (type))),
1124 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1129 expand_java_INSTANCEOF (type)
1132 tree value = pop_value (object_ptr_type_node);
1133 value = build_instanceof (value, type);
1138 expand_java_CHECKCAST (type)
1141 tree value = pop_value (ptr_type_node);
1142 value = build (CALL_EXPR, promote_type (type),
1143 build_address_of (soft_checkcast_node),
1144 tree_cons (NULL_TREE, build_class_ref (type),
1145 build_tree_list (NULL_TREE, value)),
1151 expand_iinc (local_var_index, ival, pc)
1152 unsigned int local_var_index;
1156 tree local_var, res;
1157 tree constant_value;
1159 flush_quick_stack ();
1160 local_var = find_local_variable (local_var_index, int_type_node, pc);
1161 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1162 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1163 expand_assignment (local_var, res, 0, 0);
1168 build_java_soft_divmod (op, type, op1, op2)
1170 tree type, op1, op2;
1173 tree arg1 = convert (type, op1);
1174 tree arg2 = convert (type, op2);
1176 if (type == int_type_node)
1180 case TRUNC_DIV_EXPR:
1181 call = soft_idiv_node;
1183 case TRUNC_MOD_EXPR:
1184 call = soft_irem_node;
1190 else if (type == long_type_node)
1194 case TRUNC_DIV_EXPR:
1195 call = soft_ldiv_node;
1197 case TRUNC_MOD_EXPR:
1198 call = soft_lrem_node;
1206 fatal ("Internal compiler error in build_java_soft_divmod");
1208 call = build (CALL_EXPR, type,
1209 build_address_of (call),
1210 tree_cons (NULL_TREE, arg1,
1211 build_tree_list (NULL_TREE, arg2)),
1218 build_java_binop (op, type, arg1, arg2)
1220 tree type, arg1, arg2;
1227 tree u_type = unsigned_type (type);
1228 arg1 = convert (u_type, arg1);
1229 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1230 return convert (type, arg1);
1234 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1235 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1238 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1239 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1240 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1242 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1243 boolean_type_node, arg1, arg2));
1244 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1245 tree second_compare = fold (build (COND_EXPR, int_type_node,
1246 ifexp2, integer_zero_node,
1247 op == COMPARE_L_EXPR
1248 ? integer_negative_one_node
1249 : integer_one_node));
1250 return fold (build (COND_EXPR, int_type_node, ifexp1,
1251 op == COMPARE_L_EXPR ? integer_one_node
1252 : integer_negative_one_node,
1256 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1258 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1259 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1260 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1261 ifexp2, integer_one_node,
1262 integer_zero_node));
1263 return fold (build (COND_EXPR, int_type_node,
1264 ifexp1, integer_negative_one_node, second_compare));
1266 case TRUNC_DIV_EXPR:
1267 case TRUNC_MOD_EXPR:
1268 if (TREE_CODE (type) == REAL_TYPE
1269 && op == TRUNC_MOD_EXPR)
1272 if (type != double_type_node)
1274 arg1 = convert (double_type_node, arg1);
1275 arg2 = convert (double_type_node, arg2);
1277 call = build (CALL_EXPR, double_type_node,
1278 build_address_of (soft_fmod_node),
1279 tree_cons (NULL_TREE, arg1,
1280 build_tree_list (NULL_TREE, arg2)),
1282 if (type != double_type_node)
1283 call = convert (type, call);
1287 if (TREE_CODE (type) == INTEGER_TYPE
1288 && flag_use_divide_subroutine
1289 && ! flag_syntax_only)
1290 return build_java_soft_divmod (op, type, arg1, arg2);
1295 return fold (build (op, type, arg1, arg2));
1299 expand_java_binop (type, op)
1300 tree type; enum tree_code op;
1310 rtype = int_type_node;
1311 rarg = pop_value (rtype);
1314 rarg = pop_value (rtype);
1316 larg = pop_value (ltype);
1317 push_value (build_java_binop (op, type, larg, rarg));
1320 /* Lookup the field named NAME in *TYPEP or its super classes.
1321 If not found, return NULL_TREE.
1322 (If the *TYPEP is not found, or if the field reference is
1323 ambiguous, return error_mark_node.)
1324 If found, return the FIELD_DECL, and set *TYPEP to the
1325 class containing the field. */
1328 lookup_field (typep, name)
1332 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1334 load_class (*typep, 1);
1335 safe_layout_class (*typep);
1336 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1337 return error_mark_node;
1341 tree field, basetype_vec;
1345 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1346 if (DECL_NAME (field) == name)
1349 /* If *typep is an innerclass, lookup the field in its enclosing
1351 if (INNER_CLASS_TYPE_P (*typep))
1353 tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1355 if ((field = lookup_field (&outer_type, name)))
1359 /* Process implemented interfaces. */
1360 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1361 n = TREE_VEC_LENGTH (basetype_vec);
1362 save_field = NULL_TREE;
1363 for (i = 0; i < n; i++)
1365 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1366 if ((field = lookup_field (&t, name)))
1368 if (save_field == field)
1370 if (save_field == NULL_TREE)
1374 tree i1 = DECL_CONTEXT (save_field);
1375 tree i2 = DECL_CONTEXT (field);
1376 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1377 IDENTIFIER_POINTER (name),
1378 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1379 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1380 return error_mark_node;
1385 if (save_field != NULL_TREE)
1388 *typep = CLASSTYPE_SUPER (*typep);
1393 /* Look up the field named NAME in object SELF_VALUE,
1394 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1395 SELF_VALUE is NULL_TREE if looking for a static field. */
1398 build_field_ref (self_value, self_class, name)
1399 tree self_value, self_class, name;
1401 tree base_class = self_class;
1402 tree field_decl = lookup_field (&base_class, name);
1403 if (field_decl == NULL_TREE)
1405 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1406 return error_mark_node;
1408 if (self_value == NULL_TREE)
1410 return build_static_field_ref (field_decl);
1414 tree base_handle_type = promote_type (base_class);
1415 if (base_handle_type != TREE_TYPE (self_value))
1416 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1417 #ifdef JAVA_USE_HANDLES
1418 self_value = unhand_expr (self_value);
1420 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1422 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1423 self_value, field_decl));
1433 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1434 name = get_identifier (buf);
1435 if (IDENTIFIER_LOCAL_VALUE (name))
1436 return IDENTIFIER_LOCAL_VALUE (name);
1439 /* The type of the address of a label is return_address_type_node. */
1440 tree decl = create_label_decl (name);
1441 LABEL_PC (decl) = pc;
1443 return pushdecl (decl);
1447 /* Generate a unique name for the purpose of loops and switches
1448 labels, and try-catch-finally blocks label or temporary variables. */
1453 static int l_number = 0;
1455 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1457 return get_identifier (buff);
1461 create_label_decl (name)
1465 push_obstacks (&permanent_obstack, &permanent_obstack);
1466 decl = build_decl (LABEL_DECL, name,
1467 TREE_TYPE (return_address_type_node));
1469 DECL_CONTEXT (decl) = current_function_decl;
1470 DECL_IGNORED_P (decl) = 1;
1474 /* This maps a bytecode offset (PC) to various flags. */
1475 char *instruction_bits;
1478 note_label (current_pc, target_pc)
1479 int current_pc ATTRIBUTE_UNUSED, target_pc;
1481 lookup_label (target_pc);
1482 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1485 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1486 where CONDITION is one of one the compare operators. */
1489 expand_compare (condition, value1, value2, target_pc)
1490 enum tree_code condition;
1491 tree value1, value2;
1494 tree target = lookup_label (target_pc);
1495 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1496 expand_start_cond (truthvalue_conversion (cond), 0);
1497 expand_goto (target);
1501 /* Emit code for a TEST-type opcode. */
1504 expand_test (condition, type, target_pc)
1505 enum tree_code condition;
1509 tree value1, value2;
1510 flush_quick_stack ();
1511 value1 = pop_value (type);
1512 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1513 expand_compare (condition, value1, value2, target_pc);
1516 /* Emit code for a COND-type opcode. */
1519 expand_cond (condition, type, target_pc)
1520 enum tree_code condition;
1524 tree value1, value2;
1525 flush_quick_stack ();
1526 /* note: pop values in opposite order */
1527 value2 = pop_value (type);
1528 value1 = pop_value (type);
1529 /* Maybe should check value1 and value2 for type compatibility ??? */
1530 expand_compare (condition, value1, value2, target_pc);
1534 expand_java_goto (target_pc)
1537 tree target_label = lookup_label (target_pc);
1538 flush_quick_stack ();
1539 expand_goto (target_label);
1544 expand_java_call (target_pc, return_address)
1545 int target_pc, return_address;
1547 tree target_label = lookup_label (target_pc);
1548 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1550 flush_quick_stack ();
1551 expand_goto (target_label);
1555 expand_java_ret (return_address)
1556 tree return_address ATTRIBUTE_UNUSED;
1558 warning ("ret instruction not implemented");
1560 tree target_label = lookup_label (target_pc);
1561 flush_quick_stack ();
1562 expand_goto (target_label);
1567 /* Recursive helper function to pop argument types during verifiation. */
1570 pop_argument_types (arg_types)
1573 if (arg_types == end_params_node)
1575 if (TREE_CODE (arg_types) == TREE_LIST)
1577 pop_argument_types (TREE_CHAIN (arg_types));
1578 pop_type (TREE_VALUE (arg_types));
1585 pop_arguments (arg_types)
1588 if (arg_types == end_params_node)
1590 if (TREE_CODE (arg_types) == TREE_LIST)
1592 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1593 tree type = TREE_VALUE (arg_types);
1594 tree arg = pop_value (type);
1595 if (PROMOTE_PROTOTYPES
1596 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1597 && INTEGRAL_TYPE_P (type))
1598 arg = convert (integer_type_node, arg);
1599 return tree_cons (NULL_TREE, arg, tail);
1604 /* Build an expression to initialize the class CLAS.
1605 if EXPR is non-NULL, returns an expression to first call the initializer
1606 (if it is needed) and then calls EXPR. */
1609 build_class_init (clas, expr)
1613 struct init_test_hash_entry *ite;
1614 if (inherits_from_p (current_class, clas))
1617 if (always_initialize_class_p)
1619 init = build (CALL_EXPR, void_type_node,
1620 build_address_of (soft_initclass_node),
1621 build_tree_list (NULL_TREE, build_class_ref (clas)),
1623 TREE_SIDE_EFFECTS (init) = 1;
1627 ite = (struct init_test_hash_entry *)
1628 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1629 (const hash_table_key) clas,
1632 if (ite->init_test_decl == 0)
1633 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1635 /* Tell the check-init code to ignore this decl. */
1636 DECL_BIT_INDEX(ite->init_test_decl) = -1;
1638 init = build (CALL_EXPR, void_type_node,
1639 build_address_of (soft_initclass_node),
1640 build_tree_list (NULL_TREE, build_class_ref (clas)),
1642 TREE_SIDE_EFFECTS (init) = 1;
1643 call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1644 build (MODIFY_EXPR, boolean_type_node,
1645 ite->init_test_decl, boolean_true_node));
1646 TREE_SIDE_EFFECTS (call) = 1;
1647 init = build (COND_EXPR, void_type_node,
1648 build (EQ_EXPR, boolean_type_node,
1649 ite->init_test_decl, boolean_false_node),
1650 call, integer_zero_node);
1651 TREE_SIDE_EFFECTS (init) = 1;
1654 if (expr != NULL_TREE)
1656 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1657 TREE_SIDE_EFFECTS (expr) = 1;
1664 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1665 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1666 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1669 if (is_compiled_class (self_type))
1671 make_decl_rtl (method, NULL, 1);
1672 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1676 /* We don't know whether the method has been (statically) compiled.
1677 Compile this code to get a reference to the method's code:
1679 SELF_TYPE->methods[METHOD_INDEX].ncode
1681 This is guaranteed to work (assuming SELF_TYPE has
1682 been initialized), since if the method is not compiled yet,
1683 its ncode points to a trampoline that forces compilation. */
1685 int method_index = 0;
1687 tree ref = build_class_ref (self_type);
1688 ref = build1 (INDIRECT_REF, class_type_node, ref);
1689 if (ncode_ident == NULL_TREE)
1690 ncode_ident = get_identifier ("ncode");
1691 if (methods_ident == NULL_TREE)
1692 methods_ident = get_identifier ("methods");
1693 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1694 lookup_field (&class_type_node, methods_ident));
1695 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1696 ; meth = TREE_CHAIN (meth))
1700 if (meth == NULL_TREE)
1701 fatal ("method '%s' not found in class",
1702 IDENTIFIER_POINTER (DECL_NAME (method)));
1705 method_index *= int_size_in_bytes (method_type_node);
1706 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1707 ref, build_int_2 (method_index, 0)));
1708 ref = build1 (INDIRECT_REF, method_type_node, ref);
1709 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1711 lookup_field (&method_type_node, ncode_ident));
1717 invoke_build_dtable (is_invoke_interface, arg_list)
1718 int is_invoke_interface;
1721 tree dtable, objectref;
1723 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1725 /* If we're dealing with interfaces and if the objectref
1726 argument is an array then get the dispatch table of the class
1727 Object rather than the one from the objectref. */
1728 objectref = (is_invoke_interface
1729 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1730 object_type_node : TREE_VALUE (arg_list));
1732 if (dtable_ident == NULL_TREE)
1733 dtable_ident = get_identifier ("vtable");
1734 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1735 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1736 lookup_field (&object_type_node, dtable_ident));
1742 build_invokevirtual (dtable, method)
1743 tree dtable, method;
1746 tree nativecode_ptr_ptr_type_node
1747 = build_pointer_type (nativecode_ptr_type_node);
1748 tree method_index = convert (sizetype, DECL_VINDEX (method));
1750 /* Add one to skip "class" field of dtable, and one to skip unused
1751 vtable entry (for C++ compatibility). */
1752 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1753 method_index = size_binop (MULT_EXPR, method_index,
1754 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1755 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1756 convert (nativecode_ptr_ptr_type_node, method_index)));
1757 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1763 build_invokeinterface (dtable, method)
1764 tree dtable, method;
1766 static tree class_ident = NULL_TREE;
1773 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1774 ensure that the selected method exists, is public and not
1775 abstract nor static. */
1777 if (class_ident == NULL_TREE)
1779 class_ident = get_identifier ("class");
1780 ggc_add_tree_root (&class_ident, 1);
1783 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1784 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1785 lookup_field (&dtable_type, class_ident));
1787 interface = DECL_CONTEXT (method);
1788 layout_class_methods (interface);
1791 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1795 idx = build_int_2 (i, 0);
1798 if (meth == NULL_TREE)
1799 fatal ("internal error in build_invokeinterface");
1802 lookup_arg = tree_cons (NULL_TREE, dtable,
1803 tree_cons (NULL_TREE, build_class_ref (interface),
1804 build_tree_list (NULL_TREE, idx)));
1806 return build (CALL_EXPR, ptr_type_node,
1807 build_address_of (soft_lookupinterfacemethod_node),
1808 lookup_arg, NULL_TREE);
1811 /* Expand one of the invoke_* opcodes.
1812 OCPODE is the specific opcode.
1813 METHOD_REF_INDEX is an index into the constant pool.
1814 NARGS is the number of arguments, or -1 if not specified. */
1817 expand_invoke (opcode, method_ref_index, nargs)
1819 int method_ref_index;
1820 int nargs ATTRIBUTE_UNUSED;
1822 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
1823 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
1824 tree self_type = get_class_constant
1825 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
1826 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1827 tree call, func, method, arg_list, method_type;
1828 tree cond = NULL_TREE;
1830 if (! CLASS_LOADED_P (self_type))
1832 load_class (self_type, 1);
1833 safe_layout_class (self_type);
1834 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1835 fatal ("failed to find class '%s'", self_name);
1837 layout_class_methods (self_type);
1839 if (ID_INIT_P (method_name))
1840 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1843 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1844 method_name, method_signature);
1845 if (method == NULL_TREE)
1847 error ("Class '%s' has no method named '%s' matching signature '%s'",
1849 IDENTIFIER_POINTER (method_name),
1850 IDENTIFIER_POINTER (method_signature));
1852 /* Invoke static can't invoke static/abstract method */
1853 else if (opcode == OPCODE_invokestatic)
1855 if (!METHOD_STATIC (method))
1857 error ("invokestatic on non static method");
1860 else if (METHOD_ABSTRACT (method))
1862 error ("invokestatic on abstract method");
1868 if (METHOD_STATIC (method))
1870 error ("invoke[non-static] on static method");
1875 if (method == NULL_TREE)
1877 method_type = get_type_from_signature (method_signature);
1878 pop_arguments (TYPE_ARG_TYPES (method_type));
1879 if (opcode != OPCODE_invokestatic)
1880 pop_type (self_type);
1881 method_type = promote_type (TREE_TYPE (method_type));
1882 push_value (convert (method_type, integer_zero_node));
1886 method_type = TREE_TYPE (method);
1887 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1888 flush_quick_stack ();
1891 if (opcode == OPCODE_invokestatic)
1892 func = build_known_method_ref (method, method_type, self_type,
1893 method_signature, arg_list);
1894 else if (opcode == OPCODE_invokespecial
1895 || (opcode == OPCODE_invokevirtual
1896 && (METHOD_PRIVATE (method)
1897 || METHOD_FINAL (method)
1898 || CLASS_FINAL (TYPE_NAME (self_type)))))
1900 /* If the object for the method call is null, we throw an
1901 exception. We don't do this if the object is the current
1902 method's `this'. In other cases we just rely on an
1903 optimization pass to eliminate redundant checks. FIXME:
1904 Unfortunately there doesn't seem to be a way to determine
1905 what the current method is right now. */
1906 /* We use a SAVE_EXPR here to make sure we only evaluate
1907 the new `self' expression once. */
1908 tree save_arg = save_expr (TREE_VALUE (arg_list));
1909 TREE_VALUE (arg_list) = save_arg;
1910 cond = build (EQ_EXPR, boolean_type_node, save_arg, null_pointer_node);
1911 func = build_known_method_ref (method, method_type, self_type,
1912 method_signature, arg_list);
1916 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1918 if (opcode == OPCODE_invokevirtual)
1919 func = build_invokevirtual (dtable, method);
1921 func = build_invokeinterface (dtable, method);
1923 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1924 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1925 TREE_SIDE_EFFECTS (call) = 1;
1927 if (cond != NULL_TREE)
1929 /* We have to make the `then' branch a compound expression to
1930 make the types turn out right. This seems bizarre. */
1931 call = build (COND_EXPR, TREE_TYPE (call), cond,
1932 build (COMPOUND_EXPR, TREE_TYPE (call),
1933 build (CALL_EXPR, void_type_node,
1934 build_address_of (soft_nullpointer_node),
1935 NULL_TREE, NULL_TREE),
1936 (FLOAT_TYPE_P (TREE_TYPE (call))
1937 ? build_real (TREE_TYPE (call), dconst0)
1938 : build1 (CONVERT_EXPR, TREE_TYPE (call),
1939 integer_zero_node))),
1941 TREE_SIDE_EFFECTS (call) = 1;
1944 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1945 expand_expr_stmt (call);
1949 flush_quick_stack ();
1953 /* Create a stub which will be put into the vtable but which will call
1957 build_jni_stub (method)
1960 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
1961 tree jni_func_type, tem;
1962 tree env_var, res_var = NULL_TREE, block;
1963 tree method_args, res_type;
1966 tree klass = DECL_CONTEXT (method);
1967 int from_class = ! CLASS_FROM_SOURCE_P (klass);
1968 klass = build_class_ref (klass);
1970 if (! METHOD_NATIVE (method) || ! flag_jni)
1973 DECL_ARTIFICIAL (method) = 1;
1974 DECL_EXTERNAL (method) = 0;
1976 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
1977 DECL_CONTEXT (env_var) = method;
1979 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
1981 res_var = build_decl (VAR_DECL, get_identifier ("res"),
1982 TREE_TYPE (TREE_TYPE (method)));
1983 DECL_CONTEXT (res_var) = method;
1984 TREE_CHAIN (env_var) = res_var;
1987 push_obstacks (&permanent_obstack, &permanent_obstack);
1988 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
1989 TREE_STATIC (meth_var) = 1;
1990 TREE_PUBLIC (meth_var) = 0;
1991 DECL_EXTERNAL (meth_var) = 0;
1992 make_decl_rtl (meth_var, NULL, 0);
1993 meth_var = pushdecl_top_level (meth_var);
1996 /* One strange way that the front ends are different is that they
1997 store arguments differently. */
1999 method_args = DECL_ARGUMENTS (method);
2001 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2002 block = build_block (env_var, NULL_TREE, NULL_TREE,
2003 method_args, NULL_TREE);
2004 TREE_SIDE_EFFECTS (block) = 1;
2005 /* When compiling from source we don't set the type of the block,
2006 because that will prevent patch_return from ever being run. */
2008 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2010 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2011 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2012 build (CALL_EXPR, ptr_type_node,
2013 build_address_of (soft_getjnienvnewframe_node),
2014 build_tree_list (NULL_TREE, klass),
2016 CAN_COMPLETE_NORMALLY (body) = 1;
2018 /* All the arguments to this method become arguments to the
2019 underlying JNI function. If we had to wrap object arguments in a
2020 special way, we would do that here. */
2022 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2023 args = tree_cons (NULL_TREE, tem, args);
2024 args = nreverse (args);
2025 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2027 /* For a static method the second argument is the class. For a
2028 non-static method the second argument is `this'; that is already
2029 available in the argument list. */
2030 if (METHOD_STATIC (method))
2032 args = tree_cons (NULL_TREE, klass, args);
2033 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2036 /* The JNIEnv structure is the first argument to the JNI function. */
2037 args = tree_cons (NULL_TREE, env_var, args);
2038 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2040 /* We call _Jv_LookupJNIMethod to find the actual underlying
2041 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2042 exception if this function is not found at runtime. */
2043 method_sig = build_java_signature (TREE_TYPE (method));
2045 build_tree_list (NULL_TREE,
2046 build_utf8_ref (unmangle_classname
2047 (IDENTIFIER_POINTER (method_sig),
2048 IDENTIFIER_LENGTH (method_sig))));
2049 tem = DECL_NAME (method);
2051 = tree_cons (NULL_TREE, klass,
2052 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2055 = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2058 jnifunc = build (COND_EXPR, ptr_type_node,
2060 build (MODIFY_EXPR, ptr_type_node,
2062 build (CALL_EXPR, ptr_type_node,
2063 build_address_of (soft_lookupjnimethod_node),
2064 lookup_arg, NULL_TREE)));
2066 /* Now we make the actual JNI call via the resulting function
2068 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2069 build1 (NOP_EXPR, jni_func_type, jnifunc),
2072 /* If the JNI call returned a result, capture it here. If we had to
2073 unwrap JNI object results, we would do that here. */
2074 if (res_var != NULL_TREE)
2075 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2078 TREE_SIDE_EFFECTS (call) = 1;
2079 CAN_COMPLETE_NORMALLY (call) = 1;
2081 body = build (COMPOUND_EXPR, void_type_node, body, call);
2082 TREE_SIDE_EFFECTS (body) = 1;
2084 /* Now free the environment we allocated. */
2085 call = build (CALL_EXPR, ptr_type_node,
2086 build_address_of (soft_jnipopsystemframe_node),
2087 build_tree_list (NULL_TREE, env_var),
2089 TREE_SIDE_EFFECTS (call) = 1;
2090 CAN_COMPLETE_NORMALLY (call) = 1;
2091 body = build (COMPOUND_EXPR, void_type_node, body, call);
2092 TREE_SIDE_EFFECTS (body) = 1;
2094 /* Finally, do the return. When compiling from source we rely on
2095 patch_return to patch the return value -- because DECL_RESULT is
2096 not set at the time this function is called. */
2099 res_type = void_type_node;
2100 if (res_var != NULL_TREE)
2103 if (! DECL_RESULT (method))
2105 /* Make sure we copy the result variable to the actual
2106 result. We use the type of the DECL_RESULT because it
2107 might be different from the return type of the function:
2108 it might be promoted. */
2109 drt = TREE_TYPE (DECL_RESULT (method));
2110 if (drt != TREE_TYPE (res_var))
2111 res_var = build1 (CONVERT_EXPR, drt, res_var);
2112 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2113 TREE_SIDE_EFFECTS (res_var) = 1;
2118 /* This is necessary to get patch_return to run. */
2119 res_type = NULL_TREE;
2121 body = build (COMPOUND_EXPR, void_type_node, body,
2122 build1 (RETURN_EXPR, res_type, res_var));
2123 TREE_SIDE_EFFECTS (body) = 1;
2125 BLOCK_EXPR_BODY (block) = body;
2129 /* Expand an operation to extract from or store into a field.
2130 IS_STATIC is 1 iff the field is static.
2131 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2132 FIELD_REF_INDEX is an index into the constant pool. */
2135 expand_java_field_op (is_static, is_putting, field_ref_index)
2138 int field_ref_index;
2141 get_class_constant (current_jcf,
2142 COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
2144 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2145 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
2146 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool,
2148 tree field_type = get_type_from_signature (field_signature);
2149 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2152 tree field_decl = lookup_field (&self_type, field_name);
2153 if (field_decl == error_mark_node)
2157 else if (field_decl == NULL_TREE)
2159 error ("Missing field '%s' in '%s'",
2160 IDENTIFIER_POINTER (field_name), self_name);
2163 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2165 error ("Mismatching signature for field '%s' in '%s'",
2166 IDENTIFIER_POINTER (field_name), self_name);
2169 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2173 push_value (convert (field_type, integer_zero_node));
2174 flush_quick_stack ();
2178 /* Inline references to java.lang.PRIMTYPE.TYPE.
2179 In addition to being a useful (minor) optimization,
2180 this is also needed to avoid circularities in the implementation
2181 of these fields in libjava. */
2182 if (field_name == TYPE_identifier_node && ! is_putting
2183 && ! flag_emit_class_files && field_type == class_ptr_type
2184 && strncmp (self_name, "java.lang.", 10) == 0)
2186 tree typ = build_primtype_type_ref (self_name);
2194 field_ref = build_field_ref (field_ref, self_type, field_name);
2196 field_ref = build_class_init (self_type, field_ref);
2199 flush_quick_stack ();
2200 if (FIELD_FINAL (field_decl))
2202 if (DECL_CONTEXT (field_decl) != current_class)
2203 error_with_decl (field_decl,
2204 "assignment to final field `%s' not in field's class");
2205 else if (FIELD_STATIC (field_decl))
2207 if (!DECL_CLINIT_P (current_function_decl))
2208 error_with_decl (field_decl,
2209 "assignment to final static field `%s' not in class initializer");
2213 tree cfndecl_name = DECL_NAME (current_function_decl);
2214 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2215 && !ID_FINIT_P (cfndecl_name))
2216 error_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2219 expand_assignment (field_ref, new_value, 0, 0);
2222 push_value (field_ref);
2226 build_primtype_type_ref (self_name)
2227 const char *self_name;
2229 const char *class_name = self_name+10;
2231 if (strncmp(class_name, "Byte", 4) == 0)
2232 typ = byte_type_node;
2233 else if (strncmp(class_name, "Short", 5) == 0)
2234 typ = short_type_node;
2235 else if (strncmp(class_name, "Integer", 7) == 0)
2236 typ = int_type_node;
2237 else if (strncmp(class_name, "Long", 4) == 0)
2238 typ = long_type_node;
2239 else if (strncmp(class_name, "Float", 5) == 0)
2240 typ = float_type_node;
2241 else if (strncmp(class_name, "Double", 6) == 0)
2242 typ = double_type_node;
2243 else if (strncmp(class_name, "Boolean", 7) == 0)
2244 typ = boolean_type_node;
2245 else if (strncmp(class_name, "Char", 4) == 0)
2246 typ = char_type_node;
2247 else if (strncmp(class_name, "Void", 4) == 0)
2248 typ = void_type_node;
2251 if (typ != NULL_TREE)
2252 return build_class_ref (typ);
2258 load_type_state (label)
2262 tree vec = LABEL_TYPE_STATE (label);
2263 int cur_length = TREE_VEC_LENGTH (vec);
2264 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2265 for (i = 0; i < cur_length; i++)
2266 type_map [i] = TREE_VEC_ELT (vec, i);
2269 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2270 dependant things, but they rely on gcc routines. This function is
2271 placed here because it uses things defined locally in parse.y. */
2274 case_identity (t, v)
2275 tree t __attribute__ ((__unused__));
2281 /* Return the name of the vtable for an array of a given primitive
2284 get_primitive_array_vtable (tree elt)
2287 if (elt == boolean_type_node)
2288 r = boolean_array_vtable;
2289 else if (elt == byte_type_node)
2290 r = byte_array_vtable;
2291 else if (elt == char_type_node)
2292 r = char_array_vtable;
2293 else if (elt == short_type_node)
2294 r = short_array_vtable;
2295 else if (elt == int_type_node)
2296 r = int_array_vtable;
2297 else if (elt == long_type_node)
2298 r = long_array_vtable;
2299 else if (elt == float_type_node)
2300 r = float_array_vtable;
2301 else if (elt == double_type_node)
2302 r = double_array_vtable;
2305 return build_address_of (r);
2309 java_lang_expand_expr (exp, target, tmode, modifier)
2311 rtx target ATTRIBUTE_UNUSED;
2312 enum machine_mode tmode ATTRIBUTE_UNUSED;
2313 enum expand_modifier modifier ATTRIBUTE_UNUSED;
2317 switch (TREE_CODE (exp))
2319 case NEW_ARRAY_INIT:
2322 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2323 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2324 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2325 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2326 tree length = build_int_2 (ilength, 0);
2327 tree init = TREE_OPERAND (exp, 0);
2330 /* See if we can generate the array statically. */
2331 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2332 && JPRIMITIVE_TYPE_P (element_type))
2334 tree temp, value, init_decl;
2336 push_obstacks (&permanent_obstack, &permanent_obstack);
2337 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2338 PUSH_FIELD_VALUE (temp, "vtable",
2339 get_primitive_array_vtable (element_type));
2340 if (! flag_hash_synchronization)
2341 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2342 FINISH_RECORD_CONSTRUCTOR (temp);
2343 START_RECORD_CONSTRUCTOR (value, array_type);
2344 PUSH_SUPER_VALUE (value, temp);
2345 /* FIXME: build a new `length' here to get it on the right
2347 PUSH_FIELD_VALUE (value, "length", build_int_2 (ilength, 0));
2348 PUSH_FIELD_VALUE (value, "data", init);
2349 FINISH_RECORD_CONSTRUCTOR (value);
2351 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2352 pushdecl_top_level (init_decl);
2353 TREE_STATIC (init_decl) = 1;
2354 DECL_INITIAL (init_decl) = value;
2355 DECL_IGNORED_P (init_decl) = 1;
2356 TREE_READONLY (init_decl) = 1;
2357 make_decl_rtl (init_decl, NULL, 1);
2358 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2359 r = expand_expr (init, target, tmode, modifier);
2364 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2365 expand_decl (array_decl);
2366 tmp = expand_assignment (array_decl,
2367 build_new_array (element_type, length),
2369 if (TREE_CONSTANT (init)
2370 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2373 push_obstacks (&permanent_obstack, &permanent_obstack);
2374 init_decl = build_decl (VAR_DECL, generate_name (),
2376 pushdecl_top_level (init_decl);
2377 TREE_STATIC (init_decl) = 1;
2378 DECL_INITIAL (init_decl) = init;
2379 DECL_IGNORED_P (init_decl) = 1;
2380 TREE_READONLY (init_decl) = 1;
2381 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2382 make_decl_rtl (init_decl, NULL, 1);
2386 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2387 build1 (INDIRECT_REF, array_type,
2388 array_decl), data_fld), init, 0, 0);
2392 if (BLOCK_EXPR_BODY (exp))
2395 tree body = BLOCK_EXPR_BODY (exp);
2396 pushlevel (2); /* 2 and above */
2397 expand_start_bindings (0);
2398 local = BLOCK_EXPR_DECLS (exp);
2401 tree next = TREE_CHAIN (local);
2402 layout_decl (local, 0);
2403 expand_decl (pushdecl (local));
2406 /* Avoid deep recursion for long block. */
2407 while (TREE_CODE (body) == COMPOUND_EXPR)
2409 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2411 body = TREE_OPERAND (body, 1);
2413 expand_expr (body, const0_rtx, VOIDmode, 0);
2416 expand_end_bindings (getdecls (), 1, 0);
2424 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2425 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2428 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2430 (wfl_operator, "Duplicate case label: `%s'",
2431 print_int_node (TREE_OPERAND (exp, 0)));
2437 pushcase (NULL_TREE, 0,
2438 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2442 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2443 expand_expr_stmt (TREE_OPERAND (exp, 1));
2444 expand_end_case (TREE_OPERAND (exp, 0));
2448 /* We expand a try[-catch] block */
2450 /* Expand the try block */
2451 push_obstacks (&permanent_obstack, &permanent_obstack);
2452 expand_eh_region_start ();
2454 expand_expr_stmt (TREE_OPERAND (exp, 0));
2455 push_obstacks (&permanent_obstack, &permanent_obstack);
2456 expand_start_all_catch ();
2459 /* Expand all catch clauses (EH handlers) */
2460 for (current = TREE_OPERAND (exp, 1); current;
2461 current = TREE_CHAIN (current))
2464 tree catch = TREE_OPERAND (current, 0);
2465 tree decl = BLOCK_EXPR_DECLS (catch);
2466 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2467 start_catch_handler (prepare_eh_table_type (type));
2468 expand_expr_stmt (TREE_OPERAND (current, 0));
2470 expand_resume_after_catch ();
2471 end_catch_handler ();
2473 expand_end_all_catch ();
2477 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2478 tree_code_name [TREE_CODE (exp)]);
2483 expand_byte_code (jcf, method)
2490 const unsigned char *linenumber_pointer;
2491 int dead_code_index = -1;
2493 #undef RET /* Defined by config/i386/i386.h */
2494 #undef AND /* Causes problems with opcodes for iand and land. */
2496 #define BCODE byte_ops
2497 #define BYTE_type_node byte_type_node
2498 #define SHORT_type_node short_type_node
2499 #define INT_type_node int_type_node
2500 #define LONG_type_node long_type_node
2501 #define CHAR_type_node char_type_node
2502 #define PTR_type_node ptr_type_node
2503 #define FLOAT_type_node float_type_node
2504 #define DOUBLE_type_node double_type_node
2505 #define VOID_type_node void_type_node
2507 unsigned char* byte_ops;
2508 long length = DECL_CODE_LENGTH (method);
2511 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2512 byte_ops = jcf->read_ptr;
2514 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2515 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2516 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2517 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2519 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2521 instruction_bits = oballoc (length + 1);
2522 bzero (instruction_bits, length + 1);
2524 /* We make an initial pass of the line number table, to note
2525 which instructions have associated line number entries. */
2526 linenumber_pointer = linenumber_table;
2527 for (i = 0; i < linenumber_count; i++)
2529 int pc = GET_u2 (linenumber_pointer);
2530 linenumber_pointer += 4;
2532 warning ("invalid PC in line number table");
2535 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2536 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2537 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2541 /* Do a preliminary pass.
2542 * This figures out which PC can be the targets of jumps. */
2543 for (PC = 0; PC < length;)
2545 int oldpc = PC; /* PC at instruction start. */
2546 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2547 switch (byte_ops[PC++])
2549 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2551 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2554 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2556 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2557 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2558 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2559 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2560 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2561 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2562 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2563 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2565 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2566 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2567 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2568 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2569 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2570 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2571 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2572 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2574 /* two forms of wide instructions */
2575 #define PRE_SPECIAL_WIDE(IGNORE) \
2577 int modified_opcode = IMMEDIATE_u1; \
2578 if (modified_opcode == OPCODE_iinc) \
2580 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2581 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2585 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2589 /* nothing */ /* XXX JH */
2591 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2593 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2595 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2596 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2597 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2598 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2599 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2600 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2601 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2602 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2603 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2604 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2606 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2607 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2608 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2609 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2610 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2611 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2612 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2613 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2615 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2617 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2618 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2620 #define PRE_LOOKUP_SWITCH \
2621 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2622 NOTE_LABEL (default_offset+oldpc); \
2624 while (--npairs >= 0) { \
2625 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2626 jint offset = IMMEDIATE_s4; \
2627 NOTE_LABEL (offset+oldpc); } \
2630 #define PRE_TABLE_SWITCH \
2631 { jint default_offset = IMMEDIATE_s4; \
2632 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2633 NOTE_LABEL (default_offset+oldpc); \
2635 while (low++ <= high) { \
2636 jint offset = IMMEDIATE_s4; \
2637 NOTE_LABEL (offset+oldpc); } \
2640 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2641 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2642 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2643 (void)(IMMEDIATE_u2); \
2644 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2646 #include "javaop.def"
2651 if (! verify_jvm_instructions (jcf, byte_ops, length))
2654 /* Translate bytecodes to rtl instructions. */
2655 linenumber_pointer = linenumber_table;
2656 for (PC = 0; PC < length;)
2658 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2660 tree label = lookup_label (PC);
2661 flush_quick_stack ();
2662 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2663 expand_label (label);
2664 if (LABEL_VERIFIED (label) || PC == 0)
2665 load_type_state (label);
2668 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2670 if (dead_code_index == -1)
2672 /* This is the start of a region of unreachable bytecodes.
2673 They still need to be processed in order for EH ranges
2674 to get handled correctly. However, we can simply
2675 replace these bytecodes with nops. */
2676 dead_code_index = PC;
2679 /* Turn this bytecode into a nop. */
2684 if (dead_code_index != -1)
2686 /* We've just reached the end of a region of dead code. */
2687 warning ("Unreachable bytecode from %d to before %d.",
2688 dead_code_index, PC);
2689 dead_code_index = -1;
2693 /* Handle possible line number entry for this PC.
2695 This code handles out-of-order and multiple linenumbers per PC,
2696 but is optimized for the case of line numbers increasing
2697 monotonically with PC. */
2698 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2700 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2701 || GET_u2 (linenumber_pointer) != PC)
2702 linenumber_pointer = linenumber_table;
2703 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2705 int pc = GET_u2 (linenumber_pointer);
2706 linenumber_pointer += 4;
2709 lineno = GET_u2 (linenumber_pointer - 2);
2710 emit_line_note (input_filename, lineno);
2711 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2716 maybe_pushlevels (PC);
2717 PC = process_jvm_instruction (PC, byte_ops, length);
2718 maybe_poplevels (PC);
2721 if (dead_code_index != -1)
2723 /* We've just reached the end of a region of dead code. */
2724 warning ("Unreachable bytecode from %d to the end of the method.",
2730 java_push_constant_from_pool (jcf, index)
2735 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2738 push_obstacks (&permanent_obstack, &permanent_obstack);
2739 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2740 index = alloc_name_constant (CONSTANT_String, name);
2741 c = build_ref_from_constant_pool (index);
2742 TREE_TYPE (c) = promote_type (string_type_node);
2746 c = get_constant (jcf, index);
2751 process_jvm_instruction (PC, byte_ops, length)
2753 const unsigned char* byte_ops;
2754 long length ATTRIBUTE_UNUSED;
2756 const char *opname; /* Temporary ??? */
2757 int oldpc = PC; /* PC at instruction start. */
2759 /* If the instruction is at the beginning of a exception handler,
2760 replace the top of the stack with the thrown object reference */
2761 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2763 tree type = pop_type (ptr_type_node);
2764 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2767 switch (byte_ops[PC++])
2769 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2772 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2775 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2777 int saw_index = 0; \
2778 int index = OPERAND_VALUE; \
2779 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2782 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2784 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2785 tree ret = lookup_label (PC); \
2786 build_java_jsr (where, ret); \
2787 load_type_state (ret); \
2790 /* Push a constant onto the stack. */
2791 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2792 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2793 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2794 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2796 /* internal macro added for use by the WIDE case */
2797 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2798 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2800 /* Push local variable onto the opcode stack. */
2801 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2803 /* have to do this since OPERAND_VALUE may have side-effects */ \
2804 int opvalue = OPERAND_VALUE; \
2805 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2808 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2809 expand_java_return (OPERAND_TYPE##_type_node)
2811 #define REM_EXPR TRUNC_MOD_EXPR
2812 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2813 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2815 #define FIELD(IS_STATIC, IS_PUT) \
2816 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2818 #define TEST(OPERAND_TYPE, CONDITION) \
2819 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2821 #define COND(OPERAND_TYPE, CONDITION) \
2822 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2824 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2825 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2827 #define BRANCH_GOTO(OPERAND_VALUE) \
2828 expand_java_goto (oldpc + OPERAND_VALUE)
2830 #define BRANCH_CALL(OPERAND_VALUE) \
2831 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2834 #define BRANCH_RETURN(OPERAND_VALUE) \
2836 tree type = OPERAND_TYPE##_type_node; \
2837 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2838 expand_java_ret (value); \
2842 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2843 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2844 fprintf (stderr, "(not implemented)\n")
2845 #define NOT_IMPL1(OPERAND_VALUE) \
2846 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2847 fprintf (stderr, "(not implemented)\n")
2849 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2851 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2853 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2855 #define STACK_SWAP(COUNT) java_stack_swap()
2857 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2858 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2859 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2861 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2862 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2864 #define LOOKUP_SWITCH \
2865 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2866 tree selector = pop_value (INT_type_node); \
2867 tree duplicate, label; \
2868 tree type = TREE_TYPE (selector); \
2869 flush_quick_stack (); \
2870 expand_start_case (0, selector, type, "switch statement");\
2871 push_momentary (); \
2872 while (--npairs >= 0) \
2874 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2875 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2876 TREE_TYPE (value) = type; \
2877 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2878 pushcase (value, convert, label, &duplicate); \
2879 expand_java_goto (oldpc + offset); \
2881 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2882 pushcase (NULL_TREE, 0, label, &duplicate); \
2883 expand_java_goto (oldpc + default_offset); \
2885 expand_end_case (selector); \
2888 #define TABLE_SWITCH \
2889 { jint default_offset = IMMEDIATE_s4; \
2890 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2891 tree selector = pop_value (INT_type_node); \
2892 tree duplicate, label; \
2893 tree type = TREE_TYPE (selector); \
2894 flush_quick_stack (); \
2895 expand_start_case (0, selector, type, "switch statement");\
2896 push_momentary (); \
2897 for (; low <= high; low++) \
2899 jint offset = IMMEDIATE_s4; \
2900 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2901 TREE_TYPE (value) = type; \
2902 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2903 pushcase (value, convert, label, &duplicate); \
2904 expand_java_goto (oldpc + offset); \
2906 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2907 pushcase (NULL_TREE, 0, label, &duplicate); \
2908 expand_java_goto (oldpc + default_offset); \
2910 expand_end_case (selector); \
2913 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2914 { int opcode = byte_ops[PC-1]; \
2915 int method_ref_index = IMMEDIATE_u2; \
2917 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2919 expand_invoke (opcode, method_ref_index, nargs); \
2922 /* Handle new, checkcast, instanceof */
2923 #define OBJECT(TYPE, OP) \
2924 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2926 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2928 #define ARRAY_LOAD(OPERAND_TYPE) \
2930 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2933 #define ARRAY_STORE(OPERAND_TYPE) \
2935 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2938 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2939 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2940 #define ARRAY_NEW_PTR() \
2941 push_value (build_anewarray (get_class_constant (current_jcf, \
2943 pop_value (int_type_node)));
2944 #define ARRAY_NEW_NUM() \
2946 int atype = IMMEDIATE_u1; \
2947 push_value (build_newarray (atype, pop_value (int_type_node)));\
2949 #define ARRAY_NEW_MULTI() \
2951 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2952 int ndims = IMMEDIATE_u1; \
2953 expand_java_multianewarray( class, ndims ); \
2956 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2957 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2958 pop_value (OPERAND_TYPE##_type_node))));
2960 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2962 push_value (build1 (NOP_EXPR, int_type_node, \
2963 (convert (TO_TYPE##_type_node, \
2964 pop_value (FROM_TYPE##_type_node))))); \
2967 #define CONVERT(FROM_TYPE, TO_TYPE) \
2969 push_value (convert (TO_TYPE##_type_node, \
2970 pop_value (FROM_TYPE##_type_node))); \
2973 /* internal macro added for use by the WIDE case
2974 Added TREE_TYPE (decl) assignment, apbianco */
2975 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2978 int var = OPVALUE; \
2979 tree type = OPTYPE; \
2980 value = pop_value (type); \
2981 type = TREE_TYPE (value); \
2982 decl = find_local_variable (var, type, oldpc); \
2983 set_local_type (var, type ); \
2984 expand_assignment (decl, value, 0, 0); \
2987 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2989 /* have to do this since OPERAND_VALUE may have side-effects */ \
2990 int opvalue = OPERAND_VALUE; \
2991 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2994 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2995 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2997 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2998 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3000 #define MONITOR_OPERATION(call) \
3002 tree o = pop_value (ptr_type_node); \
3004 flush_quick_stack (); \
3005 c = build_java_monitor (call, o); \
3006 TREE_SIDE_EFFECTS (c) = 1; \
3007 expand_expr_stmt (c); \
3010 #define SPECIAL_IINC(IGNORED) \
3012 unsigned int local_var_index = IMMEDIATE_u1; \
3013 int ival = IMMEDIATE_s1; \
3014 expand_iinc(local_var_index, ival, oldpc); \
3017 #define SPECIAL_WIDE(IGNORED) \
3019 int modified_opcode = IMMEDIATE_u1; \
3020 unsigned int local_var_index = IMMEDIATE_u2; \
3021 switch (modified_opcode) \
3025 int ival = IMMEDIATE_s2; \
3026 expand_iinc (local_var_index, ival, oldpc); \
3029 case OPCODE_iload: \
3030 case OPCODE_lload: \
3031 case OPCODE_fload: \
3032 case OPCODE_dload: \
3033 case OPCODE_aload: \
3035 /* duplicate code from LOAD macro */ \
3036 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3039 case OPCODE_istore: \
3040 case OPCODE_lstore: \
3041 case OPCODE_fstore: \
3042 case OPCODE_dstore: \
3043 case OPCODE_astore: \
3045 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3049 error ("unrecogized wide sub-instruction"); \
3053 #define SPECIAL_THROW(IGNORED) \
3054 build_java_athrow (pop_value (throwable_type_node))
3056 #define SPECIAL_BREAK NOT_IMPL1
3057 #define IMPL NOT_IMPL
3059 #include "javaop.def"
3062 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3067 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3068 order, as specified by Java Language Specification.
3070 The problem is that while expand_expr will evaluate its sub-operands in
3071 left-to-right order, for variables it will just return an rtx (i.e.
3072 an lvalue) for the variable (rather than an rvalue). So it is possible
3073 that a later sub-operand will change the register, and when the
3074 actual operation is done, it will use the new value, when it should
3075 have used the original value.
3077 We fix this by using save_expr. This forces the sub-operand to be
3078 copied into a fresh virtual register,
3080 For method invocation, we modify the arguments so that a
3081 left-to-right order evaluation is performed. Saved expressions
3082 will, in CALL_EXPR order, be reused when the call will be expanded.
3086 force_evaluation_order (node)
3089 if (flag_syntax_only)
3091 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3093 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3094 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3096 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
3100 if (!TREE_OPERAND (node, 1))
3103 /* This reverses the evaluation order. This is a desired effect. */
3104 for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1);
3105 arg; arg = TREE_CHAIN (arg))
3107 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3108 cmp = (cmp == NULL_TREE ? saved :
3109 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3110 TREE_VALUE (arg) = saved;
3113 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3114 TREE_SIDE_EFFECTS (cmp) = 1;
3118 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3119 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3120 TREE_SIDE_EFFECTS (cmp) = 1;