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"
44 static void flush_quick_stack PARAMS ((void));
45 static void push_value PARAMS ((tree));
46 static tree pop_value PARAMS ((tree));
47 static void java_stack_swap PARAMS ((void));
48 static void java_stack_dup PARAMS ((int, int));
49 static void build_java_athrow PARAMS ((tree));
50 static void build_java_jsr PARAMS ((tree, tree));
51 static void build_java_ret PARAMS ((tree));
52 static void expand_java_multianewarray PARAMS ((tree, int));
53 static void expand_java_arraystore PARAMS ((tree));
54 static void expand_java_arrayload PARAMS ((tree));
55 static void expand_java_array_length PARAMS ((void));
56 static tree build_java_monitor PARAMS ((tree, tree));
57 static void expand_java_pushc PARAMS ((int, tree));
58 static void expand_java_return PARAMS ((tree));
59 static void expand_java_NEW PARAMS ((tree));
60 static void expand_java_INSTANCEOF PARAMS ((tree));
61 static void expand_java_CHECKCAST PARAMS ((tree));
62 static void expand_iinc PARAMS ((unsigned int, int, int));
63 static void expand_java_binop PARAMS ((tree, enum tree_code));
64 static void note_label PARAMS ((int, int));
65 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
66 static void expand_test PARAMS ((enum tree_code, tree, int));
67 static void expand_cond PARAMS ((enum tree_code, tree, int));
68 static void expand_java_goto PARAMS ((int));
70 static void expand_java_call PARAMS ((int, int));
71 static void expand_java_ret PARAMS ((tree));
73 static tree pop_arguments PARAMS ((tree));
74 static void expand_invoke PARAMS ((int, int, int));
75 static void expand_java_field_op PARAMS ((int, int, int));
76 static void java_push_constant_from_pool PARAMS ((struct JCF *, int));
77 static void java_stack_pop PARAMS ((int));
78 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
79 static tree build_java_check_indexed_type PARAMS ((tree, tree));
80 static tree java_array_data_offset PARAMS ((tree));
81 static tree case_identity PARAMS ((tree, tree));
83 static tree operand_type[59];
84 extern struct obstack permanent_obstack;
86 /* Set to non-zero value in order to emit class initilization code
87 before static field references. */
88 int always_initialize_class_p;
91 init_expr_processing()
93 operand_type[21] = operand_type[54] = int_type_node;
94 operand_type[22] = operand_type[55] = long_type_node;
95 operand_type[23] = operand_type[56] = float_type_node;
96 operand_type[24] = operand_type[57] = double_type_node;
97 operand_type[25] = operand_type[58] = ptr_type_node;
100 /* We store the stack state in two places:
101 Within a basic block, we use the quick_stack, which is a
102 pushdown list (TREE_LISTs) of expression nodes.
103 This is the top part of the stack; below that we use find_stack_slot.
104 At the end of a basic block, the quick_stack must be flushed
105 to the stack slot array (as handled by find_stack_slot).
106 Using quick_stack generates better code (especially when
107 compiled without optimization), because we do not have to
108 explicitly store and load trees to temporary variables.
110 If a variable is on the quick stack, it means the value of variable
111 when the quick stack was last flushed. Conceptually, flush_quick_stack
112 saves all the the quick_stack elements in parellel. However, that is
113 complicated, so it actually saves them (i.e. copies each stack value
114 to is home virtual register) from low indexes. This allows a quick_stack
115 element at index i (counting from the bottom of stack the) to references
116 slot virtuals for register that are >= i, but not those that are deeper.
117 This convention makes most operations easier. For example iadd works
118 even when the stack contains (reg[0], reg[1]): It results in the
119 stack containing (reg[0]+reg[1]), which is OK. However, some stack
120 operations are more complicated. For example dup given a stack
121 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
122 the convention, since stack value 1 would refer to a register with
123 lower index (reg[0]), which flush_quick_stack does not safely handle.
124 So dup cannot just add an extra element to the quick_stack, but iadd can.
127 tree quick_stack = NULL_TREE;
129 /* A free-list of unused permamnet TREE_LIST nodes. */
130 tree tree_list_free_list = NULL_TREE;
132 /* The stack pointer of the Java virtual machine.
133 This does include the size of the quick_stack. */
137 const unsigned char *linenumber_table;
138 int linenumber_count;
141 truthvalue_conversion (expr)
144 /* It is simpler and generates better code to have only TRUTH_*_EXPR
145 or comparison expressions as truth values at this level.
147 This function should normally be identity for Java. */
149 switch (TREE_CODE (expr))
152 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
153 case TRUTH_ANDIF_EXPR:
154 case TRUTH_ORIF_EXPR:
161 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
164 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
166 /* are these legal? XXX JH */
171 /* These don't change whether an object is non-zero or zero. */
172 return truthvalue_conversion (TREE_OPERAND (expr, 0));
175 /* Distribute the conversion into the arms of a COND_EXPR. */
176 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
177 truthvalue_conversion (TREE_OPERAND (expr, 1)),
178 truthvalue_conversion (TREE_OPERAND (expr, 2))));
181 /* If this is widening the argument, we can ignore it. */
182 if (TYPE_PRECISION (TREE_TYPE (expr))
183 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
184 return truthvalue_conversion (TREE_OPERAND (expr, 0));
185 /* fall through to default */
188 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
192 #ifdef JAVA_USE_HANDLES
193 /* Given a pointer to a handle, get a pointer to an object. */
199 tree field, handle_type;
200 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
201 handle_type = TREE_TYPE (expr);
202 field = TYPE_FIELDS (handle_type);
203 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
208 /* Save any stack slots that happen to be in the quick_stack into their
209 home virtual register slots.
211 The copy order is from low stack index to high, to support the invariant
212 that the expression for a slot may contain decls for stack slots with
213 higher (or the same) index, but not lower. */
218 int stack_index = stack_pointer;
219 register tree prev, cur, next;
221 /* First reverse the quick_stack, and count the number of slots it has. */
222 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
224 next = TREE_CHAIN (cur);
225 TREE_CHAIN (cur) = prev;
227 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
231 while (quick_stack != NULL_TREE)
234 tree node = quick_stack, type;
235 quick_stack = TREE_CHAIN (node);
236 TREE_CHAIN (node) = tree_list_free_list;
237 tree_list_free_list = node;
238 node = TREE_VALUE (node);
239 type = TREE_TYPE (node);
241 decl = find_stack_slot (stack_index, type);
243 expand_assignment (decl, node, 0, 0);
244 stack_index += 1 + TYPE_IS_WIDE (type);
253 type = promote_type (type);
254 n_words = 1 + TYPE_IS_WIDE (type);
255 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
256 fatal ("stack overflow");
257 stack_type_map[stack_pointer++] = type;
259 while (--n_words >= 0)
260 stack_type_map[stack_pointer++] = TYPE_SECOND;
267 tree type = TREE_TYPE (value);
268 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
270 type = promote_type (type);
271 value = convert (type, value);
274 if (tree_list_free_list == NULL_TREE)
275 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
278 tree node = tree_list_free_list;
279 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
280 TREE_VALUE (node) = value;
281 TREE_CHAIN (node) = quick_stack;
286 /* Pop a type from the type stack.
287 TYPE is the expected type. Return the actual type, which must be
288 convertible to TYPE, otherwise NULL_TREE is returned. */
296 if (TREE_CODE (type) == RECORD_TYPE)
297 type = promote_type (type);
298 n_words = 1 + TYPE_IS_WIDE (type);
299 if (stack_pointer < n_words)
300 fatal ("stack underflow");
301 while (--n_words > 0)
303 if (stack_type_map[--stack_pointer] != void_type_node)
304 fatal ("Invalid multi-word value on type stack");
306 t = stack_type_map[--stack_pointer];
307 if (type == NULL_TREE || t == type)
309 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
310 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
312 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
314 if (type == ptr_type_node || type == object_ptr_type_node)
316 else if (t == ptr_type_node) /* Special case for null reference. */
318 else if (can_widen_reference_to (t, type))
320 /* This is a kludge, but matches what Sun's verifier does.
321 It can be tricked, but is safe as long as type errors
322 (i.e. interface method calls) are caught at run-time. */
323 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
324 && t == object_ptr_type_node)
330 /* Pop a type from the type stack.
331 TYPE is the expected type. Return the actual type, which must be
332 convertible to TYPE, otherwise call error. */
338 tree t = pop_type_0 (type);
341 error ("unexpected type on stack");
345 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
346 Handles array types and interfaces. */
349 can_widen_reference_to (source_type, target_type)
350 tree source_type, target_type;
352 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
355 /* Get rid of pointers */
356 if (TREE_CODE (source_type) == POINTER_TYPE)
357 source_type = TREE_TYPE (source_type);
358 if (TREE_CODE (target_type) == POINTER_TYPE)
359 target_type = TREE_TYPE (target_type);
361 if (source_type == target_type)
365 source_type = HANDLE_TO_CLASS_TYPE (source_type);
366 target_type = HANDLE_TO_CLASS_TYPE (target_type);
367 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
369 HOST_WIDE_INT source_length, target_length;
370 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
372 target_length = java_array_type_length (target_type);
373 if (target_length >= 0)
375 source_length = java_array_type_length (source_type);
376 if (source_length != target_length)
379 source_type = TYPE_ARRAY_ELEMENT (source_type);
380 target_type = TYPE_ARRAY_ELEMENT (target_type);
381 if (source_type == target_type)
383 if (TREE_CODE (source_type) != POINTER_TYPE
384 || TREE_CODE (target_type) != POINTER_TYPE)
386 return can_widen_reference_to (source_type, target_type);
390 int source_depth = class_depth (source_type);
391 int target_depth = class_depth (target_type);
393 /* class_depth can return a negative depth if an error occurred */
394 if (source_depth < 0 || target_depth < 0)
397 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
399 /* target_type is OK if source_type or source_type ancestors
400 implement target_type. We handle multiple sub-interfaces */
402 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
403 int n = TREE_VEC_LENGTH (basetype_vec), i;
404 for (i=0 ; i < n; i++)
405 if (can_widen_reference_to
406 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
413 for ( ; source_depth > target_depth; source_depth--)
415 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
417 return source_type == target_type;
426 type = pop_type (type);
429 tree node = quick_stack;
430 quick_stack = TREE_CHAIN (quick_stack);
431 TREE_CHAIN (node) = tree_list_free_list;
432 tree_list_free_list = node;
433 node = TREE_VALUE (node);
437 return find_stack_slot (stack_pointer, promote_type (type));
441 /* Pop and discrad the top COUNT stack slots. */
444 java_stack_pop (count)
450 if (stack_pointer == 0)
451 fatal ("stack underflow");
452 type = stack_type_map[stack_pointer - 1];
453 if (type == TYPE_SECOND)
456 if (stack_pointer == 1 || count <= 0)
457 fatal ("stack underflow");
458 type = stack_type_map[stack_pointer - 2];
460 val = pop_value (type);
465 /* Implement the 'swap' operator (to swap two top stack slots). */
474 if (stack_pointer < 2
475 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
476 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
477 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
478 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
479 fatal ("bad stack swap");
481 flush_quick_stack ();
482 decl1 = find_stack_slot (stack_pointer - 1, type1);
483 decl2 = find_stack_slot (stack_pointer - 2, type2);
484 temp = copy_to_reg (DECL_RTL (decl1));
485 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
486 emit_move_insn (DECL_RTL (decl2), temp);
487 stack_type_map[stack_pointer - 1] = type2;
488 stack_type_map[stack_pointer - 2] = type1;
492 java_stack_dup (size, offset)
495 int low_index = stack_pointer - size - offset;
498 error ("stack underflow - dup* operation");
500 flush_quick_stack ();
502 stack_pointer += size;
503 dst_index = stack_pointer;
505 for (dst_index = stack_pointer; --dst_index >= low_index; )
508 int src_index = dst_index - size;
509 if (src_index < low_index)
510 src_index = dst_index + size + offset;
511 type = stack_type_map [src_index];
512 if (type == TYPE_SECOND)
514 if (src_index <= low_index)
515 fatal ("dup operation splits 64-bit number");
516 stack_type_map[dst_index] = type;
517 src_index--; dst_index--;
518 type = stack_type_map[src_index];
519 if (! TYPE_IS_WIDE (type))
520 fatal ("internal error - dup operation");
522 else if (TYPE_IS_WIDE (type))
523 fatal ("internal error - dup operation");
524 if (src_index != dst_index)
526 tree src_decl = find_stack_slot (src_index, type);
527 tree dst_decl = find_stack_slot (dst_index, type);
528 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
529 stack_type_map[dst_index] = type;
534 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
538 build_java_athrow (node)
543 call = build (CALL_EXPR,
545 build_address_of (throw_node[exceptions_via_longjmp ? 1 : 0]),
546 build_tree_list (NULL_TREE, node),
548 TREE_SIDE_EFFECTS (call) = 1;
549 expand_expr_stmt (call);
550 java_stack_pop (stack_pointer);
553 /* Implementation for jsr/ret */
556 build_java_jsr (where, ret)
560 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
561 push_value (ret_label);
562 flush_quick_stack ();
563 emit_jump (label_rtx (where));
568 build_java_ret (location)
571 expand_computed_goto (location);
574 /* Implementation of operations on array: new, load, store, length */
576 /* Array core info access macros */
578 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
579 byte_position (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))
582 decode_newarray_type (atype)
587 case 4: return boolean_type_node;
588 case 5: return char_type_node;
589 case 6: return float_type_node;
590 case 7: return double_type_node;
591 case 8: return byte_type_node;
592 case 9: return short_type_node;
593 case 10: return int_type_node;
594 case 11: return long_type_node;
595 default: return NULL_TREE;
599 /* Map primitive type to the code used by OPCODE_newarray. */
602 encode_newarray_type (type)
605 if (type == boolean_type_node)
607 else if (type == char_type_node)
609 else if (type == float_type_node)
611 else if (type == double_type_node)
613 else if (type == byte_type_node)
615 else if (type == short_type_node)
617 else if (type == int_type_node)
619 else if (type == long_type_node)
622 fatal ("Can't compute type code - patch_newarray");
625 /* Build a call to _Jv_ThrowBadArrayIndex(), the
626 ArrayIndexOfBoundsException exception handler. */
629 build_java_throw_out_of_bounds_exception (index)
632 tree node = build (CALL_EXPR, int_type_node,
633 build_address_of (soft_badarrayindex_node),
634 build_tree_list (NULL_TREE, index), NULL_TREE);
635 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
639 /* Return the length of an array. Doesn't perform any checking on the nature
640 or value of the array NODE. May be used to implement some bytecodes. */
643 build_java_array_length_access (node)
646 tree type = TREE_TYPE (node);
647 HOST_WIDE_INT length;
648 if (!is_array_type_p (type))
649 fatal ("array length on a non-array reference");
650 length = java_array_type_length (type);
652 return build_int_2 (length, 0);
653 return fold (build1 (INDIRECT_REF,
655 fold (build (PLUS_EXPR, ptr_type_node,
657 JAVA_ARRAY_LENGTH_OFFSET(node)))));
660 /* Optionally checks an array against the NULL pointer, eventually throwing a
661 NullPointerException. It could replace signal handling, but tied to NULL.
662 ARG1: the pointer to check, ARG2: the expression to use if
663 the pointer is non-null and ARG3 the type that should be returned. */
666 build_java_arraynull_check (node, expr, type)
667 tree node ATTRIBUTE_UNUSED;
669 tree type ATTRIBUTE_UNUSED;
672 static int java_array_access_throws_null_exception = 0;
674 if (java_array_access_throws_null_exception)
675 return (build (COND_EXPR,
677 build (EQ_EXPR, int_type_node, node, null_pointer_node),
678 build_java_athrow (node), expr ));
685 java_array_data_offset (array)
688 tree array_type = TREE_TYPE (TREE_TYPE (array));
689 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
691 if (data_fld == NULL_TREE)
692 return size_in_bytes (array_type);
694 return byte_position (data_fld);
697 /* Implement array indexing (either as l-value or r-value).
698 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
699 Optionally performs bounds checking and/or test to NULL.
700 At this point, ARRAY should have been verified as an array. */
703 build_java_arrayaccess (array, type, index)
704 tree array, type, index;
706 tree arith, node, throw = NULL_TREE;
708 arith = fold (build (PLUS_EXPR, int_type_node,
709 java_array_data_offset (array),
710 fold (build (MULT_EXPR, int_type_node,
711 index, size_in_bytes(type)))));
713 if (flag_bounds_check)
716 * (unsigned jint) INDEX >= (unsigned jint) LEN
717 * && throw ArrayIndexOutOfBoundsException.
718 * Note this is equivalent to and more efficient than:
719 * INDEX < 0 || INDEX >= LEN && throw ... */
721 tree len = build_java_array_length_access (array);
722 TREE_TYPE (len) = unsigned_int_type_node;
723 test = fold (build (GE_EXPR, boolean_type_node,
724 convert (unsigned_int_type_node, index),
726 if (! integer_zerop (test))
728 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
729 build_java_throw_out_of_bounds_exception (index));
730 /* allows expansion within COMPOUND */
731 TREE_SIDE_EFFECTS( throw ) = 1;
735 node = build1 (INDIRECT_REF, type,
736 fold (build (PLUS_EXPR, ptr_type_node,
738 (throw ? build (COMPOUND_EXPR, int_type_node,
742 return (fold (build_java_arraynull_check (array, node, type)));
745 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
746 ARRAY_NODE. This function is used to retrieve something less vague than
747 a pointer type when indexing the first dimension of something like [[<t>.
748 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
750 As a side effect, it also makes sure that ARRAY_NODE is an array. */
753 build_java_check_indexed_type (array_node, indexed_type)
759 if (!is_array_type_p (TREE_TYPE (array_node)))
760 fatal ("array indexing on a non-array reference");
762 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
764 if (indexed_type == ptr_type_node )
765 return promote_type (elt_type);
767 /* BYTE/BOOLEAN store and load are used for both type */
768 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
769 return boolean_type_node;
771 if (indexed_type != elt_type )
772 fatal ("type array element mismatch");
777 /* newarray triggers a call to _Jv_NewArray. This function should be called
778 with an integer code (the type of array to create) and get from the stack
779 the size of the dimmension. */
782 build_newarray (atype_value, length)
787 = build_java_array_type (decode_newarray_type (atype_value),
788 host_integerp (length, 0) == INTEGER_CST
789 ? tree_low_cst (length, 0) : -1);
791 return build (CALL_EXPR, promote_type (type),
792 build_address_of (soft_newarray_node),
793 tree_cons (NULL_TREE,
794 build_int_2 (atype_value, 0),
795 build_tree_list (NULL_TREE, length)),
799 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
803 build_anewarray (class_type, length)
808 = build_java_array_type (class_type,
809 host_integerp (length, 0)
810 ? tree_low_cst (length, 0) : -1);
812 return build (CALL_EXPR, promote_type (type),
813 build_address_of (soft_anewarray_node),
814 tree_cons (NULL_TREE, length,
815 tree_cons (NULL_TREE, build_class_ref (class_type),
816 build_tree_list (NULL_TREE,
817 null_pointer_node))),
821 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
824 build_new_array (type, length)
828 if (JPRIMITIVE_TYPE_P (type))
829 return build_newarray (encode_newarray_type (type), length);
831 return build_anewarray (TREE_TYPE (type), length);
834 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
835 class pointer, a number of dimensions and the matching number of
836 dimensions. The argument list is NULL terminated. */
839 expand_java_multianewarray (class_type, ndim)
844 tree args = build_tree_list( NULL_TREE, null_pointer_node );
846 for( i = 0; i < ndim; i++ )
847 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
849 push_value (build (CALL_EXPR,
850 promote_type (class_type),
851 build_address_of (soft_multianewarray_node),
852 tree_cons (NULL_TREE, build_class_ref (class_type),
853 tree_cons (NULL_TREE,
854 build_int_2 (ndim, 0), args )),
858 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
859 ARRAY is an array type. May expand some bound checking and NULL
860 pointer checking. RHS_TYPE_NODE we are going to store. In the case
861 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
862 INT. In those cases, we make the convertion.
864 if ARRAy is a reference type, the assignment is checked at run-time
865 to make sure that the RHS can be assigned to the array element
866 type. It is not necessary to generate this code if ARRAY is final. */
869 expand_java_arraystore (rhs_type_node)
872 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
873 && TYPE_PRECISION (rhs_type_node) <= 32) ?
874 int_type_node : rhs_type_node);
875 tree index = pop_value (int_type_node);
876 tree array = pop_value (ptr_type_node);
878 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
880 flush_quick_stack ();
882 index = save_expr (index);
883 array = save_expr (array);
885 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
887 tree check = build (CALL_EXPR, void_type_node,
888 build_address_of (soft_checkarraystore_node),
889 tree_cons (NULL_TREE, array,
890 build_tree_list (NULL_TREE, rhs_node)),
892 TREE_SIDE_EFFECTS (check) = 1;
893 expand_expr_stmt (check);
896 expand_assignment (build_java_arrayaccess (array,
902 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
903 sure that LHS is an array type. May expand some bound checking and NULL
905 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
906 BOOLEAN/SHORT, we push a promoted type back to the stack.
910 expand_java_arrayload (lhs_type_node )
914 tree index_node = pop_value (int_type_node);
915 tree array_node = pop_value (ptr_type_node);
917 index_node = save_expr (index_node);
918 array_node = save_expr (array_node);
919 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
921 load_node = build_java_arrayaccess (array_node,
925 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
926 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
927 push_value (load_node);
930 /* Expands .length. Makes sure that we deal with and array and may expand
931 a NULL check on the array object. */
934 expand_java_array_length ()
936 tree array = pop_value (ptr_type_node);
937 tree length = build_java_array_length_access (array);
939 push_value (build_java_arraynull_check (array, length, int_type_node));
942 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
943 either soft_monitorenter_node or soft_monitorexit_node. */
946 build_java_monitor (call, object)
950 return (build (CALL_EXPR,
952 build_address_of (call),
953 build_tree_list (NULL_TREE, object),
957 /* Emit code for one of the PUSHC instructions. */
960 expand_java_pushc (ival, type)
965 if (type == ptr_type_node && ival == 0)
966 value = null_pointer_node;
967 else if (type == int_type_node || type == long_type_node)
969 value = build_int_2 (ival, ival < 0 ? -1 : 0);
970 TREE_TYPE (value) = type;
972 else if (type == float_type_node || type == double_type_node)
975 #ifdef REAL_ARITHMETIC
976 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
980 value = build_real (type, x);
983 fatal ("internal error in expand_java_pushc");
987 #ifndef INT_TYPE_SIZE
988 #define INT_TYPE_SIZE BITS_PER_WORD
992 expand_java_return (type)
995 if (type == void_type_node)
996 expand_null_return ();
999 tree retval = pop_value (type);
1000 tree res = DECL_RESULT (current_function_decl);
1001 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1003 /* Handle the situation where the native integer type is smaller
1004 than the JVM integer. It can happen for many cross compilers.
1005 The whole if expression just goes away if INT_TYPE_SIZE < 32
1007 if (INT_TYPE_SIZE < 32
1008 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1009 < GET_MODE_SIZE (TYPE_MODE (type))))
1010 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1012 TREE_SIDE_EFFECTS (retval) = 1;
1013 expand_return (retval);
1018 build_address_of (value)
1021 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1025 expand_java_NEW (type)
1028 if (! CLASS_LOADED_P (type))
1029 load_class (type, 1);
1030 safe_layout_class (type);
1031 push_value (build (CALL_EXPR, promote_type (type),
1032 build_address_of (alloc_object_node),
1033 tree_cons (NULL_TREE, build_class_ref (type),
1034 build_tree_list (NULL_TREE,
1035 size_in_bytes (type))),
1039 /* This returns an expression which will extract the class of an
1043 build_get_class (value)
1046 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1047 tree vtable_field = lookup_field (&object_type_node,
1048 get_identifier ("vtable"));
1049 return build (COMPONENT_REF, class_ptr_type,
1050 build1 (INDIRECT_REF, dtable_type,
1051 build (COMPONENT_REF, dtable_ptr_type,
1052 build1 (INDIRECT_REF, object_type_node, value),
1057 /* This builds the tree representation of the `instanceof' operator.
1058 It tries various tricks to optimize this in cases where types are
1062 build_instanceof (value, type)
1066 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1067 tree valtype = TREE_TYPE (TREE_TYPE (value));
1068 tree valclass = TYPE_NAME (valtype);
1071 /* When compiling from bytecode, we need to ensure that TYPE has
1073 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1075 load_class (type, 1);
1076 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1077 return error_mark_node;
1079 klass = TYPE_NAME (type);
1081 if (type == object_type_node || inherits_from_p (valtype, type))
1083 /* Anything except `null' is an instance of Object. Likewise,
1084 if the object is known to be an instance of the class, then
1085 we only need to check for `null'. */
1086 expr = build (COND_EXPR, itype,
1088 boolean_true_node, boolean_false_node);
1090 else if (! CLASS_INTERFACE (valclass)
1091 && ! CLASS_INTERFACE (klass)
1092 && ! inherits_from_p (type, valtype)
1093 && (CLASS_FINAL (klass)
1094 || ! inherits_from_p (valtype, type)))
1096 /* The classes are from different branches of the derivation
1097 tree, so we immediately know the answer. */
1098 expr = boolean_false_node;
1100 else if (CLASS_FINAL (klass))
1102 tree save = save_expr (value);
1103 expr = build (COND_EXPR, itype,
1105 build (EQ_EXPR, itype,
1106 build_get_class (save),
1107 build_class_ref (type)),
1108 boolean_false_node);
1112 expr = build (CALL_EXPR, itype,
1113 build_address_of (soft_instanceof_node),
1114 tree_cons (NULL_TREE, value,
1115 build_tree_list (NULL_TREE,
1116 build_class_ref (type))),
1119 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1124 expand_java_INSTANCEOF (type)
1127 tree value = pop_value (object_ptr_type_node);
1128 value = build_instanceof (value, type);
1133 expand_java_CHECKCAST (type)
1136 tree value = pop_value (ptr_type_node);
1137 value = build (CALL_EXPR, promote_type (type),
1138 build_address_of (soft_checkcast_node),
1139 tree_cons (NULL_TREE, build_class_ref (type),
1140 build_tree_list (NULL_TREE, value)),
1146 expand_iinc (local_var_index, ival, pc)
1147 unsigned int local_var_index;
1151 tree local_var, res;
1152 tree constant_value;
1154 flush_quick_stack ();
1155 local_var = find_local_variable (local_var_index, int_type_node, pc);
1156 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1157 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1158 expand_assignment (local_var, res, 0, 0);
1163 build_java_soft_divmod (op, type, op1, op2)
1165 tree type, op1, op2;
1168 tree arg1 = convert (type, op1);
1169 tree arg2 = convert (type, op2);
1171 if (type == int_type_node)
1175 case TRUNC_DIV_EXPR:
1176 call = soft_idiv_node;
1178 case TRUNC_MOD_EXPR:
1179 call = soft_irem_node;
1185 else if (type == long_type_node)
1189 case TRUNC_DIV_EXPR:
1190 call = soft_ldiv_node;
1192 case TRUNC_MOD_EXPR:
1193 call = soft_lrem_node;
1201 fatal ("Internal compiler error in build_java_soft_divmod");
1203 call = build (CALL_EXPR, type,
1204 build_address_of (call),
1205 tree_cons (NULL_TREE, arg1,
1206 build_tree_list (NULL_TREE, arg2)),
1213 build_java_binop (op, type, arg1, arg2)
1215 tree type, arg1, arg2;
1222 tree u_type = unsigned_type (type);
1223 arg1 = convert (u_type, arg1);
1224 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1225 return convert (type, arg1);
1229 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1230 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1233 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1234 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1235 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1237 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1238 boolean_type_node, arg1, arg2));
1239 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1240 tree second_compare = fold (build (COND_EXPR, int_type_node,
1241 ifexp2, integer_zero_node,
1242 op == COMPARE_L_EXPR
1243 ? integer_negative_one_node
1244 : integer_one_node));
1245 return fold (build (COND_EXPR, int_type_node, ifexp1,
1246 op == COMPARE_L_EXPR ? integer_one_node
1247 : integer_negative_one_node,
1251 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1253 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1254 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1255 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1256 ifexp2, integer_one_node,
1257 integer_zero_node));
1258 return fold (build (COND_EXPR, int_type_node,
1259 ifexp1, integer_negative_one_node, second_compare));
1261 case TRUNC_DIV_EXPR:
1262 case TRUNC_MOD_EXPR:
1263 if (TREE_CODE (type) == REAL_TYPE
1264 && op == TRUNC_MOD_EXPR)
1267 if (type != double_type_node)
1269 arg1 = convert (double_type_node, arg1);
1270 arg2 = convert (double_type_node, arg2);
1272 call = build (CALL_EXPR, double_type_node,
1273 build_address_of (soft_fmod_node),
1274 tree_cons (NULL_TREE, arg1,
1275 build_tree_list (NULL_TREE, arg2)),
1277 if (type != double_type_node)
1278 call = convert (type, call);
1282 if (TREE_CODE (type) == INTEGER_TYPE
1283 && flag_use_divide_subroutine
1284 && ! flag_syntax_only)
1285 return build_java_soft_divmod (op, type, arg1, arg2);
1290 return fold (build (op, type, arg1, arg2));
1294 expand_java_binop (type, op)
1295 tree type; enum tree_code op;
1305 rtype = int_type_node;
1306 rarg = pop_value (rtype);
1309 rarg = pop_value (rtype);
1311 larg = pop_value (ltype);
1312 push_value (build_java_binop (op, type, larg, rarg));
1315 /* Lookup the field named NAME in *TYPEP or its super classes.
1316 If not found, return NULL_TREE.
1317 (If the *TYPEP is not found, return error_mark_node.)
1318 If found, return the FIELD_DECL, and set *TYPEP to the
1319 class containing the field. */
1322 lookup_field (typep, name)
1326 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1328 load_class (*typep, 1);
1329 safe_layout_class (*typep);
1330 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1331 return error_mark_node;
1335 tree field, basetype_vec;
1338 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1339 if (DECL_NAME (field) == name)
1342 /* If *typep is an innerclass, lookup the field in its enclosing
1344 if (INNER_CLASS_TYPE_P (*typep))
1346 tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1348 if ((field = lookup_field (&outer_type, name)))
1352 /* Process implemented interfaces. */
1353 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1354 n = TREE_VEC_LENGTH (basetype_vec);
1355 for (i = 0; i < n; i++)
1357 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1358 if ((field = lookup_field (&t, name)))
1361 *typep = CLASSTYPE_SUPER (*typep);
1366 /* Look up the field named NAME in object SELF_VALUE,
1367 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1368 SELF_VALUE is NULL_TREE if looking for a static field. */
1371 build_field_ref (self_value, self_class, name)
1372 tree self_value, self_class, name;
1374 tree base_class = self_class;
1375 tree field_decl = lookup_field (&base_class, name);
1376 if (field_decl == NULL_TREE)
1378 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1379 return error_mark_node;
1381 if (self_value == NULL_TREE)
1383 return build_static_field_ref (field_decl);
1387 tree base_handle_type = promote_type (base_class);
1388 if (base_handle_type != TREE_TYPE (self_value))
1389 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1390 #ifdef JAVA_USE_HANDLES
1391 self_value = unhand_expr (self_value);
1393 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1395 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1396 self_value, field_decl));
1406 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1407 name = get_identifier (buf);
1408 if (IDENTIFIER_LOCAL_VALUE (name))
1409 return IDENTIFIER_LOCAL_VALUE (name);
1412 /* The type of the address of a label is return_address_type_node. */
1413 tree decl = create_label_decl (name);
1414 LABEL_PC (decl) = pc;
1416 return pushdecl (decl);
1420 /* Generate a unique name for the purpose of loops and switches
1421 labels, and try-catch-finally blocks label or temporary variables. */
1426 static int l_number = 0;
1428 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1430 return get_identifier (buff);
1434 create_label_decl (name)
1438 push_obstacks (&permanent_obstack, &permanent_obstack);
1439 decl = build_decl (LABEL_DECL, name,
1440 TREE_TYPE (return_address_type_node));
1442 DECL_CONTEXT (decl) = current_function_decl;
1443 DECL_IGNORED_P (decl) = 1;
1447 /* This maps a bytecode offset (PC) to various flags. */
1448 char *instruction_bits;
1451 note_label (current_pc, target_pc)
1452 int current_pc ATTRIBUTE_UNUSED, target_pc;
1454 lookup_label (target_pc);
1455 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1458 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1459 where CONDITION is one of one the compare operators. */
1462 expand_compare (condition, value1, value2, target_pc)
1463 enum tree_code condition;
1464 tree value1, value2;
1467 tree target = lookup_label (target_pc);
1468 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1469 expand_start_cond (truthvalue_conversion (cond), 0);
1470 expand_goto (target);
1474 /* Emit code for a TEST-type opcode. */
1477 expand_test (condition, type, target_pc)
1478 enum tree_code condition;
1482 tree value1, value2;
1483 flush_quick_stack ();
1484 value1 = pop_value (type);
1485 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1486 expand_compare (condition, value1, value2, target_pc);
1489 /* Emit code for a COND-type opcode. */
1492 expand_cond (condition, type, target_pc)
1493 enum tree_code condition;
1497 tree value1, value2;
1498 flush_quick_stack ();
1499 /* note: pop values in opposite order */
1500 value2 = pop_value (type);
1501 value1 = pop_value (type);
1502 /* Maybe should check value1 and value2 for type compatibility ??? */
1503 expand_compare (condition, value1, value2, target_pc);
1507 expand_java_goto (target_pc)
1510 tree target_label = lookup_label (target_pc);
1511 flush_quick_stack ();
1512 expand_goto (target_label);
1517 expand_java_call (target_pc, return_address)
1518 int target_pc, return_address;
1520 tree target_label = lookup_label (target_pc);
1521 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1523 flush_quick_stack ();
1524 expand_goto (target_label);
1528 expand_java_ret (return_address)
1529 tree return_address ATTRIBUTE_UNUSED;
1531 warning ("ret instruction not implemented");
1533 tree target_label = lookup_label (target_pc);
1534 flush_quick_stack ();
1535 expand_goto (target_label);
1540 /* Recursive helper function to pop argument types during verifiation. */
1543 pop_argument_types (arg_types)
1546 if (arg_types == end_params_node)
1548 if (TREE_CODE (arg_types) == TREE_LIST)
1550 pop_argument_types (TREE_CHAIN (arg_types));
1551 pop_type (TREE_VALUE (arg_types));
1558 pop_arguments (arg_types)
1561 if (arg_types == end_params_node)
1563 if (TREE_CODE (arg_types) == TREE_LIST)
1565 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1566 tree type = TREE_VALUE (arg_types);
1567 tree arg = pop_value (type);
1568 if (PROMOTE_PROTOTYPES
1569 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1570 && INTEGRAL_TYPE_P (type))
1571 arg = convert (integer_type_node, arg);
1572 return tree_cons (NULL_TREE, arg, tail);
1577 /* Build an expression to initialize the class CLAS.
1578 if EXPR is non-NULL, returns an expression to first call the initializer
1579 (if it is needed) and then calls EXPR. */
1582 build_class_init (clas, expr)
1586 struct init_test_hash_entry *ite;
1587 if (inherits_from_p (current_class, clas))
1590 if (always_initialize_class_p)
1592 init = build (CALL_EXPR, void_type_node,
1593 build_address_of (soft_initclass_node),
1594 build_tree_list (NULL_TREE, build_class_ref (clas)),
1596 TREE_SIDE_EFFECTS (init) = 1;
1600 ite = (struct init_test_hash_entry *)
1601 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1602 (const hash_table_key) clas,
1605 if (ite->init_test_decl == 0)
1606 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1608 /* Tell the check-init code to ignore this decl. */
1609 DECL_BIT_INDEX(ite->init_test_decl) = -1;
1611 init = build (CALL_EXPR, void_type_node,
1612 build_address_of (soft_initclass_node),
1613 build_tree_list (NULL_TREE, build_class_ref (clas)),
1615 TREE_SIDE_EFFECTS (init) = 1;
1616 call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1617 build (MODIFY_EXPR, boolean_type_node,
1618 ite->init_test_decl, boolean_true_node));
1619 TREE_SIDE_EFFECTS (call) = 1;
1620 init = build (COND_EXPR, void_type_node,
1621 build (EQ_EXPR, boolean_type_node,
1622 ite->init_test_decl, boolean_false_node),
1623 call, integer_zero_node);
1624 TREE_SIDE_EFFECTS (init) = 1;
1627 if (expr != NULL_TREE)
1629 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1630 TREE_SIDE_EFFECTS (expr) = 1;
1636 static tree methods_ident = NULL_TREE;
1637 static tree ncode_ident = NULL_TREE;
1638 tree dtable_ident = NULL_TREE;
1641 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1642 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1643 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1646 if (is_compiled_class (self_type))
1648 make_decl_rtl (method, NULL, 1);
1649 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1653 /* We don't know whether the method has been (statically) compiled.
1654 Compile this code to get a reference to the method's code:
1656 SELF_TYPE->methods[METHOD_INDEX].ncode
1658 This is guaranteed to work (assuming SELF_TYPE has
1659 been initialized), since if the method is not compiled yet,
1660 its ncode points to a trampoline that forces compilation. */
1662 int method_index = 0;
1664 tree ref = build_class_ref (self_type);
1665 ref = build1 (INDIRECT_REF, class_type_node, ref);
1666 if (ncode_ident == NULL_TREE)
1667 ncode_ident = get_identifier ("ncode");
1668 if (methods_ident == NULL_TREE)
1669 methods_ident = get_identifier ("methods");
1670 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1671 lookup_field (&class_type_node, methods_ident));
1672 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1673 ; meth = TREE_CHAIN (meth))
1677 if (meth == NULL_TREE)
1678 fatal ("method '%s' not found in class",
1679 IDENTIFIER_POINTER (DECL_NAME (method)));
1682 method_index *= int_size_in_bytes (method_type_node);
1683 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1684 ref, build_int_2 (method_index, 0)));
1685 ref = build1 (INDIRECT_REF, method_type_node, ref);
1686 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1688 lookup_field (&method_type_node, ncode_ident));
1694 invoke_build_dtable (is_invoke_interface, arg_list)
1695 int is_invoke_interface;
1698 tree dtable, objectref;
1700 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1702 /* If we're dealing with interfaces and if the objectref
1703 argument is an array then get the dispatch table of the class
1704 Object rather than the one from the objectref. */
1705 objectref = (is_invoke_interface
1706 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1707 object_type_node : TREE_VALUE (arg_list));
1709 if (dtable_ident == NULL_TREE)
1710 dtable_ident = get_identifier ("vtable");
1711 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1712 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1713 lookup_field (&object_type_node, dtable_ident));
1719 build_invokevirtual (dtable, method)
1720 tree dtable, method;
1723 tree nativecode_ptr_ptr_type_node
1724 = build_pointer_type (nativecode_ptr_type_node);
1725 tree method_index = convert (sizetype, DECL_VINDEX (method));
1727 /* Add one to skip "class" field of dtable, and one to skip unused
1728 vtable entry (for C++ compatibility). */
1729 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1730 method_index = size_binop (MULT_EXPR, method_index,
1731 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1732 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1733 convert (nativecode_ptr_ptr_type_node, method_index)));
1734 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1740 build_invokeinterface (dtable, method)
1741 tree dtable, method;
1743 static tree class_ident = NULL_TREE;
1750 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1751 ensure that the selected method exists, is public and not
1752 abstract nor static. */
1754 if (class_ident == NULL_TREE)
1755 class_ident = get_identifier ("class");
1757 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1758 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1759 lookup_field (&dtable_type, class_ident));
1761 interface = DECL_CONTEXT (method);
1764 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1768 idx = build_int_2 (i, 0);
1771 if (meth == NULL_TREE)
1772 fatal ("internal error in build_invokeinterface");
1775 lookup_arg = tree_cons (NULL_TREE, dtable,
1776 tree_cons (NULL_TREE, build_class_ref (interface),
1777 build_tree_list (NULL_TREE, idx)));
1779 return build (CALL_EXPR, ptr_type_node,
1780 build_address_of (soft_lookupinterfacemethod_node),
1781 lookup_arg, NULL_TREE);
1784 /* Expand one of the invoke_* opcodes.
1785 OCPODE is the specific opcode.
1786 METHOD_REF_INDEX is an index into the constant pool.
1787 NARGS is the number of arguments, or -1 if not specified. */
1790 expand_invoke (opcode, method_ref_index, nargs)
1792 int method_ref_index;
1793 int nargs ATTRIBUTE_UNUSED;
1795 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
1796 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
1797 tree self_type = get_class_constant
1798 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
1799 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1800 tree call, func, method, arg_list, method_type;
1801 tree cond = NULL_TREE;
1803 if (! CLASS_LOADED_P (self_type))
1805 load_class (self_type, 1);
1806 safe_layout_class (self_type);
1807 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1808 fatal ("failed to find class '%s'", self_name);
1810 layout_class_methods (self_type);
1812 if (ID_INIT_P (method_name))
1813 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1816 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1817 method_name, method_signature);
1818 if (method == NULL_TREE)
1820 error ("Class '%s' has no method named '%s' matching signature '%s'",
1822 IDENTIFIER_POINTER (method_name),
1823 IDENTIFIER_POINTER (method_signature));
1825 /* Invoke static can't invoke static/abstract method */
1826 else if (opcode == OPCODE_invokestatic)
1828 if (!METHOD_STATIC (method))
1830 error ("invokestatic on non static method");
1833 else if (METHOD_ABSTRACT (method))
1835 error ("invokestatic on abstract method");
1841 if (METHOD_STATIC (method))
1843 error ("invoke[non-static] on static method");
1848 if (method == NULL_TREE)
1850 method_type = get_type_from_signature (method_signature);
1851 pop_arguments (TYPE_ARG_TYPES (method_type));
1852 if (opcode != OPCODE_invokestatic)
1853 pop_type (self_type);
1854 method_type = promote_type (TREE_TYPE (method_type));
1855 push_value (convert (method_type, integer_zero_node));
1859 method_type = TREE_TYPE (method);
1860 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1861 flush_quick_stack ();
1864 if (opcode == OPCODE_invokestatic)
1865 func = build_known_method_ref (method, method_type, self_type,
1866 method_signature, arg_list);
1867 else if (opcode == OPCODE_invokespecial
1868 || (opcode == OPCODE_invokevirtual
1869 && (METHOD_PRIVATE (method)
1870 || METHOD_FINAL (method)
1871 || CLASS_FINAL (TYPE_NAME (self_type)))))
1873 /* If the object for the method call is null, we throw an
1874 exception. We don't do this if the object is the current
1875 method's `this'. In other cases we just rely on an
1876 optimization pass to eliminate redundant checks. FIXME:
1877 Unfortunately there doesn't seem to be a way to determine
1878 what the current method is right now. */
1879 /* We use a SAVE_EXPR here to make sure we only evaluate
1880 the new `self' expression once. */
1881 tree save_arg = save_expr (TREE_VALUE (arg_list));
1882 TREE_VALUE (arg_list) = save_arg;
1883 cond = build (EQ_EXPR, boolean_type_node, save_arg, null_pointer_node);
1884 func = build_known_method_ref (method, method_type, self_type,
1885 method_signature, arg_list);
1889 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1891 if (opcode == OPCODE_invokevirtual)
1892 func = build_invokevirtual (dtable, method);
1894 func = build_invokeinterface (dtable, method);
1896 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1897 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1898 TREE_SIDE_EFFECTS (call) = 1;
1900 if (cond != NULL_TREE)
1902 /* We have to make the `then' branch a compound expression to
1903 make the types turn out right. This seems bizarre. */
1904 call = build (COND_EXPR, TREE_TYPE (call), cond,
1905 build (COMPOUND_EXPR, TREE_TYPE (call),
1906 build (CALL_EXPR, void_type_node,
1907 build_address_of (soft_nullpointer_node),
1908 NULL_TREE, NULL_TREE),
1909 (FLOAT_TYPE_P (TREE_TYPE (call))
1910 ? build_real (TREE_TYPE (call), dconst0)
1911 : build1 (CONVERT_EXPR, TREE_TYPE (call),
1912 integer_zero_node))),
1914 TREE_SIDE_EFFECTS (call) = 1;
1917 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1918 expand_expr_stmt (call);
1922 flush_quick_stack ();
1926 /* Create a stub which will be put into the vtable but which will call
1930 build_jni_stub (method)
1933 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
1934 tree jni_func_type, tem;
1935 tree env_var, res_var = NULL_TREE, block;
1936 tree method_args, res_type;
1939 tree klass = DECL_CONTEXT (method);
1940 int from_class = ! CLASS_FROM_SOURCE_P (klass);
1941 klass = build_class_ref (klass);
1943 if (! METHOD_NATIVE (method) || ! flag_jni)
1946 DECL_ARTIFICIAL (method) = 1;
1947 DECL_EXTERNAL (method) = 0;
1949 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
1950 DECL_CONTEXT (env_var) = method;
1952 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
1954 res_var = build_decl (VAR_DECL, get_identifier ("res"),
1955 TREE_TYPE (TREE_TYPE (method)));
1956 DECL_CONTEXT (res_var) = method;
1957 TREE_CHAIN (env_var) = res_var;
1960 push_obstacks (&permanent_obstack, &permanent_obstack);
1961 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
1962 TREE_STATIC (meth_var) = 1;
1963 TREE_PUBLIC (meth_var) = 0;
1964 DECL_EXTERNAL (meth_var) = 0;
1965 make_decl_rtl (meth_var, NULL, 0);
1966 meth_var = pushdecl_top_level (meth_var);
1969 /* One strange way that the front ends are different is that they
1970 store arguments differently. */
1972 method_args = DECL_ARGUMENTS (method);
1974 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
1975 block = build_block (env_var, NULL_TREE, NULL_TREE,
1976 method_args, NULL_TREE);
1977 TREE_SIDE_EFFECTS (block) = 1;
1978 /* When compiling from source we don't set the type of the block,
1979 because that will prevent patch_return from ever being run. */
1981 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
1983 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
1984 body = build (MODIFY_EXPR, ptr_type_node, env_var,
1985 build (CALL_EXPR, ptr_type_node,
1986 build_address_of (soft_getjnienvnewframe_node),
1987 build_tree_list (NULL_TREE, klass),
1989 CAN_COMPLETE_NORMALLY (body) = 1;
1991 /* All the arguments to this method become arguments to the
1992 underlying JNI function. If we had to wrap object arguments in a
1993 special way, we would do that here. */
1995 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
1996 args = tree_cons (NULL_TREE, tem, args);
1997 args = nreverse (args);
1998 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2000 /* For a static method the second argument is the class. For a
2001 non-static method the second argument is `this'; that is already
2002 available in the argument list. */
2003 if (METHOD_STATIC (method))
2005 args = tree_cons (NULL_TREE, klass, args);
2006 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2009 /* The JNIEnv structure is the first argument to the JNI function. */
2010 args = tree_cons (NULL_TREE, env_var, args);
2011 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2013 /* We call _Jv_LookupJNIMethod to find the actual underlying
2014 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2015 exception if this function is not found at runtime. */
2016 method_sig = build_java_signature (TREE_TYPE (method));
2018 build_tree_list (NULL_TREE,
2019 build_utf8_ref (unmangle_classname
2020 (IDENTIFIER_POINTER (method_sig),
2021 IDENTIFIER_LENGTH (method_sig))));
2022 tem = DECL_NAME (method);
2024 = tree_cons (NULL_TREE, klass,
2025 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2028 = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2031 jnifunc = build (COND_EXPR, ptr_type_node,
2033 build (MODIFY_EXPR, ptr_type_node,
2035 build (CALL_EXPR, ptr_type_node,
2036 build_address_of (soft_lookupjnimethod_node),
2037 lookup_arg, NULL_TREE)));
2039 /* Now we make the actual JNI call via the resulting function
2041 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2042 build1 (NOP_EXPR, jni_func_type, jnifunc),
2045 /* If the JNI call returned a result, capture it here. If we had to
2046 unwrap JNI object results, we would do that here. */
2047 if (res_var != NULL_TREE)
2048 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2051 TREE_SIDE_EFFECTS (call) = 1;
2052 CAN_COMPLETE_NORMALLY (call) = 1;
2054 body = build (COMPOUND_EXPR, void_type_node, body, call);
2055 TREE_SIDE_EFFECTS (body) = 1;
2057 /* Now free the environment we allocated. */
2058 call = build (CALL_EXPR, ptr_type_node,
2059 build_address_of (soft_jnipopsystemframe_node),
2060 build_tree_list (NULL_TREE, env_var),
2062 TREE_SIDE_EFFECTS (call) = 1;
2063 CAN_COMPLETE_NORMALLY (call) = 1;
2064 body = build (COMPOUND_EXPR, void_type_node, body, call);
2065 TREE_SIDE_EFFECTS (body) = 1;
2067 /* Finally, do the return. When compiling from source we rely on
2068 patch_return to patch the return value -- because DECL_RESULT is
2069 not set at the time this function is called. */
2072 res_type = void_type_node;
2073 if (res_var != NULL_TREE)
2076 if (! DECL_RESULT (method))
2078 /* Make sure we copy the result variable to the actual
2079 result. We use the type of the DECL_RESULT because it
2080 might be different from the return type of the function:
2081 it might be promoted. */
2082 drt = TREE_TYPE (DECL_RESULT (method));
2083 if (drt != TREE_TYPE (res_var))
2084 res_var = build1 (CONVERT_EXPR, drt, res_var);
2085 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2086 TREE_SIDE_EFFECTS (res_var) = 1;
2091 /* This is necessary to get patch_return to run. */
2092 res_type = NULL_TREE;
2094 body = build (COMPOUND_EXPR, void_type_node, body,
2095 build1 (RETURN_EXPR, res_type, res_var));
2096 TREE_SIDE_EFFECTS (body) = 1;
2098 BLOCK_EXPR_BODY (block) = body;
2102 /* Expand an operation to extract from or store into a field.
2103 IS_STATIC is 1 iff the field is static.
2104 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2105 FIELD_REF_INDEX is an index into the constant pool. */
2108 expand_java_field_op (is_static, is_putting, field_ref_index)
2111 int field_ref_index;
2114 get_class_constant (current_jcf,
2115 COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
2117 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2118 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
2119 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool,
2121 tree field_type = get_type_from_signature (field_signature);
2122 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2125 tree field_decl = lookup_field (&self_type, field_name);
2126 if (field_decl == error_mark_node)
2130 else if (field_decl == NULL_TREE)
2132 error ("Missing field '%s' in '%s'",
2133 IDENTIFIER_POINTER (field_name), self_name);
2136 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2138 error ("Mismatching signature for field '%s' in '%s'",
2139 IDENTIFIER_POINTER (field_name), self_name);
2142 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2146 push_value (convert (field_type, integer_zero_node));
2147 flush_quick_stack ();
2151 /* Inline references to java.lang.PRIMTYPE.TYPE.
2152 In addition to being a useful (minor) optimization,
2153 this is also needed to avoid circularities in the implementation
2154 of these fields in libjava. */
2155 if (field_name == TYPE_identifier_node && ! is_putting
2156 && ! flag_emit_class_files && field_type == class_ptr_type
2157 && strncmp (self_name, "java.lang.", 10) == 0)
2159 tree typ = build_primtype_type_ref (self_name);
2167 field_ref = build_field_ref (field_ref, self_type, field_name);
2169 field_ref = build_class_init (self_type, field_ref);
2172 flush_quick_stack ();
2173 if (FIELD_FINAL (field_decl))
2175 if (DECL_CONTEXT (field_decl) != current_class)
2176 error_with_decl (field_decl,
2177 "assignment to final field `%s' not in field's class");
2178 else if (FIELD_STATIC (field_decl))
2180 if (!DECL_CLINIT_P (current_function_decl))
2181 error_with_decl (field_decl,
2182 "assignment to final static field `%s' not in class initializer");
2186 tree cfndecl_name = DECL_NAME (current_function_decl);
2187 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2188 && (cfndecl_name != finit_identifier_node))
2189 error_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2192 expand_assignment (field_ref, new_value, 0, 0);
2195 push_value (field_ref);
2199 build_primtype_type_ref (self_name)
2200 const char *self_name;
2202 const char *class_name = self_name+10;
2204 if (strncmp(class_name, "Byte", 4) == 0)
2205 typ = byte_type_node;
2206 else if (strncmp(class_name, "Short", 5) == 0)
2207 typ = short_type_node;
2208 else if (strncmp(class_name, "Integer", 7) == 0)
2209 typ = int_type_node;
2210 else if (strncmp(class_name, "Long", 4) == 0)
2211 typ = long_type_node;
2212 else if (strncmp(class_name, "Float", 5) == 0)
2213 typ = float_type_node;
2214 else if (strncmp(class_name, "Double", 6) == 0)
2215 typ = double_type_node;
2216 else if (strncmp(class_name, "Boolean", 7) == 0)
2217 typ = boolean_type_node;
2218 else if (strncmp(class_name, "Char", 4) == 0)
2219 typ = char_type_node;
2220 else if (strncmp(class_name, "Void", 4) == 0)
2221 typ = void_type_node;
2224 if (typ != NULL_TREE)
2225 return build_class_ref (typ);
2231 load_type_state (label)
2235 tree vec = LABEL_TYPE_STATE (label);
2236 int cur_length = TREE_VEC_LENGTH (vec);
2237 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2238 for (i = 0; i < cur_length; i++)
2239 type_map [i] = TREE_VEC_ELT (vec, i);
2242 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2243 dependant things, but they rely on gcc routines. This function is
2244 placed here because it uses things defined locally in parse.y. */
2247 case_identity (t, v)
2248 tree t __attribute__ ((__unused__));
2255 java_lang_expand_expr (exp, target, tmode, modifier)
2257 rtx target ATTRIBUTE_UNUSED;
2258 enum machine_mode tmode ATTRIBUTE_UNUSED;
2259 enum expand_modifier modifier ATTRIBUTE_UNUSED;
2263 switch (TREE_CODE (exp))
2265 case NEW_ARRAY_INIT:
2268 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2269 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2270 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2271 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2272 tree length = build_int_2 (ilength, 0);
2273 tree init = TREE_OPERAND (exp, 0);
2276 /* Enable this once we can set the vtable field statically. FIXME */
2277 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2278 && JPRIMITIVE_TYPE_P (element_type))
2280 tree temp, value, init_decl;
2281 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2282 PUSH_FIELD_VALUE (temp, "vtable",
2283 null_pointer_node /* FIXME */
2285 if (! flag_hash_synchronization)
2286 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2287 FINISH_RECORD_CONSTRUCTOR (temp);
2288 START_RECORD_CONSTRUCTOR (value, array_type);
2289 PUSH_SUPER_VALUE (value, temp);
2290 PUSH_FIELD_VALUE (value, "length", length);
2291 PUSH_FIELD_VALUE (value, "data", init);
2292 FINISH_RECORD_CONSTRUCTOR (value);
2294 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2295 pushdecl_top_level (init_decl);
2296 TREE_STATIC (init_decl) = 1;
2297 DECL_INITIAL (init_decl) = value;
2298 DECL_IGNORED_P (init_decl) = 1;
2299 TREE_READONLY (init_decl) = 1;
2300 make_decl_rtl (init_decl, NULL, 1);
2301 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2302 return expand_expr (init, target, tmode, modifier);
2305 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2306 expand_decl (array_decl);
2307 tmp = expand_assignment (array_decl,
2308 build_new_array (element_type, length),
2310 if (TREE_CONSTANT (init)
2311 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2314 push_obstacks (&permanent_obstack, &permanent_obstack);
2315 init_decl = build_decl (VAR_DECL, generate_name (),
2317 pushdecl_top_level (init_decl);
2318 TREE_STATIC (init_decl) = 1;
2319 DECL_INITIAL (init_decl) = init;
2320 DECL_IGNORED_P (init_decl) = 1;
2321 TREE_READONLY (init_decl) = 1;
2322 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2323 make_decl_rtl (init_decl, NULL, 1);
2327 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2328 build1 (INDIRECT_REF, array_type,
2329 array_decl), data_fld), init, 0, 0);
2333 if (BLOCK_EXPR_BODY (exp))
2336 tree body = BLOCK_EXPR_BODY (exp);
2337 pushlevel (2); /* 2 and above */
2338 expand_start_bindings (0);
2339 local = BLOCK_EXPR_DECLS (exp);
2342 tree next = TREE_CHAIN (local);
2343 layout_decl (local, 0);
2344 expand_decl (pushdecl (local));
2347 /* Avoid deep recursion for long block. */
2348 while (TREE_CODE (body) == COMPOUND_EXPR)
2350 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2352 body = TREE_OPERAND (body, 1);
2354 expand_expr (body, const0_rtx, VOIDmode, 0);
2357 expand_end_bindings (getdecls (), 1, 0);
2365 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2366 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2369 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2371 (wfl_operator, "Duplicate case label: `%s'",
2372 print_int_node (TREE_OPERAND (exp, 0)));
2378 pushcase (NULL_TREE, 0,
2379 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2383 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2384 expand_expr_stmt (TREE_OPERAND (exp, 1));
2385 expand_end_case (TREE_OPERAND (exp, 0));
2389 /* We expand a try[-catch] block */
2391 /* Expand the try block */
2392 push_obstacks (&permanent_obstack, &permanent_obstack);
2393 expand_eh_region_start ();
2395 expand_expr_stmt (TREE_OPERAND (exp, 0));
2396 push_obstacks (&permanent_obstack, &permanent_obstack);
2397 expand_start_all_catch ();
2400 /* Expand all catch clauses (EH handlers) */
2401 for (current = TREE_OPERAND (exp, 1); current;
2402 current = TREE_CHAIN (current))
2405 tree catch = TREE_OPERAND (current, 0);
2406 tree decl = BLOCK_EXPR_DECLS (catch);
2407 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2408 start_catch_handler (prepare_eh_table_type (type));
2409 expand_expr_stmt (TREE_OPERAND (current, 0));
2411 expand_resume_after_catch ();
2412 end_catch_handler ();
2414 expand_end_all_catch ();
2418 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2419 tree_code_name [TREE_CODE (exp)]);
2424 expand_byte_code (jcf, method)
2431 const unsigned char *linenumber_pointer;
2432 int dead_code_index = -1;
2434 #undef RET /* Defined by config/i386/i386.h */
2435 #undef AND /* Causes problems with opcodes for iand and land. */
2437 #define BCODE byte_ops
2438 #define BYTE_type_node byte_type_node
2439 #define SHORT_type_node short_type_node
2440 #define INT_type_node int_type_node
2441 #define LONG_type_node long_type_node
2442 #define CHAR_type_node char_type_node
2443 #define PTR_type_node ptr_type_node
2444 #define FLOAT_type_node float_type_node
2445 #define DOUBLE_type_node double_type_node
2446 #define VOID_type_node void_type_node
2448 unsigned char* byte_ops;
2449 long length = DECL_CODE_LENGTH (method);
2452 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2453 byte_ops = jcf->read_ptr;
2455 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2456 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2457 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2458 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2460 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2462 instruction_bits = oballoc (length + 1);
2463 bzero (instruction_bits, length + 1);
2465 /* We make an initial pass of the line number table, to note
2466 which instructions have associated line number entries. */
2467 linenumber_pointer = linenumber_table;
2468 for (i = 0; i < linenumber_count; i++)
2470 int pc = GET_u2 (linenumber_pointer);
2471 linenumber_pointer += 4;
2473 warning ("invalid PC in line number table");
2476 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2477 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2478 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2482 /* Do a preliminary pass.
2483 * This figures out which PC can be the targets of jumps. */
2484 for (PC = 0; PC < length;)
2486 int oldpc = PC; /* PC at instruction start. */
2487 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2488 switch (byte_ops[PC++])
2490 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2492 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2495 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2497 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2498 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2499 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2500 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2501 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2502 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2503 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2504 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2506 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2507 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2508 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2509 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2510 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2511 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2512 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2513 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2515 /* two forms of wide instructions */
2516 #define PRE_SPECIAL_WIDE(IGNORE) \
2518 int modified_opcode = IMMEDIATE_u1; \
2519 if (modified_opcode == OPCODE_iinc) \
2521 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2522 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2526 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2530 /* nothing */ /* XXX JH */
2532 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2534 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2536 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2537 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2538 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2539 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2540 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2541 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2542 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2543 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2544 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2545 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2547 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2548 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2549 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2550 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2551 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2552 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2553 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2554 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2556 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2558 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2559 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2561 #define PRE_LOOKUP_SWITCH \
2562 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2563 NOTE_LABEL (default_offset+oldpc); \
2565 while (--npairs >= 0) { \
2566 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2567 jint offset = IMMEDIATE_s4; \
2568 NOTE_LABEL (offset+oldpc); } \
2571 #define PRE_TABLE_SWITCH \
2572 { jint default_offset = IMMEDIATE_s4; \
2573 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2574 NOTE_LABEL (default_offset+oldpc); \
2576 while (low++ <= high) { \
2577 jint offset = IMMEDIATE_s4; \
2578 NOTE_LABEL (offset+oldpc); } \
2581 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2582 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2583 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2584 (void)(IMMEDIATE_u2); \
2585 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2587 #include "javaop.def"
2592 if (! verify_jvm_instructions (jcf, byte_ops, length))
2595 /* Translate bytecodes to rtl instructions. */
2596 linenumber_pointer = linenumber_table;
2597 for (PC = 0; PC < length;)
2599 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2601 tree label = lookup_label (PC);
2602 flush_quick_stack ();
2603 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2604 expand_label (label);
2605 if (LABEL_VERIFIED (label) || PC == 0)
2606 load_type_state (label);
2609 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2611 if (dead_code_index == -1)
2613 /* This is the start of a region of unreachable bytecodes.
2614 They still need to be processed in order for EH ranges
2615 to get handled correctly. However, we can simply
2616 replace these bytecodes with nops. */
2617 dead_code_index = PC;
2620 /* Turn this bytecode into a nop. */
2625 if (dead_code_index != -1)
2627 /* We've just reached the end of a region of dead code. */
2628 warning ("Unreachable bytecode from %d to before %d.",
2629 dead_code_index, PC);
2630 dead_code_index = -1;
2634 /* Handle possible line number entry for this PC.
2636 This code handles out-of-order and multiple linenumbers per PC,
2637 but is optimized for the case of line numbers increasing
2638 monotonically with PC. */
2639 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2641 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2642 || GET_u2 (linenumber_pointer) != PC)
2643 linenumber_pointer = linenumber_table;
2644 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2646 int pc = GET_u2 (linenumber_pointer);
2647 linenumber_pointer += 4;
2650 lineno = GET_u2 (linenumber_pointer - 2);
2651 emit_line_note (input_filename, lineno);
2652 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2657 maybe_pushlevels (PC);
2658 PC = process_jvm_instruction (PC, byte_ops, length);
2659 maybe_poplevels (PC);
2662 if (dead_code_index != -1)
2664 /* We've just reached the end of a region of dead code. */
2665 warning ("Unreachable bytecode from %d to the end of the method.",
2671 java_push_constant_from_pool (jcf, index)
2676 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2679 push_obstacks (&permanent_obstack, &permanent_obstack);
2680 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2681 index = alloc_name_constant (CONSTANT_String, name);
2682 c = build_ref_from_constant_pool (index);
2683 TREE_TYPE (c) = promote_type (string_type_node);
2687 c = get_constant (jcf, index);
2692 process_jvm_instruction (PC, byte_ops, length)
2694 const unsigned char* byte_ops;
2695 long length ATTRIBUTE_UNUSED;
2697 const char *opname; /* Temporary ??? */
2698 int oldpc = PC; /* PC at instruction start. */
2700 /* If the instruction is at the beginning of a exception handler,
2701 replace the top of the stack with the thrown object reference */
2702 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2704 tree type = pop_type (ptr_type_node);
2705 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2708 switch (byte_ops[PC++])
2710 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2713 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2716 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2718 int saw_index = 0; \
2719 int index = OPERAND_VALUE; \
2720 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2723 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2725 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2726 tree ret = lookup_label (PC); \
2727 build_java_jsr (where, ret); \
2728 load_type_state (ret); \
2731 /* Push a constant onto the stack. */
2732 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2733 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2734 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2735 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2737 /* internal macro added for use by the WIDE case */
2738 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2739 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2741 /* Push local variable onto the opcode stack. */
2742 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2744 /* have to do this since OPERAND_VALUE may have side-effects */ \
2745 int opvalue = OPERAND_VALUE; \
2746 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2749 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2750 expand_java_return (OPERAND_TYPE##_type_node)
2752 #define REM_EXPR TRUNC_MOD_EXPR
2753 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2754 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2756 #define FIELD(IS_STATIC, IS_PUT) \
2757 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2759 #define TEST(OPERAND_TYPE, CONDITION) \
2760 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2762 #define COND(OPERAND_TYPE, CONDITION) \
2763 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2765 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2766 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2768 #define BRANCH_GOTO(OPERAND_VALUE) \
2769 expand_java_goto (oldpc + OPERAND_VALUE)
2771 #define BRANCH_CALL(OPERAND_VALUE) \
2772 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2775 #define BRANCH_RETURN(OPERAND_VALUE) \
2777 tree type = OPERAND_TYPE##_type_node; \
2778 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2779 expand_java_ret (value); \
2783 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2784 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2785 fprintf (stderr, "(not implemented)\n")
2786 #define NOT_IMPL1(OPERAND_VALUE) \
2787 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2788 fprintf (stderr, "(not implemented)\n")
2790 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2792 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2794 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2796 #define STACK_SWAP(COUNT) java_stack_swap()
2798 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2799 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2800 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2802 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2803 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2805 #define LOOKUP_SWITCH \
2806 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2807 tree selector = pop_value (INT_type_node); \
2808 tree duplicate, label; \
2809 tree type = TREE_TYPE (selector); \
2810 flush_quick_stack (); \
2811 expand_start_case (0, selector, type, "switch statement");\
2812 push_momentary (); \
2813 while (--npairs >= 0) \
2815 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2816 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2817 TREE_TYPE (value) = type; \
2818 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2819 pushcase (value, convert, label, &duplicate); \
2820 expand_java_goto (oldpc + offset); \
2822 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2823 pushcase (NULL_TREE, 0, label, &duplicate); \
2824 expand_java_goto (oldpc + default_offset); \
2826 expand_end_case (selector); \
2829 #define TABLE_SWITCH \
2830 { jint default_offset = IMMEDIATE_s4; \
2831 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2832 tree selector = pop_value (INT_type_node); \
2833 tree duplicate, label; \
2834 tree type = TREE_TYPE (selector); \
2835 flush_quick_stack (); \
2836 expand_start_case (0, selector, type, "switch statement");\
2837 push_momentary (); \
2838 for (; low <= high; low++) \
2840 jint offset = IMMEDIATE_s4; \
2841 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2842 TREE_TYPE (value) = type; \
2843 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2844 pushcase (value, convert, label, &duplicate); \
2845 expand_java_goto (oldpc + offset); \
2847 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2848 pushcase (NULL_TREE, 0, label, &duplicate); \
2849 expand_java_goto (oldpc + default_offset); \
2851 expand_end_case (selector); \
2854 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2855 { int opcode = byte_ops[PC-1]; \
2856 int method_ref_index = IMMEDIATE_u2; \
2858 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2860 expand_invoke (opcode, method_ref_index, nargs); \
2863 /* Handle new, checkcast, instanceof */
2864 #define OBJECT(TYPE, OP) \
2865 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2867 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2869 #define ARRAY_LOAD(OPERAND_TYPE) \
2871 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2874 #define ARRAY_STORE(OPERAND_TYPE) \
2876 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2879 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2880 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2881 #define ARRAY_NEW_PTR() \
2882 push_value (build_anewarray (get_class_constant (current_jcf, \
2884 pop_value (int_type_node)));
2885 #define ARRAY_NEW_NUM() \
2887 int atype = IMMEDIATE_u1; \
2888 push_value (build_newarray (atype, pop_value (int_type_node)));\
2890 #define ARRAY_NEW_MULTI() \
2892 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2893 int ndims = IMMEDIATE_u1; \
2894 expand_java_multianewarray( class, ndims ); \
2897 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2898 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2899 pop_value (OPERAND_TYPE##_type_node))));
2901 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2903 push_value (build1 (NOP_EXPR, int_type_node, \
2904 (convert (TO_TYPE##_type_node, \
2905 pop_value (FROM_TYPE##_type_node))))); \
2908 #define CONVERT(FROM_TYPE, TO_TYPE) \
2910 push_value (convert (TO_TYPE##_type_node, \
2911 pop_value (FROM_TYPE##_type_node))); \
2914 /* internal macro added for use by the WIDE case
2915 Added TREE_TYPE (decl) assignment, apbianco */
2916 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2919 int var = OPVALUE; \
2920 tree type = OPTYPE; \
2921 value = pop_value (type); \
2922 type = TREE_TYPE (value); \
2923 decl = find_local_variable (var, type, oldpc); \
2924 set_local_type (var, type ); \
2925 expand_assignment (decl, value, 0, 0); \
2928 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2930 /* have to do this since OPERAND_VALUE may have side-effects */ \
2931 int opvalue = OPERAND_VALUE; \
2932 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2935 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2936 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2938 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2939 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2941 #define MONITOR_OPERATION(call) \
2943 tree o = pop_value (ptr_type_node); \
2945 flush_quick_stack (); \
2946 c = build_java_monitor (call, o); \
2947 TREE_SIDE_EFFECTS (c) = 1; \
2948 expand_expr_stmt (c); \
2951 #define SPECIAL_IINC(IGNORED) \
2953 unsigned int local_var_index = IMMEDIATE_u1; \
2954 int ival = IMMEDIATE_s1; \
2955 expand_iinc(local_var_index, ival, oldpc); \
2958 #define SPECIAL_WIDE(IGNORED) \
2960 int modified_opcode = IMMEDIATE_u1; \
2961 unsigned int local_var_index = IMMEDIATE_u2; \
2962 switch (modified_opcode) \
2966 int ival = IMMEDIATE_s2; \
2967 expand_iinc (local_var_index, ival, oldpc); \
2970 case OPCODE_iload: \
2971 case OPCODE_lload: \
2972 case OPCODE_fload: \
2973 case OPCODE_dload: \
2974 case OPCODE_aload: \
2976 /* duplicate code from LOAD macro */ \
2977 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2980 case OPCODE_istore: \
2981 case OPCODE_lstore: \
2982 case OPCODE_fstore: \
2983 case OPCODE_dstore: \
2984 case OPCODE_astore: \
2986 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2990 error ("unrecogized wide sub-instruction"); \
2994 #define SPECIAL_THROW(IGNORED) \
2995 build_java_athrow (pop_value (throwable_type_node))
2997 #define SPECIAL_BREAK NOT_IMPL1
2998 #define IMPL NOT_IMPL
3000 #include "javaop.def"
3003 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3008 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3009 order, as specified by Java Language Specification.
3011 The problem is that while expand_expr will evaluate its sub-operands in
3012 left-to-right order, for variables it will just return an rtx (i.e.
3013 an lvalue) for the variable (rather than an rvalue). So it is possible
3014 that a later sub-operand will change the register, and when the
3015 actual operation is done, it will use the new value, when it should
3016 have used the original value.
3018 We fix this by using save_expr. This forces the sub-operand to be
3019 copied into a fresh virtual register,
3021 For method invocation, we modify the arguments so that a
3022 left-to-right order evaluation is performed. Saved expressions
3023 will, in CALL_EXPR order, be reused when the call will be expanded.
3027 force_evaluation_order (node)
3030 if (flag_syntax_only)
3032 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3034 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3035 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3037 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
3041 if (!TREE_OPERAND (node, 1))
3044 /* This reverses the evaluation order. This is a desired effect. */
3045 for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1);
3046 arg; arg = TREE_CHAIN (arg))
3048 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3049 cmp = (cmp == NULL_TREE ? saved :
3050 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3051 TREE_VALUE (arg) = saved;
3054 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3055 TREE_SIDE_EFFECTS (cmp) = 1;
3059 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3060 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3061 TREE_SIDE_EFFECTS (cmp) = 1;