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