PR other/16240
[official-gcc.git] / gcc / java / expr.c
blobc998a68cbd02d121dcc30b19e5d2731bad37c478
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 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
1145 class_has_finalize_method (tree type)
1147 tree super = CLASSTYPE_SUPER (type);
1149 if (super == NULL_TREE)
1150 return false; /* Every class with a real finalizer inherits */
1151 /* from java.lang.Object. */
1152 else
1153 return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1156 static void
1157 expand_java_NEW (tree type)
1159 tree alloc_node;
1161 alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1162 : alloc_no_finalizer_node);
1163 if (! CLASS_LOADED_P (type))
1164 load_class (type, 1);
1165 safe_layout_class (type);
1166 push_value (build (CALL_EXPR, promote_type (type),
1167 build_address_of (alloc_node),
1168 build_tree_list (NULL_TREE, build_class_ref (type)),
1169 NULL_TREE));
1172 /* This returns an expression which will extract the class of an
1173 object. */
1175 tree
1176 build_get_class (tree value)
1178 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1179 tree vtable_field = lookup_field (&object_type_node,
1180 get_identifier ("vtable"));
1181 return build (COMPONENT_REF, class_ptr_type,
1182 build1 (INDIRECT_REF, dtable_type,
1183 build (COMPONENT_REF, dtable_ptr_type,
1184 build_java_indirect_ref (object_type_node, value,
1185 flag_check_references),
1186 vtable_field, NULL_TREE)),
1187 class_field, NULL_TREE);
1190 /* This builds the tree representation of the `instanceof' operator.
1191 It tries various tricks to optimize this in cases where types are
1192 known. */
1194 tree
1195 build_instanceof (tree value, tree type)
1197 tree expr;
1198 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1199 tree valtype = TREE_TYPE (TREE_TYPE (value));
1200 tree valclass = TYPE_NAME (valtype);
1201 tree klass;
1203 /* When compiling from bytecode, we need to ensure that TYPE has
1204 been loaded. */
1205 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1207 load_class (type, 1);
1208 safe_layout_class (type);
1209 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1210 return error_mark_node;
1212 klass = TYPE_NAME (type);
1214 if (type == object_type_node || inherits_from_p (valtype, type))
1216 /* Anything except `null' is an instance of Object. Likewise,
1217 if the object is known to be an instance of the class, then
1218 we only need to check for `null'. */
1219 expr = build (NE_EXPR, itype, value, null_pointer_node);
1221 else if (! TYPE_ARRAY_P (type)
1222 && ! TYPE_ARRAY_P (valtype)
1223 && DECL_P (klass) && DECL_P (valclass)
1224 && ! CLASS_INTERFACE (valclass)
1225 && ! CLASS_INTERFACE (klass)
1226 && ! inherits_from_p (type, valtype)
1227 && (CLASS_FINAL (klass)
1228 || ! inherits_from_p (valtype, type)))
1230 /* The classes are from different branches of the derivation
1231 tree, so we immediately know the answer. */
1232 expr = boolean_false_node;
1234 else if (DECL_P (klass) && CLASS_FINAL (klass))
1236 tree save = save_expr (value);
1237 expr = build (COND_EXPR, itype,
1238 build (NE_EXPR, boolean_type_node,
1239 save, null_pointer_node),
1240 build (EQ_EXPR, itype,
1241 build_get_class (save),
1242 build_class_ref (type)),
1243 boolean_false_node);
1245 else
1247 expr = build (CALL_EXPR, itype,
1248 build_address_of (soft_instanceof_node),
1249 tree_cons (NULL_TREE, value,
1250 build_tree_list (NULL_TREE,
1251 build_class_ref (type))),
1252 NULL_TREE);
1254 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1255 return expr;
1258 static void
1259 expand_java_INSTANCEOF (tree type)
1261 tree value = pop_value (object_ptr_type_node);
1262 value = build_instanceof (value, type);
1263 push_value (value);
1266 static void
1267 expand_java_CHECKCAST (tree type)
1269 tree value = pop_value (ptr_type_node);
1270 value = build (CALL_EXPR, promote_type (type),
1271 build_address_of (soft_checkcast_node),
1272 tree_cons (NULL_TREE, build_class_ref (type),
1273 build_tree_list (NULL_TREE, value)),
1274 NULL_TREE);
1275 push_value (value);
1278 static void
1279 expand_iinc (unsigned int local_var_index, int ival, int pc)
1281 tree local_var, res;
1282 tree constant_value;
1284 flush_quick_stack ();
1285 local_var = find_local_variable (local_var_index, int_type_node, pc);
1286 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1287 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1288 java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (local_var), local_var, res));
1289 update_aliases (local_var, local_var_index);
1293 tree
1294 build_java_soft_divmod (enum tree_code op, tree type, tree op1, tree op2)
1296 tree call = NULL;
1297 tree arg1 = convert (type, op1);
1298 tree arg2 = convert (type, op2);
1300 if (type == int_type_node)
1302 switch (op)
1304 case TRUNC_DIV_EXPR:
1305 call = soft_idiv_node;
1306 break;
1307 case TRUNC_MOD_EXPR:
1308 call = soft_irem_node;
1309 break;
1310 default:
1311 break;
1314 else if (type == long_type_node)
1316 switch (op)
1318 case TRUNC_DIV_EXPR:
1319 call = soft_ldiv_node;
1320 break;
1321 case TRUNC_MOD_EXPR:
1322 call = soft_lrem_node;
1323 break;
1324 default:
1325 break;
1329 if (! call)
1330 abort ();
1332 call = build (CALL_EXPR, type,
1333 build_address_of (call),
1334 tree_cons (NULL_TREE, arg1,
1335 build_tree_list (NULL_TREE, arg2)),
1336 NULL_TREE);
1338 return call;
1341 tree
1342 build_java_binop (enum tree_code op, tree type, tree arg1, tree arg2)
1344 tree mask;
1345 switch (op)
1347 case URSHIFT_EXPR:
1349 tree u_type = java_unsigned_type (type);
1350 arg1 = convert (u_type, arg1);
1351 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1352 return convert (type, arg1);
1354 case LSHIFT_EXPR:
1355 case RSHIFT_EXPR:
1356 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1357 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1358 break;
1360 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1361 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1362 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1364 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1365 boolean_type_node, arg1, arg2));
1366 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1367 tree second_compare = fold (build (COND_EXPR, int_type_node,
1368 ifexp2, integer_zero_node,
1369 op == COMPARE_L_EXPR
1370 ? integer_minus_one_node
1371 : integer_one_node));
1372 return fold (build (COND_EXPR, int_type_node, ifexp1,
1373 op == COMPARE_L_EXPR ? integer_one_node
1374 : integer_minus_one_node,
1375 second_compare));
1377 case COMPARE_EXPR:
1378 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1380 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1381 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1382 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1383 ifexp2, integer_one_node,
1384 integer_zero_node));
1385 return fold (build (COND_EXPR, int_type_node,
1386 ifexp1, integer_minus_one_node, second_compare));
1388 case TRUNC_DIV_EXPR:
1389 case TRUNC_MOD_EXPR:
1390 if (TREE_CODE (type) == REAL_TYPE
1391 && op == TRUNC_MOD_EXPR)
1393 tree call;
1394 if (type != double_type_node)
1396 arg1 = convert (double_type_node, arg1);
1397 arg2 = convert (double_type_node, arg2);
1399 call = build (CALL_EXPR, double_type_node,
1400 build_address_of (soft_fmod_node),
1401 tree_cons (NULL_TREE, arg1,
1402 build_tree_list (NULL_TREE, arg2)),
1403 NULL_TREE);
1404 if (type != double_type_node)
1405 call = convert (type, call);
1406 return call;
1409 if (TREE_CODE (type) == INTEGER_TYPE
1410 && flag_use_divide_subroutine
1411 && ! flag_syntax_only)
1412 return build_java_soft_divmod (op, type, arg1, arg2);
1414 break;
1415 default: ;
1417 return fold (build (op, type, arg1, arg2));
1420 static void
1421 expand_java_binop (tree type, enum tree_code op)
1423 tree larg, rarg;
1424 tree ltype = type;
1425 tree rtype = type;
1426 switch (op)
1428 case LSHIFT_EXPR:
1429 case RSHIFT_EXPR:
1430 case URSHIFT_EXPR:
1431 rtype = int_type_node;
1432 rarg = pop_value (rtype);
1433 break;
1434 default:
1435 rarg = pop_value (rtype);
1437 larg = pop_value (ltype);
1438 push_value (build_java_binop (op, type, larg, rarg));
1441 /* Lookup the field named NAME in *TYPEP or its super classes.
1442 If not found, return NULL_TREE.
1443 (If the *TYPEP is not found, or if the field reference is
1444 ambiguous, return error_mark_node.)
1445 If found, return the FIELD_DECL, and set *TYPEP to the
1446 class containing the field. */
1448 tree
1449 lookup_field (tree *typep, tree name)
1451 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1453 load_class (*typep, 1);
1454 safe_layout_class (*typep);
1455 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1456 return error_mark_node;
1460 tree field, basetype_vec;
1461 tree save_field;
1462 int n, i;
1464 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1465 if (DECL_NAME (field) == name)
1466 return field;
1468 /* Process implemented interfaces. */
1469 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1470 n = TREE_VEC_LENGTH (basetype_vec);
1471 save_field = NULL_TREE;
1472 for (i = 0; i < n; i++)
1474 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1475 if ((field = lookup_field (&t, name)))
1477 if (save_field == field)
1478 continue;
1479 if (save_field == NULL_TREE)
1480 save_field = field;
1481 else
1483 tree i1 = DECL_CONTEXT (save_field);
1484 tree i2 = DECL_CONTEXT (field);
1485 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1486 IDENTIFIER_POINTER (name),
1487 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1488 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1489 return error_mark_node;
1494 if (save_field != NULL_TREE)
1495 return save_field;
1497 *typep = CLASSTYPE_SUPER (*typep);
1498 } while (*typep);
1499 return NULL_TREE;
1502 /* Look up the field named NAME in object SELF_VALUE,
1503 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1504 SELF_VALUE is NULL_TREE if looking for a static field. */
1506 tree
1507 build_field_ref (tree self_value, tree self_class, tree name)
1509 tree base_class = self_class;
1510 tree field_decl = lookup_field (&base_class, name);
1511 if (field_decl == NULL_TREE)
1513 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1514 return error_mark_node;
1516 if (self_value == NULL_TREE)
1518 return build_static_field_ref (field_decl);
1520 else
1522 int check = (flag_check_references
1523 && ! (DECL_P (self_value)
1524 && DECL_NAME (self_value) == this_identifier_node));
1526 tree base_type = promote_type (base_class);
1527 if (base_type != TREE_TYPE (self_value))
1528 self_value = fold (build1 (NOP_EXPR, base_type, self_value));
1529 if (flag_indirect_dispatch
1530 && output_class != self_class)
1531 /* FIXME: output_class != self_class is not exactly the right
1532 test. What we really want to know is whether self_class is
1533 in the same translation unit as output_class. If it is,
1534 we can make a direct reference. */
1536 tree otable_index
1537 = build_int_2 (get_symbol_table_index
1538 (field_decl, &TYPE_OTABLE_METHODS (output_class)),
1540 tree field_offset
1541 = build (ARRAY_REF, integer_type_node,
1542 TYPE_OTABLE_DECL (output_class), otable_index,
1543 NULL_TREE, NULL_TREE);
1544 tree address;
1546 field_offset = fold (convert (sizetype, field_offset));
1547 address
1548 = fold (build (PLUS_EXPR,
1549 build_pointer_type (TREE_TYPE (field_decl)),
1550 self_value, field_offset));
1551 return fold (build1 (INDIRECT_REF, TREE_TYPE (field_decl), address));
1554 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1555 self_value, check);
1556 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1557 self_value, field_decl, NULL_TREE));
1561 tree
1562 lookup_label (int pc)
1564 tree name;
1565 char buf[32];
1566 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1567 name = get_identifier (buf);
1568 if (IDENTIFIER_LOCAL_VALUE (name))
1569 return IDENTIFIER_LOCAL_VALUE (name);
1570 else
1572 /* The type of the address of a label is return_address_type_node. */
1573 tree decl = create_label_decl (name);
1574 LABEL_PC (decl) = pc;
1575 return pushdecl (decl);
1579 /* Generate a unique name for the purpose of loops and switches
1580 labels, and try-catch-finally blocks label or temporary variables. */
1582 tree
1583 generate_name (void)
1585 static int l_number = 0;
1586 char buff [32];
1587 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1588 l_number++;
1589 return get_identifier (buff);
1592 tree
1593 create_label_decl (tree name)
1595 tree decl;
1596 decl = build_decl (LABEL_DECL, name,
1597 TREE_TYPE (return_address_type_node));
1598 DECL_CONTEXT (decl) = current_function_decl;
1599 DECL_IGNORED_P (decl) = 1;
1600 return decl;
1603 /* This maps a bytecode offset (PC) to various flags. */
1604 char *instruction_bits;
1606 static void
1607 note_label (int current_pc ATTRIBUTE_UNUSED, int target_pc)
1609 lookup_label (target_pc);
1610 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1613 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1614 where CONDITION is one of one the compare operators. */
1616 static void
1617 expand_compare (enum tree_code condition, tree value1, tree value2,
1618 int target_pc)
1620 tree target = lookup_label (target_pc);
1621 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1622 java_add_stmt
1623 (build (COND_EXPR, void_type_node, java_truthvalue_conversion (cond),
1624 build (GOTO_EXPR, void_type_node, target),
1625 build_java_empty_stmt ()));
1628 /* Emit code for a TEST-type opcode. */
1630 static void
1631 expand_test (enum tree_code condition, tree type, int target_pc)
1633 tree value1, value2;
1634 flush_quick_stack ();
1635 value1 = pop_value (type);
1636 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1637 expand_compare (condition, value1, value2, target_pc);
1640 /* Emit code for a COND-type opcode. */
1642 static void
1643 expand_cond (enum tree_code condition, tree type, int target_pc)
1645 tree value1, value2;
1646 flush_quick_stack ();
1647 /* note: pop values in opposite order */
1648 value2 = pop_value (type);
1649 value1 = pop_value (type);
1650 /* Maybe should check value1 and value2 for type compatibility ??? */
1651 expand_compare (condition, value1, value2, target_pc);
1654 static void
1655 expand_java_goto (int target_pc)
1657 tree target_label = lookup_label (target_pc);
1658 flush_quick_stack ();
1659 java_add_stmt (build (GOTO_EXPR, void_type_node, target_label));
1662 static tree
1663 expand_java_switch (tree selector, int default_pc)
1665 tree switch_expr, x;
1667 flush_quick_stack ();
1668 switch_expr = build (SWITCH_EXPR, TREE_TYPE (selector), selector,
1669 NULL_TREE, NULL_TREE);
1670 java_add_stmt (switch_expr);
1672 x = build (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
1673 create_artificial_label ());
1674 append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1676 x = build (GOTO_EXPR, void_type_node, lookup_label (default_pc));
1677 append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1679 return switch_expr;
1682 static void
1683 expand_java_add_case (tree switch_expr, int match, int target_pc)
1685 tree value, x;
1687 value = build_int_2 (match, match < 0 ? -1 : 0);
1688 TREE_TYPE (value) = TREE_TYPE (switch_expr);
1690 x = build (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
1691 create_artificial_label ());
1692 append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1694 x = build (GOTO_EXPR, void_type_node, lookup_label (target_pc));
1695 append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1698 #if 0
1699 static void
1700 expand_java_call (int target_pc, int 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
2045 = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
2046 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
2047 tree self_type
2048 = get_class_constant (current_jcf,
2049 COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool,
2050 method_ref_index));
2051 const char *const self_name
2052 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2053 tree call, func, method, arg_list, method_type;
2054 tree check = NULL_TREE;
2056 if (! CLASS_LOADED_P (self_type))
2058 load_class (self_type, 1);
2059 safe_layout_class (self_type);
2060 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2061 fatal_error ("failed to find class '%s'", self_name);
2063 layout_class_methods (self_type);
2065 if (ID_INIT_P (method_name))
2066 method = lookup_java_constructor (self_type, method_signature);
2067 else
2068 method = lookup_java_method (self_type, method_name, method_signature);
2069 if (method == NULL_TREE)
2071 error ("class '%s' has no method named '%s' matching signature '%s'",
2072 self_name,
2073 IDENTIFIER_POINTER (method_name),
2074 IDENTIFIER_POINTER (method_signature));
2076 /* Invoke static can't invoke static/abstract method */
2077 else if (opcode == OPCODE_invokestatic)
2079 if (!METHOD_STATIC (method))
2081 error ("invokestatic on non static method");
2082 method = NULL_TREE;
2084 else if (METHOD_ABSTRACT (method))
2086 error ("invokestatic on abstract method");
2087 method = NULL_TREE;
2090 else
2092 if (METHOD_STATIC (method))
2094 error ("invoke[non-static] on static method");
2095 method = NULL_TREE;
2099 if (method == NULL_TREE)
2101 method_type = get_type_from_signature (method_signature);
2102 pop_arguments (TYPE_ARG_TYPES (method_type));
2103 if (opcode != OPCODE_invokestatic)
2104 pop_type (self_type);
2105 method_type = promote_type (TREE_TYPE (method_type));
2106 push_value (convert (method_type, integer_zero_node));
2107 return;
2110 method_type = TREE_TYPE (method);
2111 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2112 flush_quick_stack ();
2114 func = NULL_TREE;
2115 if (opcode == OPCODE_invokestatic)
2116 func = build_known_method_ref (method, method_type, self_type,
2117 method_signature, arg_list);
2118 else if (opcode == OPCODE_invokespecial
2119 || (opcode == OPCODE_invokevirtual
2120 && (METHOD_PRIVATE (method)
2121 || METHOD_FINAL (method)
2122 || CLASS_FINAL (TYPE_NAME (self_type)))))
2124 /* If the object for the method call is null, we throw an
2125 exception. We don't do this if the object is the current
2126 method's `this'. In other cases we just rely on an
2127 optimization pass to eliminate redundant checks. FIXME:
2128 Unfortunately there doesn't seem to be a way to determine
2129 what the current method is right now.
2130 We do omit the check if we're calling <init>. */
2131 /* We use a SAVE_EXPR here to make sure we only evaluate
2132 the new `self' expression once. */
2133 tree save_arg = save_expr (TREE_VALUE (arg_list));
2134 TREE_VALUE (arg_list) = save_arg;
2135 check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2136 func = build_known_method_ref (method, method_type, self_type,
2137 method_signature, arg_list);
2139 else
2141 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
2142 arg_list);
2143 if (opcode == OPCODE_invokevirtual)
2144 func = build_invokevirtual (dtable, method);
2145 else
2146 func = build_invokeinterface (dtable, method);
2149 if (TREE_CODE (func) == ADDR_EXPR)
2150 TREE_TYPE (func) = build_pointer_type (method_type);
2151 else
2152 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2154 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
2155 TREE_SIDE_EFFECTS (call) = 1;
2156 call = check_for_builtin (method, call);
2158 if (check != NULL_TREE)
2160 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2161 TREE_SIDE_EFFECTS (call) = 1;
2164 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2165 java_add_stmt (call);
2166 else
2168 push_value (call);
2169 flush_quick_stack ();
2173 /* Create a stub which will be put into the vtable but which will call
2174 a JNI function. */
2176 tree
2177 build_jni_stub (tree method)
2179 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2180 tree jni_func_type, tem;
2181 tree env_var, res_var = NULL_TREE, block;
2182 tree method_args, res_type;
2183 tree meth_var;
2184 tree bind;
2186 int args_size = 0;
2188 tree klass = DECL_CONTEXT (method);
2189 int from_class = ! CLASS_FROM_SOURCE_P (klass);
2190 klass = build_class_ref (klass);
2192 if (! METHOD_NATIVE (method) || ! flag_jni)
2193 abort ();
2195 DECL_ARTIFICIAL (method) = 1;
2196 DECL_EXTERNAL (method) = 0;
2198 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2199 DECL_CONTEXT (env_var) = method;
2201 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2203 res_var = build_decl (VAR_DECL, get_identifier ("res"),
2204 TREE_TYPE (TREE_TYPE (method)));
2205 DECL_CONTEXT (res_var) = method;
2206 TREE_CHAIN (env_var) = res_var;
2209 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2210 TREE_STATIC (meth_var) = 1;
2211 TREE_PUBLIC (meth_var) = 0;
2212 DECL_EXTERNAL (meth_var) = 0;
2213 DECL_CONTEXT (meth_var) = method;
2214 DECL_ARTIFICIAL (meth_var) = 1;
2215 DECL_INITIAL (meth_var) = null_pointer_node;
2216 TREE_USED (meth_var) = 1;
2217 chainon (env_var, meth_var);
2218 build_result_decl (method);
2220 /* One strange way that the front ends are different is that they
2221 store arguments differently. */
2222 if (from_class)
2223 method_args = DECL_ARGUMENTS (method);
2224 else
2225 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2226 block = build_block (env_var, NULL_TREE, NULL_TREE,
2227 method_args, NULL_TREE);
2228 TREE_SIDE_EFFECTS (block) = 1;
2229 /* When compiling from source we don't set the type of the block,
2230 because that will prevent patch_return from ever being run. */
2231 if (from_class)
2232 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2234 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2235 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2236 build (CALL_EXPR, ptr_type_node,
2237 build_address_of (soft_getjnienvnewframe_node),
2238 build_tree_list (NULL_TREE, klass),
2239 NULL_TREE));
2240 CAN_COMPLETE_NORMALLY (body) = 1;
2242 /* All the arguments to this method become arguments to the
2243 underlying JNI function. If we had to wrap object arguments in a
2244 special way, we would do that here. */
2245 args = NULL_TREE;
2246 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2248 int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (tem)));
2249 #ifdef PARM_BOUNDARY
2250 arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
2251 * PARM_BOUNDARY);
2252 #endif
2253 args_size += (arg_bits / BITS_PER_UNIT);
2255 args = tree_cons (NULL_TREE, tem, args);
2257 args = nreverse (args);
2258 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2260 /* For a static method the second argument is the class. For a
2261 non-static method the second argument is `this'; that is already
2262 available in the argument list. */
2263 if (METHOD_STATIC (method))
2265 args_size += int_size_in_bytes (TREE_TYPE (klass));
2266 args = tree_cons (NULL_TREE, klass, args);
2267 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2270 /* The JNIEnv structure is the first argument to the JNI function. */
2271 args_size += int_size_in_bytes (TREE_TYPE (env_var));
2272 args = tree_cons (NULL_TREE, env_var, args);
2273 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2275 /* We call _Jv_LookupJNIMethod to find the actual underlying
2276 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2277 exception if this function is not found at runtime. */
2278 tem = build_tree_list (NULL_TREE, build_int_2 (args_size, 0));
2279 method_sig = build_java_signature (TREE_TYPE (method));
2280 lookup_arg = tree_cons (NULL_TREE,
2281 build_utf8_ref (unmangle_classname
2282 (IDENTIFIER_POINTER (method_sig),
2283 IDENTIFIER_LENGTH (method_sig))),
2284 tem);
2285 tem = DECL_NAME (method);
2286 lookup_arg
2287 = tree_cons (NULL_TREE, klass,
2288 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2290 tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
2292 #ifdef MODIFY_JNI_METHOD_CALL
2293 tem = MODIFY_JNI_METHOD_CALL (tem);
2294 #endif
2296 jni_func_type = build_pointer_type (tem);
2298 jnifunc = build (COND_EXPR, ptr_type_node,
2299 meth_var, meth_var,
2300 build (MODIFY_EXPR, ptr_type_node,
2301 meth_var,
2302 build (CALL_EXPR, ptr_type_node,
2303 build_address_of (soft_lookupjnimethod_node),
2304 lookup_arg, NULL_TREE)));
2306 /* Now we make the actual JNI call via the resulting function
2307 pointer. */
2308 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2309 build1 (NOP_EXPR, jni_func_type, jnifunc),
2310 args, NULL_TREE);
2312 /* If the JNI call returned a result, capture it here. If we had to
2313 unwrap JNI object results, we would do that here. */
2314 if (res_var != NULL_TREE)
2315 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2316 res_var, call);
2318 TREE_SIDE_EFFECTS (call) = 1;
2319 CAN_COMPLETE_NORMALLY (call) = 1;
2321 body = build (COMPOUND_EXPR, void_type_node, body, call);
2322 TREE_SIDE_EFFECTS (body) = 1;
2324 /* Now free the environment we allocated. */
2325 call = build (CALL_EXPR, ptr_type_node,
2326 build_address_of (soft_jnipopsystemframe_node),
2327 build_tree_list (NULL_TREE, env_var),
2328 NULL_TREE);
2329 TREE_SIDE_EFFECTS (call) = 1;
2330 CAN_COMPLETE_NORMALLY (call) = 1;
2331 body = build (COMPOUND_EXPR, void_type_node, body, call);
2332 TREE_SIDE_EFFECTS (body) = 1;
2334 /* Finally, do the return. */
2335 res_type = void_type_node;
2336 if (res_var != NULL_TREE)
2338 tree drt;
2339 if (! DECL_RESULT (method))
2340 abort ();
2341 /* Make sure we copy the result variable to the actual
2342 result. We use the type of the DECL_RESULT because it
2343 might be different from the return type of the function:
2344 it might be promoted. */
2345 drt = TREE_TYPE (DECL_RESULT (method));
2346 if (drt != TREE_TYPE (res_var))
2347 res_var = build1 (CONVERT_EXPR, drt, res_var);
2348 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2349 TREE_SIDE_EFFECTS (res_var) = 1;
2352 body = build (COMPOUND_EXPR, void_type_node, body,
2353 build1 (RETURN_EXPR, res_type, res_var));
2354 TREE_SIDE_EFFECTS (body) = 1;
2356 bind = build (BIND_EXPR, void_type_node, BLOCK_VARS (block),
2357 body, block);
2358 return bind;
2361 /* Expand an operation to extract from or store into a field.
2362 IS_STATIC is 1 iff the field is static.
2363 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2364 FIELD_REF_INDEX is an index into the constant pool. */
2366 static void
2367 expand_java_field_op (int is_static, int is_putting, int field_ref_index)
2369 tree self_type
2370 = get_class_constant (current_jcf,
2371 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2372 field_ref_index));
2373 const char *self_name
2374 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2375 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2376 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2377 field_ref_index);
2378 tree field_type = get_type_from_signature (field_signature);
2379 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2380 tree field_ref;
2381 int is_error = 0;
2382 tree field_decl;
2384 if (! CLASS_LOADED_P (self_type))
2385 load_class (self_type, 1);
2386 field_decl = lookup_field (&self_type, field_name);
2387 if (field_decl == error_mark_node)
2389 is_error = 1;
2391 else if (field_decl == NULL_TREE)
2393 error ("missing field '%s' in '%s'",
2394 IDENTIFIER_POINTER (field_name), self_name);
2395 is_error = 1;
2397 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2399 error ("mismatching signature for field '%s' in '%s'",
2400 IDENTIFIER_POINTER (field_name), self_name);
2401 is_error = 1;
2403 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2404 if (is_error)
2406 if (! is_putting)
2407 push_value (convert (field_type, integer_zero_node));
2408 flush_quick_stack ();
2409 return;
2412 field_ref = build_field_ref (field_ref, self_type, field_name);
2413 if (is_static)
2414 field_ref = build_class_init (self_type, field_ref);
2415 if (is_putting)
2417 flush_quick_stack ();
2418 if (FIELD_FINAL (field_decl))
2420 if (DECL_CONTEXT (field_decl) != current_class)
2421 error ("%Jassignment to final field '%D' not in field's class",
2422 field_decl, field_decl);
2423 else if (FIELD_STATIC (field_decl))
2425 if (!DECL_CLINIT_P (current_function_decl))
2426 warning ("%Jassignment to final static field `%D' not in "
2427 "class initializer",
2428 field_decl, field_decl);
2430 else
2432 tree cfndecl_name = DECL_NAME (current_function_decl);
2433 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2434 && !ID_FINIT_P (cfndecl_name))
2435 warning ("%Jassignment to final field '%D' not in constructor",
2436 field_decl, field_decl);
2439 java_add_stmt (build (MODIFY_EXPR,
2440 TREE_TYPE (field_ref), field_ref, new_value));
2442 else
2443 push_value (field_ref);
2446 void
2447 load_type_state (tree label)
2449 int i;
2450 tree vec = LABEL_TYPE_STATE (label);
2451 int cur_length = TREE_VEC_LENGTH (vec);
2452 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2453 for (i = 0; i < cur_length; i++)
2454 type_map [i] = TREE_VEC_ELT (vec, i);
2457 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2458 dependent things, but they rely on gcc routines. This function is
2459 placed here because it uses things defined locally in parse.y. */
2461 static tree
2462 case_identity (tree t __attribute__ ((__unused__)), tree v)
2464 return v;
2467 /* Return the name of the vtable for an array of a given primitive
2468 type. */
2469 static tree
2470 get_primitive_array_vtable (tree elt)
2472 tree r;
2473 if (elt == boolean_type_node)
2474 r = boolean_array_vtable;
2475 else if (elt == byte_type_node)
2476 r = byte_array_vtable;
2477 else if (elt == char_type_node)
2478 r = char_array_vtable;
2479 else if (elt == short_type_node)
2480 r = short_array_vtable;
2481 else if (elt == int_type_node)
2482 r = int_array_vtable;
2483 else if (elt == long_type_node)
2484 r = long_array_vtable;
2485 else if (elt == float_type_node)
2486 r = float_array_vtable;
2487 else if (elt == double_type_node)
2488 r = double_array_vtable;
2489 else
2490 abort ();
2491 return build_address_of (r);
2494 struct rtx_def *
2495 java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
2496 int modifier /* Actually an enum expand_modifier. */,
2497 rtx *alt_rtl ATTRIBUTE_UNUSED)
2499 tree current;
2501 abort ();
2503 switch (TREE_CODE (exp))
2506 case EXPR_WITH_FILE_LOCATION:
2508 rtx to_return;
2509 const char *saved_input_filename = input_filename;
2510 int saved_lineno = input_line;
2511 input_filename = EXPR_WFL_FILENAME (exp);
2512 input_line = EXPR_WFL_LINENO (exp);
2513 if (EXPR_WFL_EMIT_LINE_NOTE (exp))
2514 emit_line_note (input_location);
2515 /* Possibly avoid switching back and forth here. */
2516 to_return = expand_expr (EXPR_WFL_NODE (exp), target, tmode, modifier);
2517 input_filename = saved_input_filename;
2518 input_line = saved_lineno;
2519 return to_return;
2522 case NEW_ARRAY_INIT:
2524 rtx tmp;
2525 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2526 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2527 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2528 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2529 tree length = build_int_2 (ilength, 0);
2530 tree init = TREE_OPERAND (exp, 0);
2531 tree array_decl;
2533 /* See if we can generate the array statically. */
2534 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2535 && JPRIMITIVE_TYPE_P (element_type))
2537 tree temp, value, init_decl;
2538 struct rtx_def *r;
2539 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2540 PUSH_FIELD_VALUE (temp, "vtable",
2541 get_primitive_array_vtable (element_type));
2542 if (! flag_hash_synchronization)
2543 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2544 FINISH_RECORD_CONSTRUCTOR (temp);
2545 START_RECORD_CONSTRUCTOR (value, array_type);
2546 PUSH_SUPER_VALUE (value, temp);
2547 PUSH_FIELD_VALUE (value, "length", length);
2548 PUSH_FIELD_VALUE (value, "data", init);
2549 FINISH_RECORD_CONSTRUCTOR (value);
2551 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2552 pushdecl_top_level (init_decl);
2553 TREE_STATIC (init_decl) = 1;
2554 DECL_INITIAL (init_decl) = value;
2555 DECL_IGNORED_P (init_decl) = 1;
2556 TREE_READONLY (init_decl) = 1;
2557 /* Hash synchronization requires at least 64-bit alignment. */
2558 if (flag_hash_synchronization && POINTER_SIZE < 64)
2559 DECL_ALIGN (init_decl) = 64;
2560 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2561 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2562 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2563 r = expand_expr (init, target, tmode, modifier);
2564 return r;
2567 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2568 expand_decl (array_decl);
2569 tmp = expand_assignment (array_decl,
2570 build_new_array (element_type, length),
2572 if (TREE_CONSTANT (init)
2573 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2575 tree init_decl;
2576 init_decl = build_decl (VAR_DECL, generate_name (),
2577 TREE_TYPE (init));
2578 pushdecl_top_level (init_decl);
2579 TREE_STATIC (init_decl) = 1;
2580 DECL_INITIAL (init_decl) = init;
2581 DECL_IGNORED_P (init_decl) = 1;
2582 TREE_READONLY (init_decl) = 1;
2583 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2584 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2585 init = init_decl;
2587 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2588 build_java_indirect_ref (array_type,
2589 array_decl, flag_check_references),
2590 data_fld, NULL_TREE),
2591 init, 0);
2592 return tmp;
2594 case BLOCK:
2595 if (BLOCK_EXPR_BODY (exp))
2597 tree local;
2598 rtx last;
2599 tree body = BLOCK_EXPR_BODY (exp);
2600 /* Set to 1 or more when we found a static class
2601 initialization flag. */
2602 int found_class_initialization_flag = 0;
2604 pushlevel (2); /* 2 and above */
2605 expand_start_bindings (0);
2606 local = BLOCK_EXPR_DECLS (exp);
2607 while (local)
2609 tree next = TREE_CHAIN (local);
2610 found_class_initialization_flag +=
2611 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
2612 layout_decl (local, 0);
2613 expand_decl (pushdecl (local));
2614 local = next;
2617 /* Emit initialization code for test flags if we saw one. */
2618 if (! always_initialize_class_p
2619 && current_function_decl
2620 && found_class_initialization_flag)
2621 htab_traverse
2622 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
2623 emit_init_test_initialization, NULL);
2625 /* Avoid deep recursion for long block. */
2626 while (TREE_CODE (body) == COMPOUND_EXPR)
2628 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2629 emit_queue ();
2630 body = TREE_OPERAND (body, 1);
2632 last = expand_expr (body, NULL_RTX, VOIDmode, 0);
2633 emit_queue ();
2634 expand_end_bindings (getdecls (), 1, 0);
2635 poplevel (1, 1, 0);
2636 return last;
2638 return const0_rtx;
2640 case CASE_EXPR:
2642 tree duplicate;
2643 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2644 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2645 &duplicate) == 2)
2647 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2648 parse_error_context
2649 (wfl_operator, "Duplicate case label: `%s'",
2650 print_int_node (TREE_OPERAND (exp, 0)));
2652 return const0_rtx;
2655 case DEFAULT_EXPR:
2656 pushcase (NULL_TREE, 0,
2657 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2658 return const0_rtx;
2660 case TRY_EXPR:
2661 /* We expand a try[-catch] block */
2663 /* Expand the try block */
2664 expand_eh_region_start ();
2665 expand_expr_stmt (TREE_OPERAND (exp, 0));
2666 expand_start_all_catch ();
2668 /* Expand all catch clauses (EH handlers) */
2669 for (current = TREE_OPERAND (exp, 1); current;
2670 current = TREE_CHAIN (current))
2672 tree catch = TREE_OPERAND (current, 0);
2673 tree decl = BLOCK_EXPR_DECLS (catch);
2674 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2676 expand_start_catch (prepare_eh_table_type (type));
2677 expand_expr_stmt (TREE_OPERAND (current, 0));
2678 expand_end_catch ();
2680 expand_end_all_catch ();
2681 return const0_rtx;
2683 case JAVA_EXC_OBJ_EXPR:
2684 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2685 target, tmode, modifier);
2687 default:
2688 internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
2692 /* Go over METHOD's bytecode and note instruction starts in
2693 instruction_bits[]. */
2695 void
2696 note_instructions (JCF *jcf, tree method)
2698 int PC;
2699 unsigned char* byte_ops;
2700 long length = DECL_CODE_LENGTH (method);
2702 int saw_index;
2703 jint INT_temp;
2705 #undef RET /* Defined by config/i386/i386.h */
2706 #undef PTR
2707 #define BCODE byte_ops
2708 #define BYTE_type_node byte_type_node
2709 #define SHORT_type_node short_type_node
2710 #define INT_type_node int_type_node
2711 #define LONG_type_node long_type_node
2712 #define CHAR_type_node char_type_node
2713 #define PTR_type_node ptr_type_node
2714 #define FLOAT_type_node float_type_node
2715 #define DOUBLE_type_node double_type_node
2716 #define VOID_type_node void_type_node
2717 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2718 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2719 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2720 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2722 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2724 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2725 byte_ops = jcf->read_ptr;
2726 instruction_bits = xrealloc (instruction_bits, length + 1);
2727 memset (instruction_bits, 0, length + 1);
2729 /* This pass figures out which PC can be the targets of jumps. */
2730 for (PC = 0; PC < length;)
2732 int oldpc = PC; /* PC at instruction start. */
2733 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2734 switch (byte_ops[PC++])
2736 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2737 case OPCODE: \
2738 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2739 break;
2741 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2743 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2744 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2745 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2746 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2747 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2748 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2749 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2750 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2752 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2753 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2754 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2755 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2756 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2757 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2758 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2759 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2761 /* two forms of wide instructions */
2762 #define PRE_SPECIAL_WIDE(IGNORE) \
2764 int modified_opcode = IMMEDIATE_u1; \
2765 if (modified_opcode == OPCODE_iinc) \
2767 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2768 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2770 else \
2772 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2776 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2778 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2780 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2781 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2782 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2783 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2784 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2785 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2786 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2787 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2788 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2789 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2791 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2792 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2793 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2794 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2795 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2796 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2797 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2798 NOTE_LABEL (PC); \
2799 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2801 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2803 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2804 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2806 #define PRE_LOOKUP_SWITCH \
2807 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2808 NOTE_LABEL (default_offset+oldpc); \
2809 if (npairs >= 0) \
2810 while (--npairs >= 0) { \
2811 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2812 jint offset = IMMEDIATE_s4; \
2813 NOTE_LABEL (offset+oldpc); } \
2816 #define PRE_TABLE_SWITCH \
2817 { jint default_offset = IMMEDIATE_s4; \
2818 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2819 NOTE_LABEL (default_offset+oldpc); \
2820 if (low <= high) \
2821 while (low++ <= high) { \
2822 jint offset = IMMEDIATE_s4; \
2823 NOTE_LABEL (offset+oldpc); } \
2826 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2827 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2828 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2829 (void)(IMMEDIATE_u2); \
2830 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2832 #include "javaop.def"
2833 #undef JAVAOP
2835 } /* for */
2838 void
2839 expand_byte_code (JCF *jcf, tree method)
2841 int PC;
2842 int i;
2843 const unsigned char *linenumber_pointer;
2844 int dead_code_index = -1;
2845 unsigned char* byte_ops;
2846 long length = DECL_CODE_LENGTH (method);
2848 stack_pointer = 0;
2849 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2850 byte_ops = jcf->read_ptr;
2852 /* We make an initial pass of the line number table, to note
2853 which instructions have associated line number entries. */
2854 linenumber_pointer = linenumber_table;
2855 for (i = 0; i < linenumber_count; i++)
2857 int pc = GET_u2 (linenumber_pointer);
2858 linenumber_pointer += 4;
2859 if (pc >= length)
2860 warning ("invalid PC in line number table");
2861 else
2863 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2864 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2865 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2869 if (! verify_jvm_instructions (jcf, byte_ops, length))
2870 return;
2872 /* Translate bytecodes. */
2873 linenumber_pointer = linenumber_table;
2874 for (PC = 0; PC < length;)
2876 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2878 tree label = lookup_label (PC);
2879 flush_quick_stack ();
2880 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2881 java_add_stmt (build (LABEL_EXPR, void_type_node, label));
2882 if (LABEL_VERIFIED (label) || PC == 0)
2883 load_type_state (label);
2886 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2888 if (dead_code_index == -1)
2890 /* This is the start of a region of unreachable bytecodes.
2891 They still need to be processed in order for EH ranges
2892 to get handled correctly. However, we can simply
2893 replace these bytecodes with nops. */
2894 dead_code_index = PC;
2897 /* Turn this bytecode into a nop. */
2898 byte_ops[PC] = 0x0;
2900 else
2902 if (dead_code_index != -1)
2904 /* We've just reached the end of a region of dead code. */
2905 if (extra_warnings)
2906 warning ("unreachable bytecode from %d to before %d",
2907 dead_code_index, PC);
2908 dead_code_index = -1;
2912 /* Handle possible line number entry for this PC.
2914 This code handles out-of-order and multiple linenumbers per PC,
2915 but is optimized for the case of line numbers increasing
2916 monotonically with PC. */
2917 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2919 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2920 || GET_u2 (linenumber_pointer) != PC)
2921 linenumber_pointer = linenumber_table;
2922 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2924 int pc = GET_u2 (linenumber_pointer);
2925 linenumber_pointer += 4;
2926 if (pc == PC)
2928 input_location.line = GET_u2 (linenumber_pointer - 2);
2929 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2930 break;
2934 maybe_pushlevels (PC);
2935 PC = process_jvm_instruction (PC, byte_ops, length);
2936 maybe_poplevels (PC);
2937 } /* for */
2939 if (dead_code_index != -1)
2941 /* We've just reached the end of a region of dead code. */
2942 if (extra_warnings)
2943 warning ("unreachable bytecode from %d to the end of the method",
2944 dead_code_index);
2948 static void
2949 java_push_constant_from_pool (JCF *jcf, int index)
2951 tree c;
2952 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2954 tree name;
2955 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2956 index = alloc_name_constant (CONSTANT_String, name);
2957 c = build_ref_from_constant_pool (index);
2958 c = convert (promote_type (string_type_node), c);
2960 else
2961 c = get_constant (jcf, index);
2962 push_value (c);
2966 process_jvm_instruction (int PC, const unsigned char* byte_ops,
2967 long length ATTRIBUTE_UNUSED)
2969 const char *opname; /* Temporary ??? */
2970 int oldpc = PC; /* PC at instruction start. */
2972 /* If the instruction is at the beginning of a exception handler,
2973 replace the top of the stack with the thrown object reference */
2974 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2976 tree type = pop_type (ptr_type_node);
2977 push_value (build_exception_object_ref (type));
2980 switch (byte_ops[PC++])
2982 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2983 case OPCODE: \
2984 opname = #OPNAME; \
2985 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2986 break;
2988 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2990 int saw_index = 0; \
2991 int index = OPERAND_VALUE; \
2992 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2995 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2997 /* OPERAND_VALUE may have side-effects on PC */ \
2998 int opvalue = OPERAND_VALUE; \
2999 build_java_jsr (oldpc + opvalue, PC); \
3002 /* Push a constant onto the stack. */
3003 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
3004 { int saw_index = 0; int ival = (OPERAND_VALUE); \
3005 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
3006 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
3008 /* internal macro added for use by the WIDE case */
3009 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
3010 expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
3012 /* Push local variable onto the opcode stack. */
3013 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
3015 /* have to do this since OPERAND_VALUE may have side-effects */ \
3016 int opvalue = OPERAND_VALUE; \
3017 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3020 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
3021 expand_java_return (OPERAND_TYPE##_type_node)
3023 #define REM_EXPR TRUNC_MOD_EXPR
3024 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
3025 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
3027 #define FIELD(IS_STATIC, IS_PUT) \
3028 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
3030 #define TEST(OPERAND_TYPE, CONDITION) \
3031 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3033 #define COND(OPERAND_TYPE, CONDITION) \
3034 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3036 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
3037 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
3039 #define BRANCH_GOTO(OPERAND_VALUE) \
3040 expand_java_goto (oldpc + OPERAND_VALUE)
3042 #define BRANCH_CALL(OPERAND_VALUE) \
3043 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
3045 #if 0
3046 #define BRANCH_RETURN(OPERAND_VALUE) \
3048 tree type = OPERAND_TYPE##_type_node; \
3049 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3050 expand_java_ret (value); \
3052 #endif
3054 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3055 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3056 fprintf (stderr, "(not implemented)\n")
3057 #define NOT_IMPL1(OPERAND_VALUE) \
3058 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3059 fprintf (stderr, "(not implemented)\n")
3061 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3063 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3065 #define STACK_POP(COUNT) java_stack_pop (COUNT)
3067 #define STACK_SWAP(COUNT) java_stack_swap()
3069 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3070 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3071 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3073 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3074 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3076 #define LOOKUP_SWITCH \
3077 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
3078 tree selector = pop_value (INT_type_node); \
3079 tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3080 while (--npairs >= 0) \
3082 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3083 expand_java_add_case (switch_expr, match, oldpc + offset); \
3087 #define TABLE_SWITCH \
3088 { jint default_offset = IMMEDIATE_s4; \
3089 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3090 tree selector = pop_value (INT_type_node); \
3091 tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3092 for (; low <= high; low++) \
3094 jint offset = IMMEDIATE_s4; \
3095 expand_java_add_case (switch_expr, low, oldpc + offset); \
3099 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3100 { int opcode = byte_ops[PC-1]; \
3101 int method_ref_index = IMMEDIATE_u2; \
3102 int nargs; \
3103 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
3104 else nargs = -1; \
3105 expand_invoke (opcode, method_ref_index, nargs); \
3108 /* Handle new, checkcast, instanceof */
3109 #define OBJECT(TYPE, OP) \
3110 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3112 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3114 #define ARRAY_LOAD(OPERAND_TYPE) \
3116 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
3119 #define ARRAY_STORE(OPERAND_TYPE) \
3121 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3124 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3125 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3126 #define ARRAY_NEW_PTR() \
3127 push_value (build_anewarray (get_class_constant (current_jcf, \
3128 IMMEDIATE_u2), \
3129 pop_value (int_type_node)));
3130 #define ARRAY_NEW_NUM() \
3132 int atype = IMMEDIATE_u1; \
3133 push_value (build_newarray (atype, pop_value (int_type_node)));\
3135 #define ARRAY_NEW_MULTI() \
3137 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
3138 int ndims = IMMEDIATE_u1; \
3139 expand_java_multianewarray( class, ndims ); \
3142 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3143 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3144 pop_value (OPERAND_TYPE##_type_node))));
3146 #define CONVERT2(FROM_TYPE, TO_TYPE) \
3148 push_value (build1 (NOP_EXPR, int_type_node, \
3149 (convert (TO_TYPE##_type_node, \
3150 pop_value (FROM_TYPE##_type_node))))); \
3153 #define CONVERT(FROM_TYPE, TO_TYPE) \
3155 push_value (convert (TO_TYPE##_type_node, \
3156 pop_value (FROM_TYPE##_type_node))); \
3159 /* internal macro added for use by the WIDE case
3160 Added TREE_TYPE (decl) assignment, apbianco */
3161 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
3163 tree decl, value; \
3164 int index = OPVALUE; \
3165 tree type = OPTYPE; \
3166 value = pop_value (type); \
3167 type = TREE_TYPE (value); \
3168 decl = find_local_variable (index, type, oldpc); \
3169 set_local_type (index, type); \
3170 java_add_stmt (build (MODIFY_EXPR, type, decl, value)); \
3171 update_aliases (decl, index); \
3174 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3176 /* have to do this since OPERAND_VALUE may have side-effects */ \
3177 int opvalue = OPERAND_VALUE; \
3178 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3181 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3182 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3184 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3185 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3187 #define MONITOR_OPERATION(call) \
3189 tree o = pop_value (ptr_type_node); \
3190 tree c; \
3191 flush_quick_stack (); \
3192 c = build_java_monitor (call, o); \
3193 TREE_SIDE_EFFECTS (c) = 1; \
3194 java_add_stmt (c); \
3197 #define SPECIAL_IINC(IGNORED) \
3199 unsigned int local_var_index = IMMEDIATE_u1; \
3200 int ival = IMMEDIATE_s1; \
3201 expand_iinc(local_var_index, ival, oldpc); \
3204 #define SPECIAL_WIDE(IGNORED) \
3206 int modified_opcode = IMMEDIATE_u1; \
3207 unsigned int local_var_index = IMMEDIATE_u2; \
3208 switch (modified_opcode) \
3210 case OPCODE_iinc: \
3212 int ival = IMMEDIATE_s2; \
3213 expand_iinc (local_var_index, ival, oldpc); \
3214 break; \
3216 case OPCODE_iload: \
3217 case OPCODE_lload: \
3218 case OPCODE_fload: \
3219 case OPCODE_dload: \
3220 case OPCODE_aload: \
3222 /* duplicate code from LOAD macro */ \
3223 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3224 break; \
3226 case OPCODE_istore: \
3227 case OPCODE_lstore: \
3228 case OPCODE_fstore: \
3229 case OPCODE_dstore: \
3230 case OPCODE_astore: \
3232 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3233 break; \
3235 default: \
3236 error ("unrecogized wide sub-instruction"); \
3240 #define SPECIAL_THROW(IGNORED) \
3241 build_java_athrow (pop_value (throwable_type_node))
3243 #define SPECIAL_BREAK NOT_IMPL1
3244 #define IMPL NOT_IMPL
3246 #include "javaop.def"
3247 #undef JAVAOP
3248 default:
3249 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3251 return PC;
3254 /* Return the opcode at PC in the code section pointed to by
3255 CODE_OFFSET. */
3257 static unsigned char
3258 peek_opcode_at_pc (JCF *jcf, int code_offset, int pc)
3260 unsigned char opcode;
3261 long absolute_offset = (long)JCF_TELL (jcf);
3263 JCF_SEEK (jcf, code_offset);
3264 opcode = jcf->read_ptr [pc];
3265 JCF_SEEK (jcf, absolute_offset);
3266 return opcode;
3269 /* Some bytecode compilers are emitting accurate LocalVariableTable
3270 attributes. Here's an example:
3272 PC <t>store_<n>
3273 PC+1 ...
3275 Attribute "LocalVariableTable"
3276 slot #<n>: ... (PC: PC+1 length: L)
3278 This is accurate because the local in slot <n> really exists after
3279 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3281 This procedure recognizes this situation and extends the live range
3282 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3283 length of the store instruction.)
3285 This function is used by `give_name_to_locals' so that a local's
3286 DECL features a DECL_LOCAL_START_PC such that the first related
3287 store operation will use DECL as a destination, not a unrelated
3288 temporary created for the occasion.
3290 This function uses a global (instruction_bits) `note_instructions' should
3291 have allocated and filled properly. */
3294 maybe_adjust_start_pc (struct JCF *jcf, int code_offset,
3295 int start_pc, int slot)
3297 int first, index, opcode;
3298 int pc, insn_pc;
3299 int wide_found = 0;
3301 if (!start_pc)
3302 return start_pc;
3304 first = index = -1;
3306 /* Find last previous instruction and remember it */
3307 for (pc = start_pc-1; pc; pc--)
3308 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3309 break;
3310 insn_pc = pc;
3312 /* Retrieve the instruction, handle `wide'. */
3313 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3314 if (opcode == OPCODE_wide)
3316 wide_found = 1;
3317 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3320 switch (opcode)
3322 case OPCODE_astore_0:
3323 case OPCODE_astore_1:
3324 case OPCODE_astore_2:
3325 case OPCODE_astore_3:
3326 first = OPCODE_astore_0;
3327 break;
3329 case OPCODE_istore_0:
3330 case OPCODE_istore_1:
3331 case OPCODE_istore_2:
3332 case OPCODE_istore_3:
3333 first = OPCODE_istore_0;
3334 break;
3336 case OPCODE_lstore_0:
3337 case OPCODE_lstore_1:
3338 case OPCODE_lstore_2:
3339 case OPCODE_lstore_3:
3340 first = OPCODE_lstore_0;
3341 break;
3343 case OPCODE_fstore_0:
3344 case OPCODE_fstore_1:
3345 case OPCODE_fstore_2:
3346 case OPCODE_fstore_3:
3347 first = OPCODE_fstore_0;
3348 break;
3350 case OPCODE_dstore_0:
3351 case OPCODE_dstore_1:
3352 case OPCODE_dstore_2:
3353 case OPCODE_dstore_3:
3354 first = OPCODE_dstore_0;
3355 break;
3357 case OPCODE_astore:
3358 case OPCODE_istore:
3359 case OPCODE_lstore:
3360 case OPCODE_fstore:
3361 case OPCODE_dstore:
3362 index = peek_opcode_at_pc (jcf, code_offset, pc);
3363 if (wide_found)
3365 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3366 index = (other << 8) + index;
3368 break;
3371 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3372 means we have a <t>store. */
3373 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3374 start_pc = insn_pc;
3376 return start_pc;
3379 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3380 order, as specified by Java Language Specification.
3382 The problem is that while expand_expr will evaluate its sub-operands in
3383 left-to-right order, for variables it will just return an rtx (i.e.
3384 an lvalue) for the variable (rather than an rvalue). So it is possible
3385 that a later sub-operand will change the register, and when the
3386 actual operation is done, it will use the new value, when it should
3387 have used the original value.
3389 We fix this by using save_expr. This forces the sub-operand to be
3390 copied into a fresh virtual register,
3392 For method invocation, we modify the arguments so that a
3393 left-to-right order evaluation is performed. Saved expressions
3394 will, in CALL_EXPR order, be reused when the call will be expanded.
3397 tree
3398 force_evaluation_order (tree node)
3400 if (flag_syntax_only)
3401 return node;
3402 if (TREE_CODE (node) == CALL_EXPR
3403 || TREE_CODE (node) == NEW_CLASS_EXPR
3404 || (TREE_CODE (node) == COMPOUND_EXPR
3405 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3406 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3408 tree arg, cmp;
3410 if (!TREE_OPERAND (node, 1))
3411 return node;
3413 arg = node;
3415 /* Position arg properly, account for wrapped around ctors. */
3416 if (TREE_CODE (node) == COMPOUND_EXPR)
3417 arg = TREE_OPERAND (node, 0);
3419 arg = TREE_OPERAND (arg, 1);
3421 /* Not having a list of argument here is an error. */
3422 if (TREE_CODE (arg) != TREE_LIST)
3423 abort ();
3425 /* This reverses the evaluation order. This is a desired effect. */
3426 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3428 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3429 cmp = (cmp == NULL_TREE ? saved :
3430 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3431 TREE_VALUE (arg) = saved;
3434 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3435 TREE_SIDE_EFFECTS (cmp) = 1;
3437 if (cmp)
3439 cmp = build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
3440 if (TREE_TYPE (cmp) != void_type_node)
3441 cmp = save_expr (cmp);
3442 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3443 TREE_SIDE_EFFECTS (cmp) = 1;
3444 node = cmp;
3447 return node;
3450 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
3451 method in order to emit initialization code for each test flag. */
3453 static int
3454 emit_init_test_initialization (void **entry, void *x ATTRIBUTE_UNUSED)
3456 struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
3457 tree klass = build_class_ref (ite->key);
3458 tree rhs;
3460 /* If the DECL_INITIAL of the test flag is set to true, it
3461 means that the class is already initialized the time it
3462 is in use. */
3463 if (DECL_INITIAL (ite->value) == boolean_true_node)
3464 rhs = boolean_true_node;
3465 /* Otherwise, we initialize the class init check variable by looking
3466 at the `state' field of the class to see if it is already
3467 initialized. This makes things a bit faster if the class is
3468 already initialized, which should be the common case. */
3469 else
3470 rhs = build (GE_EXPR, boolean_type_node,
3471 build (COMPONENT_REF, byte_type_node,
3472 build1 (INDIRECT_REF, class_type_node, klass),
3473 lookup_field (&class_type_node,
3474 get_identifier ("state")),
3475 NULL_TREE),
3476 build_int_2 (JV_STATE_DONE, 0));
3478 expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
3479 ite->value, rhs));
3480 return true;
3483 /* EXPR_WITH_FILE_LOCATION are used to keep track of the exact
3484 location where an expression or an identifier were encountered. It
3485 is necessary for languages where the frontend parser will handle
3486 recursively more than one file (Java is one of them). */
3488 tree
3489 build_expr_wfl (tree node, const char *file, int line, int col)
3491 static const char *last_file = 0;
3492 static tree last_filenode = NULL_TREE;
3493 tree wfl = make_node (EXPR_WITH_FILE_LOCATION);
3495 EXPR_WFL_NODE (wfl) = node;
3496 EXPR_WFL_SET_LINECOL (wfl, line, col);
3497 if (file != last_file)
3499 last_file = file;
3500 last_filenode = file ? get_identifier (file) : NULL_TREE;
3503 EXPR_WFL_FILENAME_NODE (wfl) = last_filenode;
3504 if (node)
3506 if (IS_NON_TYPE_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
3507 TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
3508 TREE_TYPE (wfl) = TREE_TYPE (node);
3511 return wfl;
3515 /* Build a node to represent empty statements and blocks. */
3517 tree
3518 build_java_empty_stmt (void)
3520 tree t = build_empty_stmt ();
3521 CAN_COMPLETE_NORMALLY (t) = 1;
3522 return t;
3525 #include "gt-java-expr.h"