ef1a13959e1e156e80a5d715e7f016447dfb8e10
[gcc.git] / gcc / java / expr.c
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25
26 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
27
28 #include "config.h"
29 #include "system.h"
30 #include "tree.h"
31 #include "real.h"
32 #include "rtl.h"
33 #include "flags.h"
34 #include "expr.h"
35 #include "java-tree.h"
36 #include "javaop.h"
37 #include "java-opcodes.h"
38 #include "jcf.h"
39 #include "java-except.h"
40 #include "parse.h"
41 #include "toplev.h"
42 #include "except.h"
43 #include "ggc.h"
44
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_load_internal PARAMS ((int, tree, int));
61 static void expand_java_NEW PARAMS ((tree));
62 static void expand_java_INSTANCEOF PARAMS ((tree));
63 static void expand_java_CHECKCAST PARAMS ((tree));
64 static void expand_iinc PARAMS ((unsigned int, int, int));
65 static void expand_java_binop PARAMS ((tree, enum tree_code));
66 static void note_label PARAMS ((int, int));
67 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
68 static void expand_test PARAMS ((enum tree_code, tree, int));
69 static void expand_cond PARAMS ((enum tree_code, tree, int));
70 static void expand_java_goto PARAMS ((int));
71 #if 0
72 static void expand_java_call PARAMS ((int, int));
73 static void expand_java_ret PARAMS ((tree));
74 #endif
75 static tree pop_arguments PARAMS ((tree));
76 static void expand_invoke PARAMS ((int, int, int));
77 static void expand_java_field_op PARAMS ((int, int, int));
78 static void java_push_constant_from_pool PARAMS ((struct JCF *, int));
79 static void java_stack_pop PARAMS ((int));
80 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
81 static tree build_java_check_indexed_type PARAMS ((tree, tree));
82 static tree java_array_data_offset PARAMS ((tree));
83 static tree case_identity PARAMS ((tree, tree));
84 static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int));
85 static bool emit_init_test_initialization PARAMS ((struct hash_entry *,
86 PTR ptr));
87
88 static tree operand_type[59];
89 extern struct obstack permanent_obstack;
90
91 static tree methods_ident = NULL_TREE;
92 static tree ncode_ident = NULL_TREE;
93 tree dtable_ident = NULL_TREE;
94
95 /* Set to non-zero value in order to emit class initilization code
96 before static field references. */
97 int always_initialize_class_p;
98
99 /* We store the stack state in two places:
100 Within a basic block, we use the quick_stack, which is a
101 pushdown list (TREE_LISTs) of expression nodes.
102 This is the top part of the stack; below that we use find_stack_slot.
103 At the end of a basic block, the quick_stack must be flushed
104 to the stack slot array (as handled by find_stack_slot).
105 Using quick_stack generates better code (especially when
106 compiled without optimization), because we do not have to
107 explicitly store and load trees to temporary variables.
108
109 If a variable is on the quick stack, it means the value of variable
110 when the quick stack was last flushed. Conceptually, flush_quick_stack
111 saves all the the quick_stack elements in parellel. However, that is
112 complicated, so it actually saves them (i.e. copies each stack value
113 to is home virtual register) from low indexes. This allows a quick_stack
114 element at index i (counting from the bottom of stack the) to references
115 slot virtuals for register that are >= i, but not those that are deeper.
116 This convention makes most operations easier. For example iadd works
117 even when the stack contains (reg[0], reg[1]): It results in the
118 stack containing (reg[0]+reg[1]), which is OK. However, some stack
119 operations are more complicated. For example dup given a stack
120 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
121 the convention, since stack value 1 would refer to a register with
122 lower index (reg[0]), which flush_quick_stack does not safely handle.
123 So dup cannot just add an extra element to the quick_stack, but iadd can.
124 */
125
126 static tree quick_stack = NULL_TREE;
127
128 /* A free-list of unused permamnet TREE_LIST nodes. */
129 static tree tree_list_free_list = NULL_TREE;
130
131 /* The stack pointer of the Java virtual machine.
132 This does include the size of the quick_stack. */
133
134 int stack_pointer;
135
136 const unsigned char *linenumber_table;
137 int linenumber_count;
138
139 void
140 init_expr_processing()
141 {
142 operand_type[21] = operand_type[54] = int_type_node;
143 operand_type[22] = operand_type[55] = long_type_node;
144 operand_type[23] = operand_type[56] = float_type_node;
145 operand_type[24] = operand_type[57] = double_type_node;
146 operand_type[25] = operand_type[58] = ptr_type_node;
147 ggc_add_tree_root (operand_type, 59);
148 ggc_add_tree_root (&methods_ident, 1);
149 ggc_add_tree_root (&ncode_ident, 1);
150 ggc_add_tree_root (&quick_stack, 1);
151 ggc_add_tree_root (&tree_list_free_list, 1);
152 }
153
154 tree
155 truthvalue_conversion (expr)
156 tree expr;
157 {
158 /* It is simpler and generates better code to have only TRUTH_*_EXPR
159 or comparison expressions as truth values at this level.
160
161 This function should normally be identity for Java. */
162
163 switch (TREE_CODE (expr))
164 {
165 case EQ_EXPR:
166 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
167 case TRUTH_ANDIF_EXPR:
168 case TRUTH_ORIF_EXPR:
169 case TRUTH_AND_EXPR:
170 case TRUTH_OR_EXPR:
171 case ERROR_MARK:
172 return expr;
173
174 case INTEGER_CST:
175 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
176
177 case REAL_CST:
178 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
179
180 /* are these legal? XXX JH */
181 case NEGATE_EXPR:
182 case ABS_EXPR:
183 case FLOAT_EXPR:
184 case FFS_EXPR:
185 /* These don't change whether an object is non-zero or zero. */
186 return truthvalue_conversion (TREE_OPERAND (expr, 0));
187
188 case COND_EXPR:
189 /* Distribute the conversion into the arms of a COND_EXPR. */
190 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
191 truthvalue_conversion (TREE_OPERAND (expr, 1)),
192 truthvalue_conversion (TREE_OPERAND (expr, 2))));
193
194 case NOP_EXPR:
195 /* If this is widening the argument, we can ignore it. */
196 if (TYPE_PRECISION (TREE_TYPE (expr))
197 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
198 return truthvalue_conversion (TREE_OPERAND (expr, 0));
199 /* fall through to default */
200
201 default:
202 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
203 }
204 }
205
206 #ifdef JAVA_USE_HANDLES
207 /* Given a pointer to a handle, get a pointer to an object. */
208
209 tree
210 unhand_expr (expr)
211 tree expr;
212 {
213 tree field, handle_type;
214 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
215 handle_type = TREE_TYPE (expr);
216 field = TYPE_FIELDS (handle_type);
217 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
218 return expr;
219 }
220 #endif
221
222 /* Save any stack slots that happen to be in the quick_stack into their
223 home virtual register slots.
224
225 The copy order is from low stack index to high, to support the invariant
226 that the expression for a slot may contain decls for stack slots with
227 higher (or the same) index, but not lower. */
228
229 static void
230 flush_quick_stack ()
231 {
232 int stack_index = stack_pointer;
233 register tree prev, cur, next;
234
235 /* First reverse the quick_stack, and count the number of slots it has. */
236 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
237 {
238 next = TREE_CHAIN (cur);
239 TREE_CHAIN (cur) = prev;
240 prev = cur;
241 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
242 }
243 quick_stack = prev;
244
245 while (quick_stack != NULL_TREE)
246 {
247 tree decl;
248 tree node = quick_stack, type;
249 quick_stack = TREE_CHAIN (node);
250 TREE_CHAIN (node) = tree_list_free_list;
251 tree_list_free_list = node;
252 node = TREE_VALUE (node);
253 type = TREE_TYPE (node);
254
255 decl = find_stack_slot (stack_index, type);
256 if (decl != node)
257 expand_assignment (decl, node, 0, 0);
258 stack_index += 1 + TYPE_IS_WIDE (type);
259 }
260 }
261
262 /* Push TYPE on the type stack.
263 Return true on success, 0 on overflow. */
264
265 int
266 push_type_0 (type)
267 tree type;
268 {
269 int n_words;
270 type = promote_type (type);
271 n_words = 1 + TYPE_IS_WIDE (type);
272 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
273 return 0;
274 stack_type_map[stack_pointer++] = type;
275 n_words--;
276 while (--n_words >= 0)
277 stack_type_map[stack_pointer++] = TYPE_SECOND;
278 return 1;
279 }
280
281 void
282 push_type (type)
283 tree type;
284 {
285 if (! push_type_0 (type))
286 abort ();
287 }
288
289 static void
290 push_value (value)
291 tree value;
292 {
293 tree type = TREE_TYPE (value);
294 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
295 {
296 type = promote_type (type);
297 value = convert (type, value);
298 }
299 push_type (type);
300 if (tree_list_free_list == NULL_TREE)
301 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
302 else
303 {
304 tree node = tree_list_free_list;
305 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
306 TREE_VALUE (node) = value;
307 TREE_CHAIN (node) = quick_stack;
308 quick_stack = node;
309 }
310 }
311
312 /* Pop a type from the type stack.
313 TYPE is the expected type. Return the actual type, which must be
314 convertible to TYPE.
315 On an error, *MESSAGEP is set to a freshly malloc'd error message. */
316
317 tree
318 pop_type_0 (type, messagep)
319 tree type;
320 char **messagep;
321 {
322 int n_words;
323 tree t;
324 *messagep = NULL;
325 if (TREE_CODE (type) == RECORD_TYPE)
326 type = promote_type (type);
327 n_words = 1 + TYPE_IS_WIDE (type);
328 if (stack_pointer < n_words)
329 {
330 *messagep = xstrdup ("stack underflow");
331 return type;
332 }
333 while (--n_words > 0)
334 {
335 if (stack_type_map[--stack_pointer] != void_type_node)
336 {
337 *messagep = xstrdup ("Invalid multi-word value on type stack");
338 return type;
339 }
340 }
341 t = stack_type_map[--stack_pointer];
342 if (type == NULL_TREE || t == type)
343 return t;
344 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
345 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
346 return t;
347 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
348 {
349 if (type == ptr_type_node || type == object_ptr_type_node)
350 return t;
351 else if (t == ptr_type_node) /* Special case for null reference. */
352 return type;
353 else if (can_widen_reference_to (t, type))
354 return t;
355 /* This is a kludge, but matches what Sun's verifier does.
356 It can be tricked, but is safe as long as type errors
357 (i.e. interface method calls) are caught at run-time. */
358 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
359 return object_ptr_type_node;
360 }
361
362 /* lang_printable_name uses a static buffer, so we must save the result
363 from calling it the first time. */
364 {
365 char *temp = xstrdup (lang_printable_name (type, 0));
366 *messagep = concat ("expected type '", temp,
367 "' but stack contains '", lang_printable_name (t, 0),
368 "'", NULL);
369 free (temp);
370 }
371 return type;
372 }
373
374 /* Pop a type from the type stack.
375 TYPE is the expected type. Return the actual type, which must be
376 convertible to TYPE, otherwise call error. */
377
378 tree
379 pop_type (type)
380 tree type;
381 {
382 char *message = NULL;
383 type = pop_type_0 (type, &message);
384 if (message != NULL)
385 {
386 error ("%s", message);
387 free (message);
388 }
389 return type;
390 }
391
392 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
393 Handles array types and interfaces. */
394
395 int
396 can_widen_reference_to (source_type, target_type)
397 tree source_type, target_type;
398 {
399 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
400 return 1;
401
402 /* Get rid of pointers */
403 if (TREE_CODE (source_type) == POINTER_TYPE)
404 source_type = TREE_TYPE (source_type);
405 if (TREE_CODE (target_type) == POINTER_TYPE)
406 target_type = TREE_TYPE (target_type);
407
408 if (source_type == target_type)
409 return 1;
410 else
411 {
412 source_type = HANDLE_TO_CLASS_TYPE (source_type);
413 target_type = HANDLE_TO_CLASS_TYPE (target_type);
414 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
415 {
416 HOST_WIDE_INT source_length, target_length;
417 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
418 return 0;
419 target_length = java_array_type_length (target_type);
420 if (target_length >= 0)
421 {
422 source_length = java_array_type_length (source_type);
423 if (source_length != target_length)
424 return 0;
425 }
426 source_type = TYPE_ARRAY_ELEMENT (source_type);
427 target_type = TYPE_ARRAY_ELEMENT (target_type);
428 if (source_type == target_type)
429 return 1;
430 if (TREE_CODE (source_type) != POINTER_TYPE
431 || TREE_CODE (target_type) != POINTER_TYPE)
432 return 0;
433 return can_widen_reference_to (source_type, target_type);
434 }
435 else
436 {
437 int source_depth = class_depth (source_type);
438 int target_depth = class_depth (target_type);
439
440 /* class_depth can return a negative depth if an error occurred */
441 if (source_depth < 0 || target_depth < 0)
442 return 0;
443
444 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
445 {
446 /* target_type is OK if source_type or source_type ancestors
447 implement target_type. We handle multiple sub-interfaces */
448
449 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
450 int n = TREE_VEC_LENGTH (basetype_vec), i;
451 for (i=0 ; i < n; i++)
452 if (can_widen_reference_to
453 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
454 target_type))
455 return 1;
456 if (n == 0)
457 return 0;
458 }
459
460 for ( ; source_depth > target_depth; source_depth--)
461 {
462 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
463 }
464 return source_type == target_type;
465 }
466 }
467 }
468
469 static tree
470 pop_value (type)
471 tree type;
472 {
473 type = pop_type (type);
474 if (quick_stack)
475 {
476 tree node = quick_stack;
477 quick_stack = TREE_CHAIN (quick_stack);
478 TREE_CHAIN (node) = tree_list_free_list;
479 tree_list_free_list = node;
480 node = TREE_VALUE (node);
481 return node;
482 }
483 else
484 return find_stack_slot (stack_pointer, promote_type (type));
485 }
486
487
488 /* Pop and discrad the top COUNT stack slots. */
489
490 static void
491 java_stack_pop (count)
492 int count;
493 {
494 while (count > 0)
495 {
496 tree type, val;
497
498 if (stack_pointer == 0)
499 abort ();
500
501 type = stack_type_map[stack_pointer - 1];
502 if (type == TYPE_SECOND)
503 {
504 count--;
505 if (stack_pointer == 1 || count <= 0)
506 abort ();
507
508 type = stack_type_map[stack_pointer - 2];
509 }
510 val = pop_value (type);
511 count--;
512 }
513 }
514
515 /* Implement the 'swap' operator (to swap two top stack slots). */
516
517 static void
518 java_stack_swap ()
519 {
520 tree type1, type2;
521 rtx temp;
522 tree decl1, decl2;
523
524 if (stack_pointer < 2
525 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
526 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
527 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
528 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
529 /* Bad stack swap. */
530 abort ();
531
532 flush_quick_stack ();
533 decl1 = find_stack_slot (stack_pointer - 1, type1);
534 decl2 = find_stack_slot (stack_pointer - 2, type2);
535 temp = copy_to_reg (DECL_RTL (decl1));
536 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
537 emit_move_insn (DECL_RTL (decl2), temp);
538 stack_type_map[stack_pointer - 1] = type2;
539 stack_type_map[stack_pointer - 2] = type1;
540 }
541
542 static void
543 java_stack_dup (size, offset)
544 int size, offset;
545 {
546 int low_index = stack_pointer - size - offset;
547 int dst_index;
548 if (low_index < 0)
549 error ("stack underflow - dup* operation");
550
551 flush_quick_stack ();
552
553 stack_pointer += size;
554 dst_index = stack_pointer;
555
556 for (dst_index = stack_pointer; --dst_index >= low_index; )
557 {
558 tree type;
559 int src_index = dst_index - size;
560 if (src_index < low_index)
561 src_index = dst_index + size + offset;
562 type = stack_type_map [src_index];
563 if (type == TYPE_SECOND)
564 {
565 if (src_index <= low_index)
566 /* Dup operation splits 64-bit number. */
567 abort ();
568
569 stack_type_map[dst_index] = type;
570 src_index--; dst_index--;
571 type = stack_type_map[src_index];
572 if (! TYPE_IS_WIDE (type))
573 abort ();
574 }
575 else if (TYPE_IS_WIDE (type))
576 abort ();
577
578 if (src_index != dst_index)
579 {
580 tree src_decl = find_stack_slot (src_index, type);
581 tree dst_decl = find_stack_slot (dst_index, type);
582 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
583 stack_type_map[dst_index] = type;
584 }
585 }
586 }
587
588 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
589 value stack. */
590
591 static void
592 build_java_athrow (node)
593 tree node;
594 {
595 tree call;
596
597 call = build (CALL_EXPR,
598 void_type_node,
599 build_address_of (throw_node),
600 build_tree_list (NULL_TREE, node),
601 NULL_TREE);
602 TREE_SIDE_EFFECTS (call) = 1;
603 expand_expr_stmt (call);
604 java_stack_pop (stack_pointer);
605 }
606
607 /* Implementation for jsr/ret */
608
609 static void
610 build_java_jsr (where, ret)
611 tree where;
612 tree ret;
613 {
614 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
615 push_value (ret_label);
616 flush_quick_stack ();
617 emit_jump (label_rtx (where));
618 expand_label (ret);
619 }
620
621 static void
622 build_java_ret (location)
623 tree location;
624 {
625 expand_computed_goto (location);
626 }
627
628 /* Implementation of operations on array: new, load, store, length */
629
630 /* Array core info access macros */
631
632 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
633 byte_position (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))
634
635 tree
636 decode_newarray_type (atype)
637 int atype;
638 {
639 switch (atype)
640 {
641 case 4: return boolean_type_node;
642 case 5: return char_type_node;
643 case 6: return float_type_node;
644 case 7: return double_type_node;
645 case 8: return byte_type_node;
646 case 9: return short_type_node;
647 case 10: return int_type_node;
648 case 11: return long_type_node;
649 default: return NULL_TREE;
650 }
651 }
652
653 /* Map primitive type to the code used by OPCODE_newarray. */
654
655 int
656 encode_newarray_type (type)
657 tree type;
658 {
659 if (type == boolean_type_node)
660 return 4;
661 else if (type == char_type_node)
662 return 5;
663 else if (type == float_type_node)
664 return 6;
665 else if (type == double_type_node)
666 return 7;
667 else if (type == byte_type_node)
668 return 8;
669 else if (type == short_type_node)
670 return 9;
671 else if (type == int_type_node)
672 return 10;
673 else if (type == long_type_node)
674 return 11;
675 else
676 abort ();
677 }
678
679 /* Build a call to _Jv_ThrowBadArrayIndex(), the
680 ArrayIndexOfBoundsException exception handler. */
681
682 static tree
683 build_java_throw_out_of_bounds_exception (index)
684 tree index;
685 {
686 tree node = build (CALL_EXPR, int_type_node,
687 build_address_of (soft_badarrayindex_node),
688 build_tree_list (NULL_TREE, index), NULL_TREE);
689 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
690 return (node);
691 }
692
693 /* Return the length of an array. Doesn't perform any checking on the nature
694 or value of the array NODE. May be used to implement some bytecodes. */
695
696 tree
697 build_java_array_length_access (node)
698 tree node;
699 {
700 tree type = TREE_TYPE (node);
701 HOST_WIDE_INT length;
702
703 if (!is_array_type_p (type))
704 abort ();
705
706 length = java_array_type_length (type);
707 if (length >= 0)
708 return build_int_2 (length, 0);
709 node = build1 (INDIRECT_REF, int_type_node,
710 fold (build (PLUS_EXPR, ptr_type_node,
711 java_check_reference (node, 1),
712 JAVA_ARRAY_LENGTH_OFFSET(node))));
713 IS_ARRAY_LENGTH_ACCESS (node) = 1;
714 return fold (node);
715 }
716
717 /* Optionally checks a reference against the NULL pointer. ARG1: the
718 expr, ARG2: we should check the reference. Don't generate extra
719 checks if we're not generating code. */
720
721 tree
722 java_check_reference (expr, check)
723 tree expr;
724 int check;
725 {
726 if (!flag_syntax_only && check)
727 {
728 tree cond;
729 expr = save_expr (expr);
730 cond = build (COND_EXPR, void_type_node,
731 build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
732 build (CALL_EXPR, void_type_node,
733 build_address_of (soft_nullpointer_node),
734 NULL_TREE, NULL_TREE),
735 empty_stmt_node);
736 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
737 }
738
739 return expr;
740 }
741
742 /* Reference an object: just like an INDIRECT_REF, but with checking. */
743
744 tree
745 build_java_indirect_ref (type, expr, check)
746 tree type;
747 tree expr;
748 int check;
749 {
750 return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
751 }
752
753 static tree
754 java_array_data_offset (array)
755 tree array;
756 {
757 tree array_type = TREE_TYPE (TREE_TYPE (array));
758 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
759
760 if (data_fld == NULL_TREE)
761 return size_in_bytes (array_type);
762 else
763 return byte_position (data_fld);
764 }
765
766 /* Implement array indexing (either as l-value or r-value).
767 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
768 Optionally performs bounds checking and/or test to NULL.
769 At this point, ARRAY should have been verified as an array. */
770
771 tree
772 build_java_arrayaccess (array, type, index)
773 tree array, type, index;
774 {
775 tree arith, node, throw = NULL_TREE;
776
777 arith = fold (build (PLUS_EXPR, int_type_node,
778 java_array_data_offset (array),
779 fold (build (MULT_EXPR, int_type_node,
780 index, size_in_bytes(type)))));
781
782 if (flag_bounds_check)
783 {
784 /* Generate:
785 * (unsigned jint) INDEX >= (unsigned jint) LEN
786 * && throw ArrayIndexOutOfBoundsException.
787 * Note this is equivalent to and more efficient than:
788 * INDEX < 0 || INDEX >= LEN && throw ... */
789 tree test;
790 tree len = build_java_array_length_access (array);
791 TREE_TYPE (len) = unsigned_int_type_node;
792 test = fold (build (GE_EXPR, boolean_type_node,
793 convert (unsigned_int_type_node, index),
794 len));
795 if (! integer_zerop (test))
796 {
797 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
798 build_java_throw_out_of_bounds_exception (index));
799 /* allows expansion within COMPOUND */
800 TREE_SIDE_EFFECTS( throw ) = 1;
801 }
802 }
803
804 /* The SAVE_EXPR is for correct evaluation order. It would be
805 cleaner to use force_evaluation_order (see comment there), but
806 that is difficult when we also have to deal with bounds
807 checking. The SAVE_EXPR is not necessary to do that when we're
808 not checking for array bounds. */
809 if (TREE_SIDE_EFFECTS (index) && throw)
810 throw = build (COMPOUND_EXPR, int_type_node, save_expr (array), throw);
811
812 node = build1 (INDIRECT_REF, type,
813 fold (build (PLUS_EXPR, ptr_type_node,
814 java_check_reference (array,
815 flag_check_references),
816 (throw ? build (COMPOUND_EXPR, int_type_node,
817 throw, arith ) : arith))));
818 return node;
819 }
820
821 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
822 ARRAY_NODE. This function is used to retrieve something less vague than
823 a pointer type when indexing the first dimension of something like [[<t>.
824 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
825 return unchanged.
826 As a side effect, it also makes sure that ARRAY_NODE is an array. */
827
828 static tree
829 build_java_check_indexed_type (array_node, indexed_type)
830 tree array_node;
831 tree indexed_type;
832 {
833 tree elt_type;
834
835 if (!is_array_type_p (TREE_TYPE (array_node)))
836 abort ();
837
838 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
839
840 if (indexed_type == ptr_type_node )
841 return promote_type (elt_type);
842
843 /* BYTE/BOOLEAN store and load are used for both type */
844 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
845 return boolean_type_node;
846
847 if (indexed_type != elt_type )
848 abort ();
849 else
850 return indexed_type;
851 }
852
853 /* newarray triggers a call to _Jv_NewPrimArray. This function should be
854 called with an integer code (the type of array to create), and the length
855 of the array to create. */
856
857 tree
858 build_newarray (atype_value, length)
859 int atype_value;
860 tree length;
861 {
862 tree type_arg;
863
864 tree prim_type = decode_newarray_type (atype_value);
865 tree type
866 = build_java_array_type (prim_type,
867 host_integerp (length, 0) == INTEGER_CST
868 ? tree_low_cst (length, 0) : -1);
869
870 /* If compiling to native, pass a reference to the primitive type class
871 and save the runtime some work. However, the bytecode generator
872 expects to find the type_code int here. */
873 if (flag_emit_class_files)
874 type_arg = build_int_2 (atype_value, 0);
875 else
876 type_arg = build_class_ref (prim_type);
877
878 return build (CALL_EXPR, promote_type (type),
879 build_address_of (soft_newarray_node),
880 tree_cons (NULL_TREE,
881 type_arg,
882 build_tree_list (NULL_TREE, length)),
883 NULL_TREE);
884 }
885
886 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
887 of the dimension. */
888
889 tree
890 build_anewarray (class_type, length)
891 tree class_type;
892 tree length;
893 {
894 tree type
895 = build_java_array_type (class_type,
896 host_integerp (length, 0)
897 ? tree_low_cst (length, 0) : -1);
898
899 return build (CALL_EXPR, promote_type (type),
900 build_address_of (soft_anewarray_node),
901 tree_cons (NULL_TREE, length,
902 tree_cons (NULL_TREE, build_class_ref (class_type),
903 build_tree_list (NULL_TREE,
904 null_pointer_node))),
905 NULL_TREE);
906 }
907
908 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
909
910 tree
911 build_new_array (type, length)
912 tree type;
913 tree length;
914 {
915 if (JPRIMITIVE_TYPE_P (type))
916 return build_newarray (encode_newarray_type (type), length);
917 else
918 return build_anewarray (TREE_TYPE (type), length);
919 }
920
921 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
922 class pointer, a number of dimensions and the matching number of
923 dimensions. The argument list is NULL terminated. */
924
925 static void
926 expand_java_multianewarray (class_type, ndim)
927 tree class_type;
928 int ndim;
929 {
930 int i;
931 tree args = build_tree_list( NULL_TREE, null_pointer_node );
932
933 for( i = 0; i < ndim; i++ )
934 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
935
936 push_value (build (CALL_EXPR,
937 promote_type (class_type),
938 build_address_of (soft_multianewarray_node),
939 tree_cons (NULL_TREE, build_class_ref (class_type),
940 tree_cons (NULL_TREE,
941 build_int_2 (ndim, 0), args )),
942 NULL_TREE));
943 }
944
945 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
946 ARRAY is an array type. May expand some bound checking and NULL
947 pointer checking. RHS_TYPE_NODE we are going to store. In the case
948 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
949 INT. In those cases, we make the convertion.
950
951 if ARRAy is a reference type, the assignment is checked at run-time
952 to make sure that the RHS can be assigned to the array element
953 type. It is not necessary to generate this code if ARRAY is final. */
954
955 static void
956 expand_java_arraystore (rhs_type_node)
957 tree rhs_type_node;
958 {
959 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
960 && TYPE_PRECISION (rhs_type_node) <= 32) ?
961 int_type_node : rhs_type_node);
962 tree index = pop_value (int_type_node);
963 tree array = pop_value (ptr_type_node);
964
965 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
966
967 flush_quick_stack ();
968
969 index = save_expr (index);
970 array = save_expr (array);
971
972 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
973 {
974 tree check = build (CALL_EXPR, void_type_node,
975 build_address_of (soft_checkarraystore_node),
976 tree_cons (NULL_TREE, array,
977 build_tree_list (NULL_TREE, rhs_node)),
978 NULL_TREE);
979 TREE_SIDE_EFFECTS (check) = 1;
980 expand_expr_stmt (check);
981 }
982
983 expand_assignment (build_java_arrayaccess (array,
984 rhs_type_node,
985 index),
986 rhs_node, 0, 0);
987 }
988
989 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
990 sure that LHS is an array type. May expand some bound checking and NULL
991 pointer checking.
992 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
993 BOOLEAN/SHORT, we push a promoted type back to the stack.
994 */
995
996 static void
997 expand_java_arrayload (lhs_type_node )
998 tree lhs_type_node;
999 {
1000 tree load_node;
1001 tree index_node = pop_value (int_type_node);
1002 tree array_node = pop_value (ptr_type_node);
1003
1004 index_node = save_expr (index_node);
1005 array_node = save_expr (array_node);
1006 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
1007
1008 load_node = build_java_arrayaccess (array_node,
1009 lhs_type_node,
1010 index_node);
1011
1012 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1013 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
1014 push_value (load_node);
1015 }
1016
1017 /* Expands .length. Makes sure that we deal with and array and may expand
1018 a NULL check on the array object. */
1019
1020 static void
1021 expand_java_array_length ()
1022 {
1023 tree array = pop_value (ptr_type_node);
1024 tree length = build_java_array_length_access (array);
1025
1026 push_value (length);
1027 }
1028
1029 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1030 either soft_monitorenter_node or soft_monitorexit_node. */
1031
1032 static tree
1033 build_java_monitor (call, object)
1034 tree call;
1035 tree object;
1036 {
1037 return (build (CALL_EXPR,
1038 void_type_node,
1039 build_address_of (call),
1040 build_tree_list (NULL_TREE, object),
1041 NULL_TREE));
1042 }
1043
1044 /* Emit code for one of the PUSHC instructions. */
1045
1046 static void
1047 expand_java_pushc (ival, type)
1048 int ival;
1049 tree type;
1050 {
1051 tree value;
1052 if (type == ptr_type_node && ival == 0)
1053 value = null_pointer_node;
1054 else if (type == int_type_node || type == long_type_node)
1055 {
1056 value = build_int_2 (ival, ival < 0 ? -1 : 0);
1057 TREE_TYPE (value) = type;
1058 }
1059 else if (type == float_type_node || type == double_type_node)
1060 {
1061 REAL_VALUE_TYPE x;
1062 #ifdef REAL_ARITHMETIC
1063 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1064 #else
1065 x = ival;
1066 #endif
1067 value = build_real (type, x);
1068 }
1069 else
1070 abort ();
1071
1072 push_value (value);
1073 }
1074
1075 static void
1076 expand_java_return (type)
1077 tree type;
1078 {
1079 if (type == void_type_node)
1080 expand_null_return ();
1081 else
1082 {
1083 tree retval = pop_value (type);
1084 tree res = DECL_RESULT (current_function_decl);
1085 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1086
1087 /* Handle the situation where the native integer type is smaller
1088 than the JVM integer. It can happen for many cross compilers.
1089 The whole if expression just goes away if INT_TYPE_SIZE < 32
1090 is false. */
1091 if (INT_TYPE_SIZE < 32
1092 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1093 < GET_MODE_SIZE (TYPE_MODE (type))))
1094 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1095
1096 TREE_SIDE_EFFECTS (retval) = 1;
1097 expand_return (retval);
1098 }
1099 }
1100
1101 static void
1102 expand_load_internal (index, type, pc)
1103 int index;
1104 tree type;
1105 int pc;
1106 {
1107 tree copy;
1108 tree var = find_local_variable (index, type, pc);
1109
1110 /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1111 on the stack. If there is an assignment to this VAR_DECL between
1112 the stack push and the use, then the wrong code could be
1113 generated. To avoid this we create a new local and copy our
1114 value into it. Then we push this new local on the stack.
1115 Hopefully this all gets optimized out. */
1116 copy = build_decl (VAR_DECL, NULL_TREE, type);
1117 DECL_CONTEXT (copy) = current_function_decl;
1118 layout_decl (copy, 0);
1119 DECL_REGISTER (copy) = 1;
1120 expand_decl (copy);
1121 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
1122 DECL_INITIAL (copy) = var;
1123 expand_decl_init (copy);
1124 push_value (copy);
1125 }
1126
1127 tree
1128 build_address_of (value)
1129 tree value;
1130 {
1131 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1132 }
1133
1134 bool class_has_finalize_method (type)
1135 tree type;
1136 {
1137 tree super = CLASSTYPE_SUPER (type);
1138
1139 if (super == NULL_TREE)
1140 return false; /* Every class with a real finalizer inherits */
1141 /* from java.lang.Object. */
1142 else
1143 return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1144 }
1145
1146 static void
1147 expand_java_NEW (type)
1148 tree type;
1149 {
1150 tree alloc_node;
1151
1152 alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1153 : alloc_no_finalizer_node);
1154 if (! CLASS_LOADED_P (type))
1155 load_class (type, 1);
1156 safe_layout_class (type);
1157 push_value (build (CALL_EXPR, promote_type (type),
1158 build_address_of (alloc_node),
1159 tree_cons (NULL_TREE, build_class_ref (type),
1160 build_tree_list (NULL_TREE,
1161 size_in_bytes (type))),
1162 NULL_TREE));
1163 }
1164
1165 /* This returns an expression which will extract the class of an
1166 object. */
1167
1168 tree
1169 build_get_class (value)
1170 tree value;
1171 {
1172 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1173 tree vtable_field = lookup_field (&object_type_node,
1174 get_identifier ("vtable"));
1175 return build (COMPONENT_REF, class_ptr_type,
1176 build1 (INDIRECT_REF, dtable_type,
1177 build (COMPONENT_REF, dtable_ptr_type,
1178 build_java_indirect_ref (object_type_node, value,
1179 flag_check_references),
1180 vtable_field)),
1181 class_field);
1182 }
1183
1184 /* This builds the tree representation of the `instanceof' operator.
1185 It tries various tricks to optimize this in cases where types are
1186 known. */
1187
1188 tree
1189 build_instanceof (value, type)
1190 tree value, type;
1191 {
1192 tree expr;
1193 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1194 tree valtype = TREE_TYPE (TREE_TYPE (value));
1195 tree valclass = TYPE_NAME (valtype);
1196 tree klass;
1197
1198 /* When compiling from bytecode, we need to ensure that TYPE has
1199 been loaded. */
1200 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1201 {
1202 load_class (type, 1);
1203 safe_layout_class (type);
1204 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1205 return error_mark_node;
1206 }
1207 klass = TYPE_NAME (type);
1208
1209 if (type == object_type_node || inherits_from_p (valtype, type))
1210 {
1211 /* Anything except `null' is an instance of Object. Likewise,
1212 if the object is known to be an instance of the class, then
1213 we only need to check for `null'. */
1214 expr = build (COND_EXPR, itype,
1215 value,
1216 boolean_true_node, boolean_false_node);
1217 }
1218 else if (! TYPE_ARRAY_P (type)
1219 && ! TYPE_ARRAY_P (valtype)
1220 && DECL_P (klass) && DECL_P (valclass)
1221 && ! CLASS_INTERFACE (valclass)
1222 && ! CLASS_INTERFACE (klass)
1223 && ! inherits_from_p (type, valtype)
1224 && (CLASS_FINAL (klass)
1225 || ! inherits_from_p (valtype, type)))
1226 {
1227 /* The classes are from different branches of the derivation
1228 tree, so we immediately know the answer. */
1229 expr = boolean_false_node;
1230 }
1231 else if (DECL_P (klass) && CLASS_FINAL (klass))
1232 {
1233 tree save = save_expr (value);
1234 expr = build (COND_EXPR, itype,
1235 save,
1236 build (EQ_EXPR, itype,
1237 build_get_class (save),
1238 build_class_ref (type)),
1239 boolean_false_node);
1240 }
1241 else
1242 {
1243 expr = build (CALL_EXPR, itype,
1244 build_address_of (soft_instanceof_node),
1245 tree_cons (NULL_TREE, value,
1246 build_tree_list (NULL_TREE,
1247 build_class_ref (type))),
1248 NULL_TREE);
1249 }
1250 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1251 return expr;
1252 }
1253
1254 static void
1255 expand_java_INSTANCEOF (type)
1256 tree type;
1257 {
1258 tree value = pop_value (object_ptr_type_node);
1259 value = build_instanceof (value, type);
1260 push_value (value);
1261 }
1262
1263 static void
1264 expand_java_CHECKCAST (type)
1265 tree type;
1266 {
1267 tree value = pop_value (ptr_type_node);
1268 value = build (CALL_EXPR, promote_type (type),
1269 build_address_of (soft_checkcast_node),
1270 tree_cons (NULL_TREE, build_class_ref (type),
1271 build_tree_list (NULL_TREE, value)),
1272 NULL_TREE);
1273 push_value (value);
1274 }
1275
1276 static void
1277 expand_iinc (local_var_index, ival, pc)
1278 unsigned int local_var_index;
1279 int ival;
1280 int pc;
1281 {
1282 tree local_var, res;
1283 tree constant_value;
1284
1285 flush_quick_stack ();
1286 local_var = find_local_variable (local_var_index, int_type_node, pc);
1287 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1288 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1289 expand_assignment (local_var, res, 0, 0);
1290 }
1291
1292
1293 tree
1294 build_java_soft_divmod (op, type, op1, op2)
1295 enum tree_code op;
1296 tree type, op1, op2;
1297 {
1298 tree call = NULL;
1299 tree arg1 = convert (type, op1);
1300 tree arg2 = convert (type, op2);
1301
1302 if (type == int_type_node)
1303 {
1304 switch (op)
1305 {
1306 case TRUNC_DIV_EXPR:
1307 call = soft_idiv_node;
1308 break;
1309 case TRUNC_MOD_EXPR:
1310 call = soft_irem_node;
1311 break;
1312 default:
1313 break;
1314 }
1315 }
1316 else if (type == long_type_node)
1317 {
1318 switch (op)
1319 {
1320 case TRUNC_DIV_EXPR:
1321 call = soft_ldiv_node;
1322 break;
1323 case TRUNC_MOD_EXPR:
1324 call = soft_lrem_node;
1325 break;
1326 default:
1327 break;
1328 }
1329 }
1330
1331 if (! call)
1332 abort ();
1333
1334 call = build (CALL_EXPR, type,
1335 build_address_of (call),
1336 tree_cons (NULL_TREE, arg1,
1337 build_tree_list (NULL_TREE, arg2)),
1338 NULL_TREE);
1339
1340 return call;
1341 }
1342
1343 tree
1344 build_java_binop (op, type, arg1, arg2)
1345 enum tree_code op;
1346 tree type, arg1, arg2;
1347 {
1348 tree mask;
1349 switch (op)
1350 {
1351 case URSHIFT_EXPR:
1352 {
1353 tree u_type = unsigned_type (type);
1354 arg1 = convert (u_type, arg1);
1355 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1356 return convert (type, arg1);
1357 }
1358 case LSHIFT_EXPR:
1359 case RSHIFT_EXPR:
1360 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1361 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1362 break;
1363
1364 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1365 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1366 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1367 {
1368 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1369 boolean_type_node, arg1, arg2));
1370 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1371 tree second_compare = fold (build (COND_EXPR, int_type_node,
1372 ifexp2, integer_zero_node,
1373 op == COMPARE_L_EXPR
1374 ? integer_minus_one_node
1375 : integer_one_node));
1376 return fold (build (COND_EXPR, int_type_node, ifexp1,
1377 op == COMPARE_L_EXPR ? integer_one_node
1378 : integer_minus_one_node,
1379 second_compare));
1380 }
1381 case COMPARE_EXPR:
1382 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1383 {
1384 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1385 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1386 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1387 ifexp2, integer_one_node,
1388 integer_zero_node));
1389 return fold (build (COND_EXPR, int_type_node,
1390 ifexp1, integer_minus_one_node, second_compare));
1391 }
1392 case TRUNC_DIV_EXPR:
1393 case TRUNC_MOD_EXPR:
1394 if (TREE_CODE (type) == REAL_TYPE
1395 && op == TRUNC_MOD_EXPR)
1396 {
1397 tree call;
1398 if (type != double_type_node)
1399 {
1400 arg1 = convert (double_type_node, arg1);
1401 arg2 = convert (double_type_node, arg2);
1402 }
1403 call = build (CALL_EXPR, double_type_node,
1404 build_address_of (soft_fmod_node),
1405 tree_cons (NULL_TREE, arg1,
1406 build_tree_list (NULL_TREE, arg2)),
1407 NULL_TREE);
1408 if (type != double_type_node)
1409 call = convert (type, call);
1410 return call;
1411 }
1412
1413 if (TREE_CODE (type) == INTEGER_TYPE
1414 && flag_use_divide_subroutine
1415 && ! flag_syntax_only)
1416 return build_java_soft_divmod (op, type, arg1, arg2);
1417
1418 break;
1419 default: ;
1420 }
1421 return fold (build (op, type, arg1, arg2));
1422 }
1423
1424 static void
1425 expand_java_binop (type, op)
1426 tree type; enum tree_code op;
1427 {
1428 tree larg, rarg;
1429 tree ltype = type;
1430 tree rtype = type;
1431 switch (op)
1432 {
1433 case LSHIFT_EXPR:
1434 case RSHIFT_EXPR:
1435 case URSHIFT_EXPR:
1436 rtype = int_type_node;
1437 rarg = pop_value (rtype);
1438 break;
1439 default:
1440 rarg = pop_value (rtype);
1441 }
1442 larg = pop_value (ltype);
1443 push_value (build_java_binop (op, type, larg, rarg));
1444 }
1445
1446 /* Lookup the field named NAME in *TYPEP or its super classes.
1447 If not found, return NULL_TREE.
1448 (If the *TYPEP is not found, or if the field reference is
1449 ambiguous, return error_mark_node.)
1450 If found, return the FIELD_DECL, and set *TYPEP to the
1451 class containing the field. */
1452
1453 tree
1454 lookup_field (typep, name)
1455 tree *typep;
1456 tree name;
1457 {
1458 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1459 {
1460 load_class (*typep, 1);
1461 safe_layout_class (*typep);
1462 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1463 return error_mark_node;
1464 }
1465 do
1466 {
1467 tree field, basetype_vec;
1468 tree save_field;
1469 int n, i;
1470
1471 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1472 if (DECL_NAME (field) == name)
1473 return field;
1474
1475 /* If *typep is an innerclass, lookup the field in its enclosing
1476 contexts */
1477 if (INNER_CLASS_TYPE_P (*typep))
1478 {
1479 tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1480
1481 if ((field = lookup_field (&outer_type, name)))
1482 return field;
1483 }
1484
1485 /* Process implemented interfaces. */
1486 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1487 n = TREE_VEC_LENGTH (basetype_vec);
1488 save_field = NULL_TREE;
1489 for (i = 0; i < n; i++)
1490 {
1491 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1492 if ((field = lookup_field (&t, name)))
1493 {
1494 if (save_field == field)
1495 continue;
1496 if (save_field == NULL_TREE)
1497 save_field = field;
1498 else
1499 {
1500 tree i1 = DECL_CONTEXT (save_field);
1501 tree i2 = DECL_CONTEXT (field);
1502 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1503 IDENTIFIER_POINTER (name),
1504 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1505 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1506 return error_mark_node;
1507 }
1508 }
1509 }
1510
1511 if (save_field != NULL_TREE)
1512 return save_field;
1513
1514 *typep = CLASSTYPE_SUPER (*typep);
1515 } while (*typep);
1516 return NULL_TREE;
1517 }
1518
1519 /* Look up the field named NAME in object SELF_VALUE,
1520 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1521 SELF_VALUE is NULL_TREE if looking for a static field. */
1522
1523 tree
1524 build_field_ref (self_value, self_class, name)
1525 tree self_value, self_class, name;
1526 {
1527 tree base_class = self_class;
1528 tree field_decl = lookup_field (&base_class, name);
1529 if (field_decl == NULL_TREE)
1530 {
1531 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1532 return error_mark_node;
1533 }
1534 if (self_value == NULL_TREE)
1535 {
1536 return build_static_field_ref (field_decl);
1537 }
1538 else
1539 {
1540 tree base_handle_type = promote_type (base_class);
1541 if (base_handle_type != TREE_TYPE (self_value))
1542 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1543 #ifdef JAVA_USE_HANDLES
1544 self_value = unhand_expr (self_value);
1545 #endif
1546 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1547 self_value, flag_check_references);
1548 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1549 self_value, field_decl));
1550 }
1551 }
1552
1553 tree
1554 lookup_label (pc)
1555 int pc;
1556 {
1557 tree name;
1558 char buf[32];
1559 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1560 name = get_identifier (buf);
1561 if (IDENTIFIER_LOCAL_VALUE (name))
1562 return IDENTIFIER_LOCAL_VALUE (name);
1563 else
1564 {
1565 /* The type of the address of a label is return_address_type_node. */
1566 tree decl = create_label_decl (name);
1567 LABEL_PC (decl) = pc;
1568 label_rtx (decl);
1569 return pushdecl (decl);
1570 }
1571 }
1572
1573 /* Generate a unique name for the purpose of loops and switches
1574 labels, and try-catch-finally blocks label or temporary variables. */
1575
1576 tree
1577 generate_name ()
1578 {
1579 static int l_number = 0;
1580 char buff [32];
1581 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1582 l_number++;
1583 return get_identifier (buff);
1584 }
1585
1586 tree
1587 create_label_decl (name)
1588 tree name;
1589 {
1590 tree decl;
1591 decl = build_decl (LABEL_DECL, name,
1592 TREE_TYPE (return_address_type_node));
1593 DECL_CONTEXT (decl) = current_function_decl;
1594 DECL_IGNORED_P (decl) = 1;
1595 return decl;
1596 }
1597
1598 /* This maps a bytecode offset (PC) to various flags. */
1599 char *instruction_bits;
1600
1601 static void
1602 note_label (current_pc, target_pc)
1603 int current_pc ATTRIBUTE_UNUSED, target_pc;
1604 {
1605 lookup_label (target_pc);
1606 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1607 }
1608
1609 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1610 where CONDITION is one of one the compare operators. */
1611
1612 static void
1613 expand_compare (condition, value1, value2, target_pc)
1614 enum tree_code condition;
1615 tree value1, value2;
1616 int target_pc;
1617 {
1618 tree target = lookup_label (target_pc);
1619 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1620 expand_start_cond (truthvalue_conversion (cond), 0);
1621 expand_goto (target);
1622 expand_end_cond ();
1623 }
1624
1625 /* Emit code for a TEST-type opcode. */
1626
1627 static void
1628 expand_test (condition, type, target_pc)
1629 enum tree_code condition;
1630 tree type;
1631 int target_pc;
1632 {
1633 tree value1, value2;
1634 flush_quick_stack ();
1635 value1 = pop_value (type);
1636 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1637 expand_compare (condition, value1, value2, target_pc);
1638 }
1639
1640 /* Emit code for a COND-type opcode. */
1641
1642 static void
1643 expand_cond (condition, type, target_pc)
1644 enum tree_code condition;
1645 tree type;
1646 int target_pc;
1647 {
1648 tree value1, value2;
1649 flush_quick_stack ();
1650 /* note: pop values in opposite order */
1651 value2 = pop_value (type);
1652 value1 = pop_value (type);
1653 /* Maybe should check value1 and value2 for type compatibility ??? */
1654 expand_compare (condition, value1, value2, target_pc);
1655 }
1656
1657 static void
1658 expand_java_goto (target_pc)
1659 int target_pc;
1660 {
1661 tree target_label = lookup_label (target_pc);
1662 flush_quick_stack ();
1663 expand_goto (target_label);
1664 }
1665
1666 #if 0
1667 static void
1668 expand_java_call (target_pc, return_address)
1669 int target_pc, return_address;
1670 {
1671 tree target_label = lookup_label (target_pc);
1672 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1673 push_value (value);
1674 flush_quick_stack ();
1675 expand_goto (target_label);
1676 }
1677
1678 static void
1679 expand_java_ret (return_address)
1680 tree return_address ATTRIBUTE_UNUSED;
1681 {
1682 warning ("ret instruction not implemented");
1683 #if 0
1684 tree target_label = lookup_label (target_pc);
1685 flush_quick_stack ();
1686 expand_goto (target_label);
1687 #endif
1688 }
1689 #endif
1690
1691 static tree
1692 pop_arguments (arg_types)
1693 tree arg_types;
1694 {
1695 if (arg_types == end_params_node)
1696 return NULL_TREE;
1697 if (TREE_CODE (arg_types) == TREE_LIST)
1698 {
1699 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1700 tree type = TREE_VALUE (arg_types);
1701 tree arg = pop_value (type);
1702 if (PROMOTE_PROTOTYPES
1703 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1704 && INTEGRAL_TYPE_P (type))
1705 arg = convert (integer_type_node, arg);
1706 return tree_cons (NULL_TREE, arg, tail);
1707 }
1708 abort ();
1709 }
1710
1711 /* Build an expression to initialize the class CLAS.
1712 if EXPR is non-NULL, returns an expression to first call the initializer
1713 (if it is needed) and then calls EXPR. */
1714
1715 tree
1716 build_class_init (clas, expr)
1717 tree clas, expr;
1718 {
1719 tree init;
1720 struct init_test_hash_entry *ite;
1721 if (inherits_from_p (current_class, clas))
1722 return expr;
1723
1724 if (always_initialize_class_p)
1725 {
1726 init = build (CALL_EXPR, void_type_node,
1727 build_address_of (soft_initclass_node),
1728 build_tree_list (NULL_TREE, build_class_ref (clas)),
1729 NULL_TREE);
1730 TREE_SIDE_EFFECTS (init) = 1;
1731 }
1732 else
1733 {
1734 ite = (struct init_test_hash_entry *)
1735 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1736 (const hash_table_key) clas,
1737 TRUE, NULL);
1738
1739 if (ite->init_test_decl == 0)
1740 {
1741 /* Build a declaration and mark it as a flag used to track
1742 static class initializations. */
1743 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1744 boolean_type_node);
1745 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (ite->init_test_decl);
1746 LOCAL_CLASS_INITIALIZATION_FLAG (ite->init_test_decl) = 1;
1747 DECL_CONTEXT (ite->init_test_decl) = current_function_decl;
1748 DECL_FUNCTION_INIT_TEST_CLASS (ite->init_test_decl) = clas;
1749 /* Tell the check-init code to ignore this decl when not
1750 optimizing class initialization. */
1751 if (!STATIC_CLASS_INIT_OPT_P ())
1752 DECL_BIT_INDEX(ite->init_test_decl) = -1;
1753 }
1754
1755 init = build (CALL_EXPR, void_type_node,
1756 build_address_of (soft_initclass_node),
1757 build_tree_list (NULL_TREE, build_class_ref (clas)),
1758 NULL_TREE);
1759 TREE_SIDE_EFFECTS (init) = 1;
1760 init = build (COND_EXPR, void_type_node,
1761 build (EQ_EXPR, boolean_type_node,
1762 ite->init_test_decl, boolean_false_node),
1763 init, integer_zero_node);
1764 TREE_SIDE_EFFECTS (init) = 1;
1765 init = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1766 build (MODIFY_EXPR, boolean_type_node,
1767 ite->init_test_decl, boolean_true_node));
1768 TREE_SIDE_EFFECTS (init) = 1;
1769 }
1770
1771 if (expr != NULL_TREE)
1772 {
1773 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1774 TREE_SIDE_EFFECTS (expr) = 1;
1775 return expr;
1776 }
1777 return init;
1778 }
1779
1780 tree
1781 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1782 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1783 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1784 {
1785 tree func;
1786 if (is_compiled_class (self_type))
1787 {
1788 make_decl_rtl (method, NULL);
1789 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1790 }
1791 else
1792 {
1793 /* We don't know whether the method has been (statically) compiled.
1794 Compile this code to get a reference to the method's code:
1795
1796 SELF_TYPE->methods[METHOD_INDEX].ncode
1797
1798 This is guaranteed to work (assuming SELF_TYPE has
1799 been initialized), since if the method is not compiled yet,
1800 its ncode points to a trampoline that forces compilation. */
1801
1802 int method_index = 0;
1803 tree meth;
1804 tree ref = build_class_ref (self_type);
1805 ref = build1 (INDIRECT_REF, class_type_node, ref);
1806 if (ncode_ident == NULL_TREE)
1807 ncode_ident = get_identifier ("ncode");
1808 if (methods_ident == NULL_TREE)
1809 methods_ident = get_identifier ("methods");
1810 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1811 lookup_field (&class_type_node, methods_ident));
1812 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1813 ; meth = TREE_CHAIN (meth))
1814 {
1815 if (method == meth)
1816 break;
1817 if (meth == NULL_TREE)
1818 fatal_error ("method '%s' not found in class",
1819 IDENTIFIER_POINTER (DECL_NAME (method)));
1820 method_index++;
1821 }
1822 method_index *= int_size_in_bytes (method_type_node);
1823 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1824 ref, build_int_2 (method_index, 0)));
1825 ref = build1 (INDIRECT_REF, method_type_node, ref);
1826 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1827 ref,
1828 lookup_field (&method_type_node, ncode_ident));
1829 }
1830 return func;
1831 }
1832
1833 tree
1834 invoke_build_dtable (is_invoke_interface, arg_list)
1835 int is_invoke_interface;
1836 tree arg_list;
1837 {
1838 tree dtable, objectref;
1839
1840 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1841
1842 /* If we're dealing with interfaces and if the objectref
1843 argument is an array then get the dispatch table of the class
1844 Object rather than the one from the objectref. */
1845 objectref = (is_invoke_interface
1846 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1847 object_type_node : TREE_VALUE (arg_list));
1848
1849 if (dtable_ident == NULL_TREE)
1850 dtable_ident = get_identifier ("vtable");
1851 dtable = build_java_indirect_ref (object_type_node, objectref,
1852 flag_check_references);
1853 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1854 lookup_field (&object_type_node, dtable_ident));
1855
1856 return dtable;
1857 }
1858
1859 tree
1860 build_invokevirtual (dtable, method)
1861 tree dtable, method;
1862 {
1863 tree func;
1864 tree nativecode_ptr_ptr_type_node
1865 = build_pointer_type (nativecode_ptr_type_node);
1866 tree method_index = convert (sizetype, DECL_VINDEX (method));
1867
1868 if (TARGET_VTABLE_USES_DESCRIPTORS)
1869 /* Add one to skip bogus descriptor for class and GC descriptor. */
1870 method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
1871 else
1872 /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
1873 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1874 method_index = size_binop (MULT_EXPR, method_index,
1875 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1876
1877 if (TARGET_VTABLE_USES_DESCRIPTORS)
1878 method_index = size_binop (MULT_EXPR, method_index,
1879 size_int (TARGET_VTABLE_USES_DESCRIPTORS));
1880
1881 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1882 convert (nativecode_ptr_ptr_type_node, method_index)));
1883
1884 if (TARGET_VTABLE_USES_DESCRIPTORS)
1885 func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
1886 else
1887 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1888
1889 return func;
1890 }
1891
1892 tree
1893 build_invokeinterface (dtable, method)
1894 tree dtable, method;
1895 {
1896 static tree class_ident = NULL_TREE;
1897 tree lookup_arg;
1898 tree interface;
1899 tree idx;
1900 tree meth;
1901 int i;
1902
1903 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1904 ensure that the selected method exists, is public and not
1905 abstract nor static. */
1906
1907 if (class_ident == NULL_TREE)
1908 {
1909 class_ident = get_identifier ("class");
1910 ggc_add_tree_root (&class_ident, 1);
1911 }
1912
1913 dtable = build_java_indirect_ref (dtable_type, dtable, flag_check_references);
1914 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1915 lookup_field (&dtable_type, class_ident));
1916
1917 interface = DECL_CONTEXT (method);
1918 layout_class_methods (interface);
1919
1920 i = 1;
1921 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1922 {
1923 if (meth == method)
1924 {
1925 idx = build_int_2 (i, 0);
1926 break;
1927 }
1928 if (meth == NULL_TREE)
1929 abort ();
1930 }
1931
1932 lookup_arg = tree_cons (NULL_TREE, dtable,
1933 tree_cons (NULL_TREE, build_class_ref (interface),
1934 build_tree_list (NULL_TREE, idx)));
1935
1936 return build (CALL_EXPR, ptr_type_node,
1937 build_address_of (soft_lookupinterfacemethod_node),
1938 lookup_arg, NULL_TREE);
1939 }
1940
1941 /* Expand one of the invoke_* opcodes.
1942 OCPODE is the specific opcode.
1943 METHOD_REF_INDEX is an index into the constant pool.
1944 NARGS is the number of arguments, or -1 if not specified. */
1945
1946 static void
1947 expand_invoke (opcode, method_ref_index, nargs)
1948 int opcode;
1949 int method_ref_index;
1950 int nargs ATTRIBUTE_UNUSED;
1951 {
1952 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1953 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1954 tree self_type = get_class_constant
1955 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1956 const char *const self_name
1957 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1958 tree call, func, method, arg_list, method_type;
1959 tree check = NULL_TREE;
1960
1961 if (! CLASS_LOADED_P (self_type))
1962 {
1963 load_class (self_type, 1);
1964 safe_layout_class (self_type);
1965 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1966 fatal_error ("failed to find class '%s'", self_name);
1967 }
1968 layout_class_methods (self_type);
1969
1970 if (ID_INIT_P (method_name))
1971 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1972 method_signature);
1973 else
1974 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1975 method_name, method_signature);
1976 if (method == NULL_TREE)
1977 {
1978 error ("class '%s' has no method named '%s' matching signature '%s'",
1979 self_name,
1980 IDENTIFIER_POINTER (method_name),
1981 IDENTIFIER_POINTER (method_signature));
1982 }
1983 /* Invoke static can't invoke static/abstract method */
1984 else if (opcode == OPCODE_invokestatic)
1985 {
1986 if (!METHOD_STATIC (method))
1987 {
1988 error ("invokestatic on non static method");
1989 method = NULL_TREE;
1990 }
1991 else if (METHOD_ABSTRACT (method))
1992 {
1993 error ("invokestatic on abstract method");
1994 method = NULL_TREE;
1995 }
1996 }
1997 else
1998 {
1999 if (METHOD_STATIC (method))
2000 {
2001 error ("invoke[non-static] on static method");
2002 method = NULL_TREE;
2003 }
2004 }
2005
2006 if (method == NULL_TREE)
2007 {
2008 method_type = get_type_from_signature (method_signature);
2009 pop_arguments (TYPE_ARG_TYPES (method_type));
2010 if (opcode != OPCODE_invokestatic)
2011 pop_type (self_type);
2012 method_type = promote_type (TREE_TYPE (method_type));
2013 push_value (convert (method_type, integer_zero_node));
2014 return;
2015 }
2016
2017 method_type = TREE_TYPE (method);
2018 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2019 flush_quick_stack ();
2020
2021 func = NULL_TREE;
2022 if (opcode == OPCODE_invokestatic)
2023 func = build_known_method_ref (method, method_type, self_type,
2024 method_signature, arg_list);
2025 else if (opcode == OPCODE_invokespecial
2026 || (opcode == OPCODE_invokevirtual
2027 && (METHOD_PRIVATE (method)
2028 || METHOD_FINAL (method)
2029 || CLASS_FINAL (TYPE_NAME (self_type)))))
2030 {
2031 /* If the object for the method call is null, we throw an
2032 exception. We don't do this if the object is the current
2033 method's `this'. In other cases we just rely on an
2034 optimization pass to eliminate redundant checks. FIXME:
2035 Unfortunately there doesn't seem to be a way to determine
2036 what the current method is right now. */
2037 /* We use a SAVE_EXPR here to make sure we only evaluate
2038 the new `self' expression once. */
2039 tree save_arg = save_expr (TREE_VALUE (arg_list));
2040 TREE_VALUE (arg_list) = save_arg;
2041 check = java_check_reference (save_arg, 1);
2042 func = build_known_method_ref (method, method_type, self_type,
2043 method_signature, arg_list);
2044 }
2045 else
2046 {
2047 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
2048 arg_list);
2049 if (opcode == OPCODE_invokevirtual)
2050 func = build_invokevirtual (dtable, method);
2051 else
2052 func = build_invokeinterface (dtable, method);
2053 }
2054 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2055 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
2056 TREE_SIDE_EFFECTS (call) = 1;
2057
2058 if (check != NULL_TREE)
2059 {
2060 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2061 TREE_SIDE_EFFECTS (call) = 1;
2062 }
2063
2064 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2065 expand_expr_stmt (call);
2066 else
2067 {
2068 push_value (call);
2069 flush_quick_stack ();
2070 }
2071 }
2072
2073 /* Create a stub which will be put into the vtable but which will call
2074 a JNI function. */
2075
2076 tree
2077 build_jni_stub (method)
2078 tree method;
2079 {
2080 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2081 tree jni_func_type, tem;
2082 tree env_var, res_var = NULL_TREE, block;
2083 tree method_args, res_type;
2084 tree meth_var;
2085
2086 tree klass = DECL_CONTEXT (method);
2087 int from_class = ! CLASS_FROM_SOURCE_P (klass);
2088 klass = build_class_ref (klass);
2089
2090 if (! METHOD_NATIVE (method) || ! flag_jni)
2091 abort ();
2092
2093 DECL_ARTIFICIAL (method) = 1;
2094 DECL_EXTERNAL (method) = 0;
2095
2096 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2097 DECL_CONTEXT (env_var) = method;
2098
2099 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2100 {
2101 res_var = build_decl (VAR_DECL, get_identifier ("res"),
2102 TREE_TYPE (TREE_TYPE (method)));
2103 DECL_CONTEXT (res_var) = method;
2104 TREE_CHAIN (env_var) = res_var;
2105 }
2106
2107 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2108 TREE_STATIC (meth_var) = 1;
2109 TREE_PUBLIC (meth_var) = 0;
2110 DECL_EXTERNAL (meth_var) = 0;
2111 DECL_CONTEXT (meth_var) = method;
2112 make_decl_rtl (meth_var, NULL);
2113 meth_var = pushdecl_top_level (meth_var);
2114
2115 /* One strange way that the front ends are different is that they
2116 store arguments differently. */
2117 if (from_class)
2118 method_args = DECL_ARGUMENTS (method);
2119 else
2120 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2121 block = build_block (env_var, NULL_TREE, NULL_TREE,
2122 method_args, NULL_TREE);
2123 TREE_SIDE_EFFECTS (block) = 1;
2124 /* When compiling from source we don't set the type of the block,
2125 because that will prevent patch_return from ever being run. */
2126 if (from_class)
2127 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2128
2129 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2130 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2131 build (CALL_EXPR, ptr_type_node,
2132 build_address_of (soft_getjnienvnewframe_node),
2133 build_tree_list (NULL_TREE, klass),
2134 NULL_TREE));
2135 CAN_COMPLETE_NORMALLY (body) = 1;
2136
2137 /* All the arguments to this method become arguments to the
2138 underlying JNI function. If we had to wrap object arguments in a
2139 special way, we would do that here. */
2140 args = NULL_TREE;
2141 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2142 args = tree_cons (NULL_TREE, tem, args);
2143 args = nreverse (args);
2144 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2145
2146 /* For a static method the second argument is the class. For a
2147 non-static method the second argument is `this'; that is already
2148 available in the argument list. */
2149 if (METHOD_STATIC (method))
2150 {
2151 args = tree_cons (NULL_TREE, klass, args);
2152 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2153 }
2154
2155 /* The JNIEnv structure is the first argument to the JNI function. */
2156 args = tree_cons (NULL_TREE, env_var, args);
2157 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2158
2159 /* We call _Jv_LookupJNIMethod to find the actual underlying
2160 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2161 exception if this function is not found at runtime. */
2162 method_sig = build_java_signature (TREE_TYPE (method));
2163 lookup_arg =
2164 build_tree_list (NULL_TREE,
2165 build_utf8_ref (unmangle_classname
2166 (IDENTIFIER_POINTER (method_sig),
2167 IDENTIFIER_LENGTH (method_sig))));
2168 tem = DECL_NAME (method);
2169 lookup_arg
2170 = tree_cons (NULL_TREE, klass,
2171 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2172
2173 jni_func_type
2174 = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2175 arg_types));
2176
2177 jnifunc = build (COND_EXPR, ptr_type_node,
2178 meth_var, meth_var,
2179 build (MODIFY_EXPR, ptr_type_node,
2180 meth_var,
2181 build (CALL_EXPR, ptr_type_node,
2182 build_address_of (soft_lookupjnimethod_node),
2183 lookup_arg, NULL_TREE)));
2184
2185 /* Now we make the actual JNI call via the resulting function
2186 pointer. */
2187 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2188 build1 (NOP_EXPR, jni_func_type, jnifunc),
2189 args, NULL_TREE);
2190
2191 /* If the JNI call returned a result, capture it here. If we had to
2192 unwrap JNI object results, we would do that here. */
2193 if (res_var != NULL_TREE)
2194 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2195 res_var, call);
2196
2197 TREE_SIDE_EFFECTS (call) = 1;
2198 CAN_COMPLETE_NORMALLY (call) = 1;
2199
2200 body = build (COMPOUND_EXPR, void_type_node, body, call);
2201 TREE_SIDE_EFFECTS (body) = 1;
2202
2203 /* Now free the environment we allocated. */
2204 call = build (CALL_EXPR, ptr_type_node,
2205 build_address_of (soft_jnipopsystemframe_node),
2206 build_tree_list (NULL_TREE, env_var),
2207 NULL_TREE);
2208 TREE_SIDE_EFFECTS (call) = 1;
2209 CAN_COMPLETE_NORMALLY (call) = 1;
2210 body = build (COMPOUND_EXPR, void_type_node, body, call);
2211 TREE_SIDE_EFFECTS (body) = 1;
2212
2213 /* Finally, do the return. When compiling from source we rely on
2214 patch_return to patch the return value -- because DECL_RESULT is
2215 not set at the time this function is called. */
2216 if (from_class)
2217 {
2218 res_type = void_type_node;
2219 if (res_var != NULL_TREE)
2220 {
2221 tree drt;
2222 if (! DECL_RESULT (method))
2223 abort ();
2224 /* Make sure we copy the result variable to the actual
2225 result. We use the type of the DECL_RESULT because it
2226 might be different from the return type of the function:
2227 it might be promoted. */
2228 drt = TREE_TYPE (DECL_RESULT (method));
2229 if (drt != TREE_TYPE (res_var))
2230 res_var = build1 (CONVERT_EXPR, drt, res_var);
2231 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2232 TREE_SIDE_EFFECTS (res_var) = 1;
2233 }
2234 }
2235 else
2236 {
2237 /* This is necessary to get patch_return to run. */
2238 res_type = NULL_TREE;
2239 }
2240 body = build (COMPOUND_EXPR, void_type_node, body,
2241 build1 (RETURN_EXPR, res_type, res_var));
2242 TREE_SIDE_EFFECTS (body) = 1;
2243
2244 BLOCK_EXPR_BODY (block) = body;
2245 return block;
2246 }
2247
2248 /* Expand an operation to extract from or store into a field.
2249 IS_STATIC is 1 iff the field is static.
2250 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2251 FIELD_REF_INDEX is an index into the constant pool. */
2252
2253 static void
2254 expand_java_field_op (is_static, is_putting, field_ref_index)
2255 int is_static;
2256 int is_putting;
2257 int field_ref_index;
2258 {
2259 tree self_type =
2260 get_class_constant (current_jcf,
2261 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2262 field_ref_index));
2263 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2264 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2265 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2266 field_ref_index);
2267 tree field_type = get_type_from_signature (field_signature);
2268 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2269 tree field_ref;
2270 int is_error = 0;
2271 tree field_decl = lookup_field (&self_type, field_name);
2272 if (field_decl == error_mark_node)
2273 {
2274 is_error = 1;
2275 }
2276 else if (field_decl == NULL_TREE)
2277 {
2278 error ("missing field '%s' in '%s'",
2279 IDENTIFIER_POINTER (field_name), self_name);
2280 is_error = 1;
2281 }
2282 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2283 {
2284 error ("mismatching signature for field '%s' in '%s'",
2285 IDENTIFIER_POINTER (field_name), self_name);
2286 is_error = 1;
2287 }
2288 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2289 if (is_error)
2290 {
2291 if (! is_putting)
2292 push_value (convert (field_type, integer_zero_node));
2293 flush_quick_stack ();
2294 return;
2295 }
2296
2297 field_ref = build_field_ref (field_ref, self_type, field_name);
2298 if (is_static)
2299 field_ref = build_class_init (self_type, field_ref);
2300 if (is_putting)
2301 {
2302 flush_quick_stack ();
2303 if (FIELD_FINAL (field_decl))
2304 {
2305 if (DECL_CONTEXT (field_decl) != current_class)
2306 error_with_decl (field_decl,
2307 "assignment to final field `%s' not in field's class");
2308 else if (FIELD_STATIC (field_decl))
2309 {
2310 if (!DECL_CLINIT_P (current_function_decl))
2311 warning_with_decl (field_decl,
2312 "assignment to final static field `%s' not in class initializer");
2313 }
2314 else
2315 {
2316 tree cfndecl_name = DECL_NAME (current_function_decl);
2317 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2318 && !ID_FINIT_P (cfndecl_name))
2319 warning_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2320 }
2321 }
2322 expand_assignment (field_ref, new_value, 0, 0);
2323 }
2324 else
2325 push_value (field_ref);
2326 }
2327
2328 void
2329 load_type_state (label)
2330 tree label;
2331 {
2332 int i;
2333 tree vec = LABEL_TYPE_STATE (label);
2334 int cur_length = TREE_VEC_LENGTH (vec);
2335 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2336 for (i = 0; i < cur_length; i++)
2337 type_map [i] = TREE_VEC_ELT (vec, i);
2338 }
2339
2340 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2341 dependant things, but they rely on gcc routines. This function is
2342 placed here because it uses things defined locally in parse.y. */
2343
2344 static tree
2345 case_identity (t, v)
2346 tree t __attribute__ ((__unused__));
2347 tree v;
2348 {
2349 return v;
2350 }
2351
2352 /* Return the name of the vtable for an array of a given primitive
2353 type. */
2354 static tree
2355 get_primitive_array_vtable (tree elt)
2356 {
2357 tree r;
2358 if (elt == boolean_type_node)
2359 r = boolean_array_vtable;
2360 else if (elt == byte_type_node)
2361 r = byte_array_vtable;
2362 else if (elt == char_type_node)
2363 r = char_array_vtable;
2364 else if (elt == short_type_node)
2365 r = short_array_vtable;
2366 else if (elt == int_type_node)
2367 r = int_array_vtable;
2368 else if (elt == long_type_node)
2369 r = long_array_vtable;
2370 else if (elt == float_type_node)
2371 r = float_array_vtable;
2372 else if (elt == double_type_node)
2373 r = double_array_vtable;
2374 else
2375 abort ();
2376 return build_address_of (r);
2377 }
2378
2379 struct rtx_def *
2380 java_lang_expand_expr (exp, target, tmode, modifier)
2381 register tree exp;
2382 rtx target;
2383 enum machine_mode tmode;
2384 enum expand_modifier modifier;
2385 {
2386 tree current;
2387
2388 switch (TREE_CODE (exp))
2389 {
2390 case NEW_ARRAY_INIT:
2391 {
2392 rtx tmp;
2393 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2394 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2395 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2396 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2397 tree length = build_int_2 (ilength, 0);
2398 tree init = TREE_OPERAND (exp, 0);
2399 tree array_decl;
2400
2401 /* See if we can generate the array statically. */
2402 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2403 && JPRIMITIVE_TYPE_P (element_type))
2404 {
2405 tree temp, value, init_decl;
2406 struct rtx_def *r;
2407 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2408 PUSH_FIELD_VALUE (temp, "vtable",
2409 get_primitive_array_vtable (element_type));
2410 if (! flag_hash_synchronization)
2411 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2412 FINISH_RECORD_CONSTRUCTOR (temp);
2413 START_RECORD_CONSTRUCTOR (value, array_type);
2414 PUSH_SUPER_VALUE (value, temp);
2415 PUSH_FIELD_VALUE (value, "length", length);
2416 PUSH_FIELD_VALUE (value, "data", init);
2417 FINISH_RECORD_CONSTRUCTOR (value);
2418
2419 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2420 pushdecl_top_level (init_decl);
2421 TREE_STATIC (init_decl) = 1;
2422 DECL_INITIAL (init_decl) = value;
2423 DECL_IGNORED_P (init_decl) = 1;
2424 TREE_READONLY (init_decl) = 1;
2425 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2426 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2427 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2428 r = expand_expr (init, target, tmode, modifier);
2429 return r;
2430 }
2431
2432 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2433 expand_decl (array_decl);
2434 tmp = expand_assignment (array_decl,
2435 build_new_array (element_type, length),
2436 1, 0);
2437 if (TREE_CONSTANT (init)
2438 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2439 {
2440 tree init_decl;
2441 init_decl = build_decl (VAR_DECL, generate_name (),
2442 TREE_TYPE (init));
2443 pushdecl_top_level (init_decl);
2444 TREE_STATIC (init_decl) = 1;
2445 DECL_INITIAL (init_decl) = init;
2446 DECL_IGNORED_P (init_decl) = 1;
2447 TREE_READONLY (init_decl) = 1;
2448 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2449 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2450 init = init_decl;
2451 }
2452 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2453 build_java_indirect_ref (array_type,
2454 array_decl, flag_check_references),
2455 data_fld), init, 0, 0);
2456 return tmp;
2457 }
2458 case BLOCK:
2459 if (BLOCK_EXPR_BODY (exp))
2460 {
2461 tree local;
2462 tree body = BLOCK_EXPR_BODY (exp);
2463 /* Set to 1 or more when we found a static class
2464 initialization flag. */
2465 int found_class_initialization_flag = 0;
2466
2467 pushlevel (2); /* 2 and above */
2468 expand_start_bindings (0);
2469 local = BLOCK_EXPR_DECLS (exp);
2470 while (local)
2471 {
2472 tree next = TREE_CHAIN (local);
2473 found_class_initialization_flag +=
2474 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
2475 layout_decl (local, 0);
2476 expand_decl (pushdecl (local));
2477 local = next;
2478 }
2479
2480 /* Emit initialization code for test flags if we saw one. */
2481 if (! always_initialize_class_p
2482 && current_function_decl
2483 && found_class_initialization_flag)
2484 hash_traverse
2485 (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
2486 emit_init_test_initialization, NULL);
2487
2488 /* Avoid deep recursion for long block. */
2489 while (TREE_CODE (body) == COMPOUND_EXPR)
2490 {
2491 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2492 emit_queue ();
2493 body = TREE_OPERAND (body, 1);
2494 }
2495 expand_expr (body, const0_rtx, VOIDmode, 0);
2496 emit_queue ();
2497 expand_end_bindings (getdecls (), 1, 0);
2498 poplevel (1, 1, 0);
2499 return const0_rtx;
2500 }
2501 return const0_rtx;
2502
2503 case CASE_EXPR:
2504 {
2505 tree duplicate;
2506 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2507 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2508 &duplicate) == 2)
2509 {
2510 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2511 parse_error_context
2512 (wfl_operator, "Duplicate case label: `%s'",
2513 print_int_node (TREE_OPERAND (exp, 0)));
2514 }
2515 return const0_rtx;
2516 }
2517
2518 case DEFAULT_EXPR:
2519 pushcase (NULL_TREE, 0,
2520 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2521 return const0_rtx;
2522
2523 case SWITCH_EXPR:
2524 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2525 expand_expr_stmt (TREE_OPERAND (exp, 1));
2526 expand_end_case (TREE_OPERAND (exp, 0));
2527 return const0_rtx;
2528
2529 case TRY_EXPR:
2530 /* We expand a try[-catch] block */
2531
2532 /* Expand the try block */
2533 expand_eh_region_start ();
2534 expand_expr_stmt (TREE_OPERAND (exp, 0));
2535 expand_start_all_catch ();
2536
2537 /* Expand all catch clauses (EH handlers) */
2538 for (current = TREE_OPERAND (exp, 1); current;
2539 current = TREE_CHAIN (current))
2540 {
2541 tree catch = TREE_OPERAND (current, 0);
2542 tree decl = BLOCK_EXPR_DECLS (catch);
2543 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2544
2545 expand_start_catch (type);
2546 expand_expr_stmt (TREE_OPERAND (current, 0));
2547 expand_end_catch ();
2548 }
2549 expand_end_all_catch ();
2550 return const0_rtx;
2551
2552 case JAVA_EXC_OBJ_EXPR:
2553 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2554 target, tmode, modifier);
2555
2556 default:
2557 internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
2558 }
2559 }
2560
2561 /* Go over METHOD's bytecode and note instruction starts in
2562 instruction_bits[]. */
2563
2564 void
2565 note_instructions (jcf, method)
2566 JCF *jcf;
2567 tree method;
2568 {
2569 int PC;
2570 unsigned char* byte_ops;
2571 long length = DECL_CODE_LENGTH (method);
2572
2573 int saw_index;
2574 jint INT_temp;
2575
2576 #undef RET /* Defined by config/i386/i386.h */
2577 #undef AND /* Causes problems with opcodes for iand and land. */
2578 #undef PTR
2579 #define BCODE byte_ops
2580 #define BYTE_type_node byte_type_node
2581 #define SHORT_type_node short_type_node
2582 #define INT_type_node int_type_node
2583 #define LONG_type_node long_type_node
2584 #define CHAR_type_node char_type_node
2585 #define PTR_type_node ptr_type_node
2586 #define FLOAT_type_node float_type_node
2587 #define DOUBLE_type_node double_type_node
2588 #define VOID_type_node void_type_node
2589 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2590 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2591 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2592 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2593
2594 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2595
2596 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2597 byte_ops = jcf->read_ptr;
2598 instruction_bits = xrealloc (instruction_bits, length + 1);
2599 memset (instruction_bits, 0, length + 1);
2600
2601 /* This pass figures out which PC can be the targets of jumps. */
2602 for (PC = 0; PC < length;)
2603 {
2604 int oldpc = PC; /* PC at instruction start. */
2605 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2606 switch (byte_ops[PC++])
2607 {
2608 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2609 case OPCODE: \
2610 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2611 break;
2612
2613 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2614
2615 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2616 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2617 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2618 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2619 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2620 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2621 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2622 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2623
2624 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2625 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2626 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2627 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2628 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2629 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2630 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2631 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2632
2633 /* two forms of wide instructions */
2634 #define PRE_SPECIAL_WIDE(IGNORE) \
2635 { \
2636 int modified_opcode = IMMEDIATE_u1; \
2637 if (modified_opcode == OPCODE_iinc) \
2638 { \
2639 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2640 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2641 } \
2642 else \
2643 { \
2644 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2645 } \
2646 }
2647
2648 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2649
2650 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2651
2652 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2653 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2654 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2655 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2656 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2657 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2658 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2659 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2660 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2661 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2662
2663 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2664 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2665 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2666 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2667 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2668 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2669 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2670 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2671
2672 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2673
2674 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2675 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2676
2677 #define PRE_LOOKUP_SWITCH \
2678 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2679 NOTE_LABEL (default_offset+oldpc); \
2680 if (npairs >= 0) \
2681 while (--npairs >= 0) { \
2682 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2683 jint offset = IMMEDIATE_s4; \
2684 NOTE_LABEL (offset+oldpc); } \
2685 }
2686
2687 #define PRE_TABLE_SWITCH \
2688 { jint default_offset = IMMEDIATE_s4; \
2689 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2690 NOTE_LABEL (default_offset+oldpc); \
2691 if (low <= high) \
2692 while (low++ <= high) { \
2693 jint offset = IMMEDIATE_s4; \
2694 NOTE_LABEL (offset+oldpc); } \
2695 }
2696
2697 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2698 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2699 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2700 (void)(IMMEDIATE_u2); \
2701 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2702
2703 #include "javaop.def"
2704 #undef JAVAOP
2705 }
2706 } /* for */
2707 }
2708
2709 void
2710 expand_byte_code (jcf, method)
2711 JCF *jcf;
2712 tree method;
2713 {
2714 int PC;
2715 int i;
2716 const unsigned char *linenumber_pointer;
2717 int dead_code_index = -1;
2718 unsigned char* byte_ops;
2719 long length = DECL_CODE_LENGTH (method);
2720
2721 stack_pointer = 0;
2722 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2723 byte_ops = jcf->read_ptr;
2724
2725 /* We make an initial pass of the line number table, to note
2726 which instructions have associated line number entries. */
2727 linenumber_pointer = linenumber_table;
2728 for (i = 0; i < linenumber_count; i++)
2729 {
2730 int pc = GET_u2 (linenumber_pointer);
2731 linenumber_pointer += 4;
2732 if (pc >= length)
2733 warning ("invalid PC in line number table");
2734 else
2735 {
2736 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2737 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2738 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2739 }
2740 }
2741
2742 if (! verify_jvm_instructions (jcf, byte_ops, length))
2743 return;
2744
2745 /* Translate bytecodes to rtl instructions. */
2746 linenumber_pointer = linenumber_table;
2747 for (PC = 0; PC < length;)
2748 {
2749 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2750 {
2751 tree label = lookup_label (PC);
2752 flush_quick_stack ();
2753 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2754 expand_label (label);
2755 if (LABEL_VERIFIED (label) || PC == 0)
2756 load_type_state (label);
2757 }
2758
2759 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2760 {
2761 if (dead_code_index == -1)
2762 {
2763 /* This is the start of a region of unreachable bytecodes.
2764 They still need to be processed in order for EH ranges
2765 to get handled correctly. However, we can simply
2766 replace these bytecodes with nops. */
2767 dead_code_index = PC;
2768 }
2769
2770 /* Turn this bytecode into a nop. */
2771 byte_ops[PC] = 0x0;
2772 }
2773 else
2774 {
2775 if (dead_code_index != -1)
2776 {
2777 /* We've just reached the end of a region of dead code. */
2778 warning ("unreachable bytecode from %d to before %d",
2779 dead_code_index, PC);
2780 dead_code_index = -1;
2781 }
2782 }
2783
2784 /* Handle possible line number entry for this PC.
2785
2786 This code handles out-of-order and multiple linenumbers per PC,
2787 but is optimized for the case of line numbers increasing
2788 monotonically with PC. */
2789 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2790 {
2791 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2792 || GET_u2 (linenumber_pointer) != PC)
2793 linenumber_pointer = linenumber_table;
2794 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2795 {
2796 int pc = GET_u2 (linenumber_pointer);
2797 linenumber_pointer += 4;
2798 if (pc == PC)
2799 {
2800 lineno = GET_u2 (linenumber_pointer - 2);
2801 emit_line_note (input_filename, lineno);
2802 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2803 break;
2804 }
2805 }
2806 }
2807 maybe_pushlevels (PC);
2808 PC = process_jvm_instruction (PC, byte_ops, length);
2809 maybe_poplevels (PC);
2810 } /* for */
2811
2812 if (dead_code_index != -1)
2813 {
2814 /* We've just reached the end of a region of dead code. */
2815 warning ("unreachable bytecode from %d to the end of the method",
2816 dead_code_index);
2817 }
2818 }
2819
2820 static void
2821 java_push_constant_from_pool (jcf, index)
2822 JCF *jcf;
2823 int index;
2824 {
2825 tree c;
2826 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2827 {
2828 tree name;
2829 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2830 index = alloc_name_constant (CONSTANT_String, name);
2831 c = build_ref_from_constant_pool (index);
2832 TREE_TYPE (c) = promote_type (string_type_node);
2833 }
2834 else
2835 c = get_constant (jcf, index);
2836 push_value (c);
2837 }
2838
2839 int
2840 process_jvm_instruction (PC, byte_ops, length)
2841 int PC;
2842 const unsigned char* byte_ops;
2843 long length ATTRIBUTE_UNUSED;
2844 {
2845 const char *opname; /* Temporary ??? */
2846 int oldpc = PC; /* PC at instruction start. */
2847
2848 /* If the instruction is at the beginning of a exception handler,
2849 replace the top of the stack with the thrown object reference */
2850 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2851 {
2852 tree type = pop_type (ptr_type_node);
2853 push_value (build (JAVA_EXC_OBJ_EXPR, type));
2854 }
2855
2856 switch (byte_ops[PC++])
2857 {
2858 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2859 case OPCODE: \
2860 opname = #OPNAME; \
2861 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2862 break;
2863
2864 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2865 { \
2866 int saw_index = 0; \
2867 int index = OPERAND_VALUE; \
2868 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2869 }
2870
2871 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2872 { \
2873 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2874 tree ret = lookup_label (PC); \
2875 build_java_jsr (where, ret); \
2876 load_type_state (ret); \
2877 }
2878
2879 /* Push a constant onto the stack. */
2880 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2881 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2882 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2883 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2884
2885 /* internal macro added for use by the WIDE case */
2886 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2887 expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
2888
2889 /* Push local variable onto the opcode stack. */
2890 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2891 { \
2892 /* have to do this since OPERAND_VALUE may have side-effects */ \
2893 int opvalue = OPERAND_VALUE; \
2894 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2895 }
2896
2897 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2898 expand_java_return (OPERAND_TYPE##_type_node)
2899
2900 #define REM_EXPR TRUNC_MOD_EXPR
2901 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2902 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2903
2904 #define FIELD(IS_STATIC, IS_PUT) \
2905 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2906
2907 #define TEST(OPERAND_TYPE, CONDITION) \
2908 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2909
2910 #define COND(OPERAND_TYPE, CONDITION) \
2911 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2912
2913 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2914 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2915
2916 #define BRANCH_GOTO(OPERAND_VALUE) \
2917 expand_java_goto (oldpc + OPERAND_VALUE)
2918
2919 #define BRANCH_CALL(OPERAND_VALUE) \
2920 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2921
2922 #if 0
2923 #define BRANCH_RETURN(OPERAND_VALUE) \
2924 { \
2925 tree type = OPERAND_TYPE##_type_node; \
2926 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2927 expand_java_ret (value); \
2928 }
2929 #endif
2930
2931 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2932 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2933 fprintf (stderr, "(not implemented)\n")
2934 #define NOT_IMPL1(OPERAND_VALUE) \
2935 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2936 fprintf (stderr, "(not implemented)\n")
2937
2938 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2939
2940 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2941
2942 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2943
2944 #define STACK_SWAP(COUNT) java_stack_swap()
2945
2946 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2947 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2948 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2949
2950 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2951 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2952
2953 #define LOOKUP_SWITCH \
2954 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2955 tree selector = pop_value (INT_type_node); \
2956 tree duplicate, label; \
2957 tree type = TREE_TYPE (selector); \
2958 flush_quick_stack (); \
2959 expand_start_case (0, selector, type, "switch statement");\
2960 while (--npairs >= 0) \
2961 { \
2962 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2963 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2964 TREE_TYPE (value) = type; \
2965 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2966 pushcase (value, convert, label, &duplicate); \
2967 expand_java_goto (oldpc + offset); \
2968 } \
2969 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2970 pushcase (NULL_TREE, 0, label, &duplicate); \
2971 expand_java_goto (oldpc + default_offset); \
2972 expand_end_case (selector); \
2973 }
2974
2975 #define TABLE_SWITCH \
2976 { jint default_offset = IMMEDIATE_s4; \
2977 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2978 tree selector = pop_value (INT_type_node); \
2979 tree duplicate, label; \
2980 tree type = TREE_TYPE (selector); \
2981 flush_quick_stack (); \
2982 expand_start_case (0, selector, type, "switch statement");\
2983 for (; low <= high; low++) \
2984 { \
2985 jint offset = IMMEDIATE_s4; \
2986 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2987 TREE_TYPE (value) = type; \
2988 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2989 pushcase (value, convert, label, &duplicate); \
2990 expand_java_goto (oldpc + offset); \
2991 } \
2992 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2993 pushcase (NULL_TREE, 0, label, &duplicate); \
2994 expand_java_goto (oldpc + default_offset); \
2995 expand_end_case (selector); \
2996 }
2997
2998 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2999 { int opcode = byte_ops[PC-1]; \
3000 int method_ref_index = IMMEDIATE_u2; \
3001 int nargs; \
3002 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
3003 else nargs = -1; \
3004 expand_invoke (opcode, method_ref_index, nargs); \
3005 }
3006
3007 /* Handle new, checkcast, instanceof */
3008 #define OBJECT(TYPE, OP) \
3009 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3010
3011 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3012
3013 #define ARRAY_LOAD(OPERAND_TYPE) \
3014 { \
3015 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
3016 }
3017
3018 #define ARRAY_STORE(OPERAND_TYPE) \
3019 { \
3020 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3021 }
3022
3023 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3024 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3025 #define ARRAY_NEW_PTR() \
3026 push_value (build_anewarray (get_class_constant (current_jcf, \
3027 IMMEDIATE_u2), \
3028 pop_value (int_type_node)));
3029 #define ARRAY_NEW_NUM() \
3030 { \
3031 int atype = IMMEDIATE_u1; \
3032 push_value (build_newarray (atype, pop_value (int_type_node)));\
3033 }
3034 #define ARRAY_NEW_MULTI() \
3035 { \
3036 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
3037 int ndims = IMMEDIATE_u1; \
3038 expand_java_multianewarray( class, ndims ); \
3039 }
3040
3041 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3042 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3043 pop_value (OPERAND_TYPE##_type_node))));
3044
3045 #define CONVERT2(FROM_TYPE, TO_TYPE) \
3046 { \
3047 push_value (build1 (NOP_EXPR, int_type_node, \
3048 (convert (TO_TYPE##_type_node, \
3049 pop_value (FROM_TYPE##_type_node))))); \
3050 }
3051
3052 #define CONVERT(FROM_TYPE, TO_TYPE) \
3053 { \
3054 push_value (convert (TO_TYPE##_type_node, \
3055 pop_value (FROM_TYPE##_type_node))); \
3056 }
3057
3058 /* internal macro added for use by the WIDE case
3059 Added TREE_TYPE (decl) assignment, apbianco */
3060 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
3061 { \
3062 tree decl, value; \
3063 int var = OPVALUE; \
3064 tree type = OPTYPE; \
3065 value = pop_value (type); \
3066 type = TREE_TYPE (value); \
3067 decl = find_local_variable (var, type, oldpc); \
3068 set_local_type (var, type ); \
3069 expand_assignment (decl, value, 0, 0); \
3070 }
3071
3072 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3073 { \
3074 /* have to do this since OPERAND_VALUE may have side-effects */ \
3075 int opvalue = OPERAND_VALUE; \
3076 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3077 }
3078
3079 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3080 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3081
3082 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3083 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3084
3085 #define MONITOR_OPERATION(call) \
3086 { \
3087 tree o = pop_value (ptr_type_node); \
3088 tree c; \
3089 flush_quick_stack (); \
3090 c = build_java_monitor (call, o); \
3091 TREE_SIDE_EFFECTS (c) = 1; \
3092 expand_expr_stmt (c); \
3093 }
3094
3095 #define SPECIAL_IINC(IGNORED) \
3096 { \
3097 unsigned int local_var_index = IMMEDIATE_u1; \
3098 int ival = IMMEDIATE_s1; \
3099 expand_iinc(local_var_index, ival, oldpc); \
3100 }
3101
3102 #define SPECIAL_WIDE(IGNORED) \
3103 { \
3104 int modified_opcode = IMMEDIATE_u1; \
3105 unsigned int local_var_index = IMMEDIATE_u2; \
3106 switch (modified_opcode) \
3107 { \
3108 case OPCODE_iinc: \
3109 { \
3110 int ival = IMMEDIATE_s2; \
3111 expand_iinc (local_var_index, ival, oldpc); \
3112 break; \
3113 } \
3114 case OPCODE_iload: \
3115 case OPCODE_lload: \
3116 case OPCODE_fload: \
3117 case OPCODE_dload: \
3118 case OPCODE_aload: \
3119 { \
3120 /* duplicate code from LOAD macro */ \
3121 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3122 break; \
3123 } \
3124 case OPCODE_istore: \
3125 case OPCODE_lstore: \
3126 case OPCODE_fstore: \
3127 case OPCODE_dstore: \
3128 case OPCODE_astore: \
3129 { \
3130 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3131 break; \
3132 } \
3133 default: \
3134 error ("unrecogized wide sub-instruction"); \
3135 } \
3136 }
3137
3138 #define SPECIAL_THROW(IGNORED) \
3139 build_java_athrow (pop_value (throwable_type_node))
3140
3141 #define SPECIAL_BREAK NOT_IMPL1
3142 #define IMPL NOT_IMPL
3143
3144 #include "javaop.def"
3145 #undef JAVAOP
3146 default:
3147 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3148 }
3149 return PC;
3150 }
3151
3152 /* Return the opcode at PC in the code section pointed to by
3153 CODE_OFFSET. */
3154
3155 static unsigned char
3156 peek_opcode_at_pc (jcf, code_offset, pc)
3157 JCF *jcf;
3158 int code_offset, pc;
3159 {
3160 unsigned char opcode;
3161 long absolute_offset = (long)JCF_TELL (jcf);
3162
3163 JCF_SEEK (jcf, code_offset);
3164 opcode = jcf->read_ptr [pc];
3165 JCF_SEEK (jcf, absolute_offset);
3166 return opcode;
3167 }
3168
3169 /* Some bytecode compilers are emitting accurate LocalVariableTable
3170 attributes. Here's an example:
3171
3172 PC <t>store_<n>
3173 PC+1 ...
3174
3175 Attribute "LocalVariableTable"
3176 slot #<n>: ... (PC: PC+1 length: L)
3177
3178 This is accurate because the local in slot <n> really exists after
3179 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3180
3181 This procedure recognizes this situation and extends the live range
3182 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3183 length of the store instruction.)
3184
3185 This function is used by `give_name_to_locals' so that a local's
3186 DECL features a DECL_LOCAL_START_PC such that the first related
3187 store operation will use DECL as a destination, not a unrelated
3188 temporary created for the occasion.
3189
3190 This function uses a global (instruction_bits) `note_instructions' should
3191 have allocated and filled properly. */
3192
3193 int
3194 maybe_adjust_start_pc (jcf, code_offset, start_pc, slot)
3195 struct JCF *jcf;
3196 int code_offset, start_pc, slot;
3197 {
3198 int first, index, opcode;
3199 int pc, insn_pc;
3200 int wide_found = 0;
3201
3202 if (!start_pc)
3203 return start_pc;
3204
3205 first = index = -1;
3206
3207 /* Find last previous instruction and remember it */
3208 for (pc = start_pc-1; pc; pc--)
3209 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3210 break;
3211 insn_pc = pc;
3212
3213 /* Retrieve the instruction, handle `wide'. */
3214 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3215 if (opcode == OPCODE_wide)
3216 {
3217 wide_found = 1;
3218 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3219 }
3220
3221 switch (opcode)
3222 {
3223 case OPCODE_astore_0:
3224 case OPCODE_astore_1:
3225 case OPCODE_astore_2:
3226 case OPCODE_astore_3:
3227 first = OPCODE_astore_0;
3228 break;
3229
3230 case OPCODE_istore_0:
3231 case OPCODE_istore_1:
3232 case OPCODE_istore_2:
3233 case OPCODE_istore_3:
3234 first = OPCODE_istore_0;
3235 break;
3236
3237 case OPCODE_lstore_0:
3238 case OPCODE_lstore_1:
3239 case OPCODE_lstore_2:
3240 case OPCODE_lstore_3:
3241 first = OPCODE_lstore_0;
3242 break;
3243
3244 case OPCODE_fstore_0:
3245 case OPCODE_fstore_1:
3246 case OPCODE_fstore_2:
3247 case OPCODE_fstore_3:
3248 first = OPCODE_fstore_0;
3249 break;
3250
3251 case OPCODE_dstore_0:
3252 case OPCODE_dstore_1:
3253 case OPCODE_dstore_2:
3254 case OPCODE_dstore_3:
3255 first = OPCODE_dstore_0;
3256 break;
3257
3258 case OPCODE_astore:
3259 case OPCODE_istore:
3260 case OPCODE_lstore:
3261 case OPCODE_fstore:
3262 case OPCODE_dstore:
3263 index = peek_opcode_at_pc (jcf, code_offset, pc);
3264 if (wide_found)
3265 {
3266 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3267 index = (other << 8) + index;
3268 }
3269 break;
3270 }
3271
3272 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3273 means we have a <t>store. */
3274 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3275 start_pc = insn_pc;
3276
3277 return start_pc;
3278 }
3279
3280 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3281 order, as specified by Java Language Specification.
3282
3283 The problem is that while expand_expr will evaluate its sub-operands in
3284 left-to-right order, for variables it will just return an rtx (i.e.
3285 an lvalue) for the variable (rather than an rvalue). So it is possible
3286 that a later sub-operand will change the register, and when the
3287 actual operation is done, it will use the new value, when it should
3288 have used the original value.
3289
3290 We fix this by using save_expr. This forces the sub-operand to be
3291 copied into a fresh virtual register,
3292
3293 For method invocation, we modify the arguments so that a
3294 left-to-right order evaluation is performed. Saved expressions
3295 will, in CALL_EXPR order, be reused when the call will be expanded.
3296 */
3297
3298 tree
3299 force_evaluation_order (node)
3300 tree node;
3301 {
3302 if (flag_syntax_only)
3303 return node;
3304 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3305 {
3306 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3307 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3308 }
3309 else if (TREE_CODE (node) == CALL_EXPR
3310 || TREE_CODE (node) == NEW_CLASS_EXPR
3311 || (TREE_CODE (node) == COMPOUND_EXPR
3312 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3313 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3314 {
3315 tree arg, cmp;
3316
3317 if (!TREE_OPERAND (node, 1))
3318 return node;
3319
3320 arg = node;
3321
3322 /* Position arg properly, account for wrapped around ctors. */
3323 if (TREE_CODE (node) == COMPOUND_EXPR)
3324 arg = TREE_OPERAND (node, 0);
3325
3326 arg = TREE_OPERAND (arg, 1);
3327
3328 /* Not having a list of argument here is an error. */
3329 if (TREE_CODE (arg) != TREE_LIST)
3330 abort ();
3331
3332 /* This reverses the evaluation order. This is a desired effect. */
3333 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3334 {
3335 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3336 cmp = (cmp == NULL_TREE ? saved :
3337 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3338 TREE_VALUE (arg) = saved;
3339 }
3340
3341 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3342 TREE_SIDE_EFFECTS (cmp) = 1;
3343
3344 if (cmp)
3345 {
3346 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3347 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3348 TREE_SIDE_EFFECTS (cmp) = 1;
3349 node = cmp;
3350 }
3351 }
3352 return node;
3353 }
3354
3355 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
3356 method in order to emit initialization code for each test flag. */
3357
3358 static bool
3359 emit_init_test_initialization (entry, key)
3360 struct hash_entry *entry;
3361 hash_table_key key ATTRIBUTE_UNUSED;
3362 {
3363 struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
3364 tree klass = build_class_ref ((tree) entry->key);
3365 tree rhs;
3366
3367 /* If the DECL_INITIAL of the test flag is set to true, it
3368 means that the class is already initialized the time it
3369 is in use. */
3370 if (DECL_INITIAL (ite->init_test_decl) == boolean_true_node)
3371 rhs = boolean_true_node;
3372 /* Otherwise, we initialize the class init check variable by looking
3373 at the `state' field of the class to see if it is already
3374 initialized. This makes things a bit faster if the class is
3375 already initialized, which should be the common case. */
3376 else
3377 rhs = build (GE_EXPR, boolean_type_node,
3378 build (COMPONENT_REF, byte_type_node,
3379 build1 (INDIRECT_REF, class_type_node, klass),
3380 lookup_field (&class_type_node,
3381 get_identifier ("state"))),
3382 build_int_2 (JV_STATE_DONE, 0));
3383
3384 expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
3385 ite->init_test_decl, rhs));
3386 return true;
3387 }