* output.h (make_function_rtl): Remove prototype.
[official-gcc.git] / gcc / java / expr.c
blob4ad903ee70ecc09973ba412c6461c6d2b23e0c86
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
27 #include "config.h"
28 #include "system.h"
29 #include "tree.h"
30 #include "real.h"
31 #include "rtl.h"
32 #include "flags.h"
33 #include "expr.h"
34 #include "java-tree.h"
35 #include "javaop.h"
36 #include "java-opcodes.h"
37 #include "jcf.h"
38 #include "java-except.h"
39 #include "parse.h"
40 #include "toplev.h"
41 #include "except.h"
42 #include "defaults.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 void
260 push_type (type)
261 tree type;
263 int n_words;
264 type = promote_type (type);
265 n_words = 1 + TYPE_IS_WIDE (type);
266 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
267 fatal ("stack overflow");
268 stack_type_map[stack_pointer++] = type;
269 n_words--;
270 while (--n_words >= 0)
271 stack_type_map[stack_pointer++] = TYPE_SECOND;
274 static void
275 push_value (value)
276 tree value;
278 tree type = TREE_TYPE (value);
279 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
281 type = promote_type (type);
282 value = convert (type, value);
284 push_type (type);
285 if (tree_list_free_list == NULL_TREE)
286 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
287 else
289 tree node = tree_list_free_list;
290 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
291 TREE_VALUE (node) = value;
292 TREE_CHAIN (node) = quick_stack;
293 quick_stack = node;
297 /* Pop a type from the type stack.
298 TYPE is the expected type. Return the actual type, which must be
299 convertible to TYPE, otherwise NULL_TREE is returned. */
301 tree
302 pop_type_0 (type)
303 tree type;
305 int n_words;
306 tree t;
307 if (TREE_CODE (type) == RECORD_TYPE)
308 type = promote_type (type);
309 n_words = 1 + TYPE_IS_WIDE (type);
310 if (stack_pointer < n_words)
311 fatal ("stack underflow");
312 while (--n_words > 0)
314 if (stack_type_map[--stack_pointer] != void_type_node)
315 fatal ("Invalid multi-word value on type stack");
317 t = stack_type_map[--stack_pointer];
318 if (type == NULL_TREE || t == type)
319 return t;
320 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
321 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
322 return t;
323 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
325 if (type == ptr_type_node || type == object_ptr_type_node)
326 return t;
327 else if (t == ptr_type_node) /* Special case for null reference. */
328 return type;
329 else if (can_widen_reference_to (t, type))
330 return t;
331 /* This is a kludge, but matches what Sun's verifier does.
332 It can be tricked, but is safe as long as type errors
333 (i.e. interface method calls) are caught at run-time. */
334 /* FIXME: this is worse than a kludge, probably. */
335 return object_ptr_type_node;
337 return NULL_TREE;
340 /* Pop a type from the type stack.
341 TYPE is the expected type. Return the actual type, which must be
342 convertible to TYPE, otherwise call error. */
344 tree
345 pop_type (type)
346 tree type;
348 tree t = pop_type_0 (type);
349 if (t != NULL_TREE)
350 return t;
351 error ("unexpected type on stack");
352 return type;
355 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
356 Handles array types and interfaces. */
359 can_widen_reference_to (source_type, target_type)
360 tree source_type, target_type;
362 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
363 return 1;
365 /* Get rid of pointers */
366 if (TREE_CODE (source_type) == POINTER_TYPE)
367 source_type = TREE_TYPE (source_type);
368 if (TREE_CODE (target_type) == POINTER_TYPE)
369 target_type = TREE_TYPE (target_type);
371 if (source_type == target_type)
372 return 1;
373 else
375 source_type = HANDLE_TO_CLASS_TYPE (source_type);
376 target_type = HANDLE_TO_CLASS_TYPE (target_type);
377 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
379 HOST_WIDE_INT source_length, target_length;
380 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
381 return 0;
382 target_length = java_array_type_length (target_type);
383 if (target_length >= 0)
385 source_length = java_array_type_length (source_type);
386 if (source_length != target_length)
387 return 0;
389 source_type = TYPE_ARRAY_ELEMENT (source_type);
390 target_type = TYPE_ARRAY_ELEMENT (target_type);
391 if (source_type == target_type)
392 return 1;
393 if (TREE_CODE (source_type) != POINTER_TYPE
394 || TREE_CODE (target_type) != POINTER_TYPE)
395 return 0;
396 return can_widen_reference_to (source_type, target_type);
398 else
400 int source_depth = class_depth (source_type);
401 int target_depth = class_depth (target_type);
403 /* class_depth can return a negative depth if an error occurred */
404 if (source_depth < 0 || target_depth < 0)
405 return 0;
407 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
409 /* target_type is OK if source_type or source_type ancestors
410 implement target_type. We handle multiple sub-interfaces */
412 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
413 int n = TREE_VEC_LENGTH (basetype_vec), i;
414 for (i=0 ; i < n; i++)
415 if (can_widen_reference_to
416 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
417 target_type))
418 return 1;
419 if (n == 0)
420 return 0;
423 for ( ; source_depth > target_depth; source_depth--)
425 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
427 return source_type == target_type;
432 static tree
433 pop_value (type)
434 tree type;
436 type = pop_type (type);
437 if (quick_stack)
439 tree node = quick_stack;
440 quick_stack = TREE_CHAIN (quick_stack);
441 TREE_CHAIN (node) = tree_list_free_list;
442 tree_list_free_list = node;
443 node = TREE_VALUE (node);
444 return node;
446 else
447 return find_stack_slot (stack_pointer, promote_type (type));
451 /* Pop and discrad the top COUNT stack slots. */
453 static void
454 java_stack_pop (count)
455 int count;
457 while (count > 0)
459 tree type, val;
460 if (stack_pointer == 0)
461 fatal ("stack underflow");
462 type = stack_type_map[stack_pointer - 1];
463 if (type == TYPE_SECOND)
465 count--;
466 if (stack_pointer == 1 || count <= 0)
467 fatal ("stack underflow");
468 type = stack_type_map[stack_pointer - 2];
470 val = pop_value (type);
471 count--;
475 /* Implement the 'swap' operator (to swap two top stack slots). */
477 static void
478 java_stack_swap ()
480 tree type1, type2;
481 rtx temp;
482 tree decl1, decl2;
484 if (stack_pointer < 2
485 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
486 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
487 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
488 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
489 fatal ("bad stack swap");
491 flush_quick_stack ();
492 decl1 = find_stack_slot (stack_pointer - 1, type1);
493 decl2 = find_stack_slot (stack_pointer - 2, type2);
494 temp = copy_to_reg (DECL_RTL (decl1));
495 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
496 emit_move_insn (DECL_RTL (decl2), temp);
497 stack_type_map[stack_pointer - 1] = type2;
498 stack_type_map[stack_pointer - 2] = type1;
501 static void
502 java_stack_dup (size, offset)
503 int size, offset;
505 int low_index = stack_pointer - size - offset;
506 int dst_index;
507 if (low_index < 0)
508 error ("stack underflow - dup* operation");
510 flush_quick_stack ();
512 stack_pointer += size;
513 dst_index = stack_pointer;
515 for (dst_index = stack_pointer; --dst_index >= low_index; )
517 tree type;
518 int src_index = dst_index - size;
519 if (src_index < low_index)
520 src_index = dst_index + size + offset;
521 type = stack_type_map [src_index];
522 if (type == TYPE_SECOND)
524 if (src_index <= low_index)
525 fatal ("dup operation splits 64-bit number");
526 stack_type_map[dst_index] = type;
527 src_index--; dst_index--;
528 type = stack_type_map[src_index];
529 if (! TYPE_IS_WIDE (type))
530 fatal ("internal error - dup operation");
532 else if (TYPE_IS_WIDE (type))
533 fatal ("internal error - dup operation");
534 if (src_index != dst_index)
536 tree src_decl = find_stack_slot (src_index, type);
537 tree dst_decl = find_stack_slot (dst_index, type);
538 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
539 stack_type_map[dst_index] = type;
544 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
545 value stack. */
547 static void
548 build_java_athrow (node)
549 tree node;
551 tree call;
553 call = build (CALL_EXPR,
554 void_type_node,
555 build_address_of (throw_node[exceptions_via_longjmp ? 1 : 0]),
556 build_tree_list (NULL_TREE, node),
557 NULL_TREE);
558 TREE_SIDE_EFFECTS (call) = 1;
559 expand_expr_stmt (call);
560 java_stack_pop (stack_pointer);
563 /* Implementation for jsr/ret */
565 static void
566 build_java_jsr (where, ret)
567 tree where;
568 tree ret;
570 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
571 push_value (ret_label);
572 flush_quick_stack ();
573 emit_jump (label_rtx (where));
574 expand_label (ret);
577 static void
578 build_java_ret (location)
579 tree location;
581 expand_computed_goto (location);
584 /* Implementation of operations on array: new, load, store, length */
586 /* Array core info access macros */
588 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
589 byte_position (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))
591 tree
592 decode_newarray_type (atype)
593 int atype;
595 switch (atype)
597 case 4: return boolean_type_node;
598 case 5: return char_type_node;
599 case 6: return float_type_node;
600 case 7: return double_type_node;
601 case 8: return byte_type_node;
602 case 9: return short_type_node;
603 case 10: return int_type_node;
604 case 11: return long_type_node;
605 default: return NULL_TREE;
609 /* Map primitive type to the code used by OPCODE_newarray. */
612 encode_newarray_type (type)
613 tree type;
615 if (type == boolean_type_node)
616 return 4;
617 else if (type == char_type_node)
618 return 5;
619 else if (type == float_type_node)
620 return 6;
621 else if (type == double_type_node)
622 return 7;
623 else if (type == byte_type_node)
624 return 8;
625 else if (type == short_type_node)
626 return 9;
627 else if (type == int_type_node)
628 return 10;
629 else if (type == long_type_node)
630 return 11;
631 else
632 fatal ("Can't compute type code - patch_newarray");
635 /* Build a call to _Jv_ThrowBadArrayIndex(), the
636 ArrayIndexOfBoundsException exception handler. */
638 static tree
639 build_java_throw_out_of_bounds_exception (index)
640 tree index;
642 tree node = build (CALL_EXPR, int_type_node,
643 build_address_of (soft_badarrayindex_node),
644 build_tree_list (NULL_TREE, index), NULL_TREE);
645 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
646 return (node);
649 /* Return the length of an array. Doesn't perform any checking on the nature
650 or value of the array NODE. May be used to implement some bytecodes. */
652 tree
653 build_java_array_length_access (node)
654 tree node;
656 tree type = TREE_TYPE (node);
657 HOST_WIDE_INT length;
658 if (!is_array_type_p (type))
659 fatal ("array length on a non-array reference");
660 length = java_array_type_length (type);
661 if (length >= 0)
662 return build_int_2 (length, 0);
663 return fold (build1 (INDIRECT_REF,
664 int_type_node,
665 fold (build (PLUS_EXPR, ptr_type_node,
666 node,
667 JAVA_ARRAY_LENGTH_OFFSET(node)))));
670 /* Optionally checks an array against the NULL pointer, eventually throwing a
671 NullPointerException. It could replace signal handling, but tied to NULL.
672 ARG1: the pointer to check, ARG2: the expression to use if
673 the pointer is non-null and ARG3 the type that should be returned. */
675 tree
676 build_java_arraynull_check (node, expr, type)
677 tree node ATTRIBUTE_UNUSED;
678 tree expr;
679 tree type ATTRIBUTE_UNUSED;
681 #if 0
682 static int java_array_access_throws_null_exception = 0;
683 node = ???;
684 if (java_array_access_throws_null_exception)
685 return (build (COND_EXPR,
686 type,
687 build (EQ_EXPR, int_type_node, node, null_pointer_node),
688 build_java_athrow (node), expr ));
689 else
690 #endif
691 return (expr);
694 static tree
695 java_array_data_offset (array)
696 tree array;
698 tree array_type = TREE_TYPE (TREE_TYPE (array));
699 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
701 if (data_fld == NULL_TREE)
702 return size_in_bytes (array_type);
703 else
704 return byte_position (data_fld);
707 /* Implement array indexing (either as l-value or r-value).
708 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
709 Optionally performs bounds checking and/or test to NULL.
710 At this point, ARRAY should have been verified as an array. */
712 tree
713 build_java_arrayaccess (array, type, index)
714 tree array, type, index;
716 tree arith, node, throw = NULL_TREE;
718 arith = fold (build (PLUS_EXPR, int_type_node,
719 java_array_data_offset (array),
720 fold (build (MULT_EXPR, int_type_node,
721 index, size_in_bytes(type)))));
723 if (flag_bounds_check)
725 /* Generate:
726 * (unsigned jint) INDEX >= (unsigned jint) LEN
727 * && throw ArrayIndexOutOfBoundsException.
728 * Note this is equivalent to and more efficient than:
729 * INDEX < 0 || INDEX >= LEN && throw ... */
730 tree test;
731 tree len = build_java_array_length_access (array);
732 TREE_TYPE (len) = unsigned_int_type_node;
733 test = fold (build (GE_EXPR, boolean_type_node,
734 convert (unsigned_int_type_node, index),
735 len));
736 if (! integer_zerop (test))
738 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
739 build_java_throw_out_of_bounds_exception (index));
740 /* allows expansion within COMPOUND */
741 TREE_SIDE_EFFECTS( throw ) = 1;
745 node = build1 (INDIRECT_REF, type,
746 fold (build (PLUS_EXPR, ptr_type_node,
747 array,
748 (throw ? build (COMPOUND_EXPR, int_type_node,
749 throw, arith )
750 : arith))));
752 return (fold (build_java_arraynull_check (array, node, type)));
755 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
756 ARRAY_NODE. This function is used to retrieve something less vague than
757 a pointer type when indexing the first dimension of something like [[<t>.
758 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
759 return unchanged.
760 As a side effect, it also makes sure that ARRAY_NODE is an array. */
762 static tree
763 build_java_check_indexed_type (array_node, indexed_type)
764 tree array_node;
765 tree indexed_type;
767 tree elt_type;
769 if (!is_array_type_p (TREE_TYPE (array_node)))
770 fatal ("array indexing on a non-array reference");
772 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
774 if (indexed_type == ptr_type_node )
775 return promote_type (elt_type);
777 /* BYTE/BOOLEAN store and load are used for both type */
778 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
779 return boolean_type_node;
781 if (indexed_type != elt_type )
782 fatal ("type array element mismatch");
783 else
784 return indexed_type;
787 /* newarray triggers a call to _Jv_NewPrimArray. This function should be
788 called with an integer code (the type of array to create), and the length
789 of the array to create. */
791 tree
792 build_newarray (atype_value, length)
793 int atype_value;
794 tree length;
796 tree type_arg;
798 tree prim_type = decode_newarray_type (atype_value);
799 tree type
800 = build_java_array_type (prim_type,
801 host_integerp (length, 0) == INTEGER_CST
802 ? tree_low_cst (length, 0) : -1);
804 /* If compiling to native, pass a reference to the primitive type class
805 and save the runtime some work. However, the bytecode generator
806 expects to find the type_code int here. */
807 if (flag_emit_class_files)
808 type_arg = build_int_2 (atype_value, 0);
809 else
810 type_arg = build_class_ref (prim_type);
812 return build (CALL_EXPR, promote_type (type),
813 build_address_of (soft_newarray_node),
814 tree_cons (NULL_TREE,
815 type_arg,
816 build_tree_list (NULL_TREE, length)),
817 NULL_TREE);
820 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
821 of the dimension. */
823 tree
824 build_anewarray (class_type, length)
825 tree class_type;
826 tree length;
828 tree type
829 = build_java_array_type (class_type,
830 host_integerp (length, 0)
831 ? tree_low_cst (length, 0) : -1);
833 return build (CALL_EXPR, promote_type (type),
834 build_address_of (soft_anewarray_node),
835 tree_cons (NULL_TREE, length,
836 tree_cons (NULL_TREE, build_class_ref (class_type),
837 build_tree_list (NULL_TREE,
838 null_pointer_node))),
839 NULL_TREE);
842 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
844 tree
845 build_new_array (type, length)
846 tree type;
847 tree length;
849 if (JPRIMITIVE_TYPE_P (type))
850 return build_newarray (encode_newarray_type (type), length);
851 else
852 return build_anewarray (TREE_TYPE (type), length);
855 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
856 class pointer, a number of dimensions and the matching number of
857 dimensions. The argument list is NULL terminated. */
859 static void
860 expand_java_multianewarray (class_type, ndim)
861 tree class_type;
862 int ndim;
864 int i;
865 tree args = build_tree_list( NULL_TREE, null_pointer_node );
867 for( i = 0; i < ndim; i++ )
868 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
870 push_value (build (CALL_EXPR,
871 promote_type (class_type),
872 build_address_of (soft_multianewarray_node),
873 tree_cons (NULL_TREE, build_class_ref (class_type),
874 tree_cons (NULL_TREE,
875 build_int_2 (ndim, 0), args )),
876 NULL_TREE));
879 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
880 ARRAY is an array type. May expand some bound checking and NULL
881 pointer checking. RHS_TYPE_NODE we are going to store. In the case
882 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
883 INT. In those cases, we make the convertion.
885 if ARRAy is a reference type, the assignment is checked at run-time
886 to make sure that the RHS can be assigned to the array element
887 type. It is not necessary to generate this code if ARRAY is final. */
889 static void
890 expand_java_arraystore (rhs_type_node)
891 tree rhs_type_node;
893 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
894 && TYPE_PRECISION (rhs_type_node) <= 32) ?
895 int_type_node : rhs_type_node);
896 tree index = pop_value (int_type_node);
897 tree array = pop_value (ptr_type_node);
899 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
901 flush_quick_stack ();
903 index = save_expr (index);
904 array = save_expr (array);
906 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
908 tree check = build (CALL_EXPR, void_type_node,
909 build_address_of (soft_checkarraystore_node),
910 tree_cons (NULL_TREE, array,
911 build_tree_list (NULL_TREE, rhs_node)),
912 NULL_TREE);
913 TREE_SIDE_EFFECTS (check) = 1;
914 expand_expr_stmt (check);
917 expand_assignment (build_java_arrayaccess (array,
918 rhs_type_node,
919 index),
920 rhs_node, 0, 0);
923 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
924 sure that LHS is an array type. May expand some bound checking and NULL
925 pointer checking.
926 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
927 BOOLEAN/SHORT, we push a promoted type back to the stack.
930 static void
931 expand_java_arrayload (lhs_type_node )
932 tree lhs_type_node;
934 tree load_node;
935 tree index_node = pop_value (int_type_node);
936 tree array_node = pop_value (ptr_type_node);
938 index_node = save_expr (index_node);
939 array_node = save_expr (array_node);
940 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
942 load_node = build_java_arrayaccess (array_node,
943 lhs_type_node,
944 index_node);
946 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
947 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
948 push_value (load_node);
951 /* Expands .length. Makes sure that we deal with and array and may expand
952 a NULL check on the array object. */
954 static void
955 expand_java_array_length ()
957 tree array = pop_value (ptr_type_node);
958 tree length = build_java_array_length_access (array);
960 push_value (build_java_arraynull_check (array, length, int_type_node));
963 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
964 either soft_monitorenter_node or soft_monitorexit_node. */
966 static tree
967 build_java_monitor (call, object)
968 tree call;
969 tree object;
971 return (build (CALL_EXPR,
972 void_type_node,
973 build_address_of (call),
974 build_tree_list (NULL_TREE, object),
975 NULL_TREE));
978 /* Emit code for one of the PUSHC instructions. */
980 static void
981 expand_java_pushc (ival, type)
982 int ival;
983 tree type;
985 tree value;
986 if (type == ptr_type_node && ival == 0)
987 value = null_pointer_node;
988 else if (type == int_type_node || type == long_type_node)
990 value = build_int_2 (ival, ival < 0 ? -1 : 0);
991 TREE_TYPE (value) = type;
993 else if (type == float_type_node || type == double_type_node)
995 REAL_VALUE_TYPE x;
996 #ifdef REAL_ARITHMETIC
997 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
998 #else
999 x = ival;
1000 #endif
1001 value = build_real (type, x);
1003 else
1004 fatal ("internal error in expand_java_pushc");
1005 push_value (value);
1008 static void
1009 expand_java_return (type)
1010 tree type;
1012 if (type == void_type_node)
1013 expand_null_return ();
1014 else
1016 tree retval = pop_value (type);
1017 tree res = DECL_RESULT (current_function_decl);
1018 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1020 /* Handle the situation where the native integer type is smaller
1021 than the JVM integer. It can happen for many cross compilers.
1022 The whole if expression just goes away if INT_TYPE_SIZE < 32
1023 is false. */
1024 if (INT_TYPE_SIZE < 32
1025 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1026 < GET_MODE_SIZE (TYPE_MODE (type))))
1027 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1029 TREE_SIDE_EFFECTS (retval) = 1;
1030 expand_return (retval);
1034 tree
1035 build_address_of (value)
1036 tree value;
1038 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1041 static void
1042 expand_java_NEW (type)
1043 tree type;
1045 if (! CLASS_LOADED_P (type))
1046 load_class (type, 1);
1047 safe_layout_class (type);
1048 push_value (build (CALL_EXPR, promote_type (type),
1049 build_address_of (alloc_object_node),
1050 tree_cons (NULL_TREE, build_class_ref (type),
1051 build_tree_list (NULL_TREE,
1052 size_in_bytes (type))),
1053 NULL_TREE));
1056 /* This returns an expression which will extract the class of an
1057 object. */
1059 tree
1060 build_get_class (value)
1061 tree value;
1063 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1064 tree vtable_field = lookup_field (&object_type_node,
1065 get_identifier ("vtable"));
1066 return build (COMPONENT_REF, class_ptr_type,
1067 build1 (INDIRECT_REF, dtable_type,
1068 build (COMPONENT_REF, dtable_ptr_type,
1069 build1 (INDIRECT_REF, object_type_node, value),
1070 vtable_field)),
1071 class_field);
1074 /* This builds the tree representation of the `instanceof' operator.
1075 It tries various tricks to optimize this in cases where types are
1076 known. */
1078 tree
1079 build_instanceof (value, type)
1080 tree value, type;
1082 tree expr;
1083 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1084 tree valtype = TREE_TYPE (TREE_TYPE (value));
1085 tree valclass = TYPE_NAME (valtype);
1086 tree klass;
1088 /* When compiling from bytecode, we need to ensure that TYPE has
1089 been loaded. */
1090 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1092 load_class (type, 1);
1093 safe_layout_class (type);
1094 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1095 return error_mark_node;
1097 klass = TYPE_NAME (type);
1099 if (type == object_type_node || inherits_from_p (valtype, type))
1101 /* Anything except `null' is an instance of Object. Likewise,
1102 if the object is known to be an instance of the class, then
1103 we only need to check for `null'. */
1104 expr = build (COND_EXPR, itype,
1105 value,
1106 boolean_true_node, boolean_false_node);
1108 else if (DECL_P (klass) && DECL_P (valclass)
1109 && ! CLASS_INTERFACE (valclass)
1110 && ! CLASS_INTERFACE (klass)
1111 && ! inherits_from_p (type, valtype)
1112 && (CLASS_FINAL (klass)
1113 || ! inherits_from_p (valtype, type)))
1115 /* The classes are from different branches of the derivation
1116 tree, so we immediately know the answer. */
1117 expr = boolean_false_node;
1119 else if (DECL_P (klass) && CLASS_FINAL (klass))
1121 tree save = save_expr (value);
1122 expr = build (COND_EXPR, itype,
1123 save,
1124 build (EQ_EXPR, itype,
1125 build_get_class (save),
1126 build_class_ref (type)),
1127 boolean_false_node);
1129 else
1131 expr = build (CALL_EXPR, itype,
1132 build_address_of (soft_instanceof_node),
1133 tree_cons (NULL_TREE, value,
1134 build_tree_list (NULL_TREE,
1135 build_class_ref (type))),
1136 NULL_TREE);
1138 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1139 return expr;
1142 static void
1143 expand_java_INSTANCEOF (type)
1144 tree type;
1146 tree value = pop_value (object_ptr_type_node);
1147 value = build_instanceof (value, type);
1148 push_value (value);
1151 static void
1152 expand_java_CHECKCAST (type)
1153 tree type;
1155 tree value = pop_value (ptr_type_node);
1156 value = build (CALL_EXPR, promote_type (type),
1157 build_address_of (soft_checkcast_node),
1158 tree_cons (NULL_TREE, build_class_ref (type),
1159 build_tree_list (NULL_TREE, value)),
1160 NULL_TREE);
1161 push_value (value);
1164 static void
1165 expand_iinc (local_var_index, ival, pc)
1166 unsigned int local_var_index;
1167 int ival;
1168 int pc;
1170 tree local_var, res;
1171 tree constant_value;
1173 flush_quick_stack ();
1174 local_var = find_local_variable (local_var_index, int_type_node, pc);
1175 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1176 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1177 expand_assignment (local_var, res, 0, 0);
1181 tree
1182 build_java_soft_divmod (op, type, op1, op2)
1183 enum tree_code op;
1184 tree type, op1, op2;
1186 tree call = NULL;
1187 tree arg1 = convert (type, op1);
1188 tree arg2 = convert (type, op2);
1190 if (type == int_type_node)
1192 switch (op)
1194 case TRUNC_DIV_EXPR:
1195 call = soft_idiv_node;
1196 break;
1197 case TRUNC_MOD_EXPR:
1198 call = soft_irem_node;
1199 break;
1200 default:
1201 break;
1204 else if (type == long_type_node)
1206 switch (op)
1208 case TRUNC_DIV_EXPR:
1209 call = soft_ldiv_node;
1210 break;
1211 case TRUNC_MOD_EXPR:
1212 call = soft_lrem_node;
1213 break;
1214 default:
1215 break;
1219 if (! call)
1220 fatal ("Internal compiler error in build_java_soft_divmod");
1222 call = build (CALL_EXPR, type,
1223 build_address_of (call),
1224 tree_cons (NULL_TREE, arg1,
1225 build_tree_list (NULL_TREE, arg2)),
1226 NULL_TREE);
1228 return call;
1231 tree
1232 build_java_binop (op, type, arg1, arg2)
1233 enum tree_code op;
1234 tree type, arg1, arg2;
1236 tree mask;
1237 switch (op)
1239 case URSHIFT_EXPR:
1241 tree u_type = unsigned_type (type);
1242 arg1 = convert (u_type, arg1);
1243 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1244 return convert (type, arg1);
1246 case LSHIFT_EXPR:
1247 case RSHIFT_EXPR:
1248 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1249 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1250 break;
1252 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1253 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1254 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1256 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1257 boolean_type_node, arg1, arg2));
1258 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1259 tree second_compare = fold (build (COND_EXPR, int_type_node,
1260 ifexp2, integer_zero_node,
1261 op == COMPARE_L_EXPR
1262 ? integer_negative_one_node
1263 : integer_one_node));
1264 return fold (build (COND_EXPR, int_type_node, ifexp1,
1265 op == COMPARE_L_EXPR ? integer_one_node
1266 : integer_negative_one_node,
1267 second_compare));
1269 case COMPARE_EXPR:
1270 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1272 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1273 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1274 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1275 ifexp2, integer_one_node,
1276 integer_zero_node));
1277 return fold (build (COND_EXPR, int_type_node,
1278 ifexp1, integer_negative_one_node, second_compare));
1280 case TRUNC_DIV_EXPR:
1281 case TRUNC_MOD_EXPR:
1282 if (TREE_CODE (type) == REAL_TYPE
1283 && op == TRUNC_MOD_EXPR)
1285 tree call;
1286 if (type != double_type_node)
1288 arg1 = convert (double_type_node, arg1);
1289 arg2 = convert (double_type_node, arg2);
1291 call = build (CALL_EXPR, double_type_node,
1292 build_address_of (soft_fmod_node),
1293 tree_cons (NULL_TREE, arg1,
1294 build_tree_list (NULL_TREE, arg2)),
1295 NULL_TREE);
1296 if (type != double_type_node)
1297 call = convert (type, call);
1298 return call;
1301 if (TREE_CODE (type) == INTEGER_TYPE
1302 && flag_use_divide_subroutine
1303 && ! flag_syntax_only)
1304 return build_java_soft_divmod (op, type, arg1, arg2);
1306 break;
1307 default: ;
1309 return fold (build (op, type, arg1, arg2));
1312 static void
1313 expand_java_binop (type, op)
1314 tree type; enum tree_code op;
1316 tree larg, rarg;
1317 tree ltype = type;
1318 tree rtype = type;
1319 switch (op)
1321 case LSHIFT_EXPR:
1322 case RSHIFT_EXPR:
1323 case URSHIFT_EXPR:
1324 rtype = int_type_node;
1325 rarg = pop_value (rtype);
1326 break;
1327 default:
1328 rarg = pop_value (rtype);
1330 larg = pop_value (ltype);
1331 push_value (build_java_binop (op, type, larg, rarg));
1334 /* Lookup the field named NAME in *TYPEP or its super classes.
1335 If not found, return NULL_TREE.
1336 (If the *TYPEP is not found, or if the field reference is
1337 ambiguous, return error_mark_node.)
1338 If found, return the FIELD_DECL, and set *TYPEP to the
1339 class containing the field. */
1341 tree
1342 lookup_field (typep, name)
1343 tree *typep;
1344 tree name;
1346 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1348 load_class (*typep, 1);
1349 safe_layout_class (*typep);
1350 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1351 return error_mark_node;
1355 tree field, basetype_vec;
1356 tree save_field;
1357 int n, i;
1359 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1360 if (DECL_NAME (field) == name)
1361 return field;
1363 /* If *typep is an innerclass, lookup the field in its enclosing
1364 contexts */
1365 if (INNER_CLASS_TYPE_P (*typep))
1367 tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1369 if ((field = lookup_field (&outer_type, name)))
1370 return field;
1373 /* Process implemented interfaces. */
1374 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1375 n = TREE_VEC_LENGTH (basetype_vec);
1376 save_field = NULL_TREE;
1377 for (i = 0; i < n; i++)
1379 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1380 if ((field = lookup_field (&t, name)))
1382 if (save_field == field)
1383 continue;
1384 if (save_field == NULL_TREE)
1385 save_field = field;
1386 else
1388 tree i1 = DECL_CONTEXT (save_field);
1389 tree i2 = DECL_CONTEXT (field);
1390 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1391 IDENTIFIER_POINTER (name),
1392 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1393 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1394 return error_mark_node;
1399 if (save_field != NULL_TREE)
1400 return save_field;
1402 *typep = CLASSTYPE_SUPER (*typep);
1403 } while (*typep);
1404 return NULL_TREE;
1407 /* Look up the field named NAME in object SELF_VALUE,
1408 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1409 SELF_VALUE is NULL_TREE if looking for a static field. */
1411 tree
1412 build_field_ref (self_value, self_class, name)
1413 tree self_value, self_class, name;
1415 tree base_class = self_class;
1416 tree field_decl = lookup_field (&base_class, name);
1417 if (field_decl == NULL_TREE)
1419 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1420 return error_mark_node;
1422 if (self_value == NULL_TREE)
1424 return build_static_field_ref (field_decl);
1426 else
1428 tree base_handle_type = promote_type (base_class);
1429 if (base_handle_type != TREE_TYPE (self_value))
1430 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1431 #ifdef JAVA_USE_HANDLES
1432 self_value = unhand_expr (self_value);
1433 #endif
1434 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1435 self_value);
1436 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1437 self_value, field_decl));
1441 tree
1442 lookup_label (pc)
1443 int pc;
1445 tree name;
1446 char buf[32];
1447 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1448 name = get_identifier (buf);
1449 if (IDENTIFIER_LOCAL_VALUE (name))
1450 return IDENTIFIER_LOCAL_VALUE (name);
1451 else
1453 /* The type of the address of a label is return_address_type_node. */
1454 tree decl = create_label_decl (name);
1455 LABEL_PC (decl) = pc;
1456 label_rtx (decl);
1457 return pushdecl (decl);
1461 /* Generate a unique name for the purpose of loops and switches
1462 labels, and try-catch-finally blocks label or temporary variables. */
1464 tree
1465 generate_name ()
1467 static int l_number = 0;
1468 char buff [32];
1469 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1470 l_number++;
1471 return get_identifier (buff);
1474 tree
1475 create_label_decl (name)
1476 tree name;
1478 tree decl;
1479 decl = build_decl (LABEL_DECL, name,
1480 TREE_TYPE (return_address_type_node));
1481 DECL_CONTEXT (decl) = current_function_decl;
1482 DECL_IGNORED_P (decl) = 1;
1483 return decl;
1486 /* This maps a bytecode offset (PC) to various flags. */
1487 char *instruction_bits;
1489 static void
1490 note_label (current_pc, target_pc)
1491 int current_pc ATTRIBUTE_UNUSED, target_pc;
1493 lookup_label (target_pc);
1494 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1497 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1498 where CONDITION is one of one the compare operators. */
1500 static void
1501 expand_compare (condition, value1, value2, target_pc)
1502 enum tree_code condition;
1503 tree value1, value2;
1504 int target_pc;
1506 tree target = lookup_label (target_pc);
1507 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1508 expand_start_cond (truthvalue_conversion (cond), 0);
1509 expand_goto (target);
1510 expand_end_cond ();
1513 /* Emit code for a TEST-type opcode. */
1515 static void
1516 expand_test (condition, type, target_pc)
1517 enum tree_code condition;
1518 tree type;
1519 int target_pc;
1521 tree value1, value2;
1522 flush_quick_stack ();
1523 value1 = pop_value (type);
1524 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1525 expand_compare (condition, value1, value2, target_pc);
1528 /* Emit code for a COND-type opcode. */
1530 static void
1531 expand_cond (condition, type, target_pc)
1532 enum tree_code condition;
1533 tree type;
1534 int target_pc;
1536 tree value1, value2;
1537 flush_quick_stack ();
1538 /* note: pop values in opposite order */
1539 value2 = pop_value (type);
1540 value1 = pop_value (type);
1541 /* Maybe should check value1 and value2 for type compatibility ??? */
1542 expand_compare (condition, value1, value2, target_pc);
1545 static void
1546 expand_java_goto (target_pc)
1547 int target_pc;
1549 tree target_label = lookup_label (target_pc);
1550 flush_quick_stack ();
1551 expand_goto (target_label);
1554 #if 0
1555 static void
1556 expand_java_call (target_pc, return_address)
1557 int target_pc, return_address;
1559 tree target_label = lookup_label (target_pc);
1560 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1561 push_value (value);
1562 flush_quick_stack ();
1563 expand_goto (target_label);
1566 static void
1567 expand_java_ret (return_address)
1568 tree return_address ATTRIBUTE_UNUSED;
1570 warning ("ret instruction not implemented");
1571 #if 0
1572 tree target_label = lookup_label (target_pc);
1573 flush_quick_stack ();
1574 expand_goto (target_label);
1575 #endif
1577 #endif
1579 /* Recursive helper function to pop argument types during verifiation. */
1581 void
1582 pop_argument_types (arg_types)
1583 tree arg_types;
1585 if (arg_types == end_params_node)
1586 return;
1587 if (TREE_CODE (arg_types) == TREE_LIST)
1589 pop_argument_types (TREE_CHAIN (arg_types));
1590 pop_type (TREE_VALUE (arg_types));
1591 return;
1593 abort ();
1596 static tree
1597 pop_arguments (arg_types)
1598 tree arg_types;
1600 if (arg_types == end_params_node)
1601 return NULL_TREE;
1602 if (TREE_CODE (arg_types) == TREE_LIST)
1604 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1605 tree type = TREE_VALUE (arg_types);
1606 tree arg = pop_value (type);
1607 if (PROMOTE_PROTOTYPES
1608 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1609 && INTEGRAL_TYPE_P (type))
1610 arg = convert (integer_type_node, arg);
1611 return tree_cons (NULL_TREE, arg, tail);
1613 abort ();
1616 /* Build an expression to initialize the class CLAS.
1617 if EXPR is non-NULL, returns an expression to first call the initializer
1618 (if it is needed) and then calls EXPR. */
1620 tree
1621 build_class_init (clas, expr)
1622 tree clas, expr;
1624 tree init, call;
1625 struct init_test_hash_entry *ite;
1626 if (inherits_from_p (current_class, clas))
1627 return expr;
1629 if (always_initialize_class_p)
1631 init = build (CALL_EXPR, void_type_node,
1632 build_address_of (soft_initclass_node),
1633 build_tree_list (NULL_TREE, build_class_ref (clas)),
1634 NULL_TREE);
1635 TREE_SIDE_EFFECTS (init) = 1;
1637 else
1639 ite = (struct init_test_hash_entry *)
1640 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1641 (const hash_table_key) clas,
1642 TRUE, NULL);
1644 if (ite->init_test_decl == 0)
1645 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1646 boolean_type_node);
1647 /* Tell the check-init code to ignore this decl. */
1648 DECL_BIT_INDEX(ite->init_test_decl) = -1;
1650 init = build (CALL_EXPR, void_type_node,
1651 build_address_of (soft_initclass_node),
1652 build_tree_list (NULL_TREE, build_class_ref (clas)),
1653 NULL_TREE);
1654 TREE_SIDE_EFFECTS (init) = 1;
1655 call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1656 build (MODIFY_EXPR, boolean_type_node,
1657 ite->init_test_decl, boolean_true_node));
1658 TREE_SIDE_EFFECTS (call) = 1;
1659 init = build (COND_EXPR, void_type_node,
1660 build (EQ_EXPR, boolean_type_node,
1661 ite->init_test_decl, boolean_false_node),
1662 call, integer_zero_node);
1663 TREE_SIDE_EFFECTS (init) = 1;
1666 if (expr != NULL_TREE)
1668 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1669 TREE_SIDE_EFFECTS (expr) = 1;
1670 return expr;
1672 return init;
1675 tree
1676 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1677 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1678 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1680 tree func;
1681 if (is_compiled_class (self_type))
1683 make_decl_rtl (method, NULL);
1684 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1686 else
1688 /* We don't know whether the method has been (statically) compiled.
1689 Compile this code to get a reference to the method's code:
1691 SELF_TYPE->methods[METHOD_INDEX].ncode
1693 This is guaranteed to work (assuming SELF_TYPE has
1694 been initialized), since if the method is not compiled yet,
1695 its ncode points to a trampoline that forces compilation. */
1697 int method_index = 0;
1698 tree meth;
1699 tree ref = build_class_ref (self_type);
1700 ref = build1 (INDIRECT_REF, class_type_node, ref);
1701 if (ncode_ident == NULL_TREE)
1702 ncode_ident = get_identifier ("ncode");
1703 if (methods_ident == NULL_TREE)
1704 methods_ident = get_identifier ("methods");
1705 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1706 lookup_field (&class_type_node, methods_ident));
1707 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1708 ; meth = TREE_CHAIN (meth))
1710 if (method == meth)
1711 break;
1712 if (meth == NULL_TREE)
1713 fatal ("method '%s' not found in class",
1714 IDENTIFIER_POINTER (DECL_NAME (method)));
1715 method_index++;
1717 method_index *= int_size_in_bytes (method_type_node);
1718 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1719 ref, build_int_2 (method_index, 0)));
1720 ref = build1 (INDIRECT_REF, method_type_node, ref);
1721 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1722 ref,
1723 lookup_field (&method_type_node, ncode_ident));
1725 return func;
1728 tree
1729 invoke_build_dtable (is_invoke_interface, arg_list)
1730 int is_invoke_interface;
1731 tree arg_list;
1733 tree dtable, objectref;
1735 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1737 /* If we're dealing with interfaces and if the objectref
1738 argument is an array then get the dispatch table of the class
1739 Object rather than the one from the objectref. */
1740 objectref = (is_invoke_interface
1741 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1742 object_type_node : TREE_VALUE (arg_list));
1744 if (dtable_ident == NULL_TREE)
1745 dtable_ident = get_identifier ("vtable");
1746 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1747 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1748 lookup_field (&object_type_node, dtable_ident));
1750 return dtable;
1753 tree
1754 build_invokevirtual (dtable, method)
1755 tree dtable, method;
1757 tree func;
1758 tree nativecode_ptr_ptr_type_node
1759 = build_pointer_type (nativecode_ptr_type_node);
1760 tree method_index = convert (sizetype, DECL_VINDEX (method));
1762 /* Add one to skip "class" field of dtable, and one to skip unused
1763 vtable entry (for C++ compatibility). */
1764 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1765 method_index = size_binop (MULT_EXPR, method_index,
1766 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1767 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1768 convert (nativecode_ptr_ptr_type_node, method_index)));
1769 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1771 return func;
1774 tree
1775 build_invokeinterface (dtable, method)
1776 tree dtable, method;
1778 static tree class_ident = NULL_TREE;
1779 tree lookup_arg;
1780 tree interface;
1781 tree idx;
1782 tree meth;
1783 int i;
1785 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1786 ensure that the selected method exists, is public and not
1787 abstract nor static. */
1789 if (class_ident == NULL_TREE)
1791 class_ident = get_identifier ("class");
1792 ggc_add_tree_root (&class_ident, 1);
1795 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1796 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1797 lookup_field (&dtable_type, class_ident));
1799 interface = DECL_CONTEXT (method);
1800 layout_class_methods (interface);
1802 i = 1;
1803 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1805 if (meth == method)
1807 idx = build_int_2 (i, 0);
1808 break;
1810 if (meth == NULL_TREE)
1811 fatal ("internal error in build_invokeinterface");
1814 lookup_arg = tree_cons (NULL_TREE, dtable,
1815 tree_cons (NULL_TREE, build_class_ref (interface),
1816 build_tree_list (NULL_TREE, idx)));
1818 return build (CALL_EXPR, ptr_type_node,
1819 build_address_of (soft_lookupinterfacemethod_node),
1820 lookup_arg, NULL_TREE);
1823 /* Expand one of the invoke_* opcodes.
1824 OCPODE is the specific opcode.
1825 METHOD_REF_INDEX is an index into the constant pool.
1826 NARGS is the number of arguments, or -1 if not specified. */
1828 static void
1829 expand_invoke (opcode, method_ref_index, nargs)
1830 int opcode;
1831 int method_ref_index;
1832 int nargs ATTRIBUTE_UNUSED;
1834 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1835 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1836 tree self_type = get_class_constant
1837 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1838 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1839 tree call, func, method, arg_list, method_type;
1840 tree cond = NULL_TREE;
1842 if (! CLASS_LOADED_P (self_type))
1844 load_class (self_type, 1);
1845 safe_layout_class (self_type);
1846 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1847 fatal ("failed to find class '%s'", self_name);
1849 layout_class_methods (self_type);
1851 if (ID_INIT_P (method_name))
1852 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1853 method_signature);
1854 else
1855 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1856 method_name, method_signature);
1857 if (method == NULL_TREE)
1859 error ("Class '%s' has no method named '%s' matching signature '%s'",
1860 self_name,
1861 IDENTIFIER_POINTER (method_name),
1862 IDENTIFIER_POINTER (method_signature));
1864 /* Invoke static can't invoke static/abstract method */
1865 else if (opcode == OPCODE_invokestatic)
1867 if (!METHOD_STATIC (method))
1869 error ("invokestatic on non static method");
1870 method = NULL_TREE;
1872 else if (METHOD_ABSTRACT (method))
1874 error ("invokestatic on abstract method");
1875 method = NULL_TREE;
1878 else
1880 if (METHOD_STATIC (method))
1882 error ("invoke[non-static] on static method");
1883 method = NULL_TREE;
1887 if (method == NULL_TREE)
1889 method_type = get_type_from_signature (method_signature);
1890 pop_arguments (TYPE_ARG_TYPES (method_type));
1891 if (opcode != OPCODE_invokestatic)
1892 pop_type (self_type);
1893 method_type = promote_type (TREE_TYPE (method_type));
1894 push_value (convert (method_type, integer_zero_node));
1895 return;
1898 method_type = TREE_TYPE (method);
1899 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1900 flush_quick_stack ();
1902 func = NULL_TREE;
1903 if (opcode == OPCODE_invokestatic)
1904 func = build_known_method_ref (method, method_type, self_type,
1905 method_signature, arg_list);
1906 else if (opcode == OPCODE_invokespecial
1907 || (opcode == OPCODE_invokevirtual
1908 && (METHOD_PRIVATE (method)
1909 || METHOD_FINAL (method)
1910 || CLASS_FINAL (TYPE_NAME (self_type)))))
1912 /* If the object for the method call is null, we throw an
1913 exception. We don't do this if the object is the current
1914 method's `this'. In other cases we just rely on an
1915 optimization pass to eliminate redundant checks. FIXME:
1916 Unfortunately there doesn't seem to be a way to determine
1917 what the current method is right now. */
1918 /* We use a SAVE_EXPR here to make sure we only evaluate
1919 the new `self' expression once. */
1920 tree save_arg = save_expr (TREE_VALUE (arg_list));
1921 TREE_VALUE (arg_list) = save_arg;
1922 cond = build (EQ_EXPR, boolean_type_node, save_arg, null_pointer_node);
1923 func = build_known_method_ref (method, method_type, self_type,
1924 method_signature, arg_list);
1926 else
1928 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1929 arg_list);
1930 if (opcode == OPCODE_invokevirtual)
1931 func = build_invokevirtual (dtable, method);
1932 else
1933 func = build_invokeinterface (dtable, method);
1935 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1936 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1937 TREE_SIDE_EFFECTS (call) = 1;
1939 if (cond != NULL_TREE)
1941 /* We have to make the `then' branch a compound expression to
1942 make the types turn out right. This seems bizarre. */
1943 call = build (COND_EXPR, TREE_TYPE (call), cond,
1944 build (COMPOUND_EXPR, TREE_TYPE (call),
1945 build (CALL_EXPR, void_type_node,
1946 build_address_of (soft_nullpointer_node),
1947 NULL_TREE, NULL_TREE),
1948 (FLOAT_TYPE_P (TREE_TYPE (call))
1949 ? build_real (TREE_TYPE (call), dconst0)
1950 : build1 (CONVERT_EXPR, TREE_TYPE (call),
1951 integer_zero_node))),
1952 call);
1953 TREE_SIDE_EFFECTS (call) = 1;
1956 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1957 expand_expr_stmt (call);
1958 else
1960 push_value (call);
1961 flush_quick_stack ();
1965 /* Create a stub which will be put into the vtable but which will call
1966 a JNI function. */
1968 tree
1969 build_jni_stub (method)
1970 tree method;
1972 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
1973 tree jni_func_type, tem;
1974 tree env_var, res_var = NULL_TREE, block;
1975 tree method_args, res_type;
1976 tree meth_var;
1978 tree klass = DECL_CONTEXT (method);
1979 int from_class = ! CLASS_FROM_SOURCE_P (klass);
1980 klass = build_class_ref (klass);
1982 if (! METHOD_NATIVE (method) || ! flag_jni)
1983 abort ();
1985 DECL_ARTIFICIAL (method) = 1;
1986 DECL_EXTERNAL (method) = 0;
1988 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
1989 DECL_CONTEXT (env_var) = method;
1991 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
1993 res_var = build_decl (VAR_DECL, get_identifier ("res"),
1994 TREE_TYPE (TREE_TYPE (method)));
1995 DECL_CONTEXT (res_var) = method;
1996 TREE_CHAIN (env_var) = res_var;
1999 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2000 TREE_STATIC (meth_var) = 1;
2001 TREE_PUBLIC (meth_var) = 0;
2002 DECL_EXTERNAL (meth_var) = 0;
2003 make_decl_rtl (meth_var, NULL);
2004 meth_var = pushdecl_top_level (meth_var);
2006 /* One strange way that the front ends are different is that they
2007 store arguments differently. */
2008 if (from_class)
2009 method_args = DECL_ARGUMENTS (method);
2010 else
2011 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2012 block = build_block (env_var, NULL_TREE, NULL_TREE,
2013 method_args, NULL_TREE);
2014 TREE_SIDE_EFFECTS (block) = 1;
2015 /* When compiling from source we don't set the type of the block,
2016 because that will prevent patch_return from ever being run. */
2017 if (from_class)
2018 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2020 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2021 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2022 build (CALL_EXPR, ptr_type_node,
2023 build_address_of (soft_getjnienvnewframe_node),
2024 build_tree_list (NULL_TREE, klass),
2025 NULL_TREE));
2026 CAN_COMPLETE_NORMALLY (body) = 1;
2028 /* All the arguments to this method become arguments to the
2029 underlying JNI function. If we had to wrap object arguments in a
2030 special way, we would do that here. */
2031 args = NULL_TREE;
2032 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2033 args = tree_cons (NULL_TREE, tem, args);
2034 args = nreverse (args);
2035 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2037 /* For a static method the second argument is the class. For a
2038 non-static method the second argument is `this'; that is already
2039 available in the argument list. */
2040 if (METHOD_STATIC (method))
2042 args = tree_cons (NULL_TREE, klass, args);
2043 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2046 /* The JNIEnv structure is the first argument to the JNI function. */
2047 args = tree_cons (NULL_TREE, env_var, args);
2048 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2050 /* We call _Jv_LookupJNIMethod to find the actual underlying
2051 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2052 exception if this function is not found at runtime. */
2053 method_sig = build_java_signature (TREE_TYPE (method));
2054 lookup_arg =
2055 build_tree_list (NULL_TREE,
2056 build_utf8_ref (unmangle_classname
2057 (IDENTIFIER_POINTER (method_sig),
2058 IDENTIFIER_LENGTH (method_sig))));
2059 tem = DECL_NAME (method);
2060 lookup_arg
2061 = tree_cons (NULL_TREE, klass,
2062 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2064 jni_func_type
2065 = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2066 arg_types));
2068 jnifunc = build (COND_EXPR, ptr_type_node,
2069 meth_var, meth_var,
2070 build (MODIFY_EXPR, ptr_type_node,
2071 meth_var,
2072 build (CALL_EXPR, ptr_type_node,
2073 build_address_of (soft_lookupjnimethod_node),
2074 lookup_arg, NULL_TREE)));
2076 /* Now we make the actual JNI call via the resulting function
2077 pointer. */
2078 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2079 build1 (NOP_EXPR, jni_func_type, jnifunc),
2080 args, NULL_TREE);
2082 /* If the JNI call returned a result, capture it here. If we had to
2083 unwrap JNI object results, we would do that here. */
2084 if (res_var != NULL_TREE)
2085 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2086 res_var, call);
2088 TREE_SIDE_EFFECTS (call) = 1;
2089 CAN_COMPLETE_NORMALLY (call) = 1;
2091 body = build (COMPOUND_EXPR, void_type_node, body, call);
2092 TREE_SIDE_EFFECTS (body) = 1;
2094 /* Now free the environment we allocated. */
2095 call = build (CALL_EXPR, ptr_type_node,
2096 build_address_of (soft_jnipopsystemframe_node),
2097 build_tree_list (NULL_TREE, env_var),
2098 NULL_TREE);
2099 TREE_SIDE_EFFECTS (call) = 1;
2100 CAN_COMPLETE_NORMALLY (call) = 1;
2101 body = build (COMPOUND_EXPR, void_type_node, body, call);
2102 TREE_SIDE_EFFECTS (body) = 1;
2104 /* Finally, do the return. When compiling from source we rely on
2105 patch_return to patch the return value -- because DECL_RESULT is
2106 not set at the time this function is called. */
2107 if (from_class)
2109 res_type = void_type_node;
2110 if (res_var != NULL_TREE)
2112 tree drt;
2113 if (! DECL_RESULT (method))
2114 abort ();
2115 /* Make sure we copy the result variable to the actual
2116 result. We use the type of the DECL_RESULT because it
2117 might be different from the return type of the function:
2118 it might be promoted. */
2119 drt = TREE_TYPE (DECL_RESULT (method));
2120 if (drt != TREE_TYPE (res_var))
2121 res_var = build1 (CONVERT_EXPR, drt, res_var);
2122 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2123 TREE_SIDE_EFFECTS (res_var) = 1;
2126 else
2128 /* This is necessary to get patch_return to run. */
2129 res_type = NULL_TREE;
2131 body = build (COMPOUND_EXPR, void_type_node, body,
2132 build1 (RETURN_EXPR, res_type, res_var));
2133 TREE_SIDE_EFFECTS (body) = 1;
2135 BLOCK_EXPR_BODY (block) = body;
2136 return block;
2139 /* Expand an operation to extract from or store into a field.
2140 IS_STATIC is 1 iff the field is static.
2141 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2142 FIELD_REF_INDEX is an index into the constant pool. */
2144 static void
2145 expand_java_field_op (is_static, is_putting, field_ref_index)
2146 int is_static;
2147 int is_putting;
2148 int field_ref_index;
2150 tree self_type =
2151 get_class_constant (current_jcf,
2152 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2153 field_ref_index));
2154 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2155 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2156 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2157 field_ref_index);
2158 tree field_type = get_type_from_signature (field_signature);
2159 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2160 tree field_ref;
2161 int is_error = 0;
2162 tree field_decl = lookup_field (&self_type, field_name);
2163 if (field_decl == error_mark_node)
2165 is_error = 1;
2167 else if (field_decl == NULL_TREE)
2169 error ("Missing field '%s' in '%s'",
2170 IDENTIFIER_POINTER (field_name), self_name);
2171 is_error = 1;
2173 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2175 error ("Mismatching signature for field '%s' in '%s'",
2176 IDENTIFIER_POINTER (field_name), self_name);
2177 is_error = 1;
2179 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2180 if (is_error)
2182 if (! is_putting)
2183 push_value (convert (field_type, integer_zero_node));
2184 flush_quick_stack ();
2185 return;
2188 /* Inline references to java.lang.PRIMTYPE.TYPE.
2189 In addition to being a useful (minor) optimization,
2190 this is also needed to avoid circularities in the implementation
2191 of these fields in libjava. */
2192 if (field_name == TYPE_identifier_node && ! is_putting
2193 && ! flag_emit_class_files && field_type == class_ptr_type
2194 && strncmp (self_name, "java.lang.", 10) == 0)
2196 tree typ = build_primtype_type_ref (self_name);
2197 if (typ)
2199 push_value (typ);
2200 return;
2204 field_ref = build_field_ref (field_ref, self_type, field_name);
2205 if (is_static)
2206 field_ref = build_class_init (self_type, field_ref);
2207 if (is_putting)
2209 flush_quick_stack ();
2210 if (FIELD_FINAL (field_decl))
2212 if (DECL_CONTEXT (field_decl) != current_class)
2213 error_with_decl (field_decl,
2214 "assignment to final field `%s' not in field's class");
2215 else if (FIELD_STATIC (field_decl))
2217 if (!DECL_CLINIT_P (current_function_decl))
2218 error_with_decl (field_decl,
2219 "assignment to final static field `%s' not in class initializer");
2221 else
2223 tree cfndecl_name = DECL_NAME (current_function_decl);
2224 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2225 && !ID_FINIT_P (cfndecl_name))
2226 error_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2229 expand_assignment (field_ref, new_value, 0, 0);
2231 else
2232 push_value (field_ref);
2235 tree
2236 build_primtype_type_ref (self_name)
2237 const char *self_name;
2239 const char *class_name = self_name+10;
2240 tree typ;
2241 if (strncmp(class_name, "Byte", 4) == 0)
2242 typ = byte_type_node;
2243 else if (strncmp(class_name, "Short", 5) == 0)
2244 typ = short_type_node;
2245 else if (strncmp(class_name, "Integer", 7) == 0)
2246 typ = int_type_node;
2247 else if (strncmp(class_name, "Long", 4) == 0)
2248 typ = long_type_node;
2249 else if (strncmp(class_name, "Float", 5) == 0)
2250 typ = float_type_node;
2251 else if (strncmp(class_name, "Double", 6) == 0)
2252 typ = double_type_node;
2253 else if (strncmp(class_name, "Boolean", 7) == 0)
2254 typ = boolean_type_node;
2255 else if (strncmp(class_name, "Char", 4) == 0)
2256 typ = char_type_node;
2257 else if (strncmp(class_name, "Void", 4) == 0)
2258 typ = void_type_node;
2259 else
2260 typ = NULL_TREE;
2261 if (typ != NULL_TREE)
2262 return build_class_ref (typ);
2263 else
2264 return NULL_TREE;
2267 void
2268 load_type_state (label)
2269 tree label;
2271 int i;
2272 tree vec = LABEL_TYPE_STATE (label);
2273 int cur_length = TREE_VEC_LENGTH (vec);
2274 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2275 for (i = 0; i < cur_length; i++)
2276 type_map [i] = TREE_VEC_ELT (vec, i);
2279 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2280 dependant things, but they rely on gcc routines. This function is
2281 placed here because it uses things defined locally in parse.y. */
2283 static tree
2284 case_identity (t, v)
2285 tree t __attribute__ ((__unused__));
2286 tree v;
2288 return v;
2291 /* Return the name of the vtable for an array of a given primitive
2292 type. */
2293 static tree
2294 get_primitive_array_vtable (tree elt)
2296 tree r;
2297 if (elt == boolean_type_node)
2298 r = boolean_array_vtable;
2299 else if (elt == byte_type_node)
2300 r = byte_array_vtable;
2301 else if (elt == char_type_node)
2302 r = char_array_vtable;
2303 else if (elt == short_type_node)
2304 r = short_array_vtable;
2305 else if (elt == int_type_node)
2306 r = int_array_vtable;
2307 else if (elt == long_type_node)
2308 r = long_array_vtable;
2309 else if (elt == float_type_node)
2310 r = float_array_vtable;
2311 else if (elt == double_type_node)
2312 r = double_array_vtable;
2313 else
2314 abort ();
2315 return build_address_of (r);
2318 struct rtx_def *
2319 java_lang_expand_expr (exp, target, tmode, modifier)
2320 register tree exp;
2321 rtx target ATTRIBUTE_UNUSED;
2322 enum machine_mode tmode ATTRIBUTE_UNUSED;
2323 enum expand_modifier modifier ATTRIBUTE_UNUSED;
2325 tree current;
2327 switch (TREE_CODE (exp))
2329 case NEW_ARRAY_INIT:
2331 rtx tmp;
2332 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2333 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2334 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2335 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2336 tree length = build_int_2 (ilength, 0);
2337 tree init = TREE_OPERAND (exp, 0);
2338 tree array_decl;
2340 /* See if we can generate the array statically. */
2341 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2342 && JPRIMITIVE_TYPE_P (element_type))
2344 tree temp, value, init_decl;
2345 struct rtx_def *r;
2346 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2347 PUSH_FIELD_VALUE (temp, "vtable",
2348 get_primitive_array_vtable (element_type));
2349 if (! flag_hash_synchronization)
2350 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2351 FINISH_RECORD_CONSTRUCTOR (temp);
2352 START_RECORD_CONSTRUCTOR (value, array_type);
2353 PUSH_SUPER_VALUE (value, temp);
2354 /* FIXME: build a new `length' here to get it on the right
2355 obstack. */
2356 PUSH_FIELD_VALUE (value, "length", build_int_2 (ilength, 0));
2357 PUSH_FIELD_VALUE (value, "data", init);
2358 FINISH_RECORD_CONSTRUCTOR (value);
2360 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2361 pushdecl_top_level (init_decl);
2362 TREE_STATIC (init_decl) = 1;
2363 DECL_INITIAL (init_decl) = value;
2364 DECL_IGNORED_P (init_decl) = 1;
2365 TREE_READONLY (init_decl) = 1;
2366 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2367 make_decl_rtl (init_decl, NULL);
2368 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2369 r = expand_expr (init, target, tmode, modifier);
2370 return r;
2373 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2374 expand_decl (array_decl);
2375 tmp = expand_assignment (array_decl,
2376 build_new_array (element_type, length),
2377 1, 0);
2378 if (TREE_CONSTANT (init)
2379 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2381 tree init_decl;
2382 init_decl = build_decl (VAR_DECL, generate_name (),
2383 TREE_TYPE (init));
2384 pushdecl_top_level (init_decl);
2385 TREE_STATIC (init_decl) = 1;
2386 DECL_INITIAL (init_decl) = init;
2387 DECL_IGNORED_P (init_decl) = 1;
2388 TREE_READONLY (init_decl) = 1;
2389 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2390 make_decl_rtl (init_decl, NULL);
2391 init = init_decl;
2393 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2394 build1 (INDIRECT_REF, array_type,
2395 array_decl), data_fld), init, 0, 0);
2396 return tmp;
2398 case BLOCK:
2399 if (BLOCK_EXPR_BODY (exp))
2401 tree local;
2402 tree body = BLOCK_EXPR_BODY (exp);
2403 pushlevel (2); /* 2 and above */
2404 expand_start_bindings (0);
2405 local = BLOCK_EXPR_DECLS (exp);
2406 while (local)
2408 tree next = TREE_CHAIN (local);
2409 layout_decl (local, 0);
2410 expand_decl (pushdecl (local));
2411 local = next;
2413 /* Avoid deep recursion for long block. */
2414 while (TREE_CODE (body) == COMPOUND_EXPR)
2416 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2417 emit_queue ();
2418 body = TREE_OPERAND (body, 1);
2420 expand_expr (body, const0_rtx, VOIDmode, 0);
2421 emit_queue ();
2422 poplevel (1, 1, 0);
2423 expand_end_bindings (getdecls (), 1, 0);
2424 return const0_rtx;
2426 return const0_rtx;
2428 case CASE_EXPR:
2430 tree duplicate;
2431 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2432 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2433 &duplicate) == 2)
2435 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2436 parse_error_context
2437 (wfl_operator, "Duplicate case label: `%s'",
2438 print_int_node (TREE_OPERAND (exp, 0)));
2440 return const0_rtx;
2443 case DEFAULT_EXPR:
2444 pushcase (NULL_TREE, 0,
2445 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2446 return const0_rtx;
2448 case SWITCH_EXPR:
2449 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2450 expand_expr_stmt (TREE_OPERAND (exp, 1));
2451 expand_end_case (TREE_OPERAND (exp, 0));
2452 return const0_rtx;
2454 case TRY_EXPR:
2455 /* We expand a try[-catch] block */
2457 /* Expand the try block */
2458 expand_eh_region_start ();
2459 expand_expr_stmt (TREE_OPERAND (exp, 0));
2460 expand_start_all_catch ();
2462 /* Expand all catch clauses (EH handlers) */
2463 for (current = TREE_OPERAND (exp, 1); current;
2464 current = TREE_CHAIN (current))
2466 tree type;
2467 tree catch = TREE_OPERAND (current, 0);
2468 tree decl = BLOCK_EXPR_DECLS (catch);
2469 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2470 start_catch_handler (prepare_eh_table_type (type));
2471 expand_expr_stmt (TREE_OPERAND (current, 0));
2473 expand_resume_after_catch ();
2474 end_catch_handler ();
2476 expand_end_all_catch ();
2477 return const0_rtx;
2479 default:
2480 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2481 tree_code_name [TREE_CODE (exp)]);
2485 /* Go over METHOD's bytecode and note instruction starts in
2486 instruction_bits[]. */
2488 void
2489 note_instructions (jcf, method)
2490 JCF *jcf;
2491 tree method;
2493 int PC;
2494 unsigned char* byte_ops;
2495 long length = DECL_CODE_LENGTH (method);
2497 int saw_index;
2498 jint INT_temp;
2500 #undef RET /* Defined by config/i386/i386.h */
2501 #undef AND /* Causes problems with opcodes for iand and land. */
2502 #undef PTR
2503 #define BCODE byte_ops
2504 #define BYTE_type_node byte_type_node
2505 #define SHORT_type_node short_type_node
2506 #define INT_type_node int_type_node
2507 #define LONG_type_node long_type_node
2508 #define CHAR_type_node char_type_node
2509 #define PTR_type_node ptr_type_node
2510 #define FLOAT_type_node float_type_node
2511 #define DOUBLE_type_node double_type_node
2512 #define VOID_type_node void_type_node
2513 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2514 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2515 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2516 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2518 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2520 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2521 byte_ops = jcf->read_ptr;
2522 instruction_bits = xrealloc (instruction_bits, length + 1);
2523 memset (instruction_bits, 0, length + 1);
2525 /* This pass figures out which PC can be the targets of jumps. */
2526 for (PC = 0; PC < length;)
2528 int oldpc = PC; /* PC at instruction start. */
2529 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2530 switch (byte_ops[PC++])
2532 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2533 case OPCODE: \
2534 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2535 break;
2537 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2539 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2540 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2541 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2542 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2543 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2544 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2545 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2546 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2548 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2549 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2550 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2551 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2552 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2553 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2554 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2555 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2557 /* two forms of wide instructions */
2558 #define PRE_SPECIAL_WIDE(IGNORE) \
2560 int modified_opcode = IMMEDIATE_u1; \
2561 if (modified_opcode == OPCODE_iinc) \
2563 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2564 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2566 else \
2568 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2572 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2574 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2576 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2577 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2578 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2579 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2580 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2581 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2582 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2583 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2584 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2585 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2587 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2588 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2589 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2590 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2591 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2592 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2593 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2594 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2596 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2598 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2599 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2601 #define PRE_LOOKUP_SWITCH \
2602 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2603 NOTE_LABEL (default_offset+oldpc); \
2604 if (npairs >= 0) \
2605 while (--npairs >= 0) { \
2606 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2607 jint offset = IMMEDIATE_s4; \
2608 NOTE_LABEL (offset+oldpc); } \
2611 #define PRE_TABLE_SWITCH \
2612 { jint default_offset = IMMEDIATE_s4; \
2613 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2614 NOTE_LABEL (default_offset+oldpc); \
2615 if (low <= high) \
2616 while (low++ <= high) { \
2617 jint offset = IMMEDIATE_s4; \
2618 NOTE_LABEL (offset+oldpc); } \
2621 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2622 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2623 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2624 (void)(IMMEDIATE_u2); \
2625 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2627 #include "javaop.def"
2628 #undef JAVAOP
2630 } /* for */
2633 void
2634 expand_byte_code (jcf, method)
2635 JCF *jcf;
2636 tree method;
2638 int PC;
2639 int i;
2640 const unsigned char *linenumber_pointer;
2641 int dead_code_index = -1;
2642 unsigned char* byte_ops;
2643 long length = DECL_CODE_LENGTH (method);
2645 stack_pointer = 0;
2646 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2647 byte_ops = jcf->read_ptr;
2649 /* We make an initial pass of the line number table, to note
2650 which instructions have associated line number entries. */
2651 linenumber_pointer = linenumber_table;
2652 for (i = 0; i < linenumber_count; i++)
2654 int pc = GET_u2 (linenumber_pointer);
2655 linenumber_pointer += 4;
2656 if (pc >= length)
2657 warning ("invalid PC in line number table");
2658 else
2660 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2661 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2662 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2666 if (! verify_jvm_instructions (jcf, byte_ops, length))
2667 return;
2669 /* Translate bytecodes to rtl instructions. */
2670 linenumber_pointer = linenumber_table;
2671 for (PC = 0; PC < length;)
2673 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2675 tree label = lookup_label (PC);
2676 flush_quick_stack ();
2677 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2678 expand_label (label);
2679 if (LABEL_VERIFIED (label) || PC == 0)
2680 load_type_state (label);
2683 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2685 if (dead_code_index == -1)
2687 /* This is the start of a region of unreachable bytecodes.
2688 They still need to be processed in order for EH ranges
2689 to get handled correctly. However, we can simply
2690 replace these bytecodes with nops. */
2691 dead_code_index = PC;
2694 /* Turn this bytecode into a nop. */
2695 byte_ops[PC] = 0x0;
2697 else
2699 if (dead_code_index != -1)
2701 /* We've just reached the end of a region of dead code. */
2702 warning ("Unreachable bytecode from %d to before %d.",
2703 dead_code_index, PC);
2704 dead_code_index = -1;
2708 /* Handle possible line number entry for this PC.
2710 This code handles out-of-order and multiple linenumbers per PC,
2711 but is optimized for the case of line numbers increasing
2712 monotonically with PC. */
2713 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2715 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2716 || GET_u2 (linenumber_pointer) != PC)
2717 linenumber_pointer = linenumber_table;
2718 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2720 int pc = GET_u2 (linenumber_pointer);
2721 linenumber_pointer += 4;
2722 if (pc == PC)
2724 lineno = GET_u2 (linenumber_pointer - 2);
2725 emit_line_note (input_filename, lineno);
2726 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2727 break;
2731 maybe_pushlevels (PC);
2732 PC = process_jvm_instruction (PC, byte_ops, length);
2733 maybe_poplevels (PC);
2734 } /* for */
2736 if (dead_code_index != -1)
2738 /* We've just reached the end of a region of dead code. */
2739 warning ("Unreachable bytecode from %d to the end of the method.",
2740 dead_code_index);
2744 static void
2745 java_push_constant_from_pool (jcf, index)
2746 JCF *jcf;
2747 int index;
2749 tree c;
2750 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2752 tree name;
2753 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2754 index = alloc_name_constant (CONSTANT_String, name);
2755 c = build_ref_from_constant_pool (index);
2756 TREE_TYPE (c) = promote_type (string_type_node);
2758 else
2759 c = get_constant (jcf, index);
2760 push_value (c);
2764 process_jvm_instruction (PC, byte_ops, length)
2765 int PC;
2766 const unsigned char* byte_ops;
2767 long length ATTRIBUTE_UNUSED;
2769 const char *opname; /* Temporary ??? */
2770 int oldpc = PC; /* PC at instruction start. */
2772 /* If the instruction is at the beginning of a exception handler,
2773 replace the top of the stack with the thrown object reference */
2774 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2776 tree type = pop_type (ptr_type_node);
2777 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2780 switch (byte_ops[PC++])
2782 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2783 case OPCODE: \
2784 opname = #OPNAME; \
2785 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2786 break;
2788 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2790 int saw_index = 0; \
2791 int index = OPERAND_VALUE; \
2792 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2795 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2797 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2798 tree ret = lookup_label (PC); \
2799 build_java_jsr (where, ret); \
2800 load_type_state (ret); \
2803 /* Push a constant onto the stack. */
2804 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2805 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2806 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2807 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2809 /* internal macro added for use by the WIDE case */
2810 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2811 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2813 /* Push local variable onto the opcode stack. */
2814 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2816 /* have to do this since OPERAND_VALUE may have side-effects */ \
2817 int opvalue = OPERAND_VALUE; \
2818 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2821 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2822 expand_java_return (OPERAND_TYPE##_type_node)
2824 #define REM_EXPR TRUNC_MOD_EXPR
2825 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2826 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2828 #define FIELD(IS_STATIC, IS_PUT) \
2829 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2831 #define TEST(OPERAND_TYPE, CONDITION) \
2832 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2834 #define COND(OPERAND_TYPE, CONDITION) \
2835 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2837 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2838 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2840 #define BRANCH_GOTO(OPERAND_VALUE) \
2841 expand_java_goto (oldpc + OPERAND_VALUE)
2843 #define BRANCH_CALL(OPERAND_VALUE) \
2844 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2846 #if 0
2847 #define BRANCH_RETURN(OPERAND_VALUE) \
2849 tree type = OPERAND_TYPE##_type_node; \
2850 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2851 expand_java_ret (value); \
2853 #endif
2855 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2856 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2857 fprintf (stderr, "(not implemented)\n")
2858 #define NOT_IMPL1(OPERAND_VALUE) \
2859 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2860 fprintf (stderr, "(not implemented)\n")
2862 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2864 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2866 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2868 #define STACK_SWAP(COUNT) java_stack_swap()
2870 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2871 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2872 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2874 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2875 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2877 #define LOOKUP_SWITCH \
2878 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2879 tree selector = pop_value (INT_type_node); \
2880 tree duplicate, label; \
2881 tree type = TREE_TYPE (selector); \
2882 flush_quick_stack (); \
2883 expand_start_case (0, selector, type, "switch statement");\
2884 while (--npairs >= 0) \
2886 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2887 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2888 TREE_TYPE (value) = type; \
2889 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2890 pushcase (value, convert, label, &duplicate); \
2891 expand_java_goto (oldpc + offset); \
2893 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2894 pushcase (NULL_TREE, 0, label, &duplicate); \
2895 expand_java_goto (oldpc + default_offset); \
2896 expand_end_case (selector); \
2899 #define TABLE_SWITCH \
2900 { jint default_offset = IMMEDIATE_s4; \
2901 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2902 tree selector = pop_value (INT_type_node); \
2903 tree duplicate, label; \
2904 tree type = TREE_TYPE (selector); \
2905 flush_quick_stack (); \
2906 expand_start_case (0, selector, type, "switch statement");\
2907 for (; low <= high; low++) \
2909 jint offset = IMMEDIATE_s4; \
2910 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2911 TREE_TYPE (value) = type; \
2912 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2913 pushcase (value, convert, label, &duplicate); \
2914 expand_java_goto (oldpc + offset); \
2916 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2917 pushcase (NULL_TREE, 0, label, &duplicate); \
2918 expand_java_goto (oldpc + default_offset); \
2919 expand_end_case (selector); \
2922 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2923 { int opcode = byte_ops[PC-1]; \
2924 int method_ref_index = IMMEDIATE_u2; \
2925 int nargs; \
2926 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2927 else nargs = -1; \
2928 expand_invoke (opcode, method_ref_index, nargs); \
2931 /* Handle new, checkcast, instanceof */
2932 #define OBJECT(TYPE, OP) \
2933 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2935 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2937 #define ARRAY_LOAD(OPERAND_TYPE) \
2939 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2942 #define ARRAY_STORE(OPERAND_TYPE) \
2944 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2947 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2948 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2949 #define ARRAY_NEW_PTR() \
2950 push_value (build_anewarray (get_class_constant (current_jcf, \
2951 IMMEDIATE_u2), \
2952 pop_value (int_type_node)));
2953 #define ARRAY_NEW_NUM() \
2955 int atype = IMMEDIATE_u1; \
2956 push_value (build_newarray (atype, pop_value (int_type_node)));\
2958 #define ARRAY_NEW_MULTI() \
2960 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2961 int ndims = IMMEDIATE_u1; \
2962 expand_java_multianewarray( class, ndims ); \
2965 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2966 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2967 pop_value (OPERAND_TYPE##_type_node))));
2969 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2971 push_value (build1 (NOP_EXPR, int_type_node, \
2972 (convert (TO_TYPE##_type_node, \
2973 pop_value (FROM_TYPE##_type_node))))); \
2976 #define CONVERT(FROM_TYPE, TO_TYPE) \
2978 push_value (convert (TO_TYPE##_type_node, \
2979 pop_value (FROM_TYPE##_type_node))); \
2982 /* internal macro added for use by the WIDE case
2983 Added TREE_TYPE (decl) assignment, apbianco */
2984 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2986 tree decl, value; \
2987 int var = OPVALUE; \
2988 tree type = OPTYPE; \
2989 value = pop_value (type); \
2990 type = TREE_TYPE (value); \
2991 decl = find_local_variable (var, type, oldpc); \
2992 set_local_type (var, type ); \
2993 expand_assignment (decl, value, 0, 0); \
2996 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2998 /* have to do this since OPERAND_VALUE may have side-effects */ \
2999 int opvalue = OPERAND_VALUE; \
3000 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3003 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3004 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3006 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3007 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3009 #define MONITOR_OPERATION(call) \
3011 tree o = pop_value (ptr_type_node); \
3012 tree c; \
3013 flush_quick_stack (); \
3014 c = build_java_monitor (call, o); \
3015 TREE_SIDE_EFFECTS (c) = 1; \
3016 expand_expr_stmt (c); \
3019 #define SPECIAL_IINC(IGNORED) \
3021 unsigned int local_var_index = IMMEDIATE_u1; \
3022 int ival = IMMEDIATE_s1; \
3023 expand_iinc(local_var_index, ival, oldpc); \
3026 #define SPECIAL_WIDE(IGNORED) \
3028 int modified_opcode = IMMEDIATE_u1; \
3029 unsigned int local_var_index = IMMEDIATE_u2; \
3030 switch (modified_opcode) \
3032 case OPCODE_iinc: \
3034 int ival = IMMEDIATE_s2; \
3035 expand_iinc (local_var_index, ival, oldpc); \
3036 break; \
3038 case OPCODE_iload: \
3039 case OPCODE_lload: \
3040 case OPCODE_fload: \
3041 case OPCODE_dload: \
3042 case OPCODE_aload: \
3044 /* duplicate code from LOAD macro */ \
3045 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3046 break; \
3048 case OPCODE_istore: \
3049 case OPCODE_lstore: \
3050 case OPCODE_fstore: \
3051 case OPCODE_dstore: \
3052 case OPCODE_astore: \
3054 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3055 break; \
3057 default: \
3058 error ("unrecogized wide sub-instruction"); \
3062 #define SPECIAL_THROW(IGNORED) \
3063 build_java_athrow (pop_value (throwable_type_node))
3065 #define SPECIAL_BREAK NOT_IMPL1
3066 #define IMPL NOT_IMPL
3068 #include "javaop.def"
3069 #undef JAVAOP
3070 default:
3071 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3073 return PC;
3076 /* Return the opcode at PC in the code section pointed to by
3077 CODE_OFFSET. */
3079 static unsigned char
3080 peek_opcode_at_pc (jcf, code_offset, pc)
3081 JCF *jcf;
3082 int code_offset, pc;
3084 unsigned char opcode;
3085 long absolute_offset = (long)JCF_TELL (jcf);
3087 JCF_SEEK (jcf, code_offset);
3088 opcode = jcf->read_ptr [pc];
3089 JCF_SEEK (jcf, absolute_offset);
3090 return opcode;
3093 /* Some bytecode compilers are emitting accurate LocalVariableTable
3094 attributes. Here's an example:
3096 PC <t>store_<n>
3097 PC+1 ...
3099 Attribute "LocalVariableTable"
3100 slot #<n>: ... (PC: PC+1 length: L)
3102 This is accurate because the local in slot <n> really exists after
3103 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3105 This procedure recognizes this situation and extends the live range
3106 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3107 length of the store instruction.)
3109 This function is used by `give_name_to_locals' so that a local's
3110 DECL features a DECL_LOCAL_START_PC such that the first related
3111 store operation will use DECL as a destination, not a unrelated
3112 temporary created for the occasion.
3114 This function uses a global (instruction_bits) `note_instructions' should
3115 have allocated and filled properly. */
3118 maybe_adjust_start_pc (jcf, code_offset, start_pc, slot)
3119 struct JCF *jcf;
3120 int code_offset, start_pc, slot;
3122 int first, index, opcode;
3123 int pc, insn_pc;
3124 int wide_found = 0;
3126 if (!start_pc)
3127 return start_pc;
3129 first = index = -1;
3131 /* Find last previous instruction and remember it */
3132 for (pc = start_pc-1; pc; pc--)
3133 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3134 break;
3135 insn_pc = pc;
3137 /* Retrieve the instruction, handle `wide'. */
3138 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3139 if (opcode == OPCODE_wide)
3141 wide_found = 1;
3142 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3145 switch (opcode)
3147 case OPCODE_astore_0:
3148 case OPCODE_astore_1:
3149 case OPCODE_astore_2:
3150 case OPCODE_astore_3:
3151 first = OPCODE_astore_0;
3152 break;
3154 case OPCODE_istore_0:
3155 case OPCODE_istore_1:
3156 case OPCODE_istore_2:
3157 case OPCODE_istore_3:
3158 first = OPCODE_istore_0;
3159 break;
3161 case OPCODE_lstore_0:
3162 case OPCODE_lstore_1:
3163 case OPCODE_lstore_2:
3164 case OPCODE_lstore_3:
3165 first = OPCODE_lstore_0;
3166 break;
3168 case OPCODE_fstore_0:
3169 case OPCODE_fstore_1:
3170 case OPCODE_fstore_2:
3171 case OPCODE_fstore_3:
3172 first = OPCODE_fstore_0;
3173 break;
3175 case OPCODE_dstore_0:
3176 case OPCODE_dstore_1:
3177 case OPCODE_dstore_2:
3178 case OPCODE_dstore_3:
3179 first = OPCODE_dstore_0;
3180 break;
3182 case OPCODE_astore:
3183 case OPCODE_istore:
3184 case OPCODE_lstore:
3185 case OPCODE_fstore:
3186 case OPCODE_dstore:
3187 index = peek_opcode_at_pc (jcf, code_offset, pc);
3188 if (wide_found)
3190 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3191 index = (other << 8) + index;
3193 break;
3196 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3197 means we have a <t>store. */
3198 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3199 start_pc = insn_pc;
3201 return start_pc;
3204 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3205 order, as specified by Java Language Specification.
3207 The problem is that while expand_expr will evaluate its sub-operands in
3208 left-to-right order, for variables it will just return an rtx (i.e.
3209 an lvalue) for the variable (rather than an rvalue). So it is possible
3210 that a later sub-operand will change the register, and when the
3211 actual operation is done, it will use the new value, when it should
3212 have used the original value.
3214 We fix this by using save_expr. This forces the sub-operand to be
3215 copied into a fresh virtual register,
3217 For method invocation, we modify the arguments so that a
3218 left-to-right order evaluation is performed. Saved expressions
3219 will, in CALL_EXPR order, be reused when the call will be expanded.
3222 tree
3223 force_evaluation_order (node)
3224 tree node;
3226 if (flag_syntax_only)
3227 return node;
3228 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3230 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3231 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3233 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
3235 tree arg, cmp;
3237 if (!TREE_OPERAND (node, 1))
3238 return node;
3240 /* This reverses the evaluation order. This is a desired effect. */
3241 for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1);
3242 arg; arg = TREE_CHAIN (arg))
3244 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3245 cmp = (cmp == NULL_TREE ? saved :
3246 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3247 TREE_VALUE (arg) = saved;
3250 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3251 TREE_SIDE_EFFECTS (cmp) = 1;
3253 if (cmp)
3255 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3256 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3257 TREE_SIDE_EFFECTS (cmp) = 1;
3258 node = cmp;
3261 return node;