2001-06-04 Alexandre Petit-Bianco <apbianco@redhat.com>
[official-gcc.git] / gcc / java / expr.c
blobe9af7fcd455275694c46edd739153ca04ea7e4f6
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC 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 GNU CC 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 GNU CC; 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 "tree.h"
31 #include "real.h"
32 #include "rtl.h"
33 #include "flags.h"
34 #include "expr.h"
35 #include "java-tree.h"
36 #include "javaop.h"
37 #include "java-opcodes.h"
38 #include "jcf.h"
39 #include "java-except.h"
40 #include "parse.h"
41 #include "toplev.h"
42 #include "except.h"
43 #include "ggc.h"
45 static void flush_quick_stack PARAMS ((void));
46 static void push_value PARAMS ((tree));
47 static tree pop_value PARAMS ((tree));
48 static void java_stack_swap PARAMS ((void));
49 static void java_stack_dup PARAMS ((int, int));
50 static void build_java_athrow PARAMS ((tree));
51 static void build_java_jsr PARAMS ((tree, tree));
52 static void build_java_ret PARAMS ((tree));
53 static void expand_java_multianewarray PARAMS ((tree, int));
54 static void expand_java_arraystore PARAMS ((tree));
55 static void expand_java_arrayload PARAMS ((tree));
56 static void expand_java_array_length PARAMS ((void));
57 static tree build_java_monitor PARAMS ((tree, tree));
58 static void expand_java_pushc PARAMS ((int, tree));
59 static void expand_java_return PARAMS ((tree));
60 static void expand_java_NEW PARAMS ((tree));
61 static void expand_java_INSTANCEOF PARAMS ((tree));
62 static void expand_java_CHECKCAST PARAMS ((tree));
63 static void expand_iinc PARAMS ((unsigned int, int, int));
64 static void expand_java_binop PARAMS ((tree, enum tree_code));
65 static void note_label PARAMS ((int, int));
66 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
67 static void expand_test PARAMS ((enum tree_code, tree, int));
68 static void expand_cond PARAMS ((enum tree_code, tree, int));
69 static void expand_java_goto PARAMS ((int));
70 #if 0
71 static void expand_java_call PARAMS ((int, int));
72 static void expand_java_ret PARAMS ((tree));
73 #endif
74 static tree pop_arguments PARAMS ((tree));
75 static void expand_invoke PARAMS ((int, int, int));
76 static void expand_java_field_op PARAMS ((int, int, int));
77 static void java_push_constant_from_pool PARAMS ((struct JCF *, int));
78 static void java_stack_pop PARAMS ((int));
79 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
80 static tree build_java_check_indexed_type PARAMS ((tree, tree));
81 static tree java_array_data_offset PARAMS ((tree));
82 static tree case_identity PARAMS ((tree, tree));
83 static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int));
85 static tree operand_type[59];
86 extern struct obstack permanent_obstack;
88 static tree methods_ident = NULL_TREE;
89 static tree ncode_ident = NULL_TREE;
90 tree dtable_ident = NULL_TREE;
92 /* Set to non-zero value in order to emit class initilization code
93 before static field references. */
94 int always_initialize_class_p;
96 /* We store the stack state in two places:
97 Within a basic block, we use the quick_stack, which is a
98 pushdown list (TREE_LISTs) of expression nodes.
99 This is the top part of the stack; below that we use find_stack_slot.
100 At the end of a basic block, the quick_stack must be flushed
101 to the stack slot array (as handled by find_stack_slot).
102 Using quick_stack generates better code (especially when
103 compiled without optimization), because we do not have to
104 explicitly store and load trees to temporary variables.
106 If a variable is on the quick stack, it means the value of variable
107 when the quick stack was last flushed. Conceptually, flush_quick_stack
108 saves all the the quick_stack elements in parellel. However, that is
109 complicated, so it actually saves them (i.e. copies each stack value
110 to is home virtual register) from low indexes. This allows a quick_stack
111 element at index i (counting from the bottom of stack the) to references
112 slot virtuals for register that are >= i, but not those that are deeper.
113 This convention makes most operations easier. For example iadd works
114 even when the stack contains (reg[0], reg[1]): It results in the
115 stack containing (reg[0]+reg[1]), which is OK. However, some stack
116 operations are more complicated. For example dup given a stack
117 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
118 the convention, since stack value 1 would refer to a register with
119 lower index (reg[0]), which flush_quick_stack does not safely handle.
120 So dup cannot just add an extra element to the quick_stack, but iadd can.
123 static tree quick_stack = NULL_TREE;
125 /* A free-list of unused permamnet TREE_LIST nodes. */
126 static tree tree_list_free_list = NULL_TREE;
128 /* The stack pointer of the Java virtual machine.
129 This does include the size of the quick_stack. */
131 int stack_pointer;
133 const unsigned char *linenumber_table;
134 int linenumber_count;
136 void
137 init_expr_processing()
139 operand_type[21] = operand_type[54] = int_type_node;
140 operand_type[22] = operand_type[55] = long_type_node;
141 operand_type[23] = operand_type[56] = float_type_node;
142 operand_type[24] = operand_type[57] = double_type_node;
143 operand_type[25] = operand_type[58] = ptr_type_node;
144 ggc_add_tree_root (operand_type, 59);
145 ggc_add_tree_root (&methods_ident, 1);
146 ggc_add_tree_root (&ncode_ident, 1);
147 ggc_add_tree_root (&quick_stack, 1);
148 ggc_add_tree_root (&tree_list_free_list, 1);
151 tree
152 truthvalue_conversion (expr)
153 tree expr;
155 /* It is simpler and generates better code to have only TRUTH_*_EXPR
156 or comparison expressions as truth values at this level.
158 This function should normally be identity for Java. */
160 switch (TREE_CODE (expr))
162 case EQ_EXPR:
163 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
164 case TRUTH_ANDIF_EXPR:
165 case TRUTH_ORIF_EXPR:
166 case TRUTH_AND_EXPR:
167 case TRUTH_OR_EXPR:
168 case ERROR_MARK:
169 return expr;
171 case INTEGER_CST:
172 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
174 case REAL_CST:
175 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
177 /* are these legal? XXX JH */
178 case NEGATE_EXPR:
179 case ABS_EXPR:
180 case FLOAT_EXPR:
181 case FFS_EXPR:
182 /* These don't change whether an object is non-zero or zero. */
183 return truthvalue_conversion (TREE_OPERAND (expr, 0));
185 case COND_EXPR:
186 /* Distribute the conversion into the arms of a COND_EXPR. */
187 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
188 truthvalue_conversion (TREE_OPERAND (expr, 1)),
189 truthvalue_conversion (TREE_OPERAND (expr, 2))));
191 case NOP_EXPR:
192 /* If this is widening the argument, we can ignore it. */
193 if (TYPE_PRECISION (TREE_TYPE (expr))
194 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
195 return truthvalue_conversion (TREE_OPERAND (expr, 0));
196 /* fall through to default */
198 default:
199 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
203 #ifdef JAVA_USE_HANDLES
204 /* Given a pointer to a handle, get a pointer to an object. */
206 tree
207 unhand_expr (expr)
208 tree expr;
210 tree field, handle_type;
211 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
212 handle_type = TREE_TYPE (expr);
213 field = TYPE_FIELDS (handle_type);
214 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
215 return expr;
217 #endif
219 /* Save any stack slots that happen to be in the quick_stack into their
220 home virtual register slots.
222 The copy order is from low stack index to high, to support the invariant
223 that the expression for a slot may contain decls for stack slots with
224 higher (or the same) index, but not lower. */
226 static void
227 flush_quick_stack ()
229 int stack_index = stack_pointer;
230 register tree prev, cur, next;
232 /* First reverse the quick_stack, and count the number of slots it has. */
233 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
235 next = TREE_CHAIN (cur);
236 TREE_CHAIN (cur) = prev;
237 prev = cur;
238 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
240 quick_stack = prev;
242 while (quick_stack != NULL_TREE)
244 tree decl;
245 tree node = quick_stack, type;
246 quick_stack = TREE_CHAIN (node);
247 TREE_CHAIN (node) = tree_list_free_list;
248 tree_list_free_list = node;
249 node = TREE_VALUE (node);
250 type = TREE_TYPE (node);
252 decl = find_stack_slot (stack_index, type);
253 if (decl != node)
254 expand_assignment (decl, node, 0, 0);
255 stack_index += 1 + TYPE_IS_WIDE (type);
259 /* Push TYPE on the type stack.
260 Return true on success, 0 on overflow. */
263 push_type_0 (type)
264 tree type;
266 int n_words;
267 type = promote_type (type);
268 n_words = 1 + TYPE_IS_WIDE (type);
269 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
270 return 0;
271 stack_type_map[stack_pointer++] = type;
272 n_words--;
273 while (--n_words >= 0)
274 stack_type_map[stack_pointer++] = TYPE_SECOND;
275 return 1;
278 void
279 push_type (type)
280 tree type;
282 if (! push_type_0 (type))
283 abort ();
286 static void
287 push_value (value)
288 tree value;
290 tree type = TREE_TYPE (value);
291 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
293 type = promote_type (type);
294 value = convert (type, value);
296 push_type (type);
297 if (tree_list_free_list == NULL_TREE)
298 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
299 else
301 tree node = tree_list_free_list;
302 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
303 TREE_VALUE (node) = value;
304 TREE_CHAIN (node) = quick_stack;
305 quick_stack = node;
309 /* Pop a type from the type stack.
310 TYPE is the expected type. Return the actual type, which must be
311 convertible to TYPE.
312 On an error, *MESSAGEP is set to a freshly malloc'd error message. */
314 tree
315 pop_type_0 (type, messagep)
316 tree type;
317 char **messagep;
319 int n_words;
320 tree t;
321 *messagep = NULL;
322 if (TREE_CODE (type) == RECORD_TYPE)
323 type = promote_type (type);
324 n_words = 1 + TYPE_IS_WIDE (type);
325 if (stack_pointer < n_words)
327 *messagep = xstrdup ("stack underflow");
328 return type;
330 while (--n_words > 0)
332 if (stack_type_map[--stack_pointer] != void_type_node)
334 *messagep = xstrdup ("Invalid multi-word value on type stack");
335 return type;
338 t = stack_type_map[--stack_pointer];
339 if (type == NULL_TREE || t == type)
340 return t;
341 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
342 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
343 return t;
344 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
346 if (type == ptr_type_node || type == object_ptr_type_node)
347 return t;
348 else if (t == ptr_type_node) /* Special case for null reference. */
349 return type;
350 else if (can_widen_reference_to (t, type))
351 return t;
352 /* This is a kludge, but matches what Sun's verifier does.
353 It can be tricked, but is safe as long as type errors
354 (i.e. interface method calls) are caught at run-time. */
355 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
356 return object_ptr_type_node;
359 /* lang_printable_name uses a static buffer, so we must save the result
360 from calling it the first time. */
362 char *temp = xstrdup (lang_printable_name (type, 0));
363 *messagep = concat ("expected type '", temp,
364 "' but stack contains '", lang_printable_name (t, 0),
365 "'", NULL);
366 free (temp);
368 return type;
371 /* Pop a type from the type stack.
372 TYPE is the expected type. Return the actual type, which must be
373 convertible to TYPE, otherwise call error. */
375 tree
376 pop_type (type)
377 tree type;
379 char *message = NULL;
380 type = pop_type_0 (type, &message);
381 if (message != NULL)
383 error ("%s", message);
384 free (message);
386 return type;
389 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
390 Handles array types and interfaces. */
393 can_widen_reference_to (source_type, target_type)
394 tree source_type, target_type;
396 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
397 return 1;
399 /* Get rid of pointers */
400 if (TREE_CODE (source_type) == POINTER_TYPE)
401 source_type = TREE_TYPE (source_type);
402 if (TREE_CODE (target_type) == POINTER_TYPE)
403 target_type = TREE_TYPE (target_type);
405 if (source_type == target_type)
406 return 1;
407 else
409 source_type = HANDLE_TO_CLASS_TYPE (source_type);
410 target_type = HANDLE_TO_CLASS_TYPE (target_type);
411 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
413 HOST_WIDE_INT source_length, target_length;
414 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
415 return 0;
416 target_length = java_array_type_length (target_type);
417 if (target_length >= 0)
419 source_length = java_array_type_length (source_type);
420 if (source_length != target_length)
421 return 0;
423 source_type = TYPE_ARRAY_ELEMENT (source_type);
424 target_type = TYPE_ARRAY_ELEMENT (target_type);
425 if (source_type == target_type)
426 return 1;
427 if (TREE_CODE (source_type) != POINTER_TYPE
428 || TREE_CODE (target_type) != POINTER_TYPE)
429 return 0;
430 return can_widen_reference_to (source_type, target_type);
432 else
434 int source_depth = class_depth (source_type);
435 int target_depth = class_depth (target_type);
437 /* class_depth can return a negative depth if an error occurred */
438 if (source_depth < 0 || target_depth < 0)
439 return 0;
441 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
443 /* target_type is OK if source_type or source_type ancestors
444 implement target_type. We handle multiple sub-interfaces */
446 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
447 int n = TREE_VEC_LENGTH (basetype_vec), i;
448 for (i=0 ; i < n; i++)
449 if (can_widen_reference_to
450 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
451 target_type))
452 return 1;
453 if (n == 0)
454 return 0;
457 for ( ; source_depth > target_depth; source_depth--)
459 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
461 return source_type == target_type;
466 static tree
467 pop_value (type)
468 tree type;
470 type = pop_type (type);
471 if (quick_stack)
473 tree node = quick_stack;
474 quick_stack = TREE_CHAIN (quick_stack);
475 TREE_CHAIN (node) = tree_list_free_list;
476 tree_list_free_list = node;
477 node = TREE_VALUE (node);
478 return node;
480 else
481 return find_stack_slot (stack_pointer, promote_type (type));
485 /* Pop and discrad the top COUNT stack slots. */
487 static void
488 java_stack_pop (count)
489 int count;
491 while (count > 0)
493 tree type, val;
495 if (stack_pointer == 0)
496 abort ();
498 type = stack_type_map[stack_pointer - 1];
499 if (type == TYPE_SECOND)
501 count--;
502 if (stack_pointer == 1 || count <= 0)
503 abort ();
505 type = stack_type_map[stack_pointer - 2];
507 val = pop_value (type);
508 count--;
512 /* Implement the 'swap' operator (to swap two top stack slots). */
514 static void
515 java_stack_swap ()
517 tree type1, type2;
518 rtx temp;
519 tree decl1, decl2;
521 if (stack_pointer < 2
522 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
523 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
524 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
525 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
526 /* Bad stack swap. */
527 abort ();
529 flush_quick_stack ();
530 decl1 = find_stack_slot (stack_pointer - 1, type1);
531 decl2 = find_stack_slot (stack_pointer - 2, type2);
532 temp = copy_to_reg (DECL_RTL (decl1));
533 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
534 emit_move_insn (DECL_RTL (decl2), temp);
535 stack_type_map[stack_pointer - 1] = type2;
536 stack_type_map[stack_pointer - 2] = type1;
539 static void
540 java_stack_dup (size, offset)
541 int size, offset;
543 int low_index = stack_pointer - size - offset;
544 int dst_index;
545 if (low_index < 0)
546 error ("stack underflow - dup* operation");
548 flush_quick_stack ();
550 stack_pointer += size;
551 dst_index = stack_pointer;
553 for (dst_index = stack_pointer; --dst_index >= low_index; )
555 tree type;
556 int src_index = dst_index - size;
557 if (src_index < low_index)
558 src_index = dst_index + size + offset;
559 type = stack_type_map [src_index];
560 if (type == TYPE_SECOND)
562 if (src_index <= low_index)
563 /* Dup operation splits 64-bit number. */
564 abort ();
566 stack_type_map[dst_index] = type;
567 src_index--; dst_index--;
568 type = stack_type_map[src_index];
569 if (! TYPE_IS_WIDE (type))
570 abort ();
572 else if (TYPE_IS_WIDE (type))
573 abort ();
575 if (src_index != dst_index)
577 tree src_decl = find_stack_slot (src_index, type);
578 tree dst_decl = find_stack_slot (dst_index, type);
579 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
580 stack_type_map[dst_index] = type;
585 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
586 value stack. */
588 static void
589 build_java_athrow (node)
590 tree node;
592 tree call;
594 call = build (CALL_EXPR,
595 void_type_node,
596 build_address_of (throw_node),
597 build_tree_list (NULL_TREE, node),
598 NULL_TREE);
599 TREE_SIDE_EFFECTS (call) = 1;
600 expand_expr_stmt (call);
601 java_stack_pop (stack_pointer);
604 /* Implementation for jsr/ret */
606 static void
607 build_java_jsr (where, ret)
608 tree where;
609 tree ret;
611 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
612 push_value (ret_label);
613 flush_quick_stack ();
614 emit_jump (label_rtx (where));
615 expand_label (ret);
618 static void
619 build_java_ret (location)
620 tree location;
622 expand_computed_goto (location);
625 /* Implementation of operations on array: new, load, store, length */
627 /* Array core info access macros */
629 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
630 byte_position (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))
632 tree
633 decode_newarray_type (atype)
634 int atype;
636 switch (atype)
638 case 4: return boolean_type_node;
639 case 5: return char_type_node;
640 case 6: return float_type_node;
641 case 7: return double_type_node;
642 case 8: return byte_type_node;
643 case 9: return short_type_node;
644 case 10: return int_type_node;
645 case 11: return long_type_node;
646 default: return NULL_TREE;
650 /* Map primitive type to the code used by OPCODE_newarray. */
653 encode_newarray_type (type)
654 tree type;
656 if (type == boolean_type_node)
657 return 4;
658 else if (type == char_type_node)
659 return 5;
660 else if (type == float_type_node)
661 return 6;
662 else if (type == double_type_node)
663 return 7;
664 else if (type == byte_type_node)
665 return 8;
666 else if (type == short_type_node)
667 return 9;
668 else if (type == int_type_node)
669 return 10;
670 else if (type == long_type_node)
671 return 11;
672 else
673 abort ();
676 /* Build a call to _Jv_ThrowBadArrayIndex(), the
677 ArrayIndexOfBoundsException exception handler. */
679 static tree
680 build_java_throw_out_of_bounds_exception (index)
681 tree index;
683 tree node = build (CALL_EXPR, int_type_node,
684 build_address_of (soft_badarrayindex_node),
685 build_tree_list (NULL_TREE, index), NULL_TREE);
686 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
687 return (node);
690 /* Return the length of an array. Doesn't perform any checking on the nature
691 or value of the array NODE. May be used to implement some bytecodes. */
693 tree
694 build_java_array_length_access (node)
695 tree node;
697 tree type = TREE_TYPE (node);
698 HOST_WIDE_INT length;
700 if (!is_array_type_p (type))
701 abort ();
703 length = java_array_type_length (type);
704 if (length >= 0)
705 return build_int_2 (length, 0);
706 return fold (build1 (INDIRECT_REF, int_type_node,
707 fold (build (PLUS_EXPR, ptr_type_node,
708 java_check_reference (node, 1),
709 JAVA_ARRAY_LENGTH_OFFSET(node)))));
712 /* Optionally checks a reference against the NULL pointer. ARG1: the
713 expr, ARG2: we should check the reference. Don't generate extra
714 checks if we're not generating code. */
716 tree
717 java_check_reference (expr, check)
718 tree expr;
719 int check;
721 if (!flag_syntax_only && check)
723 tree cond;
724 expr = save_expr (expr);
725 cond = build (COND_EXPR, void_type_node,
726 build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
727 build (CALL_EXPR, void_type_node,
728 build_address_of (soft_nullpointer_node),
729 NULL_TREE, NULL_TREE),
730 empty_stmt_node);
731 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
734 return expr;
737 /* Reference an object: just like an INDIRECT_REF, but with checking. */
739 tree
740 build_java_indirect_ref (type, expr, check)
741 tree type;
742 tree expr;
743 int check;
745 return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
748 static tree
749 java_array_data_offset (array)
750 tree array;
752 tree array_type = TREE_TYPE (TREE_TYPE (array));
753 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
755 if (data_fld == NULL_TREE)
756 return size_in_bytes (array_type);
757 else
758 return byte_position (data_fld);
761 /* Implement array indexing (either as l-value or r-value).
762 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
763 Optionally performs bounds checking and/or test to NULL.
764 At this point, ARRAY should have been verified as an array. */
766 tree
767 build_java_arrayaccess (array, type, index)
768 tree array, type, index;
770 tree arith, node, throw = NULL_TREE;
772 arith = fold (build (PLUS_EXPR, int_type_node,
773 java_array_data_offset (array),
774 fold (build (MULT_EXPR, int_type_node,
775 index, size_in_bytes(type)))));
777 if (flag_bounds_check)
779 /* Generate:
780 * (unsigned jint) INDEX >= (unsigned jint) LEN
781 * && throw ArrayIndexOutOfBoundsException.
782 * Note this is equivalent to and more efficient than:
783 * INDEX < 0 || INDEX >= LEN && throw ... */
784 tree test;
785 tree len = build_java_array_length_access (array);
786 TREE_TYPE (len) = unsigned_int_type_node;
787 test = fold (build (GE_EXPR, boolean_type_node,
788 convert (unsigned_int_type_node, index),
789 len));
790 if (! integer_zerop (test))
792 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
793 build_java_throw_out_of_bounds_exception (index));
794 /* allows expansion within COMPOUND */
795 TREE_SIDE_EFFECTS( throw ) = 1;
799 node = build1 (INDIRECT_REF, type,
800 fold (build (PLUS_EXPR, ptr_type_node,
801 java_check_reference (array, flag_check_references),
802 (throw ? build (COMPOUND_EXPR, int_type_node,
803 throw, arith )
804 : arith))));
806 return node;
809 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
810 ARRAY_NODE. This function is used to retrieve something less vague than
811 a pointer type when indexing the first dimension of something like [[<t>.
812 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
813 return unchanged.
814 As a side effect, it also makes sure that ARRAY_NODE is an array. */
816 static tree
817 build_java_check_indexed_type (array_node, indexed_type)
818 tree array_node;
819 tree indexed_type;
821 tree elt_type;
823 if (!is_array_type_p (TREE_TYPE (array_node)))
824 abort ();
826 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
828 if (indexed_type == ptr_type_node )
829 return promote_type (elt_type);
831 /* BYTE/BOOLEAN store and load are used for both type */
832 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
833 return boolean_type_node;
835 if (indexed_type != elt_type )
836 abort ();
837 else
838 return indexed_type;
841 /* newarray triggers a call to _Jv_NewPrimArray. This function should be
842 called with an integer code (the type of array to create), and the length
843 of the array to create. */
845 tree
846 build_newarray (atype_value, length)
847 int atype_value;
848 tree length;
850 tree type_arg;
852 tree prim_type = decode_newarray_type (atype_value);
853 tree type
854 = build_java_array_type (prim_type,
855 host_integerp (length, 0) == INTEGER_CST
856 ? tree_low_cst (length, 0) : -1);
858 /* If compiling to native, pass a reference to the primitive type class
859 and save the runtime some work. However, the bytecode generator
860 expects to find the type_code int here. */
861 if (flag_emit_class_files)
862 type_arg = build_int_2 (atype_value, 0);
863 else
864 type_arg = build_class_ref (prim_type);
866 return build (CALL_EXPR, promote_type (type),
867 build_address_of (soft_newarray_node),
868 tree_cons (NULL_TREE,
869 type_arg,
870 build_tree_list (NULL_TREE, length)),
871 NULL_TREE);
874 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
875 of the dimension. */
877 tree
878 build_anewarray (class_type, length)
879 tree class_type;
880 tree length;
882 tree type
883 = build_java_array_type (class_type,
884 host_integerp (length, 0)
885 ? tree_low_cst (length, 0) : -1);
887 return build (CALL_EXPR, promote_type (type),
888 build_address_of (soft_anewarray_node),
889 tree_cons (NULL_TREE, length,
890 tree_cons (NULL_TREE, build_class_ref (class_type),
891 build_tree_list (NULL_TREE,
892 null_pointer_node))),
893 NULL_TREE);
896 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
898 tree
899 build_new_array (type, length)
900 tree type;
901 tree length;
903 if (JPRIMITIVE_TYPE_P (type))
904 return build_newarray (encode_newarray_type (type), length);
905 else
906 return build_anewarray (TREE_TYPE (type), length);
909 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
910 class pointer, a number of dimensions and the matching number of
911 dimensions. The argument list is NULL terminated. */
913 static void
914 expand_java_multianewarray (class_type, ndim)
915 tree class_type;
916 int ndim;
918 int i;
919 tree args = build_tree_list( NULL_TREE, null_pointer_node );
921 for( i = 0; i < ndim; i++ )
922 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
924 push_value (build (CALL_EXPR,
925 promote_type (class_type),
926 build_address_of (soft_multianewarray_node),
927 tree_cons (NULL_TREE, build_class_ref (class_type),
928 tree_cons (NULL_TREE,
929 build_int_2 (ndim, 0), args )),
930 NULL_TREE));
933 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
934 ARRAY is an array type. May expand some bound checking and NULL
935 pointer checking. RHS_TYPE_NODE we are going to store. In the case
936 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
937 INT. In those cases, we make the convertion.
939 if ARRAy is a reference type, the assignment is checked at run-time
940 to make sure that the RHS can be assigned to the array element
941 type. It is not necessary to generate this code if ARRAY is final. */
943 static void
944 expand_java_arraystore (rhs_type_node)
945 tree rhs_type_node;
947 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
948 && TYPE_PRECISION (rhs_type_node) <= 32) ?
949 int_type_node : rhs_type_node);
950 tree index = pop_value (int_type_node);
951 tree array = pop_value (ptr_type_node);
953 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
955 flush_quick_stack ();
957 index = save_expr (index);
958 array = save_expr (array);
960 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
962 tree check = build (CALL_EXPR, void_type_node,
963 build_address_of (soft_checkarraystore_node),
964 tree_cons (NULL_TREE, array,
965 build_tree_list (NULL_TREE, rhs_node)),
966 NULL_TREE);
967 TREE_SIDE_EFFECTS (check) = 1;
968 expand_expr_stmt (check);
971 expand_assignment (build_java_arrayaccess (array,
972 rhs_type_node,
973 index),
974 rhs_node, 0, 0);
977 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
978 sure that LHS is an array type. May expand some bound checking and NULL
979 pointer checking.
980 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
981 BOOLEAN/SHORT, we push a promoted type back to the stack.
984 static void
985 expand_java_arrayload (lhs_type_node )
986 tree lhs_type_node;
988 tree load_node;
989 tree index_node = pop_value (int_type_node);
990 tree array_node = pop_value (ptr_type_node);
992 index_node = save_expr (index_node);
993 array_node = save_expr (array_node);
994 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
996 load_node = build_java_arrayaccess (array_node,
997 lhs_type_node,
998 index_node);
1000 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1001 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
1002 push_value (load_node);
1005 /* Expands .length. Makes sure that we deal with and array and may expand
1006 a NULL check on the array object. */
1008 static void
1009 expand_java_array_length ()
1011 tree array = pop_value (ptr_type_node);
1012 tree length = build_java_array_length_access (array);
1014 push_value (length);
1017 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1018 either soft_monitorenter_node or soft_monitorexit_node. */
1020 static tree
1021 build_java_monitor (call, object)
1022 tree call;
1023 tree object;
1025 return (build (CALL_EXPR,
1026 void_type_node,
1027 build_address_of (call),
1028 build_tree_list (NULL_TREE, object),
1029 NULL_TREE));
1032 /* Emit code for one of the PUSHC instructions. */
1034 static void
1035 expand_java_pushc (ival, type)
1036 int ival;
1037 tree type;
1039 tree value;
1040 if (type == ptr_type_node && ival == 0)
1041 value = null_pointer_node;
1042 else if (type == int_type_node || type == long_type_node)
1044 value = build_int_2 (ival, ival < 0 ? -1 : 0);
1045 TREE_TYPE (value) = type;
1047 else if (type == float_type_node || type == double_type_node)
1049 REAL_VALUE_TYPE x;
1050 #ifdef REAL_ARITHMETIC
1051 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1052 #else
1053 x = ival;
1054 #endif
1055 value = build_real (type, x);
1057 else
1058 abort ();
1060 push_value (value);
1063 static void
1064 expand_java_return (type)
1065 tree type;
1067 if (type == void_type_node)
1068 expand_null_return ();
1069 else
1071 tree retval = pop_value (type);
1072 tree res = DECL_RESULT (current_function_decl);
1073 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1075 /* Handle the situation where the native integer type is smaller
1076 than the JVM integer. It can happen for many cross compilers.
1077 The whole if expression just goes away if INT_TYPE_SIZE < 32
1078 is false. */
1079 if (INT_TYPE_SIZE < 32
1080 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1081 < GET_MODE_SIZE (TYPE_MODE (type))))
1082 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1084 TREE_SIDE_EFFECTS (retval) = 1;
1085 expand_return (retval);
1089 tree
1090 build_address_of (value)
1091 tree value;
1093 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1096 static void
1097 expand_java_NEW (type)
1098 tree type;
1100 if (! CLASS_LOADED_P (type))
1101 load_class (type, 1);
1102 safe_layout_class (type);
1103 push_value (build (CALL_EXPR, promote_type (type),
1104 build_address_of (alloc_object_node),
1105 tree_cons (NULL_TREE, build_class_ref (type),
1106 build_tree_list (NULL_TREE,
1107 size_in_bytes (type))),
1108 NULL_TREE));
1111 /* This returns an expression which will extract the class of an
1112 object. */
1114 tree
1115 build_get_class (value)
1116 tree value;
1118 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1119 tree vtable_field = lookup_field (&object_type_node,
1120 get_identifier ("vtable"));
1121 return build (COMPONENT_REF, class_ptr_type,
1122 build1 (INDIRECT_REF, dtable_type,
1123 build (COMPONENT_REF, dtable_ptr_type,
1124 build_java_indirect_ref (object_type_node, value,
1125 flag_check_references),
1126 vtable_field)),
1127 class_field);
1130 /* This builds the tree representation of the `instanceof' operator.
1131 It tries various tricks to optimize this in cases where types are
1132 known. */
1134 tree
1135 build_instanceof (value, type)
1136 tree value, type;
1138 tree expr;
1139 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1140 tree valtype = TREE_TYPE (TREE_TYPE (value));
1141 tree valclass = TYPE_NAME (valtype);
1142 tree klass;
1144 /* When compiling from bytecode, we need to ensure that TYPE has
1145 been loaded. */
1146 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1148 load_class (type, 1);
1149 safe_layout_class (type);
1150 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1151 return error_mark_node;
1153 klass = TYPE_NAME (type);
1155 if (type == object_type_node || inherits_from_p (valtype, type))
1157 /* Anything except `null' is an instance of Object. Likewise,
1158 if the object is known to be an instance of the class, then
1159 we only need to check for `null'. */
1160 expr = build (COND_EXPR, itype,
1161 value,
1162 boolean_true_node, boolean_false_node);
1164 else if (! TYPE_ARRAY_P (type)
1165 && ! TYPE_ARRAY_P (valtype)
1166 && DECL_P (klass) && DECL_P (valclass)
1167 && ! CLASS_INTERFACE (valclass)
1168 && ! CLASS_INTERFACE (klass)
1169 && ! inherits_from_p (type, valtype)
1170 && (CLASS_FINAL (klass)
1171 || ! inherits_from_p (valtype, type)))
1173 /* The classes are from different branches of the derivation
1174 tree, so we immediately know the answer. */
1175 expr = boolean_false_node;
1177 else if (DECL_P (klass) && CLASS_FINAL (klass))
1179 tree save = save_expr (value);
1180 expr = build (COND_EXPR, itype,
1181 save,
1182 build (EQ_EXPR, itype,
1183 build_get_class (save),
1184 build_class_ref (type)),
1185 boolean_false_node);
1187 else
1189 expr = build (CALL_EXPR, itype,
1190 build_address_of (soft_instanceof_node),
1191 tree_cons (NULL_TREE, value,
1192 build_tree_list (NULL_TREE,
1193 build_class_ref (type))),
1194 NULL_TREE);
1196 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1197 return expr;
1200 static void
1201 expand_java_INSTANCEOF (type)
1202 tree type;
1204 tree value = pop_value (object_ptr_type_node);
1205 value = build_instanceof (value, type);
1206 push_value (value);
1209 static void
1210 expand_java_CHECKCAST (type)
1211 tree type;
1213 tree value = pop_value (ptr_type_node);
1214 value = build (CALL_EXPR, promote_type (type),
1215 build_address_of (soft_checkcast_node),
1216 tree_cons (NULL_TREE, build_class_ref (type),
1217 build_tree_list (NULL_TREE, value)),
1218 NULL_TREE);
1219 push_value (value);
1222 static void
1223 expand_iinc (local_var_index, ival, pc)
1224 unsigned int local_var_index;
1225 int ival;
1226 int pc;
1228 tree local_var, res;
1229 tree constant_value;
1231 flush_quick_stack ();
1232 local_var = find_local_variable (local_var_index, int_type_node, pc);
1233 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1234 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1235 expand_assignment (local_var, res, 0, 0);
1239 tree
1240 build_java_soft_divmod (op, type, op1, op2)
1241 enum tree_code op;
1242 tree type, op1, op2;
1244 tree call = NULL;
1245 tree arg1 = convert (type, op1);
1246 tree arg2 = convert (type, op2);
1248 if (type == int_type_node)
1250 switch (op)
1252 case TRUNC_DIV_EXPR:
1253 call = soft_idiv_node;
1254 break;
1255 case TRUNC_MOD_EXPR:
1256 call = soft_irem_node;
1257 break;
1258 default:
1259 break;
1262 else if (type == long_type_node)
1264 switch (op)
1266 case TRUNC_DIV_EXPR:
1267 call = soft_ldiv_node;
1268 break;
1269 case TRUNC_MOD_EXPR:
1270 call = soft_lrem_node;
1271 break;
1272 default:
1273 break;
1277 if (! call)
1278 abort ();
1280 call = build (CALL_EXPR, type,
1281 build_address_of (call),
1282 tree_cons (NULL_TREE, arg1,
1283 build_tree_list (NULL_TREE, arg2)),
1284 NULL_TREE);
1286 return call;
1289 tree
1290 build_java_binop (op, type, arg1, arg2)
1291 enum tree_code op;
1292 tree type, arg1, arg2;
1294 tree mask;
1295 switch (op)
1297 case URSHIFT_EXPR:
1299 tree u_type = unsigned_type (type);
1300 arg1 = convert (u_type, arg1);
1301 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1302 return convert (type, arg1);
1304 case LSHIFT_EXPR:
1305 case RSHIFT_EXPR:
1306 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1307 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1308 break;
1310 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1311 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1312 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1314 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1315 boolean_type_node, arg1, arg2));
1316 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1317 tree second_compare = fold (build (COND_EXPR, int_type_node,
1318 ifexp2, integer_zero_node,
1319 op == COMPARE_L_EXPR
1320 ? integer_minus_one_node
1321 : integer_one_node));
1322 return fold (build (COND_EXPR, int_type_node, ifexp1,
1323 op == COMPARE_L_EXPR ? integer_one_node
1324 : integer_minus_one_node,
1325 second_compare));
1327 case COMPARE_EXPR:
1328 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1330 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1331 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1332 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1333 ifexp2, integer_one_node,
1334 integer_zero_node));
1335 return fold (build (COND_EXPR, int_type_node,
1336 ifexp1, integer_minus_one_node, second_compare));
1338 case TRUNC_DIV_EXPR:
1339 case TRUNC_MOD_EXPR:
1340 if (TREE_CODE (type) == REAL_TYPE
1341 && op == TRUNC_MOD_EXPR)
1343 tree call;
1344 if (type != double_type_node)
1346 arg1 = convert (double_type_node, arg1);
1347 arg2 = convert (double_type_node, arg2);
1349 call = build (CALL_EXPR, double_type_node,
1350 build_address_of (soft_fmod_node),
1351 tree_cons (NULL_TREE, arg1,
1352 build_tree_list (NULL_TREE, arg2)),
1353 NULL_TREE);
1354 if (type != double_type_node)
1355 call = convert (type, call);
1356 return call;
1359 if (TREE_CODE (type) == INTEGER_TYPE
1360 && flag_use_divide_subroutine
1361 && ! flag_syntax_only)
1362 return build_java_soft_divmod (op, type, arg1, arg2);
1364 break;
1365 default: ;
1367 return fold (build (op, type, arg1, arg2));
1370 static void
1371 expand_java_binop (type, op)
1372 tree type; enum tree_code op;
1374 tree larg, rarg;
1375 tree ltype = type;
1376 tree rtype = type;
1377 switch (op)
1379 case LSHIFT_EXPR:
1380 case RSHIFT_EXPR:
1381 case URSHIFT_EXPR:
1382 rtype = int_type_node;
1383 rarg = pop_value (rtype);
1384 break;
1385 default:
1386 rarg = pop_value (rtype);
1388 larg = pop_value (ltype);
1389 push_value (build_java_binop (op, type, larg, rarg));
1392 /* Lookup the field named NAME in *TYPEP or its super classes.
1393 If not found, return NULL_TREE.
1394 (If the *TYPEP is not found, or if the field reference is
1395 ambiguous, return error_mark_node.)
1396 If found, return the FIELD_DECL, and set *TYPEP to the
1397 class containing the field. */
1399 tree
1400 lookup_field (typep, name)
1401 tree *typep;
1402 tree name;
1404 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1406 load_class (*typep, 1);
1407 safe_layout_class (*typep);
1408 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1409 return error_mark_node;
1413 tree field, basetype_vec;
1414 tree save_field;
1415 int n, i;
1417 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1418 if (DECL_NAME (field) == name)
1419 return field;
1421 /* If *typep is an innerclass, lookup the field in its enclosing
1422 contexts */
1423 if (INNER_CLASS_TYPE_P (*typep))
1425 tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1427 if ((field = lookup_field (&outer_type, name)))
1428 return field;
1431 /* Process implemented interfaces. */
1432 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1433 n = TREE_VEC_LENGTH (basetype_vec);
1434 save_field = NULL_TREE;
1435 for (i = 0; i < n; i++)
1437 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1438 if ((field = lookup_field (&t, name)))
1440 if (save_field == field)
1441 continue;
1442 if (save_field == NULL_TREE)
1443 save_field = field;
1444 else
1446 tree i1 = DECL_CONTEXT (save_field);
1447 tree i2 = DECL_CONTEXT (field);
1448 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1449 IDENTIFIER_POINTER (name),
1450 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1451 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1452 return error_mark_node;
1457 if (save_field != NULL_TREE)
1458 return save_field;
1460 *typep = CLASSTYPE_SUPER (*typep);
1461 } while (*typep);
1462 return NULL_TREE;
1465 /* Look up the field named NAME in object SELF_VALUE,
1466 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1467 SELF_VALUE is NULL_TREE if looking for a static field. */
1469 tree
1470 build_field_ref (self_value, self_class, name)
1471 tree self_value, self_class, name;
1473 tree base_class = self_class;
1474 tree field_decl = lookup_field (&base_class, name);
1475 if (field_decl == NULL_TREE)
1477 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1478 return error_mark_node;
1480 if (self_value == NULL_TREE)
1482 return build_static_field_ref (field_decl);
1484 else
1486 tree base_handle_type = promote_type (base_class);
1487 if (base_handle_type != TREE_TYPE (self_value))
1488 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1489 #ifdef JAVA_USE_HANDLES
1490 self_value = unhand_expr (self_value);
1491 #endif
1492 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1493 self_value, flag_check_references);
1494 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1495 self_value, field_decl));
1499 tree
1500 lookup_label (pc)
1501 int pc;
1503 tree name;
1504 char buf[32];
1505 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1506 name = get_identifier (buf);
1507 if (IDENTIFIER_LOCAL_VALUE (name))
1508 return IDENTIFIER_LOCAL_VALUE (name);
1509 else
1511 /* The type of the address of a label is return_address_type_node. */
1512 tree decl = create_label_decl (name);
1513 LABEL_PC (decl) = pc;
1514 label_rtx (decl);
1515 return pushdecl (decl);
1519 /* Generate a unique name for the purpose of loops and switches
1520 labels, and try-catch-finally blocks label or temporary variables. */
1522 tree
1523 generate_name ()
1525 static int l_number = 0;
1526 char buff [32];
1527 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1528 l_number++;
1529 return get_identifier (buff);
1532 tree
1533 create_label_decl (name)
1534 tree name;
1536 tree decl;
1537 decl = build_decl (LABEL_DECL, name,
1538 TREE_TYPE (return_address_type_node));
1539 DECL_CONTEXT (decl) = current_function_decl;
1540 DECL_IGNORED_P (decl) = 1;
1541 return decl;
1544 /* This maps a bytecode offset (PC) to various flags. */
1545 char *instruction_bits;
1547 static void
1548 note_label (current_pc, target_pc)
1549 int current_pc ATTRIBUTE_UNUSED, target_pc;
1551 lookup_label (target_pc);
1552 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1555 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1556 where CONDITION is one of one the compare operators. */
1558 static void
1559 expand_compare (condition, value1, value2, target_pc)
1560 enum tree_code condition;
1561 tree value1, value2;
1562 int target_pc;
1564 tree target = lookup_label (target_pc);
1565 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1566 expand_start_cond (truthvalue_conversion (cond), 0);
1567 expand_goto (target);
1568 expand_end_cond ();
1571 /* Emit code for a TEST-type opcode. */
1573 static void
1574 expand_test (condition, type, target_pc)
1575 enum tree_code condition;
1576 tree type;
1577 int target_pc;
1579 tree value1, value2;
1580 flush_quick_stack ();
1581 value1 = pop_value (type);
1582 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1583 expand_compare (condition, value1, value2, target_pc);
1586 /* Emit code for a COND-type opcode. */
1588 static void
1589 expand_cond (condition, type, target_pc)
1590 enum tree_code condition;
1591 tree type;
1592 int target_pc;
1594 tree value1, value2;
1595 flush_quick_stack ();
1596 /* note: pop values in opposite order */
1597 value2 = pop_value (type);
1598 value1 = pop_value (type);
1599 /* Maybe should check value1 and value2 for type compatibility ??? */
1600 expand_compare (condition, value1, value2, target_pc);
1603 static void
1604 expand_java_goto (target_pc)
1605 int target_pc;
1607 tree target_label = lookup_label (target_pc);
1608 flush_quick_stack ();
1609 expand_goto (target_label);
1612 #if 0
1613 static void
1614 expand_java_call (target_pc, return_address)
1615 int target_pc, return_address;
1617 tree target_label = lookup_label (target_pc);
1618 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1619 push_value (value);
1620 flush_quick_stack ();
1621 expand_goto (target_label);
1624 static void
1625 expand_java_ret (return_address)
1626 tree return_address ATTRIBUTE_UNUSED;
1628 warning ("ret instruction not implemented");
1629 #if 0
1630 tree target_label = lookup_label (target_pc);
1631 flush_quick_stack ();
1632 expand_goto (target_label);
1633 #endif
1635 #endif
1637 static tree
1638 pop_arguments (arg_types)
1639 tree arg_types;
1641 if (arg_types == end_params_node)
1642 return NULL_TREE;
1643 if (TREE_CODE (arg_types) == TREE_LIST)
1645 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1646 tree type = TREE_VALUE (arg_types);
1647 tree arg = pop_value (type);
1648 if (PROMOTE_PROTOTYPES
1649 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1650 && INTEGRAL_TYPE_P (type))
1651 arg = convert (integer_type_node, arg);
1652 return tree_cons (NULL_TREE, arg, tail);
1654 abort ();
1657 /* Build an expression to initialize the class CLAS.
1658 if EXPR is non-NULL, returns an expression to first call the initializer
1659 (if it is needed) and then calls EXPR. */
1661 tree
1662 build_class_init (clas, expr)
1663 tree clas, expr;
1665 tree init;
1666 struct init_test_hash_entry *ite;
1667 if (inherits_from_p (current_class, clas))
1668 return expr;
1670 if (always_initialize_class_p)
1672 init = build (CALL_EXPR, void_type_node,
1673 build_address_of (soft_initclass_node),
1674 build_tree_list (NULL_TREE, build_class_ref (clas)),
1675 NULL_TREE);
1676 TREE_SIDE_EFFECTS (init) = 1;
1678 else
1680 ite = (struct init_test_hash_entry *)
1681 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1682 (const hash_table_key) clas,
1683 TRUE, NULL);
1685 if (ite->init_test_decl == 0)
1686 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1687 boolean_type_node);
1688 /* Tell the check-init code to ignore this decl. */
1689 DECL_BIT_INDEX(ite->init_test_decl) = -1;
1691 init = build (CALL_EXPR, void_type_node,
1692 build_address_of (soft_initclass_node),
1693 build_tree_list (NULL_TREE, build_class_ref (clas)),
1694 NULL_TREE);
1695 TREE_SIDE_EFFECTS (init) = 1;
1696 init = build (COND_EXPR, void_type_node,
1697 build (EQ_EXPR, boolean_type_node,
1698 ite->init_test_decl, boolean_false_node),
1699 init, integer_zero_node);
1700 TREE_SIDE_EFFECTS (init) = 1;
1701 init = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1702 build (MODIFY_EXPR, boolean_type_node,
1703 ite->init_test_decl, boolean_true_node));
1704 TREE_SIDE_EFFECTS (init) = 1;
1707 if (expr != NULL_TREE)
1709 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1710 TREE_SIDE_EFFECTS (expr) = 1;
1711 return expr;
1713 return init;
1716 tree
1717 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1718 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1719 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1721 tree func;
1722 if (is_compiled_class (self_type))
1724 make_decl_rtl (method, NULL);
1725 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1727 else
1729 /* We don't know whether the method has been (statically) compiled.
1730 Compile this code to get a reference to the method's code:
1732 SELF_TYPE->methods[METHOD_INDEX].ncode
1734 This is guaranteed to work (assuming SELF_TYPE has
1735 been initialized), since if the method is not compiled yet,
1736 its ncode points to a trampoline that forces compilation. */
1738 int method_index = 0;
1739 tree meth;
1740 tree ref = build_class_ref (self_type);
1741 ref = build1 (INDIRECT_REF, class_type_node, ref);
1742 if (ncode_ident == NULL_TREE)
1743 ncode_ident = get_identifier ("ncode");
1744 if (methods_ident == NULL_TREE)
1745 methods_ident = get_identifier ("methods");
1746 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1747 lookup_field (&class_type_node, methods_ident));
1748 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1749 ; meth = TREE_CHAIN (meth))
1751 if (method == meth)
1752 break;
1753 if (meth == NULL_TREE)
1754 fatal_error ("method '%s' not found in class",
1755 IDENTIFIER_POINTER (DECL_NAME (method)));
1756 method_index++;
1758 method_index *= int_size_in_bytes (method_type_node);
1759 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1760 ref, build_int_2 (method_index, 0)));
1761 ref = build1 (INDIRECT_REF, method_type_node, ref);
1762 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1763 ref,
1764 lookup_field (&method_type_node, ncode_ident));
1766 return func;
1769 tree
1770 invoke_build_dtable (is_invoke_interface, arg_list)
1771 int is_invoke_interface;
1772 tree arg_list;
1774 tree dtable, objectref;
1776 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1778 /* If we're dealing with interfaces and if the objectref
1779 argument is an array then get the dispatch table of the class
1780 Object rather than the one from the objectref. */
1781 objectref = (is_invoke_interface
1782 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1783 object_type_node : TREE_VALUE (arg_list));
1785 if (dtable_ident == NULL_TREE)
1786 dtable_ident = get_identifier ("vtable");
1787 dtable = build_java_indirect_ref (object_type_node, objectref,
1788 flag_check_references);
1789 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1790 lookup_field (&object_type_node, dtable_ident));
1792 return dtable;
1795 tree
1796 build_invokevirtual (dtable, method)
1797 tree dtable, method;
1799 tree func;
1800 tree nativecode_ptr_ptr_type_node
1801 = build_pointer_type (nativecode_ptr_type_node);
1802 tree method_index = convert (sizetype, DECL_VINDEX (method));
1804 /* Add one to skip "class" field of dtable, and one to skip unused
1805 vtable entry (for C++ compatibility). */
1806 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1807 method_index = size_binop (MULT_EXPR, method_index,
1808 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1809 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1810 convert (nativecode_ptr_ptr_type_node, method_index)));
1811 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1813 return func;
1816 tree
1817 build_invokeinterface (dtable, method)
1818 tree dtable, method;
1820 static tree class_ident = NULL_TREE;
1821 tree lookup_arg;
1822 tree interface;
1823 tree idx;
1824 tree meth;
1825 int i;
1827 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1828 ensure that the selected method exists, is public and not
1829 abstract nor static. */
1831 if (class_ident == NULL_TREE)
1833 class_ident = get_identifier ("class");
1834 ggc_add_tree_root (&class_ident, 1);
1837 dtable = build_java_indirect_ref (dtable_type, dtable, flag_check_references);
1838 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1839 lookup_field (&dtable_type, class_ident));
1841 interface = DECL_CONTEXT (method);
1842 layout_class_methods (interface);
1844 i = 1;
1845 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1847 if (meth == method)
1849 idx = build_int_2 (i, 0);
1850 break;
1852 if (meth == NULL_TREE)
1853 abort ();
1856 lookup_arg = tree_cons (NULL_TREE, dtable,
1857 tree_cons (NULL_TREE, build_class_ref (interface),
1858 build_tree_list (NULL_TREE, idx)));
1860 return build (CALL_EXPR, ptr_type_node,
1861 build_address_of (soft_lookupinterfacemethod_node),
1862 lookup_arg, NULL_TREE);
1865 /* Expand one of the invoke_* opcodes.
1866 OCPODE is the specific opcode.
1867 METHOD_REF_INDEX is an index into the constant pool.
1868 NARGS is the number of arguments, or -1 if not specified. */
1870 static void
1871 expand_invoke (opcode, method_ref_index, nargs)
1872 int opcode;
1873 int method_ref_index;
1874 int nargs ATTRIBUTE_UNUSED;
1876 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1877 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1878 tree self_type = get_class_constant
1879 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1880 const char *self_name
1881 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1882 tree call, func, method, arg_list, method_type;
1883 tree check = NULL_TREE;
1885 if (! CLASS_LOADED_P (self_type))
1887 load_class (self_type, 1);
1888 safe_layout_class (self_type);
1889 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1890 fatal_error ("failed to find class '%s'", self_name);
1892 layout_class_methods (self_type);
1894 if (ID_INIT_P (method_name))
1895 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1896 method_signature);
1897 else
1898 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1899 method_name, method_signature);
1900 if (method == NULL_TREE)
1902 error ("Class '%s' has no method named '%s' matching signature '%s'",
1903 self_name,
1904 IDENTIFIER_POINTER (method_name),
1905 IDENTIFIER_POINTER (method_signature));
1907 /* Invoke static can't invoke static/abstract method */
1908 else if (opcode == OPCODE_invokestatic)
1910 if (!METHOD_STATIC (method))
1912 error ("invokestatic on non static method");
1913 method = NULL_TREE;
1915 else if (METHOD_ABSTRACT (method))
1917 error ("invokestatic on abstract method");
1918 method = NULL_TREE;
1921 else
1923 if (METHOD_STATIC (method))
1925 error ("invoke[non-static] on static method");
1926 method = NULL_TREE;
1930 if (method == NULL_TREE)
1932 method_type = get_type_from_signature (method_signature);
1933 pop_arguments (TYPE_ARG_TYPES (method_type));
1934 if (opcode != OPCODE_invokestatic)
1935 pop_type (self_type);
1936 method_type = promote_type (TREE_TYPE (method_type));
1937 push_value (convert (method_type, integer_zero_node));
1938 return;
1941 method_type = TREE_TYPE (method);
1942 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1943 flush_quick_stack ();
1945 func = NULL_TREE;
1946 if (opcode == OPCODE_invokestatic)
1947 func = build_known_method_ref (method, method_type, self_type,
1948 method_signature, arg_list);
1949 else if (opcode == OPCODE_invokespecial
1950 || (opcode == OPCODE_invokevirtual
1951 && (METHOD_PRIVATE (method)
1952 || METHOD_FINAL (method)
1953 || CLASS_FINAL (TYPE_NAME (self_type)))))
1955 /* If the object for the method call is null, we throw an
1956 exception. We don't do this if the object is the current
1957 method's `this'. In other cases we just rely on an
1958 optimization pass to eliminate redundant checks. FIXME:
1959 Unfortunately there doesn't seem to be a way to determine
1960 what the current method is right now. */
1961 /* We use a SAVE_EXPR here to make sure we only evaluate
1962 the new `self' expression once. */
1963 tree save_arg = save_expr (TREE_VALUE (arg_list));
1964 TREE_VALUE (arg_list) = save_arg;
1965 check = java_check_reference (save_arg, 1);
1966 func = build_known_method_ref (method, method_type, self_type,
1967 method_signature, arg_list);
1969 else
1971 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1972 arg_list);
1973 if (opcode == OPCODE_invokevirtual)
1974 func = build_invokevirtual (dtable, method);
1975 else
1976 func = build_invokeinterface (dtable, method);
1978 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1979 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1980 TREE_SIDE_EFFECTS (call) = 1;
1982 if (check != NULL_TREE)
1984 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
1985 TREE_SIDE_EFFECTS (call) = 1;
1988 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1989 expand_expr_stmt (call);
1990 else
1992 push_value (call);
1993 flush_quick_stack ();
1997 /* Create a stub which will be put into the vtable but which will call
1998 a JNI function. */
2000 tree
2001 build_jni_stub (method)
2002 tree method;
2004 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2005 tree jni_func_type, tem;
2006 tree env_var, res_var = NULL_TREE, block;
2007 tree method_args, res_type;
2008 tree meth_var;
2010 tree klass = DECL_CONTEXT (method);
2011 int from_class = ! CLASS_FROM_SOURCE_P (klass);
2012 klass = build_class_ref (klass);
2014 if (! METHOD_NATIVE (method) || ! flag_jni)
2015 abort ();
2017 DECL_ARTIFICIAL (method) = 1;
2018 DECL_EXTERNAL (method) = 0;
2020 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2021 DECL_CONTEXT (env_var) = method;
2023 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2025 res_var = build_decl (VAR_DECL, get_identifier ("res"),
2026 TREE_TYPE (TREE_TYPE (method)));
2027 DECL_CONTEXT (res_var) = method;
2028 TREE_CHAIN (env_var) = res_var;
2031 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2032 TREE_STATIC (meth_var) = 1;
2033 TREE_PUBLIC (meth_var) = 0;
2034 DECL_EXTERNAL (meth_var) = 0;
2035 DECL_CONTEXT (meth_var) = method;
2036 make_decl_rtl (meth_var, NULL);
2037 meth_var = pushdecl_top_level (meth_var);
2039 /* One strange way that the front ends are different is that they
2040 store arguments differently. */
2041 if (from_class)
2042 method_args = DECL_ARGUMENTS (method);
2043 else
2044 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2045 block = build_block (env_var, NULL_TREE, NULL_TREE,
2046 method_args, NULL_TREE);
2047 TREE_SIDE_EFFECTS (block) = 1;
2048 /* When compiling from source we don't set the type of the block,
2049 because that will prevent patch_return from ever being run. */
2050 if (from_class)
2051 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2053 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2054 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2055 build (CALL_EXPR, ptr_type_node,
2056 build_address_of (soft_getjnienvnewframe_node),
2057 build_tree_list (NULL_TREE, klass),
2058 NULL_TREE));
2059 CAN_COMPLETE_NORMALLY (body) = 1;
2061 /* All the arguments to this method become arguments to the
2062 underlying JNI function. If we had to wrap object arguments in a
2063 special way, we would do that here. */
2064 args = NULL_TREE;
2065 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2066 args = tree_cons (NULL_TREE, tem, args);
2067 args = nreverse (args);
2068 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2070 /* For a static method the second argument is the class. For a
2071 non-static method the second argument is `this'; that is already
2072 available in the argument list. */
2073 if (METHOD_STATIC (method))
2075 args = tree_cons (NULL_TREE, klass, args);
2076 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2079 /* The JNIEnv structure is the first argument to the JNI function. */
2080 args = tree_cons (NULL_TREE, env_var, args);
2081 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2083 /* We call _Jv_LookupJNIMethod to find the actual underlying
2084 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2085 exception if this function is not found at runtime. */
2086 method_sig = build_java_signature (TREE_TYPE (method));
2087 lookup_arg =
2088 build_tree_list (NULL_TREE,
2089 build_utf8_ref (unmangle_classname
2090 (IDENTIFIER_POINTER (method_sig),
2091 IDENTIFIER_LENGTH (method_sig))));
2092 tem = DECL_NAME (method);
2093 lookup_arg
2094 = tree_cons (NULL_TREE, klass,
2095 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2097 jni_func_type
2098 = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2099 arg_types));
2101 jnifunc = build (COND_EXPR, ptr_type_node,
2102 meth_var, meth_var,
2103 build (MODIFY_EXPR, ptr_type_node,
2104 meth_var,
2105 build (CALL_EXPR, ptr_type_node,
2106 build_address_of (soft_lookupjnimethod_node),
2107 lookup_arg, NULL_TREE)));
2109 /* Now we make the actual JNI call via the resulting function
2110 pointer. */
2111 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2112 build1 (NOP_EXPR, jni_func_type, jnifunc),
2113 args, NULL_TREE);
2115 /* If the JNI call returned a result, capture it here. If we had to
2116 unwrap JNI object results, we would do that here. */
2117 if (res_var != NULL_TREE)
2118 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2119 res_var, call);
2121 TREE_SIDE_EFFECTS (call) = 1;
2122 CAN_COMPLETE_NORMALLY (call) = 1;
2124 body = build (COMPOUND_EXPR, void_type_node, body, call);
2125 TREE_SIDE_EFFECTS (body) = 1;
2127 /* Now free the environment we allocated. */
2128 call = build (CALL_EXPR, ptr_type_node,
2129 build_address_of (soft_jnipopsystemframe_node),
2130 build_tree_list (NULL_TREE, env_var),
2131 NULL_TREE);
2132 TREE_SIDE_EFFECTS (call) = 1;
2133 CAN_COMPLETE_NORMALLY (call) = 1;
2134 body = build (COMPOUND_EXPR, void_type_node, body, call);
2135 TREE_SIDE_EFFECTS (body) = 1;
2137 /* Finally, do the return. When compiling from source we rely on
2138 patch_return to patch the return value -- because DECL_RESULT is
2139 not set at the time this function is called. */
2140 if (from_class)
2142 res_type = void_type_node;
2143 if (res_var != NULL_TREE)
2145 tree drt;
2146 if (! DECL_RESULT (method))
2147 abort ();
2148 /* Make sure we copy the result variable to the actual
2149 result. We use the type of the DECL_RESULT because it
2150 might be different from the return type of the function:
2151 it might be promoted. */
2152 drt = TREE_TYPE (DECL_RESULT (method));
2153 if (drt != TREE_TYPE (res_var))
2154 res_var = build1 (CONVERT_EXPR, drt, res_var);
2155 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2156 TREE_SIDE_EFFECTS (res_var) = 1;
2159 else
2161 /* This is necessary to get patch_return to run. */
2162 res_type = NULL_TREE;
2164 body = build (COMPOUND_EXPR, void_type_node, body,
2165 build1 (RETURN_EXPR, res_type, res_var));
2166 TREE_SIDE_EFFECTS (body) = 1;
2168 BLOCK_EXPR_BODY (block) = body;
2169 return block;
2172 /* Expand an operation to extract from or store into a field.
2173 IS_STATIC is 1 iff the field is static.
2174 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2175 FIELD_REF_INDEX is an index into the constant pool. */
2177 static void
2178 expand_java_field_op (is_static, is_putting, field_ref_index)
2179 int is_static;
2180 int is_putting;
2181 int field_ref_index;
2183 tree self_type =
2184 get_class_constant (current_jcf,
2185 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2186 field_ref_index));
2187 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2188 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2189 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2190 field_ref_index);
2191 tree field_type = get_type_from_signature (field_signature);
2192 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2193 tree field_ref;
2194 int is_error = 0;
2195 tree field_decl = lookup_field (&self_type, field_name);
2196 if (field_decl == error_mark_node)
2198 is_error = 1;
2200 else if (field_decl == NULL_TREE)
2202 error ("Missing field '%s' in '%s'",
2203 IDENTIFIER_POINTER (field_name), self_name);
2204 is_error = 1;
2206 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2208 error ("Mismatching signature for field '%s' in '%s'",
2209 IDENTIFIER_POINTER (field_name), self_name);
2210 is_error = 1;
2212 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2213 if (is_error)
2215 if (! is_putting)
2216 push_value (convert (field_type, integer_zero_node));
2217 flush_quick_stack ();
2218 return;
2221 /* Inline references to java.lang.PRIMTYPE.TYPE.
2222 In addition to being a useful (minor) optimization,
2223 this is also needed to avoid circularities in the implementation
2224 of these fields in libjava. */
2225 if (field_name == TYPE_identifier_node && ! is_putting
2226 && ! flag_emit_class_files && field_type == class_ptr_type
2227 && strncmp (self_name, "java.lang.", 10) == 0)
2229 tree typ = build_primtype_type_ref (self_name);
2230 if (typ)
2232 push_value (typ);
2233 return;
2237 field_ref = build_field_ref (field_ref, self_type, field_name);
2238 if (is_static)
2239 field_ref = build_class_init (self_type, field_ref);
2240 if (is_putting)
2242 flush_quick_stack ();
2243 if (FIELD_FINAL (field_decl))
2245 if (DECL_CONTEXT (field_decl) != current_class)
2246 error_with_decl (field_decl,
2247 "assignment to final field `%s' not in field's class");
2248 else if (FIELD_STATIC (field_decl))
2250 if (!DECL_CLINIT_P (current_function_decl))
2251 warning_with_decl (field_decl,
2252 "assignment to final static field `%s' not in class initializer");
2254 else
2256 tree cfndecl_name = DECL_NAME (current_function_decl);
2257 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2258 && !ID_FINIT_P (cfndecl_name))
2259 warning_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2262 expand_assignment (field_ref, new_value, 0, 0);
2264 else
2265 push_value (field_ref);
2268 tree
2269 build_primtype_type_ref (self_name)
2270 const char *self_name;
2272 const char *class_name = self_name+10;
2273 tree typ;
2274 if (strncmp(class_name, "Byte", 4) == 0)
2275 typ = byte_type_node;
2276 else if (strncmp(class_name, "Short", 5) == 0)
2277 typ = short_type_node;
2278 else if (strncmp(class_name, "Integer", 7) == 0)
2279 typ = int_type_node;
2280 else if (strncmp(class_name, "Long", 4) == 0)
2281 typ = long_type_node;
2282 else if (strncmp(class_name, "Float", 5) == 0)
2283 typ = float_type_node;
2284 else if (strncmp(class_name, "Double", 6) == 0)
2285 typ = double_type_node;
2286 else if (strncmp(class_name, "Boolean", 7) == 0)
2287 typ = boolean_type_node;
2288 else if (strncmp(class_name, "Char", 4) == 0)
2289 typ = char_type_node;
2290 else if (strncmp(class_name, "Void", 4) == 0)
2291 typ = void_type_node;
2292 else
2293 typ = NULL_TREE;
2294 if (typ != NULL_TREE)
2295 return build_class_ref (typ);
2296 else
2297 return NULL_TREE;
2300 void
2301 load_type_state (label)
2302 tree label;
2304 int i;
2305 tree vec = LABEL_TYPE_STATE (label);
2306 int cur_length = TREE_VEC_LENGTH (vec);
2307 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2308 for (i = 0; i < cur_length; i++)
2309 type_map [i] = TREE_VEC_ELT (vec, i);
2312 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2313 dependant things, but they rely on gcc routines. This function is
2314 placed here because it uses things defined locally in parse.y. */
2316 static tree
2317 case_identity (t, v)
2318 tree t __attribute__ ((__unused__));
2319 tree v;
2321 return v;
2324 /* Return the name of the vtable for an array of a given primitive
2325 type. */
2326 static tree
2327 get_primitive_array_vtable (tree elt)
2329 tree r;
2330 if (elt == boolean_type_node)
2331 r = boolean_array_vtable;
2332 else if (elt == byte_type_node)
2333 r = byte_array_vtable;
2334 else if (elt == char_type_node)
2335 r = char_array_vtable;
2336 else if (elt == short_type_node)
2337 r = short_array_vtable;
2338 else if (elt == int_type_node)
2339 r = int_array_vtable;
2340 else if (elt == long_type_node)
2341 r = long_array_vtable;
2342 else if (elt == float_type_node)
2343 r = float_array_vtable;
2344 else if (elt == double_type_node)
2345 r = double_array_vtable;
2346 else
2347 abort ();
2348 return build_address_of (r);
2351 struct rtx_def *
2352 java_lang_expand_expr (exp, target, tmode, modifier)
2353 register tree exp;
2354 rtx target;
2355 enum machine_mode tmode;
2356 enum expand_modifier modifier;
2358 tree current;
2360 switch (TREE_CODE (exp))
2362 case NEW_ARRAY_INIT:
2364 rtx tmp;
2365 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2366 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2367 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2368 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2369 tree length = build_int_2 (ilength, 0);
2370 tree init = TREE_OPERAND (exp, 0);
2371 tree array_decl;
2373 /* See if we can generate the array statically. */
2374 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2375 && JPRIMITIVE_TYPE_P (element_type))
2377 tree temp, value, init_decl;
2378 struct rtx_def *r;
2379 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2380 PUSH_FIELD_VALUE (temp, "vtable",
2381 get_primitive_array_vtable (element_type));
2382 if (! flag_hash_synchronization)
2383 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2384 FINISH_RECORD_CONSTRUCTOR (temp);
2385 START_RECORD_CONSTRUCTOR (value, array_type);
2386 PUSH_SUPER_VALUE (value, temp);
2387 PUSH_FIELD_VALUE (value, "length", length);
2388 PUSH_FIELD_VALUE (value, "data", init);
2389 FINISH_RECORD_CONSTRUCTOR (value);
2391 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2392 pushdecl_top_level (init_decl);
2393 TREE_STATIC (init_decl) = 1;
2394 DECL_INITIAL (init_decl) = value;
2395 DECL_IGNORED_P (init_decl) = 1;
2396 TREE_READONLY (init_decl) = 1;
2397 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2398 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2399 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2400 r = expand_expr (init, target, tmode, modifier);
2401 return r;
2404 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2405 expand_decl (array_decl);
2406 tmp = expand_assignment (array_decl,
2407 build_new_array (element_type, length),
2408 1, 0);
2409 if (TREE_CONSTANT (init)
2410 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2412 tree init_decl;
2413 init_decl = build_decl (VAR_DECL, generate_name (),
2414 TREE_TYPE (init));
2415 pushdecl_top_level (init_decl);
2416 TREE_STATIC (init_decl) = 1;
2417 DECL_INITIAL (init_decl) = init;
2418 DECL_IGNORED_P (init_decl) = 1;
2419 TREE_READONLY (init_decl) = 1;
2420 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2421 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2422 init = init_decl;
2424 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2425 build_java_indirect_ref (array_type,
2426 array_decl, flag_check_references),
2427 data_fld), init, 0, 0);
2428 return tmp;
2430 case BLOCK:
2431 if (BLOCK_EXPR_BODY (exp))
2433 tree local;
2434 tree body = BLOCK_EXPR_BODY (exp);
2435 pushlevel (2); /* 2 and above */
2436 expand_start_bindings (0);
2437 local = BLOCK_EXPR_DECLS (exp);
2438 while (local)
2440 tree next = TREE_CHAIN (local);
2441 layout_decl (local, 0);
2442 expand_decl (pushdecl (local));
2443 local = next;
2445 /* Avoid deep recursion for long block. */
2446 while (TREE_CODE (body) == COMPOUND_EXPR)
2448 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2449 emit_queue ();
2450 body = TREE_OPERAND (body, 1);
2452 expand_expr (body, const0_rtx, VOIDmode, 0);
2453 emit_queue ();
2454 poplevel (1, 1, 0);
2455 expand_end_bindings (getdecls (), 1, 0);
2456 return const0_rtx;
2458 return const0_rtx;
2460 case CASE_EXPR:
2462 tree duplicate;
2463 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2464 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2465 &duplicate) == 2)
2467 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2468 parse_error_context
2469 (wfl_operator, "Duplicate case label: `%s'",
2470 print_int_node (TREE_OPERAND (exp, 0)));
2472 return const0_rtx;
2475 case DEFAULT_EXPR:
2476 pushcase (NULL_TREE, 0,
2477 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2478 return const0_rtx;
2480 case SWITCH_EXPR:
2481 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2482 expand_expr_stmt (TREE_OPERAND (exp, 1));
2483 expand_end_case (TREE_OPERAND (exp, 0));
2484 return const0_rtx;
2486 case TRY_EXPR:
2487 /* We expand a try[-catch] block */
2489 /* Expand the try block */
2490 expand_eh_region_start ();
2491 expand_expr_stmt (TREE_OPERAND (exp, 0));
2492 expand_start_all_catch ();
2494 /* Expand all catch clauses (EH handlers) */
2495 for (current = TREE_OPERAND (exp, 1); current;
2496 current = TREE_CHAIN (current))
2498 tree catch = TREE_OPERAND (current, 0);
2499 tree decl = BLOCK_EXPR_DECLS (catch);
2500 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2502 expand_start_catch (type);
2503 expand_expr_stmt (TREE_OPERAND (current, 0));
2504 expand_end_catch ();
2506 expand_end_all_catch ();
2507 return const0_rtx;
2509 case JAVA_EXC_OBJ_EXPR:
2510 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2511 target, tmode, modifier);
2513 default:
2514 internal_error ("Can't expand %s", tree_code_name [TREE_CODE (exp)]);
2518 /* Go over METHOD's bytecode and note instruction starts in
2519 instruction_bits[]. */
2521 void
2522 note_instructions (jcf, method)
2523 JCF *jcf;
2524 tree method;
2526 int PC;
2527 unsigned char* byte_ops;
2528 long length = DECL_CODE_LENGTH (method);
2530 int saw_index;
2531 jint INT_temp;
2533 #undef RET /* Defined by config/i386/i386.h */
2534 #undef AND /* Causes problems with opcodes for iand and land. */
2535 #undef PTR
2536 #define BCODE byte_ops
2537 #define BYTE_type_node byte_type_node
2538 #define SHORT_type_node short_type_node
2539 #define INT_type_node int_type_node
2540 #define LONG_type_node long_type_node
2541 #define CHAR_type_node char_type_node
2542 #define PTR_type_node ptr_type_node
2543 #define FLOAT_type_node float_type_node
2544 #define DOUBLE_type_node double_type_node
2545 #define VOID_type_node void_type_node
2546 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2547 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2548 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2549 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2551 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2553 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2554 byte_ops = jcf->read_ptr;
2555 instruction_bits = xrealloc (instruction_bits, length + 1);
2556 memset (instruction_bits, 0, length + 1);
2558 /* This pass figures out which PC can be the targets of jumps. */
2559 for (PC = 0; PC < length;)
2561 int oldpc = PC; /* PC at instruction start. */
2562 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2563 switch (byte_ops[PC++])
2565 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2566 case OPCODE: \
2567 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2568 break;
2570 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2572 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2573 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2574 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2575 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2576 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2577 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2578 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2579 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2581 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2582 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2583 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2584 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2585 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2586 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2587 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2588 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2590 /* two forms of wide instructions */
2591 #define PRE_SPECIAL_WIDE(IGNORE) \
2593 int modified_opcode = IMMEDIATE_u1; \
2594 if (modified_opcode == OPCODE_iinc) \
2596 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2597 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2599 else \
2601 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2605 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2607 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2609 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2610 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2611 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2612 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2613 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2614 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2615 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2616 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2617 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2618 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2620 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2621 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2622 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2623 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2624 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2625 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2626 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2627 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2629 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2631 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2632 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2634 #define PRE_LOOKUP_SWITCH \
2635 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2636 NOTE_LABEL (default_offset+oldpc); \
2637 if (npairs >= 0) \
2638 while (--npairs >= 0) { \
2639 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2640 jint offset = IMMEDIATE_s4; \
2641 NOTE_LABEL (offset+oldpc); } \
2644 #define PRE_TABLE_SWITCH \
2645 { jint default_offset = IMMEDIATE_s4; \
2646 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2647 NOTE_LABEL (default_offset+oldpc); \
2648 if (low <= high) \
2649 while (low++ <= high) { \
2650 jint offset = IMMEDIATE_s4; \
2651 NOTE_LABEL (offset+oldpc); } \
2654 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2655 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2656 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2657 (void)(IMMEDIATE_u2); \
2658 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2660 #include "javaop.def"
2661 #undef JAVAOP
2663 } /* for */
2666 void
2667 expand_byte_code (jcf, method)
2668 JCF *jcf;
2669 tree method;
2671 int PC;
2672 int i;
2673 const unsigned char *linenumber_pointer;
2674 int dead_code_index = -1;
2675 unsigned char* byte_ops;
2676 long length = DECL_CODE_LENGTH (method);
2678 stack_pointer = 0;
2679 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2680 byte_ops = jcf->read_ptr;
2682 /* We make an initial pass of the line number table, to note
2683 which instructions have associated line number entries. */
2684 linenumber_pointer = linenumber_table;
2685 for (i = 0; i < linenumber_count; i++)
2687 int pc = GET_u2 (linenumber_pointer);
2688 linenumber_pointer += 4;
2689 if (pc >= length)
2690 warning ("invalid PC in line number table");
2691 else
2693 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2694 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2695 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2699 if (! verify_jvm_instructions (jcf, byte_ops, length))
2700 return;
2702 /* Translate bytecodes to rtl instructions. */
2703 linenumber_pointer = linenumber_table;
2704 for (PC = 0; PC < length;)
2706 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2708 tree label = lookup_label (PC);
2709 flush_quick_stack ();
2710 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2711 expand_label (label);
2712 if (LABEL_VERIFIED (label) || PC == 0)
2713 load_type_state (label);
2716 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2718 if (dead_code_index == -1)
2720 /* This is the start of a region of unreachable bytecodes.
2721 They still need to be processed in order for EH ranges
2722 to get handled correctly. However, we can simply
2723 replace these bytecodes with nops. */
2724 dead_code_index = PC;
2727 /* Turn this bytecode into a nop. */
2728 byte_ops[PC] = 0x0;
2730 else
2732 if (dead_code_index != -1)
2734 /* We've just reached the end of a region of dead code. */
2735 warning ("Unreachable bytecode from %d to before %d.",
2736 dead_code_index, PC);
2737 dead_code_index = -1;
2741 /* Handle possible line number entry for this PC.
2743 This code handles out-of-order and multiple linenumbers per PC,
2744 but is optimized for the case of line numbers increasing
2745 monotonically with PC. */
2746 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2748 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2749 || GET_u2 (linenumber_pointer) != PC)
2750 linenumber_pointer = linenumber_table;
2751 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2753 int pc = GET_u2 (linenumber_pointer);
2754 linenumber_pointer += 4;
2755 if (pc == PC)
2757 lineno = GET_u2 (linenumber_pointer - 2);
2758 emit_line_note (input_filename, lineno);
2759 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2760 break;
2764 maybe_pushlevels (PC);
2765 PC = process_jvm_instruction (PC, byte_ops, length);
2766 maybe_poplevels (PC);
2767 } /* for */
2769 if (dead_code_index != -1)
2771 /* We've just reached the end of a region of dead code. */
2772 warning ("Unreachable bytecode from %d to the end of the method.",
2773 dead_code_index);
2777 static void
2778 java_push_constant_from_pool (jcf, index)
2779 JCF *jcf;
2780 int index;
2782 tree c;
2783 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2785 tree name;
2786 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2787 index = alloc_name_constant (CONSTANT_String, name);
2788 c = build_ref_from_constant_pool (index);
2789 TREE_TYPE (c) = promote_type (string_type_node);
2791 else
2792 c = get_constant (jcf, index);
2793 push_value (c);
2797 process_jvm_instruction (PC, byte_ops, length)
2798 int PC;
2799 const unsigned char* byte_ops;
2800 long length ATTRIBUTE_UNUSED;
2802 const char *opname; /* Temporary ??? */
2803 int oldpc = PC; /* PC at instruction start. */
2805 /* If the instruction is at the beginning of a exception handler,
2806 replace the top of the stack with the thrown object reference */
2807 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2809 tree type = pop_type (ptr_type_node);
2810 push_value (build (JAVA_EXC_OBJ_EXPR, type));
2813 switch (byte_ops[PC++])
2815 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2816 case OPCODE: \
2817 opname = #OPNAME; \
2818 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2819 break;
2821 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2823 int saw_index = 0; \
2824 int index = OPERAND_VALUE; \
2825 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2828 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2830 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2831 tree ret = lookup_label (PC); \
2832 build_java_jsr (where, ret); \
2833 load_type_state (ret); \
2836 /* Push a constant onto the stack. */
2837 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2838 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2839 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2840 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2842 /* internal macro added for use by the WIDE case */
2843 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2844 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2846 /* Push local variable onto the opcode stack. */
2847 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2849 /* have to do this since OPERAND_VALUE may have side-effects */ \
2850 int opvalue = OPERAND_VALUE; \
2851 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2854 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2855 expand_java_return (OPERAND_TYPE##_type_node)
2857 #define REM_EXPR TRUNC_MOD_EXPR
2858 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2859 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2861 #define FIELD(IS_STATIC, IS_PUT) \
2862 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2864 #define TEST(OPERAND_TYPE, CONDITION) \
2865 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2867 #define COND(OPERAND_TYPE, CONDITION) \
2868 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2870 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2871 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2873 #define BRANCH_GOTO(OPERAND_VALUE) \
2874 expand_java_goto (oldpc + OPERAND_VALUE)
2876 #define BRANCH_CALL(OPERAND_VALUE) \
2877 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2879 #if 0
2880 #define BRANCH_RETURN(OPERAND_VALUE) \
2882 tree type = OPERAND_TYPE##_type_node; \
2883 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2884 expand_java_ret (value); \
2886 #endif
2888 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2889 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2890 fprintf (stderr, "(not implemented)\n")
2891 #define NOT_IMPL1(OPERAND_VALUE) \
2892 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2893 fprintf (stderr, "(not implemented)\n")
2895 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2897 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2899 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2901 #define STACK_SWAP(COUNT) java_stack_swap()
2903 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2904 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2905 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2907 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2908 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2910 #define LOOKUP_SWITCH \
2911 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2912 tree selector = pop_value (INT_type_node); \
2913 tree duplicate, label; \
2914 tree type = TREE_TYPE (selector); \
2915 flush_quick_stack (); \
2916 expand_start_case (0, selector, type, "switch statement");\
2917 while (--npairs >= 0) \
2919 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2920 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2921 TREE_TYPE (value) = type; \
2922 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2923 pushcase (value, convert, label, &duplicate); \
2924 expand_java_goto (oldpc + offset); \
2926 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2927 pushcase (NULL_TREE, 0, label, &duplicate); \
2928 expand_java_goto (oldpc + default_offset); \
2929 expand_end_case (selector); \
2932 #define TABLE_SWITCH \
2933 { jint default_offset = IMMEDIATE_s4; \
2934 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2935 tree selector = pop_value (INT_type_node); \
2936 tree duplicate, label; \
2937 tree type = TREE_TYPE (selector); \
2938 flush_quick_stack (); \
2939 expand_start_case (0, selector, type, "switch statement");\
2940 for (; low <= high; low++) \
2942 jint offset = IMMEDIATE_s4; \
2943 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2944 TREE_TYPE (value) = type; \
2945 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2946 pushcase (value, convert, label, &duplicate); \
2947 expand_java_goto (oldpc + offset); \
2949 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2950 pushcase (NULL_TREE, 0, label, &duplicate); \
2951 expand_java_goto (oldpc + default_offset); \
2952 expand_end_case (selector); \
2955 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2956 { int opcode = byte_ops[PC-1]; \
2957 int method_ref_index = IMMEDIATE_u2; \
2958 int nargs; \
2959 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2960 else nargs = -1; \
2961 expand_invoke (opcode, method_ref_index, nargs); \
2964 /* Handle new, checkcast, instanceof */
2965 #define OBJECT(TYPE, OP) \
2966 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2968 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2970 #define ARRAY_LOAD(OPERAND_TYPE) \
2972 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2975 #define ARRAY_STORE(OPERAND_TYPE) \
2977 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2980 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2981 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2982 #define ARRAY_NEW_PTR() \
2983 push_value (build_anewarray (get_class_constant (current_jcf, \
2984 IMMEDIATE_u2), \
2985 pop_value (int_type_node)));
2986 #define ARRAY_NEW_NUM() \
2988 int atype = IMMEDIATE_u1; \
2989 push_value (build_newarray (atype, pop_value (int_type_node)));\
2991 #define ARRAY_NEW_MULTI() \
2993 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2994 int ndims = IMMEDIATE_u1; \
2995 expand_java_multianewarray( class, ndims ); \
2998 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2999 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3000 pop_value (OPERAND_TYPE##_type_node))));
3002 #define CONVERT2(FROM_TYPE, TO_TYPE) \
3004 push_value (build1 (NOP_EXPR, int_type_node, \
3005 (convert (TO_TYPE##_type_node, \
3006 pop_value (FROM_TYPE##_type_node))))); \
3009 #define CONVERT(FROM_TYPE, TO_TYPE) \
3011 push_value (convert (TO_TYPE##_type_node, \
3012 pop_value (FROM_TYPE##_type_node))); \
3015 /* internal macro added for use by the WIDE case
3016 Added TREE_TYPE (decl) assignment, apbianco */
3017 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
3019 tree decl, value; \
3020 int var = OPVALUE; \
3021 tree type = OPTYPE; \
3022 value = pop_value (type); \
3023 type = TREE_TYPE (value); \
3024 decl = find_local_variable (var, type, oldpc); \
3025 set_local_type (var, type ); \
3026 expand_assignment (decl, value, 0, 0); \
3029 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3031 /* have to do this since OPERAND_VALUE may have side-effects */ \
3032 int opvalue = OPERAND_VALUE; \
3033 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3036 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3037 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3039 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3040 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3042 #define MONITOR_OPERATION(call) \
3044 tree o = pop_value (ptr_type_node); \
3045 tree c; \
3046 flush_quick_stack (); \
3047 c = build_java_monitor (call, o); \
3048 TREE_SIDE_EFFECTS (c) = 1; \
3049 expand_expr_stmt (c); \
3052 #define SPECIAL_IINC(IGNORED) \
3054 unsigned int local_var_index = IMMEDIATE_u1; \
3055 int ival = IMMEDIATE_s1; \
3056 expand_iinc(local_var_index, ival, oldpc); \
3059 #define SPECIAL_WIDE(IGNORED) \
3061 int modified_opcode = IMMEDIATE_u1; \
3062 unsigned int local_var_index = IMMEDIATE_u2; \
3063 switch (modified_opcode) \
3065 case OPCODE_iinc: \
3067 int ival = IMMEDIATE_s2; \
3068 expand_iinc (local_var_index, ival, oldpc); \
3069 break; \
3071 case OPCODE_iload: \
3072 case OPCODE_lload: \
3073 case OPCODE_fload: \
3074 case OPCODE_dload: \
3075 case OPCODE_aload: \
3077 /* duplicate code from LOAD macro */ \
3078 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3079 break; \
3081 case OPCODE_istore: \
3082 case OPCODE_lstore: \
3083 case OPCODE_fstore: \
3084 case OPCODE_dstore: \
3085 case OPCODE_astore: \
3087 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3088 break; \
3090 default: \
3091 error ("unrecogized wide sub-instruction"); \
3095 #define SPECIAL_THROW(IGNORED) \
3096 build_java_athrow (pop_value (throwable_type_node))
3098 #define SPECIAL_BREAK NOT_IMPL1
3099 #define IMPL NOT_IMPL
3101 #include "javaop.def"
3102 #undef JAVAOP
3103 default:
3104 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3106 return PC;
3109 /* Return the opcode at PC in the code section pointed to by
3110 CODE_OFFSET. */
3112 static unsigned char
3113 peek_opcode_at_pc (jcf, code_offset, pc)
3114 JCF *jcf;
3115 int code_offset, pc;
3117 unsigned char opcode;
3118 long absolute_offset = (long)JCF_TELL (jcf);
3120 JCF_SEEK (jcf, code_offset);
3121 opcode = jcf->read_ptr [pc];
3122 JCF_SEEK (jcf, absolute_offset);
3123 return opcode;
3126 /* Some bytecode compilers are emitting accurate LocalVariableTable
3127 attributes. Here's an example:
3129 PC <t>store_<n>
3130 PC+1 ...
3132 Attribute "LocalVariableTable"
3133 slot #<n>: ... (PC: PC+1 length: L)
3135 This is accurate because the local in slot <n> really exists after
3136 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3138 This procedure recognizes this situation and extends the live range
3139 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3140 length of the store instruction.)
3142 This function is used by `give_name_to_locals' so that a local's
3143 DECL features a DECL_LOCAL_START_PC such that the first related
3144 store operation will use DECL as a destination, not a unrelated
3145 temporary created for the occasion.
3147 This function uses a global (instruction_bits) `note_instructions' should
3148 have allocated and filled properly. */
3151 maybe_adjust_start_pc (jcf, code_offset, start_pc, slot)
3152 struct JCF *jcf;
3153 int code_offset, start_pc, slot;
3155 int first, index, opcode;
3156 int pc, insn_pc;
3157 int wide_found = 0;
3159 if (!start_pc)
3160 return start_pc;
3162 first = index = -1;
3164 /* Find last previous instruction and remember it */
3165 for (pc = start_pc-1; pc; pc--)
3166 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3167 break;
3168 insn_pc = pc;
3170 /* Retrieve the instruction, handle `wide'. */
3171 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3172 if (opcode == OPCODE_wide)
3174 wide_found = 1;
3175 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3178 switch (opcode)
3180 case OPCODE_astore_0:
3181 case OPCODE_astore_1:
3182 case OPCODE_astore_2:
3183 case OPCODE_astore_3:
3184 first = OPCODE_astore_0;
3185 break;
3187 case OPCODE_istore_0:
3188 case OPCODE_istore_1:
3189 case OPCODE_istore_2:
3190 case OPCODE_istore_3:
3191 first = OPCODE_istore_0;
3192 break;
3194 case OPCODE_lstore_0:
3195 case OPCODE_lstore_1:
3196 case OPCODE_lstore_2:
3197 case OPCODE_lstore_3:
3198 first = OPCODE_lstore_0;
3199 break;
3201 case OPCODE_fstore_0:
3202 case OPCODE_fstore_1:
3203 case OPCODE_fstore_2:
3204 case OPCODE_fstore_3:
3205 first = OPCODE_fstore_0;
3206 break;
3208 case OPCODE_dstore_0:
3209 case OPCODE_dstore_1:
3210 case OPCODE_dstore_2:
3211 case OPCODE_dstore_3:
3212 first = OPCODE_dstore_0;
3213 break;
3215 case OPCODE_astore:
3216 case OPCODE_istore:
3217 case OPCODE_lstore:
3218 case OPCODE_fstore:
3219 case OPCODE_dstore:
3220 index = peek_opcode_at_pc (jcf, code_offset, pc);
3221 if (wide_found)
3223 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3224 index = (other << 8) + index;
3226 break;
3229 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3230 means we have a <t>store. */
3231 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3232 start_pc = insn_pc;
3234 return start_pc;
3237 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3238 order, as specified by Java Language Specification.
3240 The problem is that while expand_expr will evaluate its sub-operands in
3241 left-to-right order, for variables it will just return an rtx (i.e.
3242 an lvalue) for the variable (rather than an rvalue). So it is possible
3243 that a later sub-operand will change the register, and when the
3244 actual operation is done, it will use the new value, when it should
3245 have used the original value.
3247 We fix this by using save_expr. This forces the sub-operand to be
3248 copied into a fresh virtual register,
3250 For method invocation, we modify the arguments so that a
3251 left-to-right order evaluation is performed. Saved expressions
3252 will, in CALL_EXPR order, be reused when the call will be expanded.
3255 tree
3256 force_evaluation_order (node)
3257 tree node;
3259 if (flag_syntax_only)
3260 return node;
3261 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3263 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3264 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3266 else if (TREE_CODE (node) == CALL_EXPR
3267 || TREE_CODE (node) == NEW_CLASS_EXPR
3268 || (TREE_CODE (node) == COMPOUND_EXPR
3269 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3270 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3272 tree arg, cmp;
3274 if (!TREE_OPERAND (node, 1))
3275 return node;
3277 arg = node;
3279 /* Position arg properly, account for wrapped around ctors. */
3280 if (TREE_CODE (node) == COMPOUND_EXPR)
3281 arg = TREE_OPERAND (node, 0);
3283 arg = TREE_OPERAND (arg, 1);
3285 /* Not having a list of argument here is an error. */
3286 if (TREE_CODE (arg) != TREE_LIST)
3287 abort ();
3289 /* This reverses the evaluation order. This is a desired effect. */
3290 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3292 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3293 cmp = (cmp == NULL_TREE ? saved :
3294 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3295 TREE_VALUE (arg) = saved;
3298 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3299 TREE_SIDE_EFFECTS (cmp) = 1;
3301 if (cmp)
3303 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3304 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3305 TREE_SIDE_EFFECTS (cmp) = 1;
3306 node = cmp;
3309 return node;