* alias.c (adjust_offset_for_component_ref): Use
[official-gcc.git] / gcc / java / expr.c
blob446f8afe2db45907a6f0e4f62a070bfd6809987a
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
28 #include "config.h"
29 #include "system.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "tree.h"
33 #include "real.h"
34 #include "rtl.h"
35 #include "flags.h"
36 #include "expr.h"
37 #include "java-tree.h"
38 #include "javaop.h"
39 #include "java-opcodes.h"
40 #include "jcf.h"
41 #include "java-except.h"
42 #include "parse.h"
43 #include "toplev.h"
44 #include "except.h"
45 #include "ggc.h"
46 #include "tree-gimple.h"
47 #include "target.h"
49 static void flush_quick_stack (void);
50 static void push_value (tree);
51 static tree pop_value (tree);
52 static void java_stack_swap (void);
53 static void java_stack_dup (int, int);
54 static void build_java_athrow (tree);
55 static void build_java_jsr (int, int);
56 static void build_java_ret (tree);
57 static void expand_java_multianewarray (tree, int);
58 static void expand_java_arraystore (tree);
59 static void expand_java_arrayload (tree);
60 static void expand_java_array_length (void);
61 static tree build_java_monitor (tree, tree);
62 static void expand_java_pushc (int, tree);
63 static void expand_java_return (tree);
64 static void expand_load_internal (int, tree, int);
65 static void expand_java_NEW (tree);
66 static void expand_java_INSTANCEOF (tree);
67 static void expand_java_CHECKCAST (tree);
68 static void expand_iinc (unsigned int, int, int);
69 static void expand_java_binop (tree, enum tree_code);
70 static void note_label (int, int);
71 static void expand_compare (enum tree_code, tree, tree, int);
72 static void expand_test (enum tree_code, tree, int);
73 static void expand_cond (enum tree_code, tree, int);
74 static void expand_java_goto (int);
75 static tree expand_java_switch (tree, int);
76 static void expand_java_add_case (tree, int, int);
77 #if 0
78 static void expand_java_call (int, int);
79 static void expand_java_ret (tree);
80 #endif
81 static tree pop_arguments (tree);
82 static void expand_invoke (int, int, int);
83 static void expand_java_field_op (int, int, int);
84 static void java_push_constant_from_pool (struct JCF *, int);
85 static void java_stack_pop (int);
86 static tree build_java_throw_out_of_bounds_exception (tree);
87 static tree build_java_check_indexed_type (tree, tree);
88 static tree case_identity (tree, tree);
89 static unsigned char peek_opcode_at_pc (struct JCF *, int, int);
90 static int emit_init_test_initialization (void **entry, void * ptr);
92 static GTY(()) tree operand_type[59];
94 static GTY(()) tree methods_ident;
95 static GTY(()) tree ncode_ident;
96 tree dtable_ident = NULL_TREE;
98 /* Set to nonzero value in order to emit class initialization code
99 before static field references. */
100 /* FIXME: Make this work with gimplify. */
101 int always_initialize_class_p = 1;
103 /* We store the stack state in two places:
104 Within a basic block, we use the quick_stack, which is a
105 pushdown list (TREE_LISTs) of expression nodes.
106 This is the top part of the stack; below that we use find_stack_slot.
107 At the end of a basic block, the quick_stack must be flushed
108 to the stack slot array (as handled by find_stack_slot).
109 Using quick_stack generates better code (especially when
110 compiled without optimization), because we do not have to
111 explicitly store and load trees to temporary variables.
113 If a variable is on the quick stack, it means the value of variable
114 when the quick stack was last flushed. Conceptually, flush_quick_stack
115 saves all the the quick_stack elements in parallel. However, that is
116 complicated, so it actually saves them (i.e. copies each stack value
117 to is home virtual register) from low indexes. This allows a quick_stack
118 element at index i (counting from the bottom of stack the) to references
119 slot virtuals for register that are >= i, but not those that are deeper.
120 This convention makes most operations easier. For example iadd works
121 even when the stack contains (reg[0], reg[1]): It results in the
122 stack containing (reg[0]+reg[1]), which is OK. However, some stack
123 operations are more complicated. For example dup given a stack
124 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
125 the convention, since stack value 1 would refer to a register with
126 lower index (reg[0]), which flush_quick_stack does not safely handle.
127 So dup cannot just add an extra element to the quick_stack, but iadd can.
130 static GTY(()) tree quick_stack;
132 /* A free-list of unused permanent TREE_LIST nodes. */
133 static GTY((deletable)) tree tree_list_free_list;
135 /* The stack pointer of the Java virtual machine.
136 This does include the size of the quick_stack. */
138 int stack_pointer;
140 const unsigned char *linenumber_table;
141 int linenumber_count;
143 void
144 init_expr_processing (void)
146 operand_type[21] = operand_type[54] = int_type_node;
147 operand_type[22] = operand_type[55] = long_type_node;
148 operand_type[23] = operand_type[56] = float_type_node;
149 operand_type[24] = operand_type[57] = double_type_node;
150 operand_type[25] = operand_type[58] = ptr_type_node;
153 tree
154 java_truthvalue_conversion (tree expr)
156 /* It is simpler and generates better code to have only TRUTH_*_EXPR
157 or comparison expressions as truth values at this level.
159 This function should normally be identity for Java. */
161 switch (TREE_CODE (expr))
163 case EQ_EXPR: case NE_EXPR: case UNEQ_EXPR: case LTGT_EXPR:
164 case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
165 case UNLE_EXPR: case UNGE_EXPR: case UNLT_EXPR: case UNGT_EXPR:
166 case ORDERED_EXPR: case UNORDERED_EXPR:
167 case TRUTH_ANDIF_EXPR:
168 case TRUTH_ORIF_EXPR:
169 case TRUTH_AND_EXPR:
170 case TRUTH_OR_EXPR:
171 case TRUTH_XOR_EXPR:
172 case TRUTH_NOT_EXPR:
173 case ERROR_MARK:
174 return expr;
176 case INTEGER_CST:
177 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
179 case REAL_CST:
180 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
182 /* are these legal? XXX JH */
183 case NEGATE_EXPR:
184 case ABS_EXPR:
185 case FLOAT_EXPR:
186 /* These don't change whether an object is nonzero or zero. */
187 return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
189 case COND_EXPR:
190 /* Distribute the conversion into the arms of a COND_EXPR. */
191 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
192 java_truthvalue_conversion (TREE_OPERAND (expr, 1)),
193 java_truthvalue_conversion (TREE_OPERAND (expr, 2))));
195 case NOP_EXPR:
196 /* If this is widening the argument, we can ignore it. */
197 if (TYPE_PRECISION (TREE_TYPE (expr))
198 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
199 return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
200 /* fall through to default */
202 default:
203 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
207 /* Save any stack slots that happen to be in the quick_stack into their
208 home virtual register slots.
210 The copy order is from low stack index to high, to support the invariant
211 that the expression for a slot may contain decls for stack slots with
212 higher (or the same) index, but not lower. */
214 static void
215 flush_quick_stack (void)
217 int stack_index = stack_pointer;
218 tree prev, cur, next;
220 /* First reverse the quick_stack, and count the number of slots it has. */
221 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
223 next = TREE_CHAIN (cur);
224 TREE_CHAIN (cur) = prev;
225 prev = cur;
226 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
228 quick_stack = prev;
230 while (quick_stack != NULL_TREE)
232 tree decl;
233 tree node = quick_stack, type;
234 quick_stack = TREE_CHAIN (node);
235 TREE_CHAIN (node) = tree_list_free_list;
236 tree_list_free_list = node;
237 node = TREE_VALUE (node);
238 type = TREE_TYPE (node);
240 decl = find_stack_slot (stack_index, type);
241 if (decl != node)
242 java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (node), decl, node));
243 stack_index += 1 + TYPE_IS_WIDE (type);
247 /* Push TYPE on the type stack.
248 Return true on success, 0 on overflow. */
251 push_type_0 (tree type)
253 int n_words;
254 type = promote_type (type);
255 n_words = 1 + TYPE_IS_WIDE (type);
256 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
257 return 0;
258 stack_type_map[stack_pointer++] = type;
259 n_words--;
260 while (--n_words >= 0)
261 stack_type_map[stack_pointer++] = TYPE_SECOND;
262 return 1;
265 void
266 push_type (tree type)
268 if (! push_type_0 (type))
269 abort ();
272 static void
273 push_value (tree value)
275 tree type = TREE_TYPE (value);
276 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
278 type = promote_type (type);
279 value = convert (type, value);
281 push_type (type);
282 if (tree_list_free_list == NULL_TREE)
283 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
284 else
286 tree node = tree_list_free_list;
287 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
288 TREE_VALUE (node) = value;
289 TREE_CHAIN (node) = quick_stack;
290 quick_stack = node;
294 /* Pop a type from the type stack.
295 TYPE is the expected type. Return the actual type, which must be
296 convertible to TYPE.
297 On an error, *MESSAGEP is set to a freshly malloc'd error message. */
299 tree
300 pop_type_0 (tree type, char **messagep)
302 int n_words;
303 tree t;
304 *messagep = NULL;
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)
310 *messagep = xstrdup ("stack underflow");
311 return type;
313 while (--n_words > 0)
315 if (stack_type_map[--stack_pointer] != void_type_node)
317 *messagep = xstrdup ("Invalid multi-word value on type stack");
318 return type;
321 t = stack_type_map[--stack_pointer];
322 if (type == NULL_TREE || t == type)
323 return t;
324 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
325 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
326 return t;
327 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
329 if (type == ptr_type_node || type == object_ptr_type_node)
330 return t;
331 else if (t == ptr_type_node) /* Special case for null reference. */
332 return type;
333 else if (can_widen_reference_to (t, type))
334 return t;
335 /* This is a kludge, but matches what Sun's verifier does.
336 It can be tricked, but is safe as long as type errors
337 (i.e. interface method calls) are caught at run-time. */
338 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
339 return object_ptr_type_node;
342 /* lang_printable_name uses a static buffer, so we must save the result
343 from calling it the first time. */
345 char *temp = xstrdup (lang_printable_name (type, 0));
346 *messagep = concat ("expected type '", temp,
347 "' but stack contains '", lang_printable_name (t, 0),
348 "'", NULL);
349 free (temp);
351 return type;
354 /* Pop a type from the type stack.
355 TYPE is the expected type. Return the actual type, which must be
356 convertible to TYPE, otherwise call error. */
358 tree
359 pop_type (tree type)
361 char *message = NULL;
362 type = pop_type_0 (type, &message);
363 if (message != NULL)
365 error ("%s", message);
366 free (message);
368 return type;
371 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
372 Handles array types and interfaces. */
375 can_widen_reference_to (tree source_type, tree target_type)
377 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
378 return 1;
380 /* Get rid of pointers */
381 if (TREE_CODE (source_type) == POINTER_TYPE)
382 source_type = TREE_TYPE (source_type);
383 if (TREE_CODE (target_type) == POINTER_TYPE)
384 target_type = TREE_TYPE (target_type);
386 if (source_type == target_type)
387 return 1;
388 else
390 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
392 HOST_WIDE_INT source_length, target_length;
393 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
395 /* An array implements Cloneable and Serializable. */
396 tree name = DECL_NAME (TYPE_NAME (target_type));
397 return (name == java_lang_cloneable_identifier_node
398 || name == java_io_serializable_identifier_node);
400 target_length = java_array_type_length (target_type);
401 if (target_length >= 0)
403 source_length = java_array_type_length (source_type);
404 if (source_length != target_length)
405 return 0;
407 source_type = TYPE_ARRAY_ELEMENT (source_type);
408 target_type = TYPE_ARRAY_ELEMENT (target_type);
409 if (source_type == target_type)
410 return 1;
411 if (TREE_CODE (source_type) != POINTER_TYPE
412 || TREE_CODE (target_type) != POINTER_TYPE)
413 return 0;
414 return can_widen_reference_to (source_type, target_type);
416 else
418 int source_depth = class_depth (source_type);
419 int target_depth = class_depth (target_type);
421 /* class_depth can return a negative depth if an error occurred */
422 if (source_depth < 0 || target_depth < 0)
423 return 0;
425 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
427 /* target_type is OK if source_type or source_type ancestors
428 implement target_type. We handle multiple sub-interfaces */
430 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
431 int n = TREE_VEC_LENGTH (basetype_vec), i;
432 for (i=0 ; i < n; i++)
433 if (can_widen_reference_to
434 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
435 target_type))
436 return 1;
437 if (n == 0)
438 return 0;
441 for ( ; source_depth > target_depth; source_depth--)
443 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
445 return source_type == target_type;
450 static tree
451 pop_value (tree type)
453 type = pop_type (type);
454 if (quick_stack)
456 tree node = quick_stack;
457 quick_stack = TREE_CHAIN (quick_stack);
458 TREE_CHAIN (node) = tree_list_free_list;
459 tree_list_free_list = node;
460 node = TREE_VALUE (node);
461 return node;
463 else
464 return find_stack_slot (stack_pointer, promote_type (type));
468 /* Pop and discard the top COUNT stack slots. */
470 static void
471 java_stack_pop (int count)
473 while (count > 0)
475 tree type, val;
477 if (stack_pointer == 0)
478 abort ();
480 type = stack_type_map[stack_pointer - 1];
481 if (type == TYPE_SECOND)
483 count--;
484 if (stack_pointer == 1 || count <= 0)
485 abort ();
487 type = stack_type_map[stack_pointer - 2];
489 val = pop_value (type);
490 count--;
494 /* Implement the 'swap' operator (to swap two top stack slots). */
496 static void
497 java_stack_swap (void)
499 tree type1, type2;
500 tree temp;
501 tree decl1, decl2;
503 if (stack_pointer < 2
504 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
505 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
506 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
507 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
508 /* Bad stack swap. */
509 abort ();
511 flush_quick_stack ();
512 decl1 = find_stack_slot (stack_pointer - 1, type1);
513 decl2 = find_stack_slot (stack_pointer - 2, type2);
514 temp = build_decl (VAR_DECL, NULL_TREE, type1);
515 java_add_local_var (temp);
516 java_add_stmt (build (MODIFY_EXPR, type1, temp, decl1));
517 java_add_stmt (build (MODIFY_EXPR, type2,
518 find_stack_slot (stack_pointer - 1, type2),
519 decl2));
520 java_add_stmt (build (MODIFY_EXPR, type1,
521 find_stack_slot (stack_pointer - 2, type1),
522 temp));
523 stack_type_map[stack_pointer - 1] = type2;
524 stack_type_map[stack_pointer - 2] = type1;
527 static void
528 java_stack_dup (int size, int offset)
530 int low_index = stack_pointer - size - offset;
531 int dst_index;
532 if (low_index < 0)
533 error ("stack underflow - dup* operation");
535 flush_quick_stack ();
537 stack_pointer += size;
538 dst_index = stack_pointer;
540 for (dst_index = stack_pointer; --dst_index >= low_index; )
542 tree type;
543 int src_index = dst_index - size;
544 if (src_index < low_index)
545 src_index = dst_index + size + offset;
546 type = stack_type_map [src_index];
547 if (type == TYPE_SECOND)
549 if (src_index <= low_index)
550 /* Dup operation splits 64-bit number. */
551 abort ();
553 stack_type_map[dst_index] = type;
554 src_index--; dst_index--;
555 type = stack_type_map[src_index];
556 if (! TYPE_IS_WIDE (type))
557 abort ();
559 else if (TYPE_IS_WIDE (type))
560 abort ();
562 if (src_index != dst_index)
564 tree src_decl = find_stack_slot (src_index, type);
565 tree dst_decl = find_stack_slot (dst_index, type);
567 java_add_stmt
568 (build (MODIFY_EXPR, TREE_TYPE (dst_decl), dst_decl, src_decl));
569 stack_type_map[dst_index] = type;
574 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
575 value stack. */
577 static void
578 build_java_athrow (tree node)
580 tree call;
582 call = build (CALL_EXPR,
583 void_type_node,
584 build_address_of (throw_node),
585 build_tree_list (NULL_TREE, node),
586 NULL_TREE);
587 TREE_SIDE_EFFECTS (call) = 1;
588 java_add_stmt (call);
589 java_stack_pop (stack_pointer);
592 /* Implementation for jsr/ret */
594 static void
595 build_java_jsr (int target_pc, int return_pc)
597 tree where = lookup_label (target_pc);
598 tree ret = lookup_label (return_pc);
599 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
600 push_value (ret_label);
601 flush_quick_stack ();
602 java_add_stmt (build (GOTO_EXPR, void_type_node, where));
604 /* Do not need to emit the label here. We noted the existance of the
605 label as a jump target in note_instructions; we'll emit the label
606 for real at the beginning of the expand_byte_code loop. */
609 static void
610 build_java_ret (tree location)
612 java_add_stmt (build (GOTO_EXPR, void_type_node, location));
615 /* Implementation of operations on array: new, load, store, length */
617 tree
618 decode_newarray_type (int atype)
620 switch (atype)
622 case 4: return boolean_type_node;
623 case 5: return char_type_node;
624 case 6: return float_type_node;
625 case 7: return double_type_node;
626 case 8: return byte_type_node;
627 case 9: return short_type_node;
628 case 10: return int_type_node;
629 case 11: return long_type_node;
630 default: return NULL_TREE;
634 /* Map primitive type to the code used by OPCODE_newarray. */
637 encode_newarray_type (tree type)
639 if (type == boolean_type_node)
640 return 4;
641 else if (type == char_type_node)
642 return 5;
643 else if (type == float_type_node)
644 return 6;
645 else if (type == double_type_node)
646 return 7;
647 else if (type == byte_type_node)
648 return 8;
649 else if (type == short_type_node)
650 return 9;
651 else if (type == int_type_node)
652 return 10;
653 else if (type == long_type_node)
654 return 11;
655 else
656 abort ();
659 /* Build a call to _Jv_ThrowBadArrayIndex(), the
660 ArrayIndexOfBoundsException exception handler. */
662 static tree
663 build_java_throw_out_of_bounds_exception (tree index)
665 tree node = build (CALL_EXPR, int_type_node,
666 build_address_of (soft_badarrayindex_node),
667 build_tree_list (NULL_TREE, index), NULL_TREE);
668 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
669 return (node);
672 /* Return the length of an array. Doesn't perform any checking on the nature
673 or value of the array NODE. May be used to implement some bytecodes. */
675 tree
676 build_java_array_length_access (tree node)
678 tree type = TREE_TYPE (node);
679 tree array_type = TREE_TYPE (type);
680 HOST_WIDE_INT length;
682 /* JVM spec: If the arrayref is null, the arraylength instruction
683 throws a NullPointerException. The only way we could get a node
684 of type ptr_type_node at this point is `aconst_null; arraylength'
685 or something equivalent. */
686 if (type == ptr_type_node)
687 return build (CALL_EXPR, int_type_node,
688 build_address_of (soft_nullpointer_node),
689 NULL_TREE, NULL_TREE);
691 if (!is_array_type_p (type))
692 abort ();
694 length = java_array_type_length (type);
695 if (length >= 0)
696 return build_int_2 (length, 0);
698 node = build (COMPONENT_REF, int_type_node,
699 build_java_indirect_ref (array_type, node,
700 flag_check_references),
701 lookup_field (&array_type, get_identifier ("length")),
702 NULL_TREE);
703 IS_ARRAY_LENGTH_ACCESS (node) = 1;
704 return node;
707 /* Optionally checks a reference against the NULL pointer. ARG1: the
708 expr, ARG2: we should check the reference. Don't generate extra
709 checks if we're not generating code. */
711 tree
712 java_check_reference (tree expr, int check)
714 if (!flag_syntax_only && check)
716 expr = save_expr (expr);
717 expr = build (COND_EXPR, TREE_TYPE (expr),
718 build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
719 build (CALL_EXPR, void_type_node,
720 build_address_of (soft_nullpointer_node),
721 NULL_TREE, NULL_TREE),
722 expr);
725 return expr;
728 /* Reference an object: just like an INDIRECT_REF, but with checking. */
730 tree
731 build_java_indirect_ref (tree type, tree expr, int check)
733 tree t;
734 t = java_check_reference (expr, check);
735 t = convert (build_pointer_type (type), t);
736 return build1 (INDIRECT_REF, type, t);
739 /* Implement array indexing (either as l-value or r-value).
740 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
741 Optionally performs bounds checking and/or test to NULL.
742 At this point, ARRAY should have been verified as an array. */
744 tree
745 build_java_arrayaccess (tree array, tree type, tree index)
747 tree node, throw = NULL_TREE;
748 tree data_field;
749 tree ref;
750 tree array_type = TREE_TYPE (TREE_TYPE (array));
752 if (flag_bounds_check)
754 /* Generate:
755 * (unsigned jint) INDEX >= (unsigned jint) LEN
756 * && throw ArrayIndexOutOfBoundsException.
757 * Note this is equivalent to and more efficient than:
758 * INDEX < 0 || INDEX >= LEN && throw ... */
759 tree test;
760 tree len = build_java_array_length_access (array);
761 TREE_TYPE (len) = unsigned_int_type_node;
762 test = fold (build (GE_EXPR, boolean_type_node,
763 convert (unsigned_int_type_node, index),
764 len));
765 if (! integer_zerop (test))
767 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
768 build_java_throw_out_of_bounds_exception (index));
769 /* allows expansion within COMPOUND */
770 TREE_SIDE_EFFECTS( throw ) = 1;
774 /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
775 to have the bounds check evaluated first. */
776 if (throw != NULL_TREE)
777 index = build (COMPOUND_EXPR, int_type_node, throw, index);
779 data_field = lookup_field (&array_type, get_identifier ("data"));
781 ref = build (COMPONENT_REF, TREE_TYPE (data_field),
782 build_java_indirect_ref (array_type, array,
783 flag_check_references),
784 data_field, NULL_TREE);
786 node = build (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
787 return node;
790 /* Generate code to throw an ArrayStoreException if OBJECT is not assignable
791 (at runtime) to an element of ARRAY. A NOP_EXPR is returned if it can
792 determine that no check is required. */
794 tree
795 build_java_arraystore_check (tree array, tree object)
797 tree check, element_type, source;
798 tree array_type_p = TREE_TYPE (array);
799 tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));
801 if (! is_array_type_p (array_type_p))
802 abort ();
804 /* Get the TYPE_DECL for ARRAY's element type. */
805 element_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
807 if (TREE_CODE (element_type) != TYPE_DECL
808 || TREE_CODE (object_type) != TYPE_DECL)
809 abort ();
811 if (!flag_store_check)
812 return build1 (NOP_EXPR, array_type_p, array);
814 /* No check is needed if the element type is final or is itself an array.
815 Also check that element_type matches object_type, since in the bytecode
816 compilation case element_type may be the actual element type of the array
817 rather than its declared type. */
818 if (element_type == object_type
819 && (TYPE_ARRAY_P (TREE_TYPE (element_type))
820 || CLASS_FINAL (element_type)))
821 return build1 (NOP_EXPR, array_type_p, array);
823 /* OBJECT might be wrapped by a SAVE_EXPR. */
824 if (TREE_CODE (object) == SAVE_EXPR)
825 source = TREE_OPERAND (object, 0);
826 else
827 source = object;
829 /* Avoid the check if OBJECT was just loaded from the same array. */
830 if (TREE_CODE (source) == ARRAY_REF)
832 tree target;
833 source = TREE_OPERAND (source, 0); /* COMPONENT_REF. */
834 source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
835 source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
836 if (TREE_CODE (source) == SAVE_EXPR)
837 source = TREE_OPERAND (source, 0);
839 target = array;
840 if (TREE_CODE (target) == SAVE_EXPR)
841 target = TREE_OPERAND (target, 0);
843 if (source == target)
844 return build1 (NOP_EXPR, array_type_p, array);
847 /* Build an invocation of _Jv_CheckArrayStore */
848 check = build (CALL_EXPR, void_type_node,
849 build_address_of (soft_checkarraystore_node),
850 tree_cons (NULL_TREE, array,
851 build_tree_list (NULL_TREE, object)),
852 NULL_TREE);
853 TREE_SIDE_EFFECTS (check) = 1;
855 return check;
858 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
859 ARRAY_NODE. This function is used to retrieve something less vague than
860 a pointer type when indexing the first dimension of something like [[<t>.
861 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
862 return unchanged.
863 As a side effect, it also makes sure that ARRAY_NODE is an array. */
865 static tree
866 build_java_check_indexed_type (tree array_node, tree indexed_type)
868 tree elt_type;
870 if (!is_array_type_p (TREE_TYPE (array_node)))
871 abort ();
873 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
875 if (indexed_type == ptr_type_node )
876 return promote_type (elt_type);
878 /* BYTE/BOOLEAN store and load are used for both type */
879 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
880 return boolean_type_node;
882 if (indexed_type != elt_type )
883 abort ();
884 else
885 return indexed_type;
888 /* newarray triggers a call to _Jv_NewPrimArray. This function should be
889 called with an integer code (the type of array to create), and the length
890 of the array to create. */
892 tree
893 build_newarray (int atype_value, tree length)
895 tree type_arg;
897 tree prim_type = decode_newarray_type (atype_value);
898 tree type
899 = build_java_array_type (prim_type,
900 host_integerp (length, 0) == INTEGER_CST
901 ? tree_low_cst (length, 0) : -1);
903 /* If compiling to native, pass a reference to the primitive type class
904 and save the runtime some work. However, the bytecode generator
905 expects to find the type_code int here. */
906 if (flag_emit_class_files)
907 type_arg = build_int_2 (atype_value, 0);
908 else
909 type_arg = build_class_ref (prim_type);
911 return build (CALL_EXPR, promote_type (type),
912 build_address_of (soft_newarray_node),
913 tree_cons (NULL_TREE,
914 type_arg,
915 build_tree_list (NULL_TREE, length)),
916 NULL_TREE);
919 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
920 of the dimension. */
922 tree
923 build_anewarray (tree class_type, tree length)
925 tree type
926 = build_java_array_type (class_type,
927 host_integerp (length, 0)
928 ? tree_low_cst (length, 0) : -1);
930 return build (CALL_EXPR, promote_type (type),
931 build_address_of (soft_anewarray_node),
932 tree_cons (NULL_TREE, length,
933 tree_cons (NULL_TREE, build_class_ref (class_type),
934 build_tree_list (NULL_TREE,
935 null_pointer_node))),
936 NULL_TREE);
939 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
941 tree
942 build_new_array (tree type, tree length)
944 if (JPRIMITIVE_TYPE_P (type))
945 return build_newarray (encode_newarray_type (type), length);
946 else
947 return build_anewarray (TREE_TYPE (type), length);
950 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
951 class pointer, a number of dimensions and the matching number of
952 dimensions. The argument list is NULL terminated. */
954 static void
955 expand_java_multianewarray (tree class_type, int ndim)
957 int i;
958 tree args = build_tree_list( NULL_TREE, null_pointer_node );
960 for( i = 0; i < ndim; i++ )
961 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
963 push_value (build (CALL_EXPR,
964 promote_type (class_type),
965 build_address_of (soft_multianewarray_node),
966 tree_cons (NULL_TREE, build_class_ref (class_type),
967 tree_cons (NULL_TREE,
968 build_int_2 (ndim, 0), args )),
969 NULL_TREE));
972 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
973 ARRAY is an array type. May expand some bound checking and NULL
974 pointer checking. RHS_TYPE_NODE we are going to store. In the case
975 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
976 INT. In those cases, we make the conversion.
978 if ARRAy is a reference type, the assignment is checked at run-time
979 to make sure that the RHS can be assigned to the array element
980 type. It is not necessary to generate this code if ARRAY is final. */
982 static void
983 expand_java_arraystore (tree rhs_type_node)
985 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
986 && TYPE_PRECISION (rhs_type_node) <= 32) ?
987 int_type_node : rhs_type_node);
988 tree index = pop_value (int_type_node);
989 tree array = pop_value (ptr_type_node);
991 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
993 flush_quick_stack ();
995 index = save_expr (index);
996 array = save_expr (array);
998 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
1000 tree check = build_java_arraystore_check (array, rhs_node);
1001 java_add_stmt (check);
1004 array = build_java_arrayaccess (array, rhs_type_node, index);
1005 java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (array), array, rhs_node));
1008 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
1009 sure that LHS is an array type. May expand some bound checking and NULL
1010 pointer checking.
1011 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
1012 BOOLEAN/SHORT, we push a promoted type back to the stack.
1015 static void
1016 expand_java_arrayload (tree lhs_type_node )
1018 tree load_node;
1019 tree index_node = pop_value (int_type_node);
1020 tree array_node = pop_value (ptr_type_node);
1022 index_node = save_expr (index_node);
1023 array_node = save_expr (array_node);
1025 if (TREE_TYPE (array_node) == ptr_type_node)
1026 /* The only way we could get a node of type ptr_type_node at this
1027 point is `aconst_null; arraylength' or something equivalent, so
1028 unconditionally throw NullPointerException. */
1029 load_node = build (CALL_EXPR, lhs_type_node,
1030 build_address_of (soft_nullpointer_node),
1031 NULL_TREE, NULL_TREE);
1032 else
1034 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
1035 load_node = build_java_arrayaccess (array_node,
1036 lhs_type_node,
1037 index_node);
1039 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1040 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
1041 push_value (load_node);
1044 /* Expands .length. Makes sure that we deal with and array and may expand
1045 a NULL check on the array object. */
1047 static void
1048 expand_java_array_length (void)
1050 tree array = pop_value (ptr_type_node);
1051 tree length = build_java_array_length_access (array);
1053 push_value (length);
1056 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1057 either soft_monitorenter_node or soft_monitorexit_node. */
1059 static tree
1060 build_java_monitor (tree call, tree object)
1062 return (build (CALL_EXPR,
1063 void_type_node,
1064 build_address_of (call),
1065 build_tree_list (NULL_TREE, object),
1066 NULL_TREE));
1069 /* Emit code for one of the PUSHC instructions. */
1071 static void
1072 expand_java_pushc (int ival, tree type)
1074 tree value;
1075 if (type == ptr_type_node && ival == 0)
1076 value = null_pointer_node;
1077 else if (type == int_type_node || type == long_type_node)
1079 value = build_int_2 (ival, ival < 0 ? -1 : 0);
1080 TREE_TYPE (value) = type;
1082 else if (type == float_type_node || type == double_type_node)
1084 REAL_VALUE_TYPE x;
1085 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1086 value = build_real (type, x);
1088 else
1089 abort ();
1091 push_value (value);
1094 static void
1095 expand_java_return (tree type)
1097 if (type == void_type_node)
1098 java_add_stmt (build (RETURN_EXPR, void_type_node, NULL));
1099 else
1101 tree retval = pop_value (type);
1102 tree res = DECL_RESULT (current_function_decl);
1103 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1105 /* Handle the situation where the native integer type is smaller
1106 than the JVM integer. It can happen for many cross compilers.
1107 The whole if expression just goes away if INT_TYPE_SIZE < 32
1108 is false. */
1109 if (INT_TYPE_SIZE < 32
1110 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1111 < GET_MODE_SIZE (TYPE_MODE (type))))
1112 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1114 TREE_SIDE_EFFECTS (retval) = 1;
1115 java_add_stmt (build (RETURN_EXPR, TREE_TYPE (retval), retval));
1119 static void
1120 expand_load_internal (int index, tree type, int pc)
1122 tree copy;
1123 tree var = find_local_variable (index, type, pc);
1125 /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1126 on the stack. If there is an assignment to this VAR_DECL between
1127 the stack push and the use, then the wrong code could be
1128 generated. To avoid this we create a new local and copy our
1129 value into it. Then we push this new local on the stack.
1130 Hopefully this all gets optimized out. */
1131 copy = build_decl (VAR_DECL, NULL_TREE, type);
1132 java_add_local_var (copy);
1133 java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (var), copy, var));
1135 push_value (copy);
1138 tree
1139 build_address_of (tree value)
1141 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1144 bool class_has_finalize_method (tree type)
1146 tree super = CLASSTYPE_SUPER (type);
1148 if (super == NULL_TREE)
1149 return false; /* Every class with a real finalizer inherits */
1150 /* from java.lang.Object. */
1151 else
1152 return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1155 static void
1156 expand_java_NEW (tree type)
1158 tree alloc_node;
1160 alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1161 : alloc_no_finalizer_node);
1162 if (! CLASS_LOADED_P (type))
1163 load_class (type, 1);
1164 safe_layout_class (type);
1165 push_value (build (CALL_EXPR, promote_type (type),
1166 build_address_of (alloc_node),
1167 build_tree_list (NULL_TREE, build_class_ref (type)),
1168 NULL_TREE));
1171 /* This returns an expression which will extract the class of an
1172 object. */
1174 tree
1175 build_get_class (tree value)
1177 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1178 tree vtable_field = lookup_field (&object_type_node,
1179 get_identifier ("vtable"));
1180 return build (COMPONENT_REF, class_ptr_type,
1181 build1 (INDIRECT_REF, dtable_type,
1182 build (COMPONENT_REF, dtable_ptr_type,
1183 build_java_indirect_ref (object_type_node, value,
1184 flag_check_references),
1185 vtable_field, NULL_TREE)),
1186 class_field, NULL_TREE);
1189 /* This builds the tree representation of the `instanceof' operator.
1190 It tries various tricks to optimize this in cases where types are
1191 known. */
1193 tree
1194 build_instanceof (tree value, tree type)
1196 tree expr;
1197 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1198 tree valtype = TREE_TYPE (TREE_TYPE (value));
1199 tree valclass = TYPE_NAME (valtype);
1200 tree klass;
1202 /* When compiling from bytecode, we need to ensure that TYPE has
1203 been loaded. */
1204 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1206 load_class (type, 1);
1207 safe_layout_class (type);
1208 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1209 return error_mark_node;
1211 klass = TYPE_NAME (type);
1213 if (type == object_type_node || inherits_from_p (valtype, type))
1215 /* Anything except `null' is an instance of Object. Likewise,
1216 if the object is known to be an instance of the class, then
1217 we only need to check for `null'. */
1218 expr = build (NE_EXPR, itype, value, null_pointer_node);
1220 else if (! TYPE_ARRAY_P (type)
1221 && ! TYPE_ARRAY_P (valtype)
1222 && DECL_P (klass) && DECL_P (valclass)
1223 && ! CLASS_INTERFACE (valclass)
1224 && ! CLASS_INTERFACE (klass)
1225 && ! inherits_from_p (type, valtype)
1226 && (CLASS_FINAL (klass)
1227 || ! inherits_from_p (valtype, type)))
1229 /* The classes are from different branches of the derivation
1230 tree, so we immediately know the answer. */
1231 expr = boolean_false_node;
1233 else if (DECL_P (klass) && CLASS_FINAL (klass))
1235 tree save = save_expr (value);
1236 expr = build (COND_EXPR, itype,
1237 build (NE_EXPR, boolean_type_node,
1238 save, null_pointer_node),
1239 build (EQ_EXPR, itype,
1240 build_get_class (save),
1241 build_class_ref (type)),
1242 boolean_false_node);
1244 else
1246 expr = build (CALL_EXPR, itype,
1247 build_address_of (soft_instanceof_node),
1248 tree_cons (NULL_TREE, value,
1249 build_tree_list (NULL_TREE,
1250 build_class_ref (type))),
1251 NULL_TREE);
1253 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1254 return expr;
1257 static void
1258 expand_java_INSTANCEOF (tree type)
1260 tree value = pop_value (object_ptr_type_node);
1261 value = build_instanceof (value, type);
1262 push_value (value);
1265 static void
1266 expand_java_CHECKCAST (tree type)
1268 tree value = pop_value (ptr_type_node);
1269 value = build (CALL_EXPR, promote_type (type),
1270 build_address_of (soft_checkcast_node),
1271 tree_cons (NULL_TREE, build_class_ref (type),
1272 build_tree_list (NULL_TREE, value)),
1273 NULL_TREE);
1274 push_value (value);
1277 static void
1278 expand_iinc (unsigned int local_var_index, int ival, int pc)
1280 tree local_var, res;
1281 tree constant_value;
1283 flush_quick_stack ();
1284 local_var = find_local_variable (local_var_index, int_type_node, pc);
1285 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1286 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1287 java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (local_var), local_var, res));
1288 update_aliases (local_var, local_var_index);
1292 tree
1293 build_java_soft_divmod (enum tree_code op, tree type, tree op1, tree op2)
1295 tree call = NULL;
1296 tree arg1 = convert (type, op1);
1297 tree arg2 = convert (type, op2);
1299 if (type == int_type_node)
1301 switch (op)
1303 case TRUNC_DIV_EXPR:
1304 call = soft_idiv_node;
1305 break;
1306 case TRUNC_MOD_EXPR:
1307 call = soft_irem_node;
1308 break;
1309 default:
1310 break;
1313 else if (type == long_type_node)
1315 switch (op)
1317 case TRUNC_DIV_EXPR:
1318 call = soft_ldiv_node;
1319 break;
1320 case TRUNC_MOD_EXPR:
1321 call = soft_lrem_node;
1322 break;
1323 default:
1324 break;
1328 if (! call)
1329 abort ();
1331 call = build (CALL_EXPR, type,
1332 build_address_of (call),
1333 tree_cons (NULL_TREE, arg1,
1334 build_tree_list (NULL_TREE, arg2)),
1335 NULL_TREE);
1337 return call;
1340 tree
1341 build_java_binop (enum tree_code op, tree type, tree arg1, tree arg2)
1343 tree mask;
1344 switch (op)
1346 case URSHIFT_EXPR:
1348 tree u_type = java_unsigned_type (type);
1349 arg1 = convert (u_type, arg1);
1350 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1351 return convert (type, arg1);
1353 case LSHIFT_EXPR:
1354 case RSHIFT_EXPR:
1355 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1356 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1357 break;
1359 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1360 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1361 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1363 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1364 boolean_type_node, arg1, arg2));
1365 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1366 tree second_compare = fold (build (COND_EXPR, int_type_node,
1367 ifexp2, integer_zero_node,
1368 op == COMPARE_L_EXPR
1369 ? integer_minus_one_node
1370 : integer_one_node));
1371 return fold (build (COND_EXPR, int_type_node, ifexp1,
1372 op == COMPARE_L_EXPR ? integer_one_node
1373 : integer_minus_one_node,
1374 second_compare));
1376 case COMPARE_EXPR:
1377 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1379 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1380 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1381 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1382 ifexp2, integer_one_node,
1383 integer_zero_node));
1384 return fold (build (COND_EXPR, int_type_node,
1385 ifexp1, integer_minus_one_node, second_compare));
1387 case TRUNC_DIV_EXPR:
1388 case TRUNC_MOD_EXPR:
1389 if (TREE_CODE (type) == REAL_TYPE
1390 && op == TRUNC_MOD_EXPR)
1392 tree call;
1393 if (type != double_type_node)
1395 arg1 = convert (double_type_node, arg1);
1396 arg2 = convert (double_type_node, arg2);
1398 call = build (CALL_EXPR, double_type_node,
1399 build_address_of (soft_fmod_node),
1400 tree_cons (NULL_TREE, arg1,
1401 build_tree_list (NULL_TREE, arg2)),
1402 NULL_TREE);
1403 if (type != double_type_node)
1404 call = convert (type, call);
1405 return call;
1408 if (TREE_CODE (type) == INTEGER_TYPE
1409 && flag_use_divide_subroutine
1410 && ! flag_syntax_only)
1411 return build_java_soft_divmod (op, type, arg1, arg2);
1413 break;
1414 default: ;
1416 return fold (build (op, type, arg1, arg2));
1419 static void
1420 expand_java_binop (tree type, enum tree_code op)
1422 tree larg, rarg;
1423 tree ltype = type;
1424 tree rtype = type;
1425 switch (op)
1427 case LSHIFT_EXPR:
1428 case RSHIFT_EXPR:
1429 case URSHIFT_EXPR:
1430 rtype = int_type_node;
1431 rarg = pop_value (rtype);
1432 break;
1433 default:
1434 rarg = pop_value (rtype);
1436 larg = pop_value (ltype);
1437 push_value (build_java_binop (op, type, larg, rarg));
1440 /* Lookup the field named NAME in *TYPEP or its super classes.
1441 If not found, return NULL_TREE.
1442 (If the *TYPEP is not found, or if the field reference is
1443 ambiguous, return error_mark_node.)
1444 If found, return the FIELD_DECL, and set *TYPEP to the
1445 class containing the field. */
1447 tree
1448 lookup_field (tree *typep, tree name)
1450 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1452 load_class (*typep, 1);
1453 safe_layout_class (*typep);
1454 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1455 return error_mark_node;
1459 tree field, basetype_vec;
1460 tree save_field;
1461 int n, i;
1463 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1464 if (DECL_NAME (field) == name)
1465 return field;
1467 /* Process implemented interfaces. */
1468 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1469 n = TREE_VEC_LENGTH (basetype_vec);
1470 save_field = NULL_TREE;
1471 for (i = 0; i < n; i++)
1473 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1474 if ((field = lookup_field (&t, name)))
1476 if (save_field == field)
1477 continue;
1478 if (save_field == NULL_TREE)
1479 save_field = field;
1480 else
1482 tree i1 = DECL_CONTEXT (save_field);
1483 tree i2 = DECL_CONTEXT (field);
1484 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1485 IDENTIFIER_POINTER (name),
1486 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1487 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1488 return error_mark_node;
1493 if (save_field != NULL_TREE)
1494 return save_field;
1496 *typep = CLASSTYPE_SUPER (*typep);
1497 } while (*typep);
1498 return NULL_TREE;
1501 /* Look up the field named NAME in object SELF_VALUE,
1502 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1503 SELF_VALUE is NULL_TREE if looking for a static field. */
1505 tree
1506 build_field_ref (tree self_value, tree self_class, tree name)
1508 tree base_class = self_class;
1509 tree field_decl = lookup_field (&base_class, name);
1510 if (field_decl == NULL_TREE)
1512 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1513 return error_mark_node;
1515 if (self_value == NULL_TREE)
1517 return build_static_field_ref (field_decl);
1519 else
1521 int check = (flag_check_references
1522 && ! (DECL_P (self_value)
1523 && DECL_NAME (self_value) == this_identifier_node));
1525 tree base_type = promote_type (base_class);
1526 if (base_type != TREE_TYPE (self_value))
1527 self_value = fold (build1 (NOP_EXPR, base_type, self_value));
1528 if (flag_indirect_dispatch
1529 && output_class != self_class)
1530 /* FIXME: output_class != self_class is not exactly the right
1531 test. What we really want to know is whether self_class is
1532 in the same translation unit as output_class. If it is,
1533 we can make a direct reference. */
1535 tree otable_index
1536 = build_int_2 (get_symbol_table_index
1537 (field_decl, &TYPE_OTABLE_METHODS (output_class)),
1539 tree field_offset
1540 = build (ARRAY_REF, integer_type_node,
1541 TYPE_OTABLE_DECL (output_class), otable_index,
1542 NULL_TREE, NULL_TREE);
1543 tree address;
1545 field_offset = fold (convert (sizetype, field_offset));
1546 address
1547 = fold (build (PLUS_EXPR,
1548 build_pointer_type (TREE_TYPE (field_decl)),
1549 self_value, field_offset));
1550 return fold (build1 (INDIRECT_REF, TREE_TYPE (field_decl), address));
1553 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1554 self_value, check);
1555 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1556 self_value, field_decl, NULL_TREE));
1560 tree
1561 lookup_label (int pc)
1563 tree name;
1564 char buf[32];
1565 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1566 name = get_identifier (buf);
1567 if (IDENTIFIER_LOCAL_VALUE (name))
1568 return IDENTIFIER_LOCAL_VALUE (name);
1569 else
1571 /* The type of the address of a label is return_address_type_node. */
1572 tree decl = create_label_decl (name);
1573 LABEL_PC (decl) = pc;
1574 return pushdecl (decl);
1578 /* Generate a unique name for the purpose of loops and switches
1579 labels, and try-catch-finally blocks label or temporary variables. */
1581 tree
1582 generate_name (void)
1584 static int l_number = 0;
1585 char buff [32];
1586 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1587 l_number++;
1588 return get_identifier (buff);
1591 tree
1592 create_label_decl (tree name)
1594 tree decl;
1595 decl = build_decl (LABEL_DECL, name,
1596 TREE_TYPE (return_address_type_node));
1597 DECL_CONTEXT (decl) = current_function_decl;
1598 DECL_IGNORED_P (decl) = 1;
1599 return decl;
1602 /* This maps a bytecode offset (PC) to various flags. */
1603 char *instruction_bits;
1605 static void
1606 note_label (int current_pc ATTRIBUTE_UNUSED, int target_pc)
1608 lookup_label (target_pc);
1609 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1612 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1613 where CONDITION is one of one the compare operators. */
1615 static void
1616 expand_compare (enum tree_code condition, tree value1, tree value2,
1617 int target_pc)
1619 tree target = lookup_label (target_pc);
1620 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1621 java_add_stmt
1622 (build (COND_EXPR, void_type_node, java_truthvalue_conversion (cond),
1623 build (GOTO_EXPR, void_type_node, target),
1624 build_java_empty_stmt ()));
1627 /* Emit code for a TEST-type opcode. */
1629 static void
1630 expand_test (enum tree_code condition, tree type, int target_pc)
1632 tree value1, value2;
1633 flush_quick_stack ();
1634 value1 = pop_value (type);
1635 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1636 expand_compare (condition, value1, value2, target_pc);
1639 /* Emit code for a COND-type opcode. */
1641 static void
1642 expand_cond (enum tree_code condition, tree type, int target_pc)
1644 tree value1, value2;
1645 flush_quick_stack ();
1646 /* note: pop values in opposite order */
1647 value2 = pop_value (type);
1648 value1 = pop_value (type);
1649 /* Maybe should check value1 and value2 for type compatibility ??? */
1650 expand_compare (condition, value1, value2, target_pc);
1653 static void
1654 expand_java_goto (int target_pc)
1656 tree target_label = lookup_label (target_pc);
1657 flush_quick_stack ();
1658 java_add_stmt (build (GOTO_EXPR, void_type_node, target_label));
1661 static tree
1662 expand_java_switch (tree selector, int default_pc)
1664 tree switch_expr, x;
1666 flush_quick_stack ();
1667 switch_expr = build (SWITCH_EXPR, TREE_TYPE (selector), selector,
1668 NULL_TREE, NULL_TREE);
1669 java_add_stmt (switch_expr);
1671 x = build (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
1672 create_artificial_label ());
1673 append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1675 x = build (GOTO_EXPR, void_type_node, lookup_label (default_pc));
1676 append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1678 return switch_expr;
1681 static void
1682 expand_java_add_case (tree switch_expr, int match, int target_pc)
1684 tree value, x;
1686 value = build_int_2 (match, match < 0 ? -1 : 0);
1687 TREE_TYPE (value) = TREE_TYPE (switch_expr);
1689 x = build (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
1690 create_artificial_label ());
1691 append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1693 x = build (GOTO_EXPR, void_type_node, lookup_label (target_pc));
1694 append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1697 #if 0
1698 static void
1699 expand_java_call (int target_pc, int return_address)
1700 int target_pc, return_address;
1702 tree target_label = lookup_label (target_pc);
1703 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1704 push_value (value);
1705 flush_quick_stack ();
1706 expand_goto (target_label);
1709 static void
1710 expand_java_ret (tree return_address ATTRIBUTE_UNUSED)
1712 warning ("ret instruction not implemented");
1713 #if 0
1714 tree target_label = lookup_label (target_pc);
1715 flush_quick_stack ();
1716 expand_goto (target_label);
1717 #endif
1719 #endif
1721 static tree
1722 pop_arguments (tree arg_types)
1724 if (arg_types == end_params_node)
1725 return NULL_TREE;
1726 if (TREE_CODE (arg_types) == TREE_LIST)
1728 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1729 tree type = TREE_VALUE (arg_types);
1730 tree arg = pop_value (type);
1731 if (targetm.calls.promote_prototypes (type)
1732 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1733 && INTEGRAL_TYPE_P (type))
1734 arg = convert (integer_type_node, arg);
1735 return tree_cons (NULL_TREE, arg, tail);
1737 abort ();
1740 /* Build an expression to initialize the class CLAS.
1741 if EXPR is non-NULL, returns an expression to first call the initializer
1742 (if it is needed) and then calls EXPR. */
1744 tree
1745 build_class_init (tree clas, tree expr)
1747 tree init;
1749 /* An optimization: if CLAS is a superclass of the class we're
1750 compiling, we don't need to initialize it. However, if CLAS is
1751 an interface, it won't necessarily be initialized, even if we
1752 implement it. */
1753 if ((! CLASS_INTERFACE (TYPE_NAME (clas))
1754 && inherits_from_p (current_class, clas))
1755 || current_class == clas)
1756 return expr;
1758 if (always_initialize_class_p)
1760 init = build (CALL_EXPR, void_type_node,
1761 build_address_of (soft_initclass_node),
1762 build_tree_list (NULL_TREE, build_class_ref (clas)),
1763 NULL_TREE);
1764 TREE_SIDE_EFFECTS (init) = 1;
1766 else
1768 tree *init_test_decl;
1769 init_test_decl = java_treetreehash_new
1770 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);
1772 if (*init_test_decl == NULL)
1774 /* Build a declaration and mark it as a flag used to track
1775 static class initializations. */
1776 *init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1777 boolean_type_node);
1778 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (*init_test_decl);
1779 LOCAL_CLASS_INITIALIZATION_FLAG (*init_test_decl) = 1;
1780 DECL_CONTEXT (*init_test_decl) = current_function_decl;
1781 DECL_FUNCTION_INIT_TEST_CLASS (*init_test_decl) = clas;
1782 /* Tell the check-init code to ignore this decl when not
1783 optimizing class initialization. */
1784 if (!STATIC_CLASS_INIT_OPT_P ())
1785 DECL_BIT_INDEX(*init_test_decl) = -1;
1786 DECL_INITIAL (*init_test_decl) = integer_zero_node;
1787 /* Don't emit any symbolic debugging info for this decl. */
1788 DECL_IGNORED_P (*init_test_decl) = 1;
1791 init = build (CALL_EXPR, void_type_node,
1792 build_address_of (soft_initclass_node),
1793 build_tree_list (NULL_TREE, build_class_ref (clas)),
1794 NULL_TREE);
1795 TREE_SIDE_EFFECTS (init) = 1;
1796 init = build (COND_EXPR, void_type_node,
1797 build (EQ_EXPR, boolean_type_node,
1798 *init_test_decl, boolean_false_node),
1799 init, integer_zero_node);
1800 TREE_SIDE_EFFECTS (init) = 1;
1801 init = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1802 build (MODIFY_EXPR, boolean_type_node,
1803 *init_test_decl, boolean_true_node));
1804 TREE_SIDE_EFFECTS (init) = 1;
1807 if (expr != NULL_TREE)
1809 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1810 TREE_SIDE_EFFECTS (expr) = 1;
1811 return expr;
1813 return init;
1816 tree
1817 build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
1818 tree self_type, tree method_signature ATTRIBUTE_UNUSED,
1819 tree arg_list ATTRIBUTE_UNUSED)
1821 tree func;
1822 if (is_compiled_class (self_type))
1824 if (!flag_indirect_dispatch
1825 || (!TREE_PUBLIC (method) && DECL_CONTEXT (method)))
1827 make_decl_rtl (method, NULL);
1828 func = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (method)),
1829 method);
1831 else
1833 tree table_index
1834 = build_int_2 (get_symbol_table_index
1835 (method, &TYPE_ATABLE_METHODS (output_class)), 0);
1836 func = build (ARRAY_REF, method_ptr_type_node,
1837 TYPE_ATABLE_DECL (output_class), table_index,
1838 NULL_TREE, NULL_TREE);
1840 func = convert (method_ptr_type_node, func);
1842 else
1844 /* We don't know whether the method has been (statically) compiled.
1845 Compile this code to get a reference to the method's code:
1847 SELF_TYPE->methods[METHOD_INDEX].ncode
1851 int method_index = 0;
1852 tree meth, ref;
1854 /* The method might actually be declared in some superclass, so
1855 we have to use its class context, not the caller's notion of
1856 where the method is. */
1857 self_type = DECL_CONTEXT (method);
1858 ref = build_class_ref (self_type);
1859 ref = build1 (INDIRECT_REF, class_type_node, ref);
1860 if (ncode_ident == NULL_TREE)
1861 ncode_ident = get_identifier ("ncode");
1862 if (methods_ident == NULL_TREE)
1863 methods_ident = get_identifier ("methods");
1864 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1865 lookup_field (&class_type_node, methods_ident), NULL_TREE);
1866 for (meth = TYPE_METHODS (self_type);
1867 ; meth = TREE_CHAIN (meth))
1869 if (method == meth)
1870 break;
1871 if (meth == NULL_TREE)
1872 fatal_error ("method '%s' not found in class",
1873 IDENTIFIER_POINTER (DECL_NAME (method)));
1874 method_index++;
1876 method_index *= int_size_in_bytes (method_type_node);
1877 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1878 ref, build_int_2 (method_index, 0)));
1879 ref = build1 (INDIRECT_REF, method_type_node, ref);
1880 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1881 ref, lookup_field (&method_type_node, ncode_ident),
1882 NULL_TREE);
1884 return func;
1887 tree
1888 invoke_build_dtable (int is_invoke_interface, tree arg_list)
1890 tree dtable, objectref;
1892 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1894 /* If we're dealing with interfaces and if the objectref
1895 argument is an array then get the dispatch table of the class
1896 Object rather than the one from the objectref. */
1897 objectref = (is_invoke_interface
1898 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1899 object_type_node : TREE_VALUE (arg_list));
1901 if (dtable_ident == NULL_TREE)
1902 dtable_ident = get_identifier ("vtable");
1903 dtable = build_java_indirect_ref (object_type_node, objectref,
1904 flag_check_references);
1905 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1906 lookup_field (&object_type_node, dtable_ident), NULL_TREE);
1908 return dtable;
1911 /* Determine the index in SYMBOL_TABLE for a reference to the decl
1912 T. If this decl has not been seen before, it will be added to the
1913 otable_methods. If it has, the existing table slot will be
1914 reused. */
1917 get_symbol_table_index (tree t, tree *symbol_table)
1919 int i = 1;
1920 tree method_list;
1922 if (*symbol_table == NULL_TREE)
1924 *symbol_table = build_tree_list (t, t);
1925 return 1;
1928 method_list = *symbol_table;
1930 while (1)
1932 tree value = TREE_VALUE (method_list);
1933 if (value == t)
1934 return i;
1935 i++;
1936 if (TREE_CHAIN (method_list) == NULL_TREE)
1937 break;
1938 else
1939 method_list = TREE_CHAIN (method_list);
1942 TREE_CHAIN (method_list) = build_tree_list (t, t);
1943 return i;
1946 tree
1947 build_invokevirtual (tree dtable, tree method)
1949 tree func;
1950 tree nativecode_ptr_ptr_type_node
1951 = build_pointer_type (nativecode_ptr_type_node);
1952 tree method_index;
1953 tree otable_index;
1955 if (flag_indirect_dispatch)
1957 otable_index
1958 = build_int_2 (get_symbol_table_index
1959 (method, &TYPE_OTABLE_METHODS (output_class)), 0);
1960 method_index = build (ARRAY_REF, integer_type_node,
1961 TYPE_OTABLE_DECL (output_class),
1962 otable_index, NULL_TREE, NULL_TREE);
1964 else
1966 /* We fetch the DECL_VINDEX field directly here, rather than
1967 using get_method_index(). DECL_VINDEX is the true offset
1968 from the vtable base to a method, regrdless of any extra
1969 words inserted at the start of the vtable. */
1970 method_index = DECL_VINDEX (method);
1971 method_index = size_binop (MULT_EXPR, method_index,
1972 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1973 if (TARGET_VTABLE_USES_DESCRIPTORS)
1974 method_index = size_binop (MULT_EXPR, method_index,
1975 size_int (TARGET_VTABLE_USES_DESCRIPTORS));
1978 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1979 convert (nativecode_ptr_ptr_type_node, method_index)));
1981 if (TARGET_VTABLE_USES_DESCRIPTORS)
1982 func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
1983 else
1984 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1986 return func;
1989 static GTY(()) tree class_ident;
1990 tree
1991 build_invokeinterface (tree dtable, tree method)
1993 tree lookup_arg;
1994 tree interface;
1995 tree idx;
1996 tree otable_index;
1998 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1999 ensure that the selected method exists, is public and not
2000 abstract nor static. */
2002 if (class_ident == NULL_TREE)
2003 class_ident = get_identifier ("class");
2005 dtable = build_java_indirect_ref (dtable_type, dtable,
2006 flag_check_references);
2007 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
2008 lookup_field (&dtable_type, class_ident), NULL_TREE);
2010 interface = DECL_CONTEXT (method);
2011 if (! CLASS_INTERFACE (TYPE_NAME (interface)))
2012 abort ();
2013 layout_class_methods (interface);
2015 if (flag_indirect_dispatch)
2017 otable_index
2018 = build_int_2 (get_symbol_table_index
2019 (method, &TYPE_OTABLE_METHODS (output_class)), 0);
2020 idx = build (ARRAY_REF, integer_type_node,
2021 TYPE_OTABLE_DECL (output_class), otable_index,
2022 NULL_TREE, NULL_TREE);
2024 else
2025 idx = build_int_2 (get_interface_method_index (method, interface), 0);
2027 lookup_arg = tree_cons (NULL_TREE, dtable,
2028 tree_cons (NULL_TREE, build_class_ref (interface),
2029 build_tree_list (NULL_TREE, idx)));
2031 return build (CALL_EXPR, ptr_type_node,
2032 build_address_of (soft_lookupinterfacemethod_node),
2033 lookup_arg, NULL_TREE);
2036 /* Expand one of the invoke_* opcodes.
2037 OCPODE is the specific opcode.
2038 METHOD_REF_INDEX is an index into the constant pool.
2039 NARGS is the number of arguments, or -1 if not specified. */
2041 static void
2042 expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
2044 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
2045 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
2046 tree self_type = get_class_constant
2047 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
2048 const char *const self_name
2049 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2050 tree call, func, method, arg_list, method_type;
2051 tree check = NULL_TREE;
2053 if (! CLASS_LOADED_P (self_type))
2055 load_class (self_type, 1);
2056 safe_layout_class (self_type);
2057 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2058 fatal_error ("failed to find class '%s'", self_name);
2060 layout_class_methods (self_type);
2062 if (ID_INIT_P (method_name))
2063 method = lookup_java_constructor (self_type, method_signature);
2064 else
2065 method = lookup_java_method (self_type, method_name, method_signature);
2066 if (method == NULL_TREE)
2068 error ("class '%s' has no method named '%s' matching signature '%s'",
2069 self_name,
2070 IDENTIFIER_POINTER (method_name),
2071 IDENTIFIER_POINTER (method_signature));
2073 /* Invoke static can't invoke static/abstract method */
2074 else if (opcode == OPCODE_invokestatic)
2076 if (!METHOD_STATIC (method))
2078 error ("invokestatic on non static method");
2079 method = NULL_TREE;
2081 else if (METHOD_ABSTRACT (method))
2083 error ("invokestatic on abstract method");
2084 method = NULL_TREE;
2087 else
2089 if (METHOD_STATIC (method))
2091 error ("invoke[non-static] on static method");
2092 method = NULL_TREE;
2096 if (method == NULL_TREE)
2098 method_type = get_type_from_signature (method_signature);
2099 pop_arguments (TYPE_ARG_TYPES (method_type));
2100 if (opcode != OPCODE_invokestatic)
2101 pop_type (self_type);
2102 method_type = promote_type (TREE_TYPE (method_type));
2103 push_value (convert (method_type, integer_zero_node));
2104 return;
2107 method_type = TREE_TYPE (method);
2108 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2109 flush_quick_stack ();
2111 func = NULL_TREE;
2112 if (opcode == OPCODE_invokestatic)
2113 func = build_known_method_ref (method, method_type, self_type,
2114 method_signature, arg_list);
2115 else if (opcode == OPCODE_invokespecial
2116 || (opcode == OPCODE_invokevirtual
2117 && (METHOD_PRIVATE (method)
2118 || METHOD_FINAL (method)
2119 || CLASS_FINAL (TYPE_NAME (self_type)))))
2121 /* If the object for the method call is null, we throw an
2122 exception. We don't do this if the object is the current
2123 method's `this'. In other cases we just rely on an
2124 optimization pass to eliminate redundant checks. FIXME:
2125 Unfortunately there doesn't seem to be a way to determine
2126 what the current method is right now.
2127 We do omit the check if we're calling <init>. */
2128 /* We use a SAVE_EXPR here to make sure we only evaluate
2129 the new `self' expression once. */
2130 tree save_arg = save_expr (TREE_VALUE (arg_list));
2131 TREE_VALUE (arg_list) = save_arg;
2132 check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2133 func = build_known_method_ref (method, method_type, self_type,
2134 method_signature, arg_list);
2136 else
2138 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
2139 arg_list);
2140 if (opcode == OPCODE_invokevirtual)
2141 func = build_invokevirtual (dtable, method);
2142 else
2143 func = build_invokeinterface (dtable, method);
2146 if (TREE_CODE (func) == ADDR_EXPR)
2147 TREE_TYPE (func) = build_pointer_type (method_type);
2148 else
2149 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2151 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
2152 TREE_SIDE_EFFECTS (call) = 1;
2153 call = check_for_builtin (method, call);
2155 if (check != NULL_TREE)
2157 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2158 TREE_SIDE_EFFECTS (call) = 1;
2161 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2162 java_add_stmt (call);
2163 else
2165 push_value (call);
2166 flush_quick_stack ();
2170 /* Create a stub which will be put into the vtable but which will call
2171 a JNI function. */
2173 tree
2174 build_jni_stub (tree method)
2176 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2177 tree jni_func_type, tem;
2178 tree env_var, res_var = NULL_TREE, block;
2179 tree method_args, res_type;
2180 tree meth_var;
2181 tree bind;
2183 int args_size = 0;
2185 tree klass = DECL_CONTEXT (method);
2186 int from_class = ! CLASS_FROM_SOURCE_P (klass);
2187 klass = build_class_ref (klass);
2189 if (! METHOD_NATIVE (method) || ! flag_jni)
2190 abort ();
2192 DECL_ARTIFICIAL (method) = 1;
2193 DECL_EXTERNAL (method) = 0;
2195 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2196 DECL_CONTEXT (env_var) = method;
2198 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2200 res_var = build_decl (VAR_DECL, get_identifier ("res"),
2201 TREE_TYPE (TREE_TYPE (method)));
2202 DECL_CONTEXT (res_var) = method;
2203 TREE_CHAIN (env_var) = res_var;
2206 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2207 TREE_STATIC (meth_var) = 1;
2208 TREE_PUBLIC (meth_var) = 0;
2209 DECL_EXTERNAL (meth_var) = 0;
2210 DECL_CONTEXT (meth_var) = method;
2211 DECL_ARTIFICIAL (meth_var) = 1;
2212 DECL_INITIAL (meth_var) = null_pointer_node;
2213 TREE_USED (meth_var) = 1;
2214 chainon (env_var, meth_var);
2215 build_result_decl (method);
2217 /* One strange way that the front ends are different is that they
2218 store arguments differently. */
2219 if (from_class)
2220 method_args = DECL_ARGUMENTS (method);
2221 else
2222 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2223 block = build_block (env_var, NULL_TREE, NULL_TREE,
2224 method_args, NULL_TREE);
2225 TREE_SIDE_EFFECTS (block) = 1;
2226 /* When compiling from source we don't set the type of the block,
2227 because that will prevent patch_return from ever being run. */
2228 if (from_class)
2229 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2231 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2232 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2233 build (CALL_EXPR, ptr_type_node,
2234 build_address_of (soft_getjnienvnewframe_node),
2235 build_tree_list (NULL_TREE, klass),
2236 NULL_TREE));
2237 CAN_COMPLETE_NORMALLY (body) = 1;
2239 /* All the arguments to this method become arguments to the
2240 underlying JNI function. If we had to wrap object arguments in a
2241 special way, we would do that here. */
2242 args = NULL_TREE;
2243 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2245 int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (tem)));
2246 #ifdef PARM_BOUNDARY
2247 arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
2248 * PARM_BOUNDARY);
2249 #endif
2250 args_size += (arg_bits / BITS_PER_UNIT);
2252 args = tree_cons (NULL_TREE, tem, args);
2254 args = nreverse (args);
2255 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2257 /* For a static method the second argument is the class. For a
2258 non-static method the second argument is `this'; that is already
2259 available in the argument list. */
2260 if (METHOD_STATIC (method))
2262 args_size += int_size_in_bytes (TREE_TYPE (klass));
2263 args = tree_cons (NULL_TREE, klass, args);
2264 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2267 /* The JNIEnv structure is the first argument to the JNI function. */
2268 args_size += int_size_in_bytes (TREE_TYPE (env_var));
2269 args = tree_cons (NULL_TREE, env_var, args);
2270 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2272 /* We call _Jv_LookupJNIMethod to find the actual underlying
2273 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2274 exception if this function is not found at runtime. */
2275 tem = build_tree_list (NULL_TREE, build_int_2 (args_size, 0));
2276 method_sig = build_java_signature (TREE_TYPE (method));
2277 lookup_arg = tree_cons (NULL_TREE,
2278 build_utf8_ref (unmangle_classname
2279 (IDENTIFIER_POINTER (method_sig),
2280 IDENTIFIER_LENGTH (method_sig))),
2281 tem);
2282 tem = DECL_NAME (method);
2283 lookup_arg
2284 = tree_cons (NULL_TREE, klass,
2285 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2287 tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
2289 #ifdef MODIFY_JNI_METHOD_CALL
2290 tem = MODIFY_JNI_METHOD_CALL (tem);
2291 #endif
2293 jni_func_type = build_pointer_type (tem);
2295 jnifunc = build (COND_EXPR, ptr_type_node,
2296 meth_var, meth_var,
2297 build (MODIFY_EXPR, ptr_type_node,
2298 meth_var,
2299 build (CALL_EXPR, ptr_type_node,
2300 build_address_of (soft_lookupjnimethod_node),
2301 lookup_arg, NULL_TREE)));
2303 /* Now we make the actual JNI call via the resulting function
2304 pointer. */
2305 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2306 build1 (NOP_EXPR, jni_func_type, jnifunc),
2307 args, NULL_TREE);
2309 /* If the JNI call returned a result, capture it here. If we had to
2310 unwrap JNI object results, we would do that here. */
2311 if (res_var != NULL_TREE)
2312 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2313 res_var, call);
2315 TREE_SIDE_EFFECTS (call) = 1;
2316 CAN_COMPLETE_NORMALLY (call) = 1;
2318 body = build (COMPOUND_EXPR, void_type_node, body, call);
2319 TREE_SIDE_EFFECTS (body) = 1;
2321 /* Now free the environment we allocated. */
2322 call = build (CALL_EXPR, ptr_type_node,
2323 build_address_of (soft_jnipopsystemframe_node),
2324 build_tree_list (NULL_TREE, env_var),
2325 NULL_TREE);
2326 TREE_SIDE_EFFECTS (call) = 1;
2327 CAN_COMPLETE_NORMALLY (call) = 1;
2328 body = build (COMPOUND_EXPR, void_type_node, body, call);
2329 TREE_SIDE_EFFECTS (body) = 1;
2331 /* Finally, do the return. */
2332 res_type = void_type_node;
2333 if (res_var != NULL_TREE)
2335 tree drt;
2336 if (! DECL_RESULT (method))
2337 abort ();
2338 /* Make sure we copy the result variable to the actual
2339 result. We use the type of the DECL_RESULT because it
2340 might be different from the return type of the function:
2341 it might be promoted. */
2342 drt = TREE_TYPE (DECL_RESULT (method));
2343 if (drt != TREE_TYPE (res_var))
2344 res_var = build1 (CONVERT_EXPR, drt, res_var);
2345 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2346 TREE_SIDE_EFFECTS (res_var) = 1;
2349 body = build (COMPOUND_EXPR, void_type_node, body,
2350 build1 (RETURN_EXPR, res_type, res_var));
2351 TREE_SIDE_EFFECTS (body) = 1;
2353 bind = build (BIND_EXPR, void_type_node, BLOCK_VARS (block),
2354 body, block);
2355 return bind;
2358 /* Expand an operation to extract from or store into a field.
2359 IS_STATIC is 1 iff the field is static.
2360 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2361 FIELD_REF_INDEX is an index into the constant pool. */
2363 static void
2364 expand_java_field_op (int is_static, int is_putting, int field_ref_index)
2366 tree self_type =
2367 get_class_constant (current_jcf,
2368 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2369 field_ref_index));
2370 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2371 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2372 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2373 field_ref_index);
2374 tree field_type = get_type_from_signature (field_signature);
2375 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2376 tree field_ref;
2377 int is_error = 0;
2378 tree field_decl = lookup_field (&self_type, field_name);
2379 if (field_decl == error_mark_node)
2381 is_error = 1;
2383 else if (field_decl == NULL_TREE)
2385 error ("missing field '%s' in '%s'",
2386 IDENTIFIER_POINTER (field_name), self_name);
2387 is_error = 1;
2389 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2391 error ("mismatching signature for field '%s' in '%s'",
2392 IDENTIFIER_POINTER (field_name), self_name);
2393 is_error = 1;
2395 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2396 if (is_error)
2398 if (! is_putting)
2399 push_value (convert (field_type, integer_zero_node));
2400 flush_quick_stack ();
2401 return;
2404 field_ref = build_field_ref (field_ref, self_type, field_name);
2405 if (is_static)
2406 field_ref = build_class_init (self_type, field_ref);
2407 if (is_putting)
2409 flush_quick_stack ();
2410 if (FIELD_FINAL (field_decl))
2412 if (DECL_CONTEXT (field_decl) != current_class)
2413 error ("%Jassignment to final field '%D' not in field's class",
2414 field_decl, field_decl);
2415 else if (FIELD_STATIC (field_decl))
2417 if (!DECL_CLINIT_P (current_function_decl))
2418 warning ("%Jassignment to final static field `%D' not in "
2419 "class initializer",
2420 field_decl, field_decl);
2422 else
2424 tree cfndecl_name = DECL_NAME (current_function_decl);
2425 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2426 && !ID_FINIT_P (cfndecl_name))
2427 warning ("%Jassignment to final field '%D' not in constructor",
2428 field_decl, field_decl);
2431 java_add_stmt (build (MODIFY_EXPR,
2432 TREE_TYPE (field_ref), field_ref, new_value));
2434 else
2435 push_value (field_ref);
2438 void
2439 load_type_state (tree label)
2441 int i;
2442 tree vec = LABEL_TYPE_STATE (label);
2443 int cur_length = TREE_VEC_LENGTH (vec);
2444 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2445 for (i = 0; i < cur_length; i++)
2446 type_map [i] = TREE_VEC_ELT (vec, i);
2449 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2450 dependent things, but they rely on gcc routines. This function is
2451 placed here because it uses things defined locally in parse.y. */
2453 static tree
2454 case_identity (tree t __attribute__ ((__unused__)), tree v)
2456 return v;
2459 /* Return the name of the vtable for an array of a given primitive
2460 type. */
2461 static tree
2462 get_primitive_array_vtable (tree elt)
2464 tree r;
2465 if (elt == boolean_type_node)
2466 r = boolean_array_vtable;
2467 else if (elt == byte_type_node)
2468 r = byte_array_vtable;
2469 else if (elt == char_type_node)
2470 r = char_array_vtable;
2471 else if (elt == short_type_node)
2472 r = short_array_vtable;
2473 else if (elt == int_type_node)
2474 r = int_array_vtable;
2475 else if (elt == long_type_node)
2476 r = long_array_vtable;
2477 else if (elt == float_type_node)
2478 r = float_array_vtable;
2479 else if (elt == double_type_node)
2480 r = double_array_vtable;
2481 else
2482 abort ();
2483 return build_address_of (r);
2486 struct rtx_def *
2487 java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
2488 int modifier /* Actually an enum expand_modifier. */,
2489 rtx *alt_rtl ATTRIBUTE_UNUSED)
2491 tree current;
2493 abort ();
2495 switch (TREE_CODE (exp))
2498 case EXPR_WITH_FILE_LOCATION:
2500 rtx to_return;
2501 const char *saved_input_filename = input_filename;
2502 int saved_lineno = input_line;
2503 input_filename = EXPR_WFL_FILENAME (exp);
2504 input_line = EXPR_WFL_LINENO (exp);
2505 if (EXPR_WFL_EMIT_LINE_NOTE (exp))
2506 emit_line_note (input_location);
2507 /* Possibly avoid switching back and forth here. */
2508 to_return = expand_expr (EXPR_WFL_NODE (exp), target, tmode, modifier);
2509 input_filename = saved_input_filename;
2510 input_line = saved_lineno;
2511 return to_return;
2514 case NEW_ARRAY_INIT:
2516 rtx tmp;
2517 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2518 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2519 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2520 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2521 tree length = build_int_2 (ilength, 0);
2522 tree init = TREE_OPERAND (exp, 0);
2523 tree array_decl;
2525 /* See if we can generate the array statically. */
2526 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2527 && JPRIMITIVE_TYPE_P (element_type))
2529 tree temp, value, init_decl;
2530 struct rtx_def *r;
2531 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2532 PUSH_FIELD_VALUE (temp, "vtable",
2533 get_primitive_array_vtable (element_type));
2534 if (! flag_hash_synchronization)
2535 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2536 FINISH_RECORD_CONSTRUCTOR (temp);
2537 START_RECORD_CONSTRUCTOR (value, array_type);
2538 PUSH_SUPER_VALUE (value, temp);
2539 PUSH_FIELD_VALUE (value, "length", length);
2540 PUSH_FIELD_VALUE (value, "data", init);
2541 FINISH_RECORD_CONSTRUCTOR (value);
2543 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2544 pushdecl_top_level (init_decl);
2545 TREE_STATIC (init_decl) = 1;
2546 DECL_INITIAL (init_decl) = value;
2547 DECL_IGNORED_P (init_decl) = 1;
2548 TREE_READONLY (init_decl) = 1;
2549 /* Hash synchronization requires at least 64-bit alignment. */
2550 if (flag_hash_synchronization && POINTER_SIZE < 64)
2551 DECL_ALIGN (init_decl) = 64;
2552 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2553 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2554 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2555 r = expand_expr (init, target, tmode, modifier);
2556 return r;
2559 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2560 expand_decl (array_decl);
2561 tmp = expand_assignment (array_decl,
2562 build_new_array (element_type, length),
2564 if (TREE_CONSTANT (init)
2565 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2567 tree init_decl;
2568 init_decl = build_decl (VAR_DECL, generate_name (),
2569 TREE_TYPE (init));
2570 pushdecl_top_level (init_decl);
2571 TREE_STATIC (init_decl) = 1;
2572 DECL_INITIAL (init_decl) = init;
2573 DECL_IGNORED_P (init_decl) = 1;
2574 TREE_READONLY (init_decl) = 1;
2575 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2576 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2577 init = init_decl;
2579 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2580 build_java_indirect_ref (array_type,
2581 array_decl, flag_check_references),
2582 data_fld, NULL_TREE),
2583 init, 0);
2584 return tmp;
2586 case BLOCK:
2587 if (BLOCK_EXPR_BODY (exp))
2589 tree local;
2590 rtx last;
2591 tree body = BLOCK_EXPR_BODY (exp);
2592 /* Set to 1 or more when we found a static class
2593 initialization flag. */
2594 int found_class_initialization_flag = 0;
2596 pushlevel (2); /* 2 and above */
2597 expand_start_bindings (0);
2598 local = BLOCK_EXPR_DECLS (exp);
2599 while (local)
2601 tree next = TREE_CHAIN (local);
2602 found_class_initialization_flag +=
2603 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
2604 layout_decl (local, 0);
2605 expand_decl (pushdecl (local));
2606 local = next;
2609 /* Emit initialization code for test flags if we saw one. */
2610 if (! always_initialize_class_p
2611 && current_function_decl
2612 && found_class_initialization_flag)
2613 htab_traverse
2614 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
2615 emit_init_test_initialization, NULL);
2617 /* Avoid deep recursion for long block. */
2618 while (TREE_CODE (body) == COMPOUND_EXPR)
2620 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2621 emit_queue ();
2622 body = TREE_OPERAND (body, 1);
2624 last = expand_expr (body, NULL_RTX, VOIDmode, 0);
2625 emit_queue ();
2626 expand_end_bindings (getdecls (), 1, 0);
2627 poplevel (1, 1, 0);
2628 return last;
2630 return const0_rtx;
2632 case CASE_EXPR:
2634 tree duplicate;
2635 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2636 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2637 &duplicate) == 2)
2639 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2640 parse_error_context
2641 (wfl_operator, "Duplicate case label: `%s'",
2642 print_int_node (TREE_OPERAND (exp, 0)));
2644 return const0_rtx;
2647 case DEFAULT_EXPR:
2648 pushcase (NULL_TREE, 0,
2649 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2650 return const0_rtx;
2652 case TRY_EXPR:
2653 /* We expand a try[-catch] block */
2655 /* Expand the try block */
2656 expand_eh_region_start ();
2657 expand_expr_stmt (TREE_OPERAND (exp, 0));
2658 expand_start_all_catch ();
2660 /* Expand all catch clauses (EH handlers) */
2661 for (current = TREE_OPERAND (exp, 1); current;
2662 current = TREE_CHAIN (current))
2664 tree catch = TREE_OPERAND (current, 0);
2665 tree decl = BLOCK_EXPR_DECLS (catch);
2666 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2668 expand_start_catch (prepare_eh_table_type (type));
2669 expand_expr_stmt (TREE_OPERAND (current, 0));
2670 expand_end_catch ();
2672 expand_end_all_catch ();
2673 return const0_rtx;
2675 case JAVA_EXC_OBJ_EXPR:
2676 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2677 target, tmode, modifier);
2679 default:
2680 internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
2684 /* Go over METHOD's bytecode and note instruction starts in
2685 instruction_bits[]. */
2687 void
2688 note_instructions (JCF *jcf, tree method)
2690 int PC;
2691 unsigned char* byte_ops;
2692 long length = DECL_CODE_LENGTH (method);
2694 int saw_index;
2695 jint INT_temp;
2697 #undef RET /* Defined by config/i386/i386.h */
2698 #undef PTR
2699 #define BCODE byte_ops
2700 #define BYTE_type_node byte_type_node
2701 #define SHORT_type_node short_type_node
2702 #define INT_type_node int_type_node
2703 #define LONG_type_node long_type_node
2704 #define CHAR_type_node char_type_node
2705 #define PTR_type_node ptr_type_node
2706 #define FLOAT_type_node float_type_node
2707 #define DOUBLE_type_node double_type_node
2708 #define VOID_type_node void_type_node
2709 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2710 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2711 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2712 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2714 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2716 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2717 byte_ops = jcf->read_ptr;
2718 instruction_bits = xrealloc (instruction_bits, length + 1);
2719 memset (instruction_bits, 0, length + 1);
2721 /* This pass figures out which PC can be the targets of jumps. */
2722 for (PC = 0; PC < length;)
2724 int oldpc = PC; /* PC at instruction start. */
2725 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2726 switch (byte_ops[PC++])
2728 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2729 case OPCODE: \
2730 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2731 break;
2733 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2735 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2736 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2737 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2738 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2739 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2740 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2741 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2742 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2744 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2745 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2746 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2747 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2748 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2749 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2750 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2751 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2753 /* two forms of wide instructions */
2754 #define PRE_SPECIAL_WIDE(IGNORE) \
2756 int modified_opcode = IMMEDIATE_u1; \
2757 if (modified_opcode == OPCODE_iinc) \
2759 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2760 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2762 else \
2764 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2768 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2770 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2772 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2773 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2774 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2775 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2776 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2777 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2778 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2779 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2780 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2781 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2783 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2784 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2785 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2786 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2787 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2788 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2789 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2790 NOTE_LABEL (PC); \
2791 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2793 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2795 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2796 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2798 #define PRE_LOOKUP_SWITCH \
2799 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2800 NOTE_LABEL (default_offset+oldpc); \
2801 if (npairs >= 0) \
2802 while (--npairs >= 0) { \
2803 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2804 jint offset = IMMEDIATE_s4; \
2805 NOTE_LABEL (offset+oldpc); } \
2808 #define PRE_TABLE_SWITCH \
2809 { jint default_offset = IMMEDIATE_s4; \
2810 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2811 NOTE_LABEL (default_offset+oldpc); \
2812 if (low <= high) \
2813 while (low++ <= high) { \
2814 jint offset = IMMEDIATE_s4; \
2815 NOTE_LABEL (offset+oldpc); } \
2818 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2819 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2820 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2821 (void)(IMMEDIATE_u2); \
2822 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2824 #include "javaop.def"
2825 #undef JAVAOP
2827 } /* for */
2830 void
2831 expand_byte_code (JCF *jcf, tree method)
2833 int PC;
2834 int i;
2835 const unsigned char *linenumber_pointer;
2836 int dead_code_index = -1;
2837 unsigned char* byte_ops;
2838 long length = DECL_CODE_LENGTH (method);
2840 stack_pointer = 0;
2841 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2842 byte_ops = jcf->read_ptr;
2844 /* We make an initial pass of the line number table, to note
2845 which instructions have associated line number entries. */
2846 linenumber_pointer = linenumber_table;
2847 for (i = 0; i < linenumber_count; i++)
2849 int pc = GET_u2 (linenumber_pointer);
2850 linenumber_pointer += 4;
2851 if (pc >= length)
2852 warning ("invalid PC in line number table");
2853 else
2855 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2856 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2857 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2861 if (! verify_jvm_instructions (jcf, byte_ops, length))
2862 return;
2864 /* Translate bytecodes. */
2865 linenumber_pointer = linenumber_table;
2866 for (PC = 0; PC < length;)
2868 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2870 tree label = lookup_label (PC);
2871 flush_quick_stack ();
2872 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2873 java_add_stmt (build (LABEL_EXPR, void_type_node, label));
2874 if (LABEL_VERIFIED (label) || PC == 0)
2875 load_type_state (label);
2878 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2880 if (dead_code_index == -1)
2882 /* This is the start of a region of unreachable bytecodes.
2883 They still need to be processed in order for EH ranges
2884 to get handled correctly. However, we can simply
2885 replace these bytecodes with nops. */
2886 dead_code_index = PC;
2889 /* Turn this bytecode into a nop. */
2890 byte_ops[PC] = 0x0;
2892 else
2894 if (dead_code_index != -1)
2896 /* We've just reached the end of a region of dead code. */
2897 if (extra_warnings)
2898 warning ("unreachable bytecode from %d to before %d",
2899 dead_code_index, PC);
2900 dead_code_index = -1;
2904 /* Handle possible line number entry for this PC.
2906 This code handles out-of-order and multiple linenumbers per PC,
2907 but is optimized for the case of line numbers increasing
2908 monotonically with PC. */
2909 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2911 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2912 || GET_u2 (linenumber_pointer) != PC)
2913 linenumber_pointer = linenumber_table;
2914 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2916 int pc = GET_u2 (linenumber_pointer);
2917 linenumber_pointer += 4;
2918 if (pc == PC)
2920 input_location.line = GET_u2 (linenumber_pointer - 2);
2921 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2922 break;
2926 maybe_pushlevels (PC);
2927 PC = process_jvm_instruction (PC, byte_ops, length);
2928 maybe_poplevels (PC);
2929 } /* for */
2931 if (dead_code_index != -1)
2933 /* We've just reached the end of a region of dead code. */
2934 if (extra_warnings)
2935 warning ("unreachable bytecode from %d to the end of the method",
2936 dead_code_index);
2940 static void
2941 java_push_constant_from_pool (JCF *jcf, int index)
2943 tree c;
2944 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2946 tree name;
2947 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2948 index = alloc_name_constant (CONSTANT_String, name);
2949 c = build_ref_from_constant_pool (index);
2950 c = convert (promote_type (string_type_node), c);
2952 else
2953 c = get_constant (jcf, index);
2954 push_value (c);
2958 process_jvm_instruction (int PC, const unsigned char* byte_ops,
2959 long length ATTRIBUTE_UNUSED)
2961 const char *opname; /* Temporary ??? */
2962 int oldpc = PC; /* PC at instruction start. */
2964 /* If the instruction is at the beginning of a exception handler,
2965 replace the top of the stack with the thrown object reference */
2966 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2968 tree type = pop_type (ptr_type_node);
2969 push_value (build_exception_object_ref (type));
2972 switch (byte_ops[PC++])
2974 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2975 case OPCODE: \
2976 opname = #OPNAME; \
2977 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2978 break;
2980 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2982 int saw_index = 0; \
2983 int index = OPERAND_VALUE; \
2984 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2987 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2989 /* OPERAND_VALUE may have side-effects on PC */ \
2990 int opvalue = OPERAND_VALUE; \
2991 build_java_jsr (oldpc + opvalue, PC); \
2994 /* Push a constant onto the stack. */
2995 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2996 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2997 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2998 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
3000 /* internal macro added for use by the WIDE case */
3001 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
3002 expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
3004 /* Push local variable onto the opcode stack. */
3005 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
3007 /* have to do this since OPERAND_VALUE may have side-effects */ \
3008 int opvalue = OPERAND_VALUE; \
3009 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3012 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
3013 expand_java_return (OPERAND_TYPE##_type_node)
3015 #define REM_EXPR TRUNC_MOD_EXPR
3016 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
3017 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
3019 #define FIELD(IS_STATIC, IS_PUT) \
3020 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
3022 #define TEST(OPERAND_TYPE, CONDITION) \
3023 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3025 #define COND(OPERAND_TYPE, CONDITION) \
3026 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3028 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
3029 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
3031 #define BRANCH_GOTO(OPERAND_VALUE) \
3032 expand_java_goto (oldpc + OPERAND_VALUE)
3034 #define BRANCH_CALL(OPERAND_VALUE) \
3035 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
3037 #if 0
3038 #define BRANCH_RETURN(OPERAND_VALUE) \
3040 tree type = OPERAND_TYPE##_type_node; \
3041 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3042 expand_java_ret (value); \
3044 #endif
3046 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3047 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3048 fprintf (stderr, "(not implemented)\n")
3049 #define NOT_IMPL1(OPERAND_VALUE) \
3050 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3051 fprintf (stderr, "(not implemented)\n")
3053 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3055 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3057 #define STACK_POP(COUNT) java_stack_pop (COUNT)
3059 #define STACK_SWAP(COUNT) java_stack_swap()
3061 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3062 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3063 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3065 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3066 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3068 #define LOOKUP_SWITCH \
3069 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
3070 tree selector = pop_value (INT_type_node); \
3071 tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3072 while (--npairs >= 0) \
3074 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3075 expand_java_add_case (switch_expr, match, oldpc + offset); \
3079 #define TABLE_SWITCH \
3080 { jint default_offset = IMMEDIATE_s4; \
3081 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3082 tree selector = pop_value (INT_type_node); \
3083 tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3084 for (; low <= high; low++) \
3086 jint offset = IMMEDIATE_s4; \
3087 expand_java_add_case (switch_expr, low, oldpc + offset); \
3091 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3092 { int opcode = byte_ops[PC-1]; \
3093 int method_ref_index = IMMEDIATE_u2; \
3094 int nargs; \
3095 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
3096 else nargs = -1; \
3097 expand_invoke (opcode, method_ref_index, nargs); \
3100 /* Handle new, checkcast, instanceof */
3101 #define OBJECT(TYPE, OP) \
3102 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3104 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3106 #define ARRAY_LOAD(OPERAND_TYPE) \
3108 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
3111 #define ARRAY_STORE(OPERAND_TYPE) \
3113 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3116 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3117 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3118 #define ARRAY_NEW_PTR() \
3119 push_value (build_anewarray (get_class_constant (current_jcf, \
3120 IMMEDIATE_u2), \
3121 pop_value (int_type_node)));
3122 #define ARRAY_NEW_NUM() \
3124 int atype = IMMEDIATE_u1; \
3125 push_value (build_newarray (atype, pop_value (int_type_node)));\
3127 #define ARRAY_NEW_MULTI() \
3129 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
3130 int ndims = IMMEDIATE_u1; \
3131 expand_java_multianewarray( class, ndims ); \
3134 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3135 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3136 pop_value (OPERAND_TYPE##_type_node))));
3138 #define CONVERT2(FROM_TYPE, TO_TYPE) \
3140 push_value (build1 (NOP_EXPR, int_type_node, \
3141 (convert (TO_TYPE##_type_node, \
3142 pop_value (FROM_TYPE##_type_node))))); \
3145 #define CONVERT(FROM_TYPE, TO_TYPE) \
3147 push_value (convert (TO_TYPE##_type_node, \
3148 pop_value (FROM_TYPE##_type_node))); \
3151 /* internal macro added for use by the WIDE case
3152 Added TREE_TYPE (decl) assignment, apbianco */
3153 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
3155 tree decl, value; \
3156 int index = OPVALUE; \
3157 tree type = OPTYPE; \
3158 value = pop_value (type); \
3159 type = TREE_TYPE (value); \
3160 decl = find_local_variable (index, type, oldpc); \
3161 set_local_type (index, type); \
3162 java_add_stmt (build (MODIFY_EXPR, type, decl, value)); \
3163 update_aliases (decl, index); \
3166 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3168 /* have to do this since OPERAND_VALUE may have side-effects */ \
3169 int opvalue = OPERAND_VALUE; \
3170 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3173 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3174 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3176 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3177 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3179 #define MONITOR_OPERATION(call) \
3181 tree o = pop_value (ptr_type_node); \
3182 tree c; \
3183 flush_quick_stack (); \
3184 c = build_java_monitor (call, o); \
3185 TREE_SIDE_EFFECTS (c) = 1; \
3186 java_add_stmt (c); \
3189 #define SPECIAL_IINC(IGNORED) \
3191 unsigned int local_var_index = IMMEDIATE_u1; \
3192 int ival = IMMEDIATE_s1; \
3193 expand_iinc(local_var_index, ival, oldpc); \
3196 #define SPECIAL_WIDE(IGNORED) \
3198 int modified_opcode = IMMEDIATE_u1; \
3199 unsigned int local_var_index = IMMEDIATE_u2; \
3200 switch (modified_opcode) \
3202 case OPCODE_iinc: \
3204 int ival = IMMEDIATE_s2; \
3205 expand_iinc (local_var_index, ival, oldpc); \
3206 break; \
3208 case OPCODE_iload: \
3209 case OPCODE_lload: \
3210 case OPCODE_fload: \
3211 case OPCODE_dload: \
3212 case OPCODE_aload: \
3214 /* duplicate code from LOAD macro */ \
3215 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3216 break; \
3218 case OPCODE_istore: \
3219 case OPCODE_lstore: \
3220 case OPCODE_fstore: \
3221 case OPCODE_dstore: \
3222 case OPCODE_astore: \
3224 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3225 break; \
3227 default: \
3228 error ("unrecogized wide sub-instruction"); \
3232 #define SPECIAL_THROW(IGNORED) \
3233 build_java_athrow (pop_value (throwable_type_node))
3235 #define SPECIAL_BREAK NOT_IMPL1
3236 #define IMPL NOT_IMPL
3238 #include "javaop.def"
3239 #undef JAVAOP
3240 default:
3241 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3243 return PC;
3246 /* Return the opcode at PC in the code section pointed to by
3247 CODE_OFFSET. */
3249 static unsigned char
3250 peek_opcode_at_pc (JCF *jcf, int code_offset, int pc)
3252 unsigned char opcode;
3253 long absolute_offset = (long)JCF_TELL (jcf);
3255 JCF_SEEK (jcf, code_offset);
3256 opcode = jcf->read_ptr [pc];
3257 JCF_SEEK (jcf, absolute_offset);
3258 return opcode;
3261 /* Some bytecode compilers are emitting accurate LocalVariableTable
3262 attributes. Here's an example:
3264 PC <t>store_<n>
3265 PC+1 ...
3267 Attribute "LocalVariableTable"
3268 slot #<n>: ... (PC: PC+1 length: L)
3270 This is accurate because the local in slot <n> really exists after
3271 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3273 This procedure recognizes this situation and extends the live range
3274 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3275 length of the store instruction.)
3277 This function is used by `give_name_to_locals' so that a local's
3278 DECL features a DECL_LOCAL_START_PC such that the first related
3279 store operation will use DECL as a destination, not a unrelated
3280 temporary created for the occasion.
3282 This function uses a global (instruction_bits) `note_instructions' should
3283 have allocated and filled properly. */
3286 maybe_adjust_start_pc (struct JCF *jcf, int code_offset,
3287 int start_pc, int slot)
3289 int first, index, opcode;
3290 int pc, insn_pc;
3291 int wide_found = 0;
3293 if (!start_pc)
3294 return start_pc;
3296 first = index = -1;
3298 /* Find last previous instruction and remember it */
3299 for (pc = start_pc-1; pc; pc--)
3300 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3301 break;
3302 insn_pc = pc;
3304 /* Retrieve the instruction, handle `wide'. */
3305 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3306 if (opcode == OPCODE_wide)
3308 wide_found = 1;
3309 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3312 switch (opcode)
3314 case OPCODE_astore_0:
3315 case OPCODE_astore_1:
3316 case OPCODE_astore_2:
3317 case OPCODE_astore_3:
3318 first = OPCODE_astore_0;
3319 break;
3321 case OPCODE_istore_0:
3322 case OPCODE_istore_1:
3323 case OPCODE_istore_2:
3324 case OPCODE_istore_3:
3325 first = OPCODE_istore_0;
3326 break;
3328 case OPCODE_lstore_0:
3329 case OPCODE_lstore_1:
3330 case OPCODE_lstore_2:
3331 case OPCODE_lstore_3:
3332 first = OPCODE_lstore_0;
3333 break;
3335 case OPCODE_fstore_0:
3336 case OPCODE_fstore_1:
3337 case OPCODE_fstore_2:
3338 case OPCODE_fstore_3:
3339 first = OPCODE_fstore_0;
3340 break;
3342 case OPCODE_dstore_0:
3343 case OPCODE_dstore_1:
3344 case OPCODE_dstore_2:
3345 case OPCODE_dstore_3:
3346 first = OPCODE_dstore_0;
3347 break;
3349 case OPCODE_astore:
3350 case OPCODE_istore:
3351 case OPCODE_lstore:
3352 case OPCODE_fstore:
3353 case OPCODE_dstore:
3354 index = peek_opcode_at_pc (jcf, code_offset, pc);
3355 if (wide_found)
3357 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3358 index = (other << 8) + index;
3360 break;
3363 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3364 means we have a <t>store. */
3365 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3366 start_pc = insn_pc;
3368 return start_pc;
3371 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3372 order, as specified by Java Language Specification.
3374 The problem is that while expand_expr will evaluate its sub-operands in
3375 left-to-right order, for variables it will just return an rtx (i.e.
3376 an lvalue) for the variable (rather than an rvalue). So it is possible
3377 that a later sub-operand will change the register, and when the
3378 actual operation is done, it will use the new value, when it should
3379 have used the original value.
3381 We fix this by using save_expr. This forces the sub-operand to be
3382 copied into a fresh virtual register,
3384 For method invocation, we modify the arguments so that a
3385 left-to-right order evaluation is performed. Saved expressions
3386 will, in CALL_EXPR order, be reused when the call will be expanded.
3389 tree
3390 force_evaluation_order (tree node)
3392 if (flag_syntax_only)
3393 return node;
3394 if (TREE_CODE (node) == CALL_EXPR
3395 || TREE_CODE (node) == NEW_CLASS_EXPR
3396 || (TREE_CODE (node) == COMPOUND_EXPR
3397 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3398 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3400 tree arg, cmp;
3402 if (!TREE_OPERAND (node, 1))
3403 return node;
3405 arg = node;
3407 /* Position arg properly, account for wrapped around ctors. */
3408 if (TREE_CODE (node) == COMPOUND_EXPR)
3409 arg = TREE_OPERAND (node, 0);
3411 arg = TREE_OPERAND (arg, 1);
3413 /* Not having a list of argument here is an error. */
3414 if (TREE_CODE (arg) != TREE_LIST)
3415 abort ();
3417 /* This reverses the evaluation order. This is a desired effect. */
3418 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3420 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3421 cmp = (cmp == NULL_TREE ? saved :
3422 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3423 TREE_VALUE (arg) = saved;
3426 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3427 TREE_SIDE_EFFECTS (cmp) = 1;
3429 if (cmp)
3431 cmp = build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
3432 if (TREE_TYPE (cmp) != void_type_node)
3433 cmp = save_expr (cmp);
3434 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3435 TREE_SIDE_EFFECTS (cmp) = 1;
3436 node = cmp;
3439 return node;
3442 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
3443 method in order to emit initialization code for each test flag. */
3445 static int
3446 emit_init_test_initialization (void **entry, void *x ATTRIBUTE_UNUSED)
3448 struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
3449 tree klass = build_class_ref (ite->key);
3450 tree rhs;
3452 /* If the DECL_INITIAL of the test flag is set to true, it
3453 means that the class is already initialized the time it
3454 is in use. */
3455 if (DECL_INITIAL (ite->value) == boolean_true_node)
3456 rhs = boolean_true_node;
3457 /* Otherwise, we initialize the class init check variable by looking
3458 at the `state' field of the class to see if it is already
3459 initialized. This makes things a bit faster if the class is
3460 already initialized, which should be the common case. */
3461 else
3462 rhs = build (GE_EXPR, boolean_type_node,
3463 build (COMPONENT_REF, byte_type_node,
3464 build1 (INDIRECT_REF, class_type_node, klass),
3465 lookup_field (&class_type_node,
3466 get_identifier ("state")),
3467 NULL_TREE),
3468 build_int_2 (JV_STATE_DONE, 0));
3470 expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
3471 ite->value, rhs));
3472 return true;
3475 /* EXPR_WITH_FILE_LOCATION are used to keep track of the exact
3476 location where an expression or an identifier were encountered. It
3477 is necessary for languages where the frontend parser will handle
3478 recursively more than one file (Java is one of them). */
3480 tree
3481 build_expr_wfl (tree node, const char *file, int line, int col)
3483 static const char *last_file = 0;
3484 static tree last_filenode = NULL_TREE;
3485 tree wfl = make_node (EXPR_WITH_FILE_LOCATION);
3487 EXPR_WFL_NODE (wfl) = node;
3488 EXPR_WFL_SET_LINECOL (wfl, line, col);
3489 if (file != last_file)
3491 last_file = file;
3492 last_filenode = file ? get_identifier (file) : NULL_TREE;
3495 EXPR_WFL_FILENAME_NODE (wfl) = last_filenode;
3496 if (node)
3498 if (IS_NON_TYPE_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
3499 TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
3500 TREE_TYPE (wfl) = TREE_TYPE (node);
3503 return wfl;
3507 /* Build a node to represent empty statements and blocks. */
3509 tree
3510 build_java_empty_stmt (void)
3512 tree t = build_empty_stmt ();
3513 CAN_COMPLETE_NORMALLY (t) = 1;
3514 return t;
3517 #include "gt-java-expr.h"