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));
83 static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int));
85 static tree operand_type[59];
86 extern struct obstack permanent_obstack;
88 static tree methods_ident = NULL_TREE;
89 static tree ncode_ident = NULL_TREE;
90 tree dtable_ident = NULL_TREE;
92 /* Set to non-zero value in order to emit class initilization code
93 before static field references. */
94 int always_initialize_class_p;
97 init_expr_processing()
99 operand_type[21] = operand_type[54] = int_type_node;
100 operand_type[22] = operand_type[55] = long_type_node;
101 operand_type[23] = operand_type[56] = float_type_node;
102 operand_type[24] = operand_type[57] = double_type_node;
103 operand_type[25] = operand_type[58] = ptr_type_node;
104 ggc_add_tree_root (operand_type, 59);
105 ggc_add_tree_root (&methods_ident, 1);
106 ggc_add_tree_root (&ncode_ident, 1);
109 /* We store the stack state in two places:
110 Within a basic block, we use the quick_stack, which is a
111 pushdown list (TREE_LISTs) of expression nodes.
112 This is the top part of the stack; below that we use find_stack_slot.
113 At the end of a basic block, the quick_stack must be flushed
114 to the stack slot array (as handled by find_stack_slot).
115 Using quick_stack generates better code (especially when
116 compiled without optimization), because we do not have to
117 explicitly store and load trees to temporary variables.
119 If a variable is on the quick stack, it means the value of variable
120 when the quick stack was last flushed. Conceptually, flush_quick_stack
121 saves all the the quick_stack elements in parellel. However, that is
122 complicated, so it actually saves them (i.e. copies each stack value
123 to is home virtual register) from low indexes. This allows a quick_stack
124 element at index i (counting from the bottom of stack the) to references
125 slot virtuals for register that are >= i, but not those that are deeper.
126 This convention makes most operations easier. For example iadd works
127 even when the stack contains (reg[0], reg[1]): It results in the
128 stack containing (reg[0]+reg[1]), which is OK. However, some stack
129 operations are more complicated. For example dup given a stack
130 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
131 the convention, since stack value 1 would refer to a register with
132 lower index (reg[0]), which flush_quick_stack does not safely handle.
133 So dup cannot just add an extra element to the quick_stack, but iadd can.
136 tree quick_stack = NULL_TREE;
138 /* A free-list of unused permamnet TREE_LIST nodes. */
139 tree tree_list_free_list = NULL_TREE;
141 /* The stack pointer of the Java virtual machine.
142 This does include the size of the quick_stack. */
146 const unsigned char *linenumber_table;
147 int linenumber_count;
150 truthvalue_conversion (expr)
153 /* It is simpler and generates better code to have only TRUTH_*_EXPR
154 or comparison expressions as truth values at this level.
156 This function should normally be identity for Java. */
158 switch (TREE_CODE (expr))
161 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
162 case TRUTH_ANDIF_EXPR:
163 case TRUTH_ORIF_EXPR:
170 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
173 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
175 /* are these legal? XXX JH */
180 /* These don't change whether an object is non-zero or zero. */
181 return truthvalue_conversion (TREE_OPERAND (expr, 0));
184 /* Distribute the conversion into the arms of a COND_EXPR. */
185 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
186 truthvalue_conversion (TREE_OPERAND (expr, 1)),
187 truthvalue_conversion (TREE_OPERAND (expr, 2))));
190 /* If this is widening the argument, we can ignore it. */
191 if (TYPE_PRECISION (TREE_TYPE (expr))
192 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
193 return truthvalue_conversion (TREE_OPERAND (expr, 0));
194 /* fall through to default */
197 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
201 #ifdef JAVA_USE_HANDLES
202 /* Given a pointer to a handle, get a pointer to an object. */
208 tree field, handle_type;
209 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
210 handle_type = TREE_TYPE (expr);
211 field = TYPE_FIELDS (handle_type);
212 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
217 /* Save any stack slots that happen to be in the quick_stack into their
218 home virtual register slots.
220 The copy order is from low stack index to high, to support the invariant
221 that the expression for a slot may contain decls for stack slots with
222 higher (or the same) index, but not lower. */
227 int stack_index = stack_pointer;
228 register tree prev, cur, next;
230 /* First reverse the quick_stack, and count the number of slots it has. */
231 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
233 next = TREE_CHAIN (cur);
234 TREE_CHAIN (cur) = prev;
236 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
240 while (quick_stack != NULL_TREE)
243 tree node = quick_stack, type;
244 quick_stack = TREE_CHAIN (node);
245 TREE_CHAIN (node) = tree_list_free_list;
246 tree_list_free_list = node;
247 node = TREE_VALUE (node);
248 type = TREE_TYPE (node);
250 decl = find_stack_slot (stack_index, type);
252 expand_assignment (decl, node, 0, 0);
253 stack_index += 1 + TYPE_IS_WIDE (type);
262 type = promote_type (type);
263 n_words = 1 + TYPE_IS_WIDE (type);
264 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
265 fatal ("stack overflow");
266 stack_type_map[stack_pointer++] = type;
268 while (--n_words >= 0)
269 stack_type_map[stack_pointer++] = TYPE_SECOND;
276 tree type = TREE_TYPE (value);
277 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
279 type = promote_type (type);
280 value = convert (type, value);
283 if (tree_list_free_list == NULL_TREE)
284 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
287 tree node = tree_list_free_list;
288 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
289 TREE_VALUE (node) = value;
290 TREE_CHAIN (node) = quick_stack;
295 /* Pop a type from the type stack.
296 TYPE is the expected type. Return the actual type, which must be
297 convertible to TYPE, otherwise NULL_TREE is returned. */
305 if (TREE_CODE (type) == RECORD_TYPE)
306 type = promote_type (type);
307 n_words = 1 + TYPE_IS_WIDE (type);
308 if (stack_pointer < n_words)
309 fatal ("stack underflow");
310 while (--n_words > 0)
312 if (stack_type_map[--stack_pointer] != void_type_node)
313 fatal ("Invalid multi-word value on type stack");
315 t = stack_type_map[--stack_pointer];
316 if (type == NULL_TREE || t == type)
318 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
319 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
321 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
323 if (type == ptr_type_node || type == object_ptr_type_node)
325 else if (t == ptr_type_node) /* Special case for null reference. */
327 else if (can_widen_reference_to (t, type))
329 /* This is a kludge, but matches what Sun's verifier does.
330 It can be tricked, but is safe as long as type errors
331 (i.e. interface method calls) are caught at run-time. */
332 /* FIXME: this is worse than a kludge, probably. */
333 return object_ptr_type_node;
338 /* Pop a type from the type stack.
339 TYPE is the expected type. Return the actual type, which must be
340 convertible to TYPE, otherwise call error. */
346 tree t = pop_type_0 (type);
349 error ("unexpected type on stack");
353 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
354 Handles array types and interfaces. */
357 can_widen_reference_to (source_type, target_type)
358 tree source_type, target_type;
360 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
363 /* Get rid of pointers */
364 if (TREE_CODE (source_type) == POINTER_TYPE)
365 source_type = TREE_TYPE (source_type);
366 if (TREE_CODE (target_type) == POINTER_TYPE)
367 target_type = TREE_TYPE (target_type);
369 if (source_type == target_type)
373 source_type = HANDLE_TO_CLASS_TYPE (source_type);
374 target_type = HANDLE_TO_CLASS_TYPE (target_type);
375 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
377 HOST_WIDE_INT source_length, target_length;
378 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
380 target_length = java_array_type_length (target_type);
381 if (target_length >= 0)
383 source_length = java_array_type_length (source_type);
384 if (source_length != target_length)
387 source_type = TYPE_ARRAY_ELEMENT (source_type);
388 target_type = TYPE_ARRAY_ELEMENT (target_type);
389 if (source_type == target_type)
391 if (TREE_CODE (source_type) != POINTER_TYPE
392 || TREE_CODE (target_type) != POINTER_TYPE)
394 return can_widen_reference_to (source_type, target_type);
398 int source_depth = class_depth (source_type);
399 int target_depth = class_depth (target_type);
401 /* class_depth can return a negative depth if an error occurred */
402 if (source_depth < 0 || target_depth < 0)
405 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
407 /* target_type is OK if source_type or source_type ancestors
408 implement target_type. We handle multiple sub-interfaces */
410 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
411 int n = TREE_VEC_LENGTH (basetype_vec), i;
412 for (i=0 ; i < n; i++)
413 if (can_widen_reference_to
414 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
421 for ( ; source_depth > target_depth; source_depth--)
423 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
425 return source_type == target_type;
434 type = pop_type (type);
437 tree node = quick_stack;
438 quick_stack = TREE_CHAIN (quick_stack);
439 TREE_CHAIN (node) = tree_list_free_list;
440 tree_list_free_list = node;
441 node = TREE_VALUE (node);
445 return find_stack_slot (stack_pointer, promote_type (type));
449 /* Pop and discrad the top COUNT stack slots. */
452 java_stack_pop (count)
458 if (stack_pointer == 0)
459 fatal ("stack underflow");
460 type = stack_type_map[stack_pointer - 1];
461 if (type == TYPE_SECOND)
464 if (stack_pointer == 1 || count <= 0)
465 fatal ("stack underflow");
466 type = stack_type_map[stack_pointer - 2];
468 val = pop_value (type);
473 /* Implement the 'swap' operator (to swap two top stack slots). */
482 if (stack_pointer < 2
483 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
484 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
485 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
486 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
487 fatal ("bad stack swap");
489 flush_quick_stack ();
490 decl1 = find_stack_slot (stack_pointer - 1, type1);
491 decl2 = find_stack_slot (stack_pointer - 2, type2);
492 temp = copy_to_reg (DECL_RTL (decl1));
493 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
494 emit_move_insn (DECL_RTL (decl2), temp);
495 stack_type_map[stack_pointer - 1] = type2;
496 stack_type_map[stack_pointer - 2] = type1;
500 java_stack_dup (size, offset)
503 int low_index = stack_pointer - size - offset;
506 error ("stack underflow - dup* operation");
508 flush_quick_stack ();
510 stack_pointer += size;
511 dst_index = stack_pointer;
513 for (dst_index = stack_pointer; --dst_index >= low_index; )
516 int src_index = dst_index - size;
517 if (src_index < low_index)
518 src_index = dst_index + size + offset;
519 type = stack_type_map [src_index];
520 if (type == TYPE_SECOND)
522 if (src_index <= low_index)
523 fatal ("dup operation splits 64-bit number");
524 stack_type_map[dst_index] = type;
525 src_index--; dst_index--;
526 type = stack_type_map[src_index];
527 if (! TYPE_IS_WIDE (type))
528 fatal ("internal error - dup operation");
530 else if (TYPE_IS_WIDE (type))
531 fatal ("internal error - dup operation");
532 if (src_index != dst_index)
534 tree src_decl = find_stack_slot (src_index, type);
535 tree dst_decl = find_stack_slot (dst_index, type);
536 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
537 stack_type_map[dst_index] = type;
542 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
546 build_java_athrow (node)
551 call = build (CALL_EXPR,
553 build_address_of (throw_node[exceptions_via_longjmp ? 1 : 0]),
554 build_tree_list (NULL_TREE, node),
556 TREE_SIDE_EFFECTS (call) = 1;
557 expand_expr_stmt (call);
558 java_stack_pop (stack_pointer);
561 /* Implementation for jsr/ret */
564 build_java_jsr (where, ret)
568 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
569 push_value (ret_label);
570 flush_quick_stack ();
571 emit_jump (label_rtx (where));
576 build_java_ret (location)
579 expand_computed_goto (location);
582 /* Implementation of operations on array: new, load, store, length */
584 /* Array core info access macros */
586 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
587 byte_position (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))
590 decode_newarray_type (atype)
595 case 4: return boolean_type_node;
596 case 5: return char_type_node;
597 case 6: return float_type_node;
598 case 7: return double_type_node;
599 case 8: return byte_type_node;
600 case 9: return short_type_node;
601 case 10: return int_type_node;
602 case 11: return long_type_node;
603 default: return NULL_TREE;
607 /* Map primitive type to the code used by OPCODE_newarray. */
610 encode_newarray_type (type)
613 if (type == boolean_type_node)
615 else if (type == char_type_node)
617 else if (type == float_type_node)
619 else if (type == double_type_node)
621 else if (type == byte_type_node)
623 else if (type == short_type_node)
625 else if (type == int_type_node)
627 else if (type == long_type_node)
630 fatal ("Can't compute type code - patch_newarray");
633 /* Build a call to _Jv_ThrowBadArrayIndex(), the
634 ArrayIndexOfBoundsException exception handler. */
637 build_java_throw_out_of_bounds_exception (index)
640 tree node = build (CALL_EXPR, int_type_node,
641 build_address_of (soft_badarrayindex_node),
642 build_tree_list (NULL_TREE, index), NULL_TREE);
643 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
647 /* Return the length of an array. Doesn't perform any checking on the nature
648 or value of the array NODE. May be used to implement some bytecodes. */
651 build_java_array_length_access (node)
654 tree type = TREE_TYPE (node);
655 HOST_WIDE_INT length;
656 if (!is_array_type_p (type))
657 fatal ("array length on a non-array reference");
658 length = java_array_type_length (type);
660 return build_int_2 (length, 0);
661 return fold (build1 (INDIRECT_REF,
663 fold (build (PLUS_EXPR, ptr_type_node,
665 JAVA_ARRAY_LENGTH_OFFSET(node)))));
668 /* Optionally checks an array against the NULL pointer, eventually throwing a
669 NullPointerException. It could replace signal handling, but tied to NULL.
670 ARG1: the pointer to check, ARG2: the expression to use if
671 the pointer is non-null and ARG3 the type that should be returned. */
674 build_java_arraynull_check (node, expr, type)
675 tree node ATTRIBUTE_UNUSED;
677 tree type ATTRIBUTE_UNUSED;
680 static int java_array_access_throws_null_exception = 0;
682 if (java_array_access_throws_null_exception)
683 return (build (COND_EXPR,
685 build (EQ_EXPR, int_type_node, node, null_pointer_node),
686 build_java_athrow (node), expr ));
693 java_array_data_offset (array)
696 tree array_type = TREE_TYPE (TREE_TYPE (array));
697 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
699 if (data_fld == NULL_TREE)
700 return size_in_bytes (array_type);
702 return byte_position (data_fld);
705 /* Implement array indexing (either as l-value or r-value).
706 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
707 Optionally performs bounds checking and/or test to NULL.
708 At this point, ARRAY should have been verified as an array. */
711 build_java_arrayaccess (array, type, index)
712 tree array, type, index;
714 tree arith, node, throw = NULL_TREE;
716 arith = fold (build (PLUS_EXPR, int_type_node,
717 java_array_data_offset (array),
718 fold (build (MULT_EXPR, int_type_node,
719 index, size_in_bytes(type)))));
721 if (flag_bounds_check)
724 * (unsigned jint) INDEX >= (unsigned jint) LEN
725 * && throw ArrayIndexOutOfBoundsException.
726 * Note this is equivalent to and more efficient than:
727 * INDEX < 0 || INDEX >= LEN && throw ... */
729 tree len = build_java_array_length_access (array);
730 TREE_TYPE (len) = unsigned_int_type_node;
731 test = fold (build (GE_EXPR, boolean_type_node,
732 convert (unsigned_int_type_node, index),
734 if (! integer_zerop (test))
736 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
737 build_java_throw_out_of_bounds_exception (index));
738 /* allows expansion within COMPOUND */
739 TREE_SIDE_EFFECTS( throw ) = 1;
743 node = build1 (INDIRECT_REF, type,
744 fold (build (PLUS_EXPR, ptr_type_node,
746 (throw ? build (COMPOUND_EXPR, int_type_node,
750 return (fold (build_java_arraynull_check (array, node, type)));
753 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
754 ARRAY_NODE. This function is used to retrieve something less vague than
755 a pointer type when indexing the first dimension of something like [[<t>.
756 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
758 As a side effect, it also makes sure that ARRAY_NODE is an array. */
761 build_java_check_indexed_type (array_node, indexed_type)
767 if (!is_array_type_p (TREE_TYPE (array_node)))
768 fatal ("array indexing on a non-array reference");
770 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
772 if (indexed_type == ptr_type_node )
773 return promote_type (elt_type);
775 /* BYTE/BOOLEAN store and load are used for both type */
776 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
777 return boolean_type_node;
779 if (indexed_type != elt_type )
780 fatal ("type array element mismatch");
785 /* newarray triggers a call to _Jv_NewArray. This function should be called
786 with an integer code (the type of array to create) and get from the stack
787 the size of the dimmension. */
790 build_newarray (atype_value, length)
795 = build_java_array_type (decode_newarray_type (atype_value),
796 host_integerp (length, 0) == INTEGER_CST
797 ? tree_low_cst (length, 0) : -1);
799 return build (CALL_EXPR, promote_type (type),
800 build_address_of (soft_newarray_node),
801 tree_cons (NULL_TREE,
802 build_int_2 (atype_value, 0),
803 build_tree_list (NULL_TREE, length)),
807 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
811 build_anewarray (class_type, length)
816 = build_java_array_type (class_type,
817 host_integerp (length, 0)
818 ? tree_low_cst (length, 0) : -1);
820 return build (CALL_EXPR, promote_type (type),
821 build_address_of (soft_anewarray_node),
822 tree_cons (NULL_TREE, length,
823 tree_cons (NULL_TREE, build_class_ref (class_type),
824 build_tree_list (NULL_TREE,
825 null_pointer_node))),
829 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
832 build_new_array (type, length)
836 if (JPRIMITIVE_TYPE_P (type))
837 return build_newarray (encode_newarray_type (type), length);
839 return build_anewarray (TREE_TYPE (type), length);
842 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
843 class pointer, a number of dimensions and the matching number of
844 dimensions. The argument list is NULL terminated. */
847 expand_java_multianewarray (class_type, ndim)
852 tree args = build_tree_list( NULL_TREE, null_pointer_node );
854 for( i = 0; i < ndim; i++ )
855 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
857 push_value (build (CALL_EXPR,
858 promote_type (class_type),
859 build_address_of (soft_multianewarray_node),
860 tree_cons (NULL_TREE, build_class_ref (class_type),
861 tree_cons (NULL_TREE,
862 build_int_2 (ndim, 0), args )),
866 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
867 ARRAY is an array type. May expand some bound checking and NULL
868 pointer checking. RHS_TYPE_NODE we are going to store. In the case
869 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
870 INT. In those cases, we make the convertion.
872 if ARRAy is a reference type, the assignment is checked at run-time
873 to make sure that the RHS can be assigned to the array element
874 type. It is not necessary to generate this code if ARRAY is final. */
877 expand_java_arraystore (rhs_type_node)
880 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
881 && TYPE_PRECISION (rhs_type_node) <= 32) ?
882 int_type_node : rhs_type_node);
883 tree index = pop_value (int_type_node);
884 tree array = pop_value (ptr_type_node);
886 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
888 flush_quick_stack ();
890 index = save_expr (index);
891 array = save_expr (array);
893 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
895 tree check = build (CALL_EXPR, void_type_node,
896 build_address_of (soft_checkarraystore_node),
897 tree_cons (NULL_TREE, array,
898 build_tree_list (NULL_TREE, rhs_node)),
900 TREE_SIDE_EFFECTS (check) = 1;
901 expand_expr_stmt (check);
904 expand_assignment (build_java_arrayaccess (array,
910 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
911 sure that LHS is an array type. May expand some bound checking and NULL
913 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
914 BOOLEAN/SHORT, we push a promoted type back to the stack.
918 expand_java_arrayload (lhs_type_node )
922 tree index_node = pop_value (int_type_node);
923 tree array_node = pop_value (ptr_type_node);
925 index_node = save_expr (index_node);
926 array_node = save_expr (array_node);
927 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
929 load_node = build_java_arrayaccess (array_node,
933 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
934 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
935 push_value (load_node);
938 /* Expands .length. Makes sure that we deal with and array and may expand
939 a NULL check on the array object. */
942 expand_java_array_length ()
944 tree array = pop_value (ptr_type_node);
945 tree length = build_java_array_length_access (array);
947 push_value (build_java_arraynull_check (array, length, int_type_node));
950 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
951 either soft_monitorenter_node or soft_monitorexit_node. */
954 build_java_monitor (call, object)
958 return (build (CALL_EXPR,
960 build_address_of (call),
961 build_tree_list (NULL_TREE, object),
965 /* Emit code for one of the PUSHC instructions. */
968 expand_java_pushc (ival, type)
973 if (type == ptr_type_node && ival == 0)
974 value = null_pointer_node;
975 else if (type == int_type_node || type == long_type_node)
977 value = build_int_2 (ival, ival < 0 ? -1 : 0);
978 TREE_TYPE (value) = type;
980 else if (type == float_type_node || type == double_type_node)
983 #ifdef REAL_ARITHMETIC
984 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
988 value = build_real (type, x);
991 fatal ("internal error in expand_java_pushc");
996 expand_java_return (type)
999 if (type == void_type_node)
1000 expand_null_return ();
1003 tree retval = pop_value (type);
1004 tree res = DECL_RESULT (current_function_decl);
1005 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1007 /* Handle the situation where the native integer type is smaller
1008 than the JVM integer. It can happen for many cross compilers.
1009 The whole if expression just goes away if INT_TYPE_SIZE < 32
1011 if (INT_TYPE_SIZE < 32
1012 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1013 < GET_MODE_SIZE (TYPE_MODE (type))))
1014 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1016 TREE_SIDE_EFFECTS (retval) = 1;
1017 expand_return (retval);
1022 build_address_of (value)
1025 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1029 expand_java_NEW (type)
1032 if (! CLASS_LOADED_P (type))
1033 load_class (type, 1);
1034 safe_layout_class (type);
1035 push_value (build (CALL_EXPR, promote_type (type),
1036 build_address_of (alloc_object_node),
1037 tree_cons (NULL_TREE, build_class_ref (type),
1038 build_tree_list (NULL_TREE,
1039 size_in_bytes (type))),
1043 /* This returns an expression which will extract the class of an
1047 build_get_class (value)
1050 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1051 tree vtable_field = lookup_field (&object_type_node,
1052 get_identifier ("vtable"));
1053 return build (COMPONENT_REF, class_ptr_type,
1054 build1 (INDIRECT_REF, dtable_type,
1055 build (COMPONENT_REF, dtable_ptr_type,
1056 build1 (INDIRECT_REF, object_type_node, value),
1061 /* This builds the tree representation of the `instanceof' operator.
1062 It tries various tricks to optimize this in cases where types are
1066 build_instanceof (value, type)
1070 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1071 tree valtype = TREE_TYPE (TREE_TYPE (value));
1072 tree valclass = TYPE_NAME (valtype);
1075 /* When compiling from bytecode, we need to ensure that TYPE has
1077 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1079 load_class (type, 1);
1080 safe_layout_class (type);
1081 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1082 return error_mark_node;
1084 klass = TYPE_NAME (type);
1086 if (type == object_type_node || inherits_from_p (valtype, type))
1088 /* Anything except `null' is an instance of Object. Likewise,
1089 if the object is known to be an instance of the class, then
1090 we only need to check for `null'. */
1091 expr = build (COND_EXPR, itype,
1093 boolean_true_node, boolean_false_node);
1095 else if (DECL_P (klass) && DECL_P (valclass)
1096 && ! CLASS_INTERFACE (valclass)
1097 && ! CLASS_INTERFACE (klass)
1098 && ! inherits_from_p (type, valtype)
1099 && (CLASS_FINAL (klass)
1100 || ! inherits_from_p (valtype, type)))
1102 /* The classes are from different branches of the derivation
1103 tree, so we immediately know the answer. */
1104 expr = boolean_false_node;
1106 else if (DECL_P (klass) && CLASS_FINAL (klass))
1108 tree save = save_expr (value);
1109 expr = build (COND_EXPR, itype,
1111 build (EQ_EXPR, itype,
1112 build_get_class (save),
1113 build_class_ref (type)),
1114 boolean_false_node);
1118 expr = build (CALL_EXPR, itype,
1119 build_address_of (soft_instanceof_node),
1120 tree_cons (NULL_TREE, value,
1121 build_tree_list (NULL_TREE,
1122 build_class_ref (type))),
1125 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1130 expand_java_INSTANCEOF (type)
1133 tree value = pop_value (object_ptr_type_node);
1134 value = build_instanceof (value, type);
1139 expand_java_CHECKCAST (type)
1142 tree value = pop_value (ptr_type_node);
1143 value = build (CALL_EXPR, promote_type (type),
1144 build_address_of (soft_checkcast_node),
1145 tree_cons (NULL_TREE, build_class_ref (type),
1146 build_tree_list (NULL_TREE, value)),
1152 expand_iinc (local_var_index, ival, pc)
1153 unsigned int local_var_index;
1157 tree local_var, res;
1158 tree constant_value;
1160 flush_quick_stack ();
1161 local_var = find_local_variable (local_var_index, int_type_node, pc);
1162 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1163 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1164 expand_assignment (local_var, res, 0, 0);
1169 build_java_soft_divmod (op, type, op1, op2)
1171 tree type, op1, op2;
1174 tree arg1 = convert (type, op1);
1175 tree arg2 = convert (type, op2);
1177 if (type == int_type_node)
1181 case TRUNC_DIV_EXPR:
1182 call = soft_idiv_node;
1184 case TRUNC_MOD_EXPR:
1185 call = soft_irem_node;
1191 else if (type == long_type_node)
1195 case TRUNC_DIV_EXPR:
1196 call = soft_ldiv_node;
1198 case TRUNC_MOD_EXPR:
1199 call = soft_lrem_node;
1207 fatal ("Internal compiler error in build_java_soft_divmod");
1209 call = build (CALL_EXPR, type,
1210 build_address_of (call),
1211 tree_cons (NULL_TREE, arg1,
1212 build_tree_list (NULL_TREE, arg2)),
1219 build_java_binop (op, type, arg1, arg2)
1221 tree type, arg1, arg2;
1228 tree u_type = unsigned_type (type);
1229 arg1 = convert (u_type, arg1);
1230 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1231 return convert (type, arg1);
1235 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1236 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1239 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1240 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1241 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1243 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1244 boolean_type_node, arg1, arg2));
1245 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1246 tree second_compare = fold (build (COND_EXPR, int_type_node,
1247 ifexp2, integer_zero_node,
1248 op == COMPARE_L_EXPR
1249 ? integer_negative_one_node
1250 : integer_one_node));
1251 return fold (build (COND_EXPR, int_type_node, ifexp1,
1252 op == COMPARE_L_EXPR ? integer_one_node
1253 : integer_negative_one_node,
1257 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1259 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1260 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1261 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1262 ifexp2, integer_one_node,
1263 integer_zero_node));
1264 return fold (build (COND_EXPR, int_type_node,
1265 ifexp1, integer_negative_one_node, second_compare));
1267 case TRUNC_DIV_EXPR:
1268 case TRUNC_MOD_EXPR:
1269 if (TREE_CODE (type) == REAL_TYPE
1270 && op == TRUNC_MOD_EXPR)
1273 if (type != double_type_node)
1275 arg1 = convert (double_type_node, arg1);
1276 arg2 = convert (double_type_node, arg2);
1278 call = build (CALL_EXPR, double_type_node,
1279 build_address_of (soft_fmod_node),
1280 tree_cons (NULL_TREE, arg1,
1281 build_tree_list (NULL_TREE, arg2)),
1283 if (type != double_type_node)
1284 call = convert (type, call);
1288 if (TREE_CODE (type) == INTEGER_TYPE
1289 && flag_use_divide_subroutine
1290 && ! flag_syntax_only)
1291 return build_java_soft_divmod (op, type, arg1, arg2);
1296 return fold (build (op, type, arg1, arg2));
1300 expand_java_binop (type, op)
1301 tree type; enum tree_code op;
1311 rtype = int_type_node;
1312 rarg = pop_value (rtype);
1315 rarg = pop_value (rtype);
1317 larg = pop_value (ltype);
1318 push_value (build_java_binop (op, type, larg, rarg));
1321 /* Lookup the field named NAME in *TYPEP or its super classes.
1322 If not found, return NULL_TREE.
1323 (If the *TYPEP is not found, or if the field reference is
1324 ambiguous, return error_mark_node.)
1325 If found, return the FIELD_DECL, and set *TYPEP to the
1326 class containing the field. */
1329 lookup_field (typep, name)
1333 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1335 load_class (*typep, 1);
1336 safe_layout_class (*typep);
1337 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1338 return error_mark_node;
1342 tree field, basetype_vec;
1346 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1347 if (DECL_NAME (field) == name)
1350 /* If *typep is an innerclass, lookup the field in its enclosing
1352 if (INNER_CLASS_TYPE_P (*typep))
1354 tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1356 if ((field = lookup_field (&outer_type, name)))
1360 /* Process implemented interfaces. */
1361 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1362 n = TREE_VEC_LENGTH (basetype_vec);
1363 save_field = NULL_TREE;
1364 for (i = 0; i < n; i++)
1366 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1367 if ((field = lookup_field (&t, name)))
1369 if (save_field == field)
1371 if (save_field == NULL_TREE)
1375 tree i1 = DECL_CONTEXT (save_field);
1376 tree i2 = DECL_CONTEXT (field);
1377 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1378 IDENTIFIER_POINTER (name),
1379 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1380 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1381 return error_mark_node;
1386 if (save_field != NULL_TREE)
1389 *typep = CLASSTYPE_SUPER (*typep);
1394 /* Look up the field named NAME in object SELF_VALUE,
1395 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1396 SELF_VALUE is NULL_TREE if looking for a static field. */
1399 build_field_ref (self_value, self_class, name)
1400 tree self_value, self_class, name;
1402 tree base_class = self_class;
1403 tree field_decl = lookup_field (&base_class, name);
1404 if (field_decl == NULL_TREE)
1406 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1407 return error_mark_node;
1409 if (self_value == NULL_TREE)
1411 return build_static_field_ref (field_decl);
1415 tree base_handle_type = promote_type (base_class);
1416 if (base_handle_type != TREE_TYPE (self_value))
1417 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1418 #ifdef JAVA_USE_HANDLES
1419 self_value = unhand_expr (self_value);
1421 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1423 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1424 self_value, field_decl));
1434 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1435 name = get_identifier (buf);
1436 if (IDENTIFIER_LOCAL_VALUE (name))
1437 return IDENTIFIER_LOCAL_VALUE (name);
1440 /* The type of the address of a label is return_address_type_node. */
1441 tree decl = create_label_decl (name);
1442 LABEL_PC (decl) = pc;
1444 return pushdecl (decl);
1448 /* Generate a unique name for the purpose of loops and switches
1449 labels, and try-catch-finally blocks label or temporary variables. */
1454 static int l_number = 0;
1456 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1458 return get_identifier (buff);
1462 create_label_decl (name)
1466 push_obstacks (&permanent_obstack, &permanent_obstack);
1467 decl = build_decl (LABEL_DECL, name,
1468 TREE_TYPE (return_address_type_node));
1470 DECL_CONTEXT (decl) = current_function_decl;
1471 DECL_IGNORED_P (decl) = 1;
1475 /* This maps a bytecode offset (PC) to various flags. */
1476 char *instruction_bits;
1479 note_label (current_pc, target_pc)
1480 int current_pc ATTRIBUTE_UNUSED, target_pc;
1482 lookup_label (target_pc);
1483 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1486 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1487 where CONDITION is one of one the compare operators. */
1490 expand_compare (condition, value1, value2, target_pc)
1491 enum tree_code condition;
1492 tree value1, value2;
1495 tree target = lookup_label (target_pc);
1496 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1497 expand_start_cond (truthvalue_conversion (cond), 0);
1498 expand_goto (target);
1502 /* Emit code for a TEST-type opcode. */
1505 expand_test (condition, type, target_pc)
1506 enum tree_code condition;
1510 tree value1, value2;
1511 flush_quick_stack ();
1512 value1 = pop_value (type);
1513 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1514 expand_compare (condition, value1, value2, target_pc);
1517 /* Emit code for a COND-type opcode. */
1520 expand_cond (condition, type, target_pc)
1521 enum tree_code condition;
1525 tree value1, value2;
1526 flush_quick_stack ();
1527 /* note: pop values in opposite order */
1528 value2 = pop_value (type);
1529 value1 = pop_value (type);
1530 /* Maybe should check value1 and value2 for type compatibility ??? */
1531 expand_compare (condition, value1, value2, target_pc);
1535 expand_java_goto (target_pc)
1538 tree target_label = lookup_label (target_pc);
1539 flush_quick_stack ();
1540 expand_goto (target_label);
1545 expand_java_call (target_pc, return_address)
1546 int target_pc, return_address;
1548 tree target_label = lookup_label (target_pc);
1549 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1551 flush_quick_stack ();
1552 expand_goto (target_label);
1556 expand_java_ret (return_address)
1557 tree return_address ATTRIBUTE_UNUSED;
1559 warning ("ret instruction not implemented");
1561 tree target_label = lookup_label (target_pc);
1562 flush_quick_stack ();
1563 expand_goto (target_label);
1568 /* Recursive helper function to pop argument types during verifiation. */
1571 pop_argument_types (arg_types)
1574 if (arg_types == end_params_node)
1576 if (TREE_CODE (arg_types) == TREE_LIST)
1578 pop_argument_types (TREE_CHAIN (arg_types));
1579 pop_type (TREE_VALUE (arg_types));
1586 pop_arguments (arg_types)
1589 if (arg_types == end_params_node)
1591 if (TREE_CODE (arg_types) == TREE_LIST)
1593 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1594 tree type = TREE_VALUE (arg_types);
1595 tree arg = pop_value (type);
1596 if (PROMOTE_PROTOTYPES
1597 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1598 && INTEGRAL_TYPE_P (type))
1599 arg = convert (integer_type_node, arg);
1600 return tree_cons (NULL_TREE, arg, tail);
1605 /* Build an expression to initialize the class CLAS.
1606 if EXPR is non-NULL, returns an expression to first call the initializer
1607 (if it is needed) and then calls EXPR. */
1610 build_class_init (clas, expr)
1614 struct init_test_hash_entry *ite;
1615 if (inherits_from_p (current_class, clas))
1618 if (always_initialize_class_p)
1620 init = build (CALL_EXPR, void_type_node,
1621 build_address_of (soft_initclass_node),
1622 build_tree_list (NULL_TREE, build_class_ref (clas)),
1624 TREE_SIDE_EFFECTS (init) = 1;
1628 ite = (struct init_test_hash_entry *)
1629 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1630 (const hash_table_key) clas,
1633 if (ite->init_test_decl == 0)
1634 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1636 /* Tell the check-init code to ignore this decl. */
1637 DECL_BIT_INDEX(ite->init_test_decl) = -1;
1639 init = build (CALL_EXPR, void_type_node,
1640 build_address_of (soft_initclass_node),
1641 build_tree_list (NULL_TREE, build_class_ref (clas)),
1643 TREE_SIDE_EFFECTS (init) = 1;
1644 call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1645 build (MODIFY_EXPR, boolean_type_node,
1646 ite->init_test_decl, boolean_true_node));
1647 TREE_SIDE_EFFECTS (call) = 1;
1648 init = build (COND_EXPR, void_type_node,
1649 build (EQ_EXPR, boolean_type_node,
1650 ite->init_test_decl, boolean_false_node),
1651 call, integer_zero_node);
1652 TREE_SIDE_EFFECTS (init) = 1;
1655 if (expr != NULL_TREE)
1657 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1658 TREE_SIDE_EFFECTS (expr) = 1;
1665 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1666 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1667 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1670 if (is_compiled_class (self_type))
1672 make_decl_rtl (method, NULL, 1);
1673 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1677 /* We don't know whether the method has been (statically) compiled.
1678 Compile this code to get a reference to the method's code:
1680 SELF_TYPE->methods[METHOD_INDEX].ncode
1682 This is guaranteed to work (assuming SELF_TYPE has
1683 been initialized), since if the method is not compiled yet,
1684 its ncode points to a trampoline that forces compilation. */
1686 int method_index = 0;
1688 tree ref = build_class_ref (self_type);
1689 ref = build1 (INDIRECT_REF, class_type_node, ref);
1690 if (ncode_ident == NULL_TREE)
1691 ncode_ident = get_identifier ("ncode");
1692 if (methods_ident == NULL_TREE)
1693 methods_ident = get_identifier ("methods");
1694 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1695 lookup_field (&class_type_node, methods_ident));
1696 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1697 ; meth = TREE_CHAIN (meth))
1701 if (meth == NULL_TREE)
1702 fatal ("method '%s' not found in class",
1703 IDENTIFIER_POINTER (DECL_NAME (method)));
1706 method_index *= int_size_in_bytes (method_type_node);
1707 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1708 ref, build_int_2 (method_index, 0)));
1709 ref = build1 (INDIRECT_REF, method_type_node, ref);
1710 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1712 lookup_field (&method_type_node, ncode_ident));
1718 invoke_build_dtable (is_invoke_interface, arg_list)
1719 int is_invoke_interface;
1722 tree dtable, objectref;
1724 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1726 /* If we're dealing with interfaces and if the objectref
1727 argument is an array then get the dispatch table of the class
1728 Object rather than the one from the objectref. */
1729 objectref = (is_invoke_interface
1730 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1731 object_type_node : TREE_VALUE (arg_list));
1733 if (dtable_ident == NULL_TREE)
1734 dtable_ident = get_identifier ("vtable");
1735 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1736 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1737 lookup_field (&object_type_node, dtable_ident));
1743 build_invokevirtual (dtable, method)
1744 tree dtable, method;
1747 tree nativecode_ptr_ptr_type_node
1748 = build_pointer_type (nativecode_ptr_type_node);
1749 tree method_index = convert (sizetype, DECL_VINDEX (method));
1751 /* Add one to skip "class" field of dtable, and one to skip unused
1752 vtable entry (for C++ compatibility). */
1753 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1754 method_index = size_binop (MULT_EXPR, method_index,
1755 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1756 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1757 convert (nativecode_ptr_ptr_type_node, method_index)));
1758 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1764 build_invokeinterface (dtable, method)
1765 tree dtable, method;
1767 static tree class_ident = NULL_TREE;
1774 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1775 ensure that the selected method exists, is public and not
1776 abstract nor static. */
1778 if (class_ident == NULL_TREE)
1780 class_ident = get_identifier ("class");
1781 ggc_add_tree_root (&class_ident, 1);
1784 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1785 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1786 lookup_field (&dtable_type, class_ident));
1788 interface = DECL_CONTEXT (method);
1789 layout_class_methods (interface);
1792 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1796 idx = build_int_2 (i, 0);
1799 if (meth == NULL_TREE)
1800 fatal ("internal error in build_invokeinterface");
1803 lookup_arg = tree_cons (NULL_TREE, dtable,
1804 tree_cons (NULL_TREE, build_class_ref (interface),
1805 build_tree_list (NULL_TREE, idx)));
1807 return build (CALL_EXPR, ptr_type_node,
1808 build_address_of (soft_lookupinterfacemethod_node),
1809 lookup_arg, NULL_TREE);
1812 /* Expand one of the invoke_* opcodes.
1813 OCPODE is the specific opcode.
1814 METHOD_REF_INDEX is an index into the constant pool.
1815 NARGS is the number of arguments, or -1 if not specified. */
1818 expand_invoke (opcode, method_ref_index, nargs)
1820 int method_ref_index;
1821 int nargs ATTRIBUTE_UNUSED;
1823 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
1824 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
1825 tree self_type = get_class_constant
1826 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
1827 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1828 tree call, func, method, arg_list, method_type;
1829 tree cond = NULL_TREE;
1831 if (! CLASS_LOADED_P (self_type))
1833 load_class (self_type, 1);
1834 safe_layout_class (self_type);
1835 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1836 fatal ("failed to find class '%s'", self_name);
1838 layout_class_methods (self_type);
1840 if (ID_INIT_P (method_name))
1841 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1844 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1845 method_name, method_signature);
1846 if (method == NULL_TREE)
1848 error ("Class '%s' has no method named '%s' matching signature '%s'",
1850 IDENTIFIER_POINTER (method_name),
1851 IDENTIFIER_POINTER (method_signature));
1853 /* Invoke static can't invoke static/abstract method */
1854 else if (opcode == OPCODE_invokestatic)
1856 if (!METHOD_STATIC (method))
1858 error ("invokestatic on non static method");
1861 else if (METHOD_ABSTRACT (method))
1863 error ("invokestatic on abstract method");
1869 if (METHOD_STATIC (method))
1871 error ("invoke[non-static] on static method");
1876 if (method == NULL_TREE)
1878 method_type = get_type_from_signature (method_signature);
1879 pop_arguments (TYPE_ARG_TYPES (method_type));
1880 if (opcode != OPCODE_invokestatic)
1881 pop_type (self_type);
1882 method_type = promote_type (TREE_TYPE (method_type));
1883 push_value (convert (method_type, integer_zero_node));
1887 method_type = TREE_TYPE (method);
1888 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1889 flush_quick_stack ();
1892 if (opcode == OPCODE_invokestatic)
1893 func = build_known_method_ref (method, method_type, self_type,
1894 method_signature, arg_list);
1895 else if (opcode == OPCODE_invokespecial
1896 || (opcode == OPCODE_invokevirtual
1897 && (METHOD_PRIVATE (method)
1898 || METHOD_FINAL (method)
1899 || CLASS_FINAL (TYPE_NAME (self_type)))))
1901 /* If the object for the method call is null, we throw an
1902 exception. We don't do this if the object is the current
1903 method's `this'. In other cases we just rely on an
1904 optimization pass to eliminate redundant checks. FIXME:
1905 Unfortunately there doesn't seem to be a way to determine
1906 what the current method is right now. */
1907 /* We use a SAVE_EXPR here to make sure we only evaluate
1908 the new `self' expression once. */
1909 tree save_arg = save_expr (TREE_VALUE (arg_list));
1910 TREE_VALUE (arg_list) = save_arg;
1911 cond = build (EQ_EXPR, boolean_type_node, save_arg, null_pointer_node);
1912 func = build_known_method_ref (method, method_type, self_type,
1913 method_signature, arg_list);
1917 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1919 if (opcode == OPCODE_invokevirtual)
1920 func = build_invokevirtual (dtable, method);
1922 func = build_invokeinterface (dtable, method);
1924 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1925 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1926 TREE_SIDE_EFFECTS (call) = 1;
1928 if (cond != NULL_TREE)
1930 /* We have to make the `then' branch a compound expression to
1931 make the types turn out right. This seems bizarre. */
1932 call = build (COND_EXPR, TREE_TYPE (call), cond,
1933 build (COMPOUND_EXPR, TREE_TYPE (call),
1934 build (CALL_EXPR, void_type_node,
1935 build_address_of (soft_nullpointer_node),
1936 NULL_TREE, NULL_TREE),
1937 (FLOAT_TYPE_P (TREE_TYPE (call))
1938 ? build_real (TREE_TYPE (call), dconst0)
1939 : build1 (CONVERT_EXPR, TREE_TYPE (call),
1940 integer_zero_node))),
1942 TREE_SIDE_EFFECTS (call) = 1;
1945 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1946 expand_expr_stmt (call);
1950 flush_quick_stack ();
1954 /* Create a stub which will be put into the vtable but which will call
1958 build_jni_stub (method)
1961 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
1962 tree jni_func_type, tem;
1963 tree env_var, res_var = NULL_TREE, block;
1964 tree method_args, res_type;
1967 tree klass = DECL_CONTEXT (method);
1968 int from_class = ! CLASS_FROM_SOURCE_P (klass);
1969 klass = build_class_ref (klass);
1971 if (! METHOD_NATIVE (method) || ! flag_jni)
1974 DECL_ARTIFICIAL (method) = 1;
1975 DECL_EXTERNAL (method) = 0;
1977 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
1978 DECL_CONTEXT (env_var) = method;
1980 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
1982 res_var = build_decl (VAR_DECL, get_identifier ("res"),
1983 TREE_TYPE (TREE_TYPE (method)));
1984 DECL_CONTEXT (res_var) = method;
1985 TREE_CHAIN (env_var) = res_var;
1988 push_obstacks (&permanent_obstack, &permanent_obstack);
1989 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
1990 TREE_STATIC (meth_var) = 1;
1991 TREE_PUBLIC (meth_var) = 0;
1992 DECL_EXTERNAL (meth_var) = 0;
1993 make_decl_rtl (meth_var, NULL, 0);
1994 meth_var = pushdecl_top_level (meth_var);
1997 /* One strange way that the front ends are different is that they
1998 store arguments differently. */
2000 method_args = DECL_ARGUMENTS (method);
2002 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2003 block = build_block (env_var, NULL_TREE, NULL_TREE,
2004 method_args, NULL_TREE);
2005 TREE_SIDE_EFFECTS (block) = 1;
2006 /* When compiling from source we don't set the type of the block,
2007 because that will prevent patch_return from ever being run. */
2009 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2011 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2012 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2013 build (CALL_EXPR, ptr_type_node,
2014 build_address_of (soft_getjnienvnewframe_node),
2015 build_tree_list (NULL_TREE, klass),
2017 CAN_COMPLETE_NORMALLY (body) = 1;
2019 /* All the arguments to this method become arguments to the
2020 underlying JNI function. If we had to wrap object arguments in a
2021 special way, we would do that here. */
2023 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2024 args = tree_cons (NULL_TREE, tem, args);
2025 args = nreverse (args);
2026 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2028 /* For a static method the second argument is the class. For a
2029 non-static method the second argument is `this'; that is already
2030 available in the argument list. */
2031 if (METHOD_STATIC (method))
2033 args = tree_cons (NULL_TREE, klass, args);
2034 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2037 /* The JNIEnv structure is the first argument to the JNI function. */
2038 args = tree_cons (NULL_TREE, env_var, args);
2039 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2041 /* We call _Jv_LookupJNIMethod to find the actual underlying
2042 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2043 exception if this function is not found at runtime. */
2044 method_sig = build_java_signature (TREE_TYPE (method));
2046 build_tree_list (NULL_TREE,
2047 build_utf8_ref (unmangle_classname
2048 (IDENTIFIER_POINTER (method_sig),
2049 IDENTIFIER_LENGTH (method_sig))));
2050 tem = DECL_NAME (method);
2052 = tree_cons (NULL_TREE, klass,
2053 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2056 = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2059 jnifunc = build (COND_EXPR, ptr_type_node,
2061 build (MODIFY_EXPR, ptr_type_node,
2063 build (CALL_EXPR, ptr_type_node,
2064 build_address_of (soft_lookupjnimethod_node),
2065 lookup_arg, NULL_TREE)));
2067 /* Now we make the actual JNI call via the resulting function
2069 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2070 build1 (NOP_EXPR, jni_func_type, jnifunc),
2073 /* If the JNI call returned a result, capture it here. If we had to
2074 unwrap JNI object results, we would do that here. */
2075 if (res_var != NULL_TREE)
2076 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2079 TREE_SIDE_EFFECTS (call) = 1;
2080 CAN_COMPLETE_NORMALLY (call) = 1;
2082 body = build (COMPOUND_EXPR, void_type_node, body, call);
2083 TREE_SIDE_EFFECTS (body) = 1;
2085 /* Now free the environment we allocated. */
2086 call = build (CALL_EXPR, ptr_type_node,
2087 build_address_of (soft_jnipopsystemframe_node),
2088 build_tree_list (NULL_TREE, env_var),
2090 TREE_SIDE_EFFECTS (call) = 1;
2091 CAN_COMPLETE_NORMALLY (call) = 1;
2092 body = build (COMPOUND_EXPR, void_type_node, body, call);
2093 TREE_SIDE_EFFECTS (body) = 1;
2095 /* Finally, do the return. When compiling from source we rely on
2096 patch_return to patch the return value -- because DECL_RESULT is
2097 not set at the time this function is called. */
2100 res_type = void_type_node;
2101 if (res_var != NULL_TREE)
2104 if (! DECL_RESULT (method))
2106 /* Make sure we copy the result variable to the actual
2107 result. We use the type of the DECL_RESULT because it
2108 might be different from the return type of the function:
2109 it might be promoted. */
2110 drt = TREE_TYPE (DECL_RESULT (method));
2111 if (drt != TREE_TYPE (res_var))
2112 res_var = build1 (CONVERT_EXPR, drt, res_var);
2113 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2114 TREE_SIDE_EFFECTS (res_var) = 1;
2119 /* This is necessary to get patch_return to run. */
2120 res_type = NULL_TREE;
2122 body = build (COMPOUND_EXPR, void_type_node, body,
2123 build1 (RETURN_EXPR, res_type, res_var));
2124 TREE_SIDE_EFFECTS (body) = 1;
2126 BLOCK_EXPR_BODY (block) = body;
2130 /* Expand an operation to extract from or store into a field.
2131 IS_STATIC is 1 iff the field is static.
2132 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2133 FIELD_REF_INDEX is an index into the constant pool. */
2136 expand_java_field_op (is_static, is_putting, field_ref_index)
2139 int field_ref_index;
2142 get_class_constant (current_jcf,
2143 COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
2145 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2146 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
2147 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool,
2149 tree field_type = get_type_from_signature (field_signature);
2150 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2153 tree field_decl = lookup_field (&self_type, field_name);
2154 if (field_decl == error_mark_node)
2158 else if (field_decl == NULL_TREE)
2160 error ("Missing field '%s' in '%s'",
2161 IDENTIFIER_POINTER (field_name), self_name);
2164 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2166 error ("Mismatching signature for field '%s' in '%s'",
2167 IDENTIFIER_POINTER (field_name), self_name);
2170 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2174 push_value (convert (field_type, integer_zero_node));
2175 flush_quick_stack ();
2179 /* Inline references to java.lang.PRIMTYPE.TYPE.
2180 In addition to being a useful (minor) optimization,
2181 this is also needed to avoid circularities in the implementation
2182 of these fields in libjava. */
2183 if (field_name == TYPE_identifier_node && ! is_putting
2184 && ! flag_emit_class_files && field_type == class_ptr_type
2185 && strncmp (self_name, "java.lang.", 10) == 0)
2187 tree typ = build_primtype_type_ref (self_name);
2195 field_ref = build_field_ref (field_ref, self_type, field_name);
2197 field_ref = build_class_init (self_type, field_ref);
2200 flush_quick_stack ();
2201 if (FIELD_FINAL (field_decl))
2203 if (DECL_CONTEXT (field_decl) != current_class)
2204 error_with_decl (field_decl,
2205 "assignment to final field `%s' not in field's class");
2206 else if (FIELD_STATIC (field_decl))
2208 if (!DECL_CLINIT_P (current_function_decl))
2209 error_with_decl (field_decl,
2210 "assignment to final static field `%s' not in class initializer");
2214 tree cfndecl_name = DECL_NAME (current_function_decl);
2215 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2216 && !ID_FINIT_P (cfndecl_name))
2217 error_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2220 expand_assignment (field_ref, new_value, 0, 0);
2223 push_value (field_ref);
2227 build_primtype_type_ref (self_name)
2228 const char *self_name;
2230 const char *class_name = self_name+10;
2232 if (strncmp(class_name, "Byte", 4) == 0)
2233 typ = byte_type_node;
2234 else if (strncmp(class_name, "Short", 5) == 0)
2235 typ = short_type_node;
2236 else if (strncmp(class_name, "Integer", 7) == 0)
2237 typ = int_type_node;
2238 else if (strncmp(class_name, "Long", 4) == 0)
2239 typ = long_type_node;
2240 else if (strncmp(class_name, "Float", 5) == 0)
2241 typ = float_type_node;
2242 else if (strncmp(class_name, "Double", 6) == 0)
2243 typ = double_type_node;
2244 else if (strncmp(class_name, "Boolean", 7) == 0)
2245 typ = boolean_type_node;
2246 else if (strncmp(class_name, "Char", 4) == 0)
2247 typ = char_type_node;
2248 else if (strncmp(class_name, "Void", 4) == 0)
2249 typ = void_type_node;
2252 if (typ != NULL_TREE)
2253 return build_class_ref (typ);
2259 load_type_state (label)
2263 tree vec = LABEL_TYPE_STATE (label);
2264 int cur_length = TREE_VEC_LENGTH (vec);
2265 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2266 for (i = 0; i < cur_length; i++)
2267 type_map [i] = TREE_VEC_ELT (vec, i);
2270 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2271 dependant things, but they rely on gcc routines. This function is
2272 placed here because it uses things defined locally in parse.y. */
2275 case_identity (t, v)
2276 tree t __attribute__ ((__unused__));
2282 /* Return the name of the vtable for an array of a given primitive
2285 get_primitive_array_vtable (tree elt)
2288 if (elt == boolean_type_node)
2289 r = boolean_array_vtable;
2290 else if (elt == byte_type_node)
2291 r = byte_array_vtable;
2292 else if (elt == char_type_node)
2293 r = char_array_vtable;
2294 else if (elt == short_type_node)
2295 r = short_array_vtable;
2296 else if (elt == int_type_node)
2297 r = int_array_vtable;
2298 else if (elt == long_type_node)
2299 r = long_array_vtable;
2300 else if (elt == float_type_node)
2301 r = float_array_vtable;
2302 else if (elt == double_type_node)
2303 r = double_array_vtable;
2306 return build_address_of (r);
2310 java_lang_expand_expr (exp, target, tmode, modifier)
2312 rtx target ATTRIBUTE_UNUSED;
2313 enum machine_mode tmode ATTRIBUTE_UNUSED;
2314 enum expand_modifier modifier ATTRIBUTE_UNUSED;
2318 switch (TREE_CODE (exp))
2320 case NEW_ARRAY_INIT:
2323 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2324 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2325 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2326 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2327 tree length = build_int_2 (ilength, 0);
2328 tree init = TREE_OPERAND (exp, 0);
2331 /* See if we can generate the array statically. */
2332 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2333 && JPRIMITIVE_TYPE_P (element_type))
2335 tree temp, value, init_decl;
2337 push_obstacks (&permanent_obstack, &permanent_obstack);
2338 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2339 PUSH_FIELD_VALUE (temp, "vtable",
2340 get_primitive_array_vtable (element_type));
2341 if (! flag_hash_synchronization)
2342 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2343 FINISH_RECORD_CONSTRUCTOR (temp);
2344 START_RECORD_CONSTRUCTOR (value, array_type);
2345 PUSH_SUPER_VALUE (value, temp);
2346 /* FIXME: build a new `length' here to get it on the right
2348 PUSH_FIELD_VALUE (value, "length", build_int_2 (ilength, 0));
2349 PUSH_FIELD_VALUE (value, "data", init);
2350 FINISH_RECORD_CONSTRUCTOR (value);
2352 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2353 pushdecl_top_level (init_decl);
2354 TREE_STATIC (init_decl) = 1;
2355 DECL_INITIAL (init_decl) = value;
2356 DECL_IGNORED_P (init_decl) = 1;
2357 TREE_READONLY (init_decl) = 1;
2358 make_decl_rtl (init_decl, NULL, 1);
2359 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2360 r = expand_expr (init, target, tmode, modifier);
2365 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2366 expand_decl (array_decl);
2367 tmp = expand_assignment (array_decl,
2368 build_new_array (element_type, length),
2370 if (TREE_CONSTANT (init)
2371 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2374 push_obstacks (&permanent_obstack, &permanent_obstack);
2375 init_decl = build_decl (VAR_DECL, generate_name (),
2377 pushdecl_top_level (init_decl);
2378 TREE_STATIC (init_decl) = 1;
2379 DECL_INITIAL (init_decl) = init;
2380 DECL_IGNORED_P (init_decl) = 1;
2381 TREE_READONLY (init_decl) = 1;
2382 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2383 make_decl_rtl (init_decl, NULL, 1);
2387 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2388 build1 (INDIRECT_REF, array_type,
2389 array_decl), data_fld), init, 0, 0);
2393 if (BLOCK_EXPR_BODY (exp))
2396 tree body = BLOCK_EXPR_BODY (exp);
2397 pushlevel (2); /* 2 and above */
2398 expand_start_bindings (0);
2399 local = BLOCK_EXPR_DECLS (exp);
2402 tree next = TREE_CHAIN (local);
2403 layout_decl (local, 0);
2404 expand_decl (pushdecl (local));
2407 /* Avoid deep recursion for long block. */
2408 while (TREE_CODE (body) == COMPOUND_EXPR)
2410 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2412 body = TREE_OPERAND (body, 1);
2414 expand_expr (body, const0_rtx, VOIDmode, 0);
2417 expand_end_bindings (getdecls (), 1, 0);
2425 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2426 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2429 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2431 (wfl_operator, "Duplicate case label: `%s'",
2432 print_int_node (TREE_OPERAND (exp, 0)));
2438 pushcase (NULL_TREE, 0,
2439 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2443 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2444 expand_expr_stmt (TREE_OPERAND (exp, 1));
2445 expand_end_case (TREE_OPERAND (exp, 0));
2449 /* We expand a try[-catch] block */
2451 /* Expand the try block */
2452 push_obstacks (&permanent_obstack, &permanent_obstack);
2453 expand_eh_region_start ();
2455 expand_expr_stmt (TREE_OPERAND (exp, 0));
2456 push_obstacks (&permanent_obstack, &permanent_obstack);
2457 expand_start_all_catch ();
2460 /* Expand all catch clauses (EH handlers) */
2461 for (current = TREE_OPERAND (exp, 1); current;
2462 current = TREE_CHAIN (current))
2465 tree catch = TREE_OPERAND (current, 0);
2466 tree decl = BLOCK_EXPR_DECLS (catch);
2467 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2468 start_catch_handler (prepare_eh_table_type (type));
2469 expand_expr_stmt (TREE_OPERAND (current, 0));
2471 expand_resume_after_catch ();
2472 end_catch_handler ();
2474 expand_end_all_catch ();
2478 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2479 tree_code_name [TREE_CODE (exp)]);
2483 /* Go over METHOD's bytecode and note instruction starts in
2484 instruction_bits[]. */
2487 note_instructions (jcf, method)
2492 unsigned char* byte_ops;
2493 long length = DECL_CODE_LENGTH (method);
2498 #undef RET /* Defined by config/i386/i386.h */
2499 #undef AND /* Causes problems with opcodes for iand and land. */
2501 #define BCODE byte_ops
2502 #define BYTE_type_node byte_type_node
2503 #define SHORT_type_node short_type_node
2504 #define INT_type_node int_type_node
2505 #define LONG_type_node long_type_node
2506 #define CHAR_type_node char_type_node
2507 #define PTR_type_node ptr_type_node
2508 #define FLOAT_type_node float_type_node
2509 #define DOUBLE_type_node double_type_node
2510 #define VOID_type_node void_type_node
2511 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2512 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2513 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2514 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2516 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2518 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2519 byte_ops = jcf->read_ptr;
2520 instruction_bits = oballoc (length + 1);
2521 bzero (instruction_bits, length + 1);
2523 /* This pass figures out which PC can be the targets of jumps. */
2524 for (PC = 0; PC < length;)
2526 int oldpc = PC; /* PC at instruction start. */
2527 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2528 switch (byte_ops[PC++])
2530 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2532 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2535 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2537 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2538 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2539 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2540 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2541 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2542 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2543 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2544 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2546 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2547 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2548 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2549 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2550 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2551 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2552 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2553 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2555 /* two forms of wide instructions */
2556 #define PRE_SPECIAL_WIDE(IGNORE) \
2558 int modified_opcode = IMMEDIATE_u1; \
2559 if (modified_opcode == OPCODE_iinc) \
2561 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2562 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2566 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2570 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2572 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2574 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2575 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2576 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2577 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2578 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2579 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2580 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2581 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2582 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2583 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2585 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2586 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2587 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2588 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2589 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2590 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2591 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2592 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2594 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2596 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2597 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2599 #define PRE_LOOKUP_SWITCH \
2600 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2601 NOTE_LABEL (default_offset+oldpc); \
2603 while (--npairs >= 0) { \
2604 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2605 jint offset = IMMEDIATE_s4; \
2606 NOTE_LABEL (offset+oldpc); } \
2609 #define PRE_TABLE_SWITCH \
2610 { jint default_offset = IMMEDIATE_s4; \
2611 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2612 NOTE_LABEL (default_offset+oldpc); \
2614 while (low++ <= high) { \
2615 jint offset = IMMEDIATE_s4; \
2616 NOTE_LABEL (offset+oldpc); } \
2619 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2620 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2621 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2622 (void)(IMMEDIATE_u2); \
2623 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2625 #include "javaop.def"
2632 expand_byte_code (jcf, method)
2638 const unsigned char *linenumber_pointer;
2639 int dead_code_index = -1;
2640 unsigned char* byte_ops;
2641 long length = DECL_CODE_LENGTH (method);
2644 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2645 byte_ops = jcf->read_ptr;
2647 /* We make an initial pass of the line number table, to note
2648 which instructions have associated line number entries. */
2649 linenumber_pointer = linenumber_table;
2650 for (i = 0; i < linenumber_count; i++)
2652 int pc = GET_u2 (linenumber_pointer);
2653 linenumber_pointer += 4;
2655 warning ("invalid PC in line number table");
2658 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2659 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2660 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2664 if (! verify_jvm_instructions (jcf, byte_ops, length))
2667 /* Translate bytecodes to rtl instructions. */
2668 linenumber_pointer = linenumber_table;
2669 for (PC = 0; PC < length;)
2671 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2673 tree label = lookup_label (PC);
2674 flush_quick_stack ();
2675 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2676 expand_label (label);
2677 if (LABEL_VERIFIED (label) || PC == 0)
2678 load_type_state (label);
2681 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2683 if (dead_code_index == -1)
2685 /* This is the start of a region of unreachable bytecodes.
2686 They still need to be processed in order for EH ranges
2687 to get handled correctly. However, we can simply
2688 replace these bytecodes with nops. */
2689 dead_code_index = PC;
2692 /* Turn this bytecode into a nop. */
2697 if (dead_code_index != -1)
2699 /* We've just reached the end of a region of dead code. */
2700 warning ("Unreachable bytecode from %d to before %d.",
2701 dead_code_index, PC);
2702 dead_code_index = -1;
2706 /* Handle possible line number entry for this PC.
2708 This code handles out-of-order and multiple linenumbers per PC,
2709 but is optimized for the case of line numbers increasing
2710 monotonically with PC. */
2711 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2713 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2714 || GET_u2 (linenumber_pointer) != PC)
2715 linenumber_pointer = linenumber_table;
2716 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2718 int pc = GET_u2 (linenumber_pointer);
2719 linenumber_pointer += 4;
2722 lineno = GET_u2 (linenumber_pointer - 2);
2723 emit_line_note (input_filename, lineno);
2724 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2729 maybe_pushlevels (PC);
2730 PC = process_jvm_instruction (PC, byte_ops, length);
2731 maybe_poplevels (PC);
2734 if (dead_code_index != -1)
2736 /* We've just reached the end of a region of dead code. */
2737 warning ("Unreachable bytecode from %d to the end of the method.",
2743 java_push_constant_from_pool (jcf, index)
2748 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2751 push_obstacks (&permanent_obstack, &permanent_obstack);
2752 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2753 index = alloc_name_constant (CONSTANT_String, name);
2754 c = build_ref_from_constant_pool (index);
2755 TREE_TYPE (c) = promote_type (string_type_node);
2759 c = get_constant (jcf, index);
2764 process_jvm_instruction (PC, byte_ops, length)
2766 const unsigned char* byte_ops;
2767 long length ATTRIBUTE_UNUSED;
2769 const char *opname; /* Temporary ??? */
2770 int oldpc = PC; /* PC at instruction start. */
2772 /* If the instruction is at the beginning of a exception handler,
2773 replace the top of the stack with the thrown object reference */
2774 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2776 tree type = pop_type (ptr_type_node);
2777 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2780 switch (byte_ops[PC++])
2782 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2785 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2788 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2790 int saw_index = 0; \
2791 int index = OPERAND_VALUE; \
2792 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2795 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2797 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2798 tree ret = lookup_label (PC); \
2799 build_java_jsr (where, ret); \
2800 load_type_state (ret); \
2803 /* Push a constant onto the stack. */
2804 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2805 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2806 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2807 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2809 /* internal macro added for use by the WIDE case */
2810 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2811 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2813 /* Push local variable onto the opcode stack. */
2814 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2816 /* have to do this since OPERAND_VALUE may have side-effects */ \
2817 int opvalue = OPERAND_VALUE; \
2818 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2821 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2822 expand_java_return (OPERAND_TYPE##_type_node)
2824 #define REM_EXPR TRUNC_MOD_EXPR
2825 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2826 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2828 #define FIELD(IS_STATIC, IS_PUT) \
2829 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2831 #define TEST(OPERAND_TYPE, CONDITION) \
2832 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2834 #define COND(OPERAND_TYPE, CONDITION) \
2835 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2837 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2838 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2840 #define BRANCH_GOTO(OPERAND_VALUE) \
2841 expand_java_goto (oldpc + OPERAND_VALUE)
2843 #define BRANCH_CALL(OPERAND_VALUE) \
2844 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2847 #define BRANCH_RETURN(OPERAND_VALUE) \
2849 tree type = OPERAND_TYPE##_type_node; \
2850 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2851 expand_java_ret (value); \
2855 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2856 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2857 fprintf (stderr, "(not implemented)\n")
2858 #define NOT_IMPL1(OPERAND_VALUE) \
2859 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2860 fprintf (stderr, "(not implemented)\n")
2862 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2864 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2866 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2868 #define STACK_SWAP(COUNT) java_stack_swap()
2870 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2871 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2872 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2874 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2875 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2877 #define LOOKUP_SWITCH \
2878 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2879 tree selector = pop_value (INT_type_node); \
2880 tree duplicate, label; \
2881 tree type = TREE_TYPE (selector); \
2882 flush_quick_stack (); \
2883 expand_start_case (0, selector, type, "switch statement");\
2884 push_momentary (); \
2885 while (--npairs >= 0) \
2887 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2888 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2889 TREE_TYPE (value) = type; \
2890 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2891 pushcase (value, convert, label, &duplicate); \
2892 expand_java_goto (oldpc + offset); \
2894 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2895 pushcase (NULL_TREE, 0, label, &duplicate); \
2896 expand_java_goto (oldpc + default_offset); \
2898 expand_end_case (selector); \
2901 #define TABLE_SWITCH \
2902 { jint default_offset = IMMEDIATE_s4; \
2903 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2904 tree selector = pop_value (INT_type_node); \
2905 tree duplicate, label; \
2906 tree type = TREE_TYPE (selector); \
2907 flush_quick_stack (); \
2908 expand_start_case (0, selector, type, "switch statement");\
2909 push_momentary (); \
2910 for (; low <= high; low++) \
2912 jint offset = IMMEDIATE_s4; \
2913 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2914 TREE_TYPE (value) = type; \
2915 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2916 pushcase (value, convert, label, &duplicate); \
2917 expand_java_goto (oldpc + offset); \
2919 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2920 pushcase (NULL_TREE, 0, label, &duplicate); \
2921 expand_java_goto (oldpc + default_offset); \
2923 expand_end_case (selector); \
2926 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2927 { int opcode = byte_ops[PC-1]; \
2928 int method_ref_index = IMMEDIATE_u2; \
2930 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2932 expand_invoke (opcode, method_ref_index, nargs); \
2935 /* Handle new, checkcast, instanceof */
2936 #define OBJECT(TYPE, OP) \
2937 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2939 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2941 #define ARRAY_LOAD(OPERAND_TYPE) \
2943 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2946 #define ARRAY_STORE(OPERAND_TYPE) \
2948 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2951 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2952 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2953 #define ARRAY_NEW_PTR() \
2954 push_value (build_anewarray (get_class_constant (current_jcf, \
2956 pop_value (int_type_node)));
2957 #define ARRAY_NEW_NUM() \
2959 int atype = IMMEDIATE_u1; \
2960 push_value (build_newarray (atype, pop_value (int_type_node)));\
2962 #define ARRAY_NEW_MULTI() \
2964 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2965 int ndims = IMMEDIATE_u1; \
2966 expand_java_multianewarray( class, ndims ); \
2969 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2970 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2971 pop_value (OPERAND_TYPE##_type_node))));
2973 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2975 push_value (build1 (NOP_EXPR, int_type_node, \
2976 (convert (TO_TYPE##_type_node, \
2977 pop_value (FROM_TYPE##_type_node))))); \
2980 #define CONVERT(FROM_TYPE, TO_TYPE) \
2982 push_value (convert (TO_TYPE##_type_node, \
2983 pop_value (FROM_TYPE##_type_node))); \
2986 /* internal macro added for use by the WIDE case
2987 Added TREE_TYPE (decl) assignment, apbianco */
2988 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2991 int var = OPVALUE; \
2992 tree type = OPTYPE; \
2993 value = pop_value (type); \
2994 type = TREE_TYPE (value); \
2995 decl = find_local_variable (var, type, oldpc); \
2996 set_local_type (var, type ); \
2997 expand_assignment (decl, value, 0, 0); \
3000 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3002 /* have to do this since OPERAND_VALUE may have side-effects */ \
3003 int opvalue = OPERAND_VALUE; \
3004 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3007 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3008 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3010 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3011 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3013 #define MONITOR_OPERATION(call) \
3015 tree o = pop_value (ptr_type_node); \
3017 flush_quick_stack (); \
3018 c = build_java_monitor (call, o); \
3019 TREE_SIDE_EFFECTS (c) = 1; \
3020 expand_expr_stmt (c); \
3023 #define SPECIAL_IINC(IGNORED) \
3025 unsigned int local_var_index = IMMEDIATE_u1; \
3026 int ival = IMMEDIATE_s1; \
3027 expand_iinc(local_var_index, ival, oldpc); \
3030 #define SPECIAL_WIDE(IGNORED) \
3032 int modified_opcode = IMMEDIATE_u1; \
3033 unsigned int local_var_index = IMMEDIATE_u2; \
3034 switch (modified_opcode) \
3038 int ival = IMMEDIATE_s2; \
3039 expand_iinc (local_var_index, ival, oldpc); \
3042 case OPCODE_iload: \
3043 case OPCODE_lload: \
3044 case OPCODE_fload: \
3045 case OPCODE_dload: \
3046 case OPCODE_aload: \
3048 /* duplicate code from LOAD macro */ \
3049 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3052 case OPCODE_istore: \
3053 case OPCODE_lstore: \
3054 case OPCODE_fstore: \
3055 case OPCODE_dstore: \
3056 case OPCODE_astore: \
3058 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3062 error ("unrecogized wide sub-instruction"); \
3066 #define SPECIAL_THROW(IGNORED) \
3067 build_java_athrow (pop_value (throwable_type_node))
3069 #define SPECIAL_BREAK NOT_IMPL1
3070 #define IMPL NOT_IMPL
3072 #include "javaop.def"
3075 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3080 /* Return the opcode at PC in the code section pointed to by
3083 static unsigned char
3084 peek_opcode_at_pc (jcf, code_offset, pc)
3086 int code_offset, pc;
3088 unsigned char opcode;
3089 long absolute_offset = (long)JCF_TELL (jcf);
3091 JCF_SEEK (jcf, code_offset);
3092 opcode = jcf->read_ptr [pc];
3093 JCF_SEEK (jcf, absolute_offset);
3097 /* Some bytecode compilers are emitting accurate LocalVariableTable
3098 attributes. Here's an example:
3103 Attribute "LocalVariableTable"
3104 slot #<n>: ... (PC: PC+1 length: L)
3106 This is accurate because the local in slot <n> really exists after
3107 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3109 This procedure recognizes this situation and extends the live range
3110 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3111 length of the store instruction.)
3113 This function is used by `give_name_to_locals' so that a local's
3114 DECL features a DECL_LOCAL_START_PC such that the first related
3115 store operation will use DECL as a destination, not a unrelated
3116 temporary created for the occasion.
3118 This function uses a global (instruction_bits) `note_instructions' should
3119 have allocated and filled properly. */
3122 maybe_adjust_start_pc (jcf, code_offset, start_pc, slot)
3124 int code_offset, start_pc, slot;
3126 int first, index, opcode;
3135 /* Find last previous instruction and remember it */
3136 for (pc = start_pc-1; pc; pc--)
3137 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3141 /* Retrieve the instruction, handle `wide'. */
3142 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3143 if (opcode == OPCODE_wide)
3146 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3151 case OPCODE_astore_0:
3152 case OPCODE_astore_1:
3153 case OPCODE_astore_2:
3154 case OPCODE_astore_3:
3155 first = OPCODE_astore_0;
3158 case OPCODE_istore_0:
3159 case OPCODE_istore_1:
3160 case OPCODE_istore_2:
3161 case OPCODE_istore_3:
3162 first = OPCODE_istore_0;
3165 case OPCODE_lstore_0:
3166 case OPCODE_lstore_1:
3167 case OPCODE_lstore_2:
3168 case OPCODE_lstore_3:
3169 first = OPCODE_lstore_0;
3172 case OPCODE_fstore_0:
3173 case OPCODE_fstore_1:
3174 case OPCODE_fstore_2:
3175 case OPCODE_fstore_3:
3176 first = OPCODE_fstore_0;
3179 case OPCODE_dstore_0:
3180 case OPCODE_dstore_1:
3181 case OPCODE_dstore_2:
3182 case OPCODE_dstore_3:
3183 first = OPCODE_dstore_0;
3191 index = peek_opcode_at_pc (jcf, code_offset, pc);
3194 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3195 index = (other << 8) + index;
3200 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3201 means we have a <t>store. */
3202 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3208 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3209 order, as specified by Java Language Specification.
3211 The problem is that while expand_expr will evaluate its sub-operands in
3212 left-to-right order, for variables it will just return an rtx (i.e.
3213 an lvalue) for the variable (rather than an rvalue). So it is possible
3214 that a later sub-operand will change the register, and when the
3215 actual operation is done, it will use the new value, when it should
3216 have used the original value.
3218 We fix this by using save_expr. This forces the sub-operand to be
3219 copied into a fresh virtual register,
3221 For method invocation, we modify the arguments so that a
3222 left-to-right order evaluation is performed. Saved expressions
3223 will, in CALL_EXPR order, be reused when the call will be expanded.
3227 force_evaluation_order (node)
3230 if (flag_syntax_only)
3232 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3234 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3235 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3237 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
3241 if (!TREE_OPERAND (node, 1))
3244 /* This reverses the evaluation order. This is a desired effect. */
3245 for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1);
3246 arg; arg = TREE_CHAIN (arg))
3248 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3249 cmp = (cmp == NULL_TREE ? saved :
3250 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3251 TREE_VALUE (arg) = saved;
3254 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3255 TREE_SIDE_EFFECTS (cmp) = 1;
3259 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3260 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3261 TREE_SIDE_EFFECTS (cmp) = 1;