00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "system.h"
00030 #include "tree.h"
00031 #include "real.h"
00032 #include "rtl.h"
00033 #include "flags.h"
00034 #include "expr.h"
00035 #include "java-tree.h"
00036 #include "javaop.h"
00037 #include "java-opcodes.h"
00038 #include "jcf.h"
00039 #include "java-except.h"
00040 #include "parse.h"
00041 #include "toplev.h"
00042 #include "except.h"
00043 #include "ggc.h"
00044
00045 static void flush_quick_stack PARAMS ((void));
00046 static void push_value PARAMS ((tree));
00047 static tree pop_value PARAMS ((tree));
00048 static void java_stack_swap PARAMS ((void));
00049 static void java_stack_dup PARAMS ((int, int));
00050 static void build_java_athrow PARAMS ((tree));
00051 static void build_java_jsr PARAMS ((int, int));
00052 static void build_java_ret PARAMS ((tree));
00053 static void expand_java_multianewarray PARAMS ((tree, int));
00054 static void expand_java_arraystore PARAMS ((tree));
00055 static void expand_java_arrayload PARAMS ((tree));
00056 static void expand_java_array_length PARAMS ((void));
00057 static tree build_java_monitor PARAMS ((tree, tree));
00058 static void expand_java_pushc PARAMS ((int, tree));
00059 static void expand_java_return PARAMS ((tree));
00060 static void expand_load_internal PARAMS ((int, tree, int));
00061 static void expand_java_NEW PARAMS ((tree));
00062 static void expand_java_INSTANCEOF PARAMS ((tree));
00063 static void expand_java_CHECKCAST PARAMS ((tree));
00064 static void expand_iinc PARAMS ((unsigned int, int, int));
00065 static void expand_java_binop PARAMS ((tree, enum tree_code));
00066 static void note_label PARAMS ((int, int));
00067 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
00068 static void expand_test PARAMS ((enum tree_code, tree, int));
00069 static void expand_cond PARAMS ((enum tree_code, tree, int));
00070 static void expand_java_goto PARAMS ((int));
00071 #if 0
00072 static void expand_java_call PARAMS ((int, int));
00073 static void expand_java_ret PARAMS ((tree));
00074 #endif
00075 static tree pop_arguments PARAMS ((tree));
00076 static void expand_invoke PARAMS ((int, int, int));
00077 static void expand_java_field_op PARAMS ((int, int, int));
00078 static void java_push_constant_from_pool PARAMS ((struct JCF *, int));
00079 static void java_stack_pop PARAMS ((int));
00080 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
00081 static tree build_java_check_indexed_type PARAMS ((tree, tree));
00082 static tree case_identity PARAMS ((tree, tree));
00083 static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int));
00084 static bool emit_init_test_initialization PARAMS ((struct hash_entry *,
00085 PTR ptr));
00086 static int get_offset_table_index PARAMS ((tree));
00087
00088 static tree operand_type[59];
00089 extern struct obstack permanent_obstack;
00090
00091 static tree methods_ident = NULL_TREE;
00092 static tree ncode_ident = NULL_TREE;
00093 tree dtable_ident = NULL_TREE;
00094
00095
00096
00097 int always_initialize_class_p;
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 static tree quick_stack = NULL_TREE;
00127
00128
00129 static tree tree_list_free_list = NULL_TREE;
00130
00131
00132
00133
00134 int stack_pointer;
00135
00136 const unsigned char *linenumber_table;
00137 int linenumber_count;
00138
00139 void
00140 init_expr_processing()
00141 {
00142 operand_type[21] = operand_type[54] = int_type_node;
00143 operand_type[22] = operand_type[55] = long_type_node;
00144 operand_type[23] = operand_type[56] = float_type_node;
00145 operand_type[24] = operand_type[57] = double_type_node;
00146 operand_type[25] = operand_type[58] = ptr_type_node;
00147 ggc_add_tree_root (operand_type, 59);
00148 ggc_add_tree_root (&methods_ident, 1);
00149 ggc_add_tree_root (&ncode_ident, 1);
00150 ggc_add_tree_root (&quick_stack, 1);
00151 ggc_add_tree_root (&tree_list_free_list, 1);
00152 }
00153
00154 tree
00155 truthvalue_conversion (expr)
00156 tree expr;
00157 {
00158
00159
00160
00161
00162
00163 switch (TREE_CODE (expr))
00164 {
00165 case EQ_EXPR:
00166 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
00167 case TRUTH_ANDIF_EXPR:
00168 case TRUTH_ORIF_EXPR:
00169 case TRUTH_AND_EXPR:
00170 case TRUTH_OR_EXPR:
00171 case ERROR_MARK:
00172 return expr;
00173
00174 case INTEGER_CST:
00175 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
00176
00177 case REAL_CST:
00178 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
00179
00180
00181 case NEGATE_EXPR:
00182 case ABS_EXPR:
00183 case FLOAT_EXPR:
00184 case FFS_EXPR:
00185
00186 return truthvalue_conversion (TREE_OPERAND (expr, 0));
00187
00188 case COND_EXPR:
00189
00190 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
00191 truthvalue_conversion (TREE_OPERAND (expr, 1)),
00192 truthvalue_conversion (TREE_OPERAND (expr, 2))));
00193
00194 case NOP_EXPR:
00195
00196 if (TYPE_PRECISION (TREE_TYPE (expr))
00197 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
00198 return truthvalue_conversion (TREE_OPERAND (expr, 0));
00199
00200
00201 default:
00202 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
00203 }
00204 }
00205
00206 #ifdef JAVA_USE_HANDLES
00207
00208
00209 tree
00210 unhand_expr (expr)
00211 tree expr;
00212 {
00213 tree field, handle_type;
00214 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
00215 handle_type = TREE_TYPE (expr);
00216 field = TYPE_FIELDS (handle_type);
00217 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
00218 return expr;
00219 }
00220 #endif
00221
00222
00223
00224
00225
00226
00227
00228
00229 static void
00230 flush_quick_stack ()
00231 {
00232 int stack_index = stack_pointer;
00233 register tree prev, cur, next;
00234
00235
00236 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
00237 {
00238 next = TREE_CHAIN (cur);
00239 TREE_CHAIN (cur) = prev;
00240 prev = cur;
00241 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
00242 }
00243 quick_stack = prev;
00244
00245 while (quick_stack != NULL_TREE)
00246 {
00247 tree decl;
00248 tree node = quick_stack, type;
00249 quick_stack = TREE_CHAIN (node);
00250 TREE_CHAIN (node) = tree_list_free_list;
00251 tree_list_free_list = node;
00252 node = TREE_VALUE (node);
00253 type = TREE_TYPE (node);
00254
00255 decl = find_stack_slot (stack_index, type);
00256 if (decl != node)
00257 expand_assignment (decl, node, 0, 0);
00258 stack_index += 1 + TYPE_IS_WIDE (type);
00259 }
00260 }
00261
00262
00263
00264
00265 int
00266 push_type_0 (type)
00267 tree type;
00268 {
00269 int n_words;
00270 type = promote_type (type);
00271 n_words = 1 + TYPE_IS_WIDE (type);
00272 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
00273 return 0;
00274 stack_type_map[stack_pointer++] = type;
00275 n_words--;
00276 while (--n_words >= 0)
00277 stack_type_map[stack_pointer++] = TYPE_SECOND;
00278 return 1;
00279 }
00280
00281 void
00282 push_type (type)
00283 tree type;
00284 {
00285 if (! push_type_0 (type))
00286 abort ();
00287 }
00288
00289 static void
00290 push_value (value)
00291 tree value;
00292 {
00293 tree type = TREE_TYPE (value);
00294 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
00295 {
00296 type = promote_type (type);
00297 value = convert (type, value);
00298 }
00299 push_type (type);
00300 if (tree_list_free_list == NULL_TREE)
00301 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
00302 else
00303 {
00304 tree node = tree_list_free_list;
00305 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
00306 TREE_VALUE (node) = value;
00307 TREE_CHAIN (node) = quick_stack;
00308 quick_stack = node;
00309 }
00310 }
00311
00312
00313
00314
00315
00316
00317 tree
00318 pop_type_0 (type, messagep)
00319 tree type;
00320 char **messagep;
00321 {
00322 int n_words;
00323 tree t;
00324 *messagep = NULL;
00325 if (TREE_CODE (type) == RECORD_TYPE)
00326 type = promote_type (type);
00327 n_words = 1 + TYPE_IS_WIDE (type);
00328 if (stack_pointer < n_words)
00329 {
00330 *messagep = xstrdup ("stack underflow");
00331 return type;
00332 }
00333 while (--n_words > 0)
00334 {
00335 if (stack_type_map[--stack_pointer] != void_type_node)
00336 {
00337 *messagep = xstrdup ("Invalid multi-word value on type stack");
00338 return type;
00339 }
00340 }
00341 t = stack_type_map[--stack_pointer];
00342 if (type == NULL_TREE || t == type)
00343 return t;
00344 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
00345 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
00346 return t;
00347 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
00348 {
00349 if (type == ptr_type_node || type == object_ptr_type_node)
00350 return t;
00351 else if (t == ptr_type_node)
00352 return type;
00353 else if (can_widen_reference_to (t, type))
00354 return t;
00355
00356
00357
00358 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
00359 return object_ptr_type_node;
00360 }
00361
00362
00363
00364 {
00365 char *temp = xstrdup (lang_printable_name (type, 0));
00366 *messagep = concat ("expected type '", temp,
00367 "' but stack contains '", lang_printable_name (t, 0),
00368 "'", NULL);
00369 free (temp);
00370 }
00371 return type;
00372 }
00373
00374
00375
00376
00377
00378 tree
00379 pop_type (type)
00380 tree type;
00381 {
00382 char *message = NULL;
00383 type = pop_type_0 (type, &message);
00384 if (message != NULL)
00385 {
00386 error ("%s", message);
00387 free (message);
00388 }
00389 return type;
00390 }
00391
00392
00393
00394
00395 int
00396 can_widen_reference_to (source_type, target_type)
00397 tree source_type, target_type;
00398 {
00399 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
00400 return 1;
00401
00402
00403 if (TREE_CODE (source_type) == POINTER_TYPE)
00404 source_type = TREE_TYPE (source_type);
00405 if (TREE_CODE (target_type) == POINTER_TYPE)
00406 target_type = TREE_TYPE (target_type);
00407
00408 if (source_type == target_type)
00409 return 1;
00410 else
00411 {
00412 source_type = HANDLE_TO_CLASS_TYPE (source_type);
00413 target_type = HANDLE_TO_CLASS_TYPE (target_type);
00414 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
00415 {
00416 HOST_WIDE_INT source_length, target_length;
00417 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
00418 return 0;
00419 target_length = java_array_type_length (target_type);
00420 if (target_length >= 0)
00421 {
00422 source_length = java_array_type_length (source_type);
00423 if (source_length != target_length)
00424 return 0;
00425 }
00426 source_type = TYPE_ARRAY_ELEMENT (source_type);
00427 target_type = TYPE_ARRAY_ELEMENT (target_type);
00428 if (source_type == target_type)
00429 return 1;
00430 if (TREE_CODE (source_type) != POINTER_TYPE
00431 || TREE_CODE (target_type) != POINTER_TYPE)
00432 return 0;
00433 return can_widen_reference_to (source_type, target_type);
00434 }
00435 else
00436 {
00437 int source_depth = class_depth (source_type);
00438 int target_depth = class_depth (target_type);
00439
00440
00441 if (source_depth < 0 || target_depth < 0)
00442 return 0;
00443
00444 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
00445 {
00446
00447
00448
00449 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
00450 int n = TREE_VEC_LENGTH (basetype_vec), i;
00451 for (i=0 ; i < n; i++)
00452 if (can_widen_reference_to
00453 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
00454 target_type))
00455 return 1;
00456 if (n == 0)
00457 return 0;
00458 }
00459
00460 for ( ; source_depth > target_depth; source_depth--)
00461 {
00462 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
00463 }
00464 return source_type == target_type;
00465 }
00466 }
00467 }
00468
00469 static tree
00470 pop_value (type)
00471 tree type;
00472 {
00473 type = pop_type (type);
00474 if (quick_stack)
00475 {
00476 tree node = quick_stack;
00477 quick_stack = TREE_CHAIN (quick_stack);
00478 TREE_CHAIN (node) = tree_list_free_list;
00479 tree_list_free_list = node;
00480 node = TREE_VALUE (node);
00481 return node;
00482 }
00483 else
00484 return find_stack_slot (stack_pointer, promote_type (type));
00485 }
00486
00487
00488
00489
00490 static void
00491 java_stack_pop (count)
00492 int count;
00493 {
00494 while (count > 0)
00495 {
00496 tree type, val;
00497
00498 if (stack_pointer == 0)
00499 abort ();
00500
00501 type = stack_type_map[stack_pointer - 1];
00502 if (type == TYPE_SECOND)
00503 {
00504 count--;
00505 if (stack_pointer == 1 || count <= 0)
00506 abort ();
00507
00508 type = stack_type_map[stack_pointer - 2];
00509 }
00510 val = pop_value (type);
00511 count--;
00512 }
00513 }
00514
00515
00516
00517 static void
00518 java_stack_swap ()
00519 {
00520 tree type1, type2;
00521 rtx temp;
00522 tree decl1, decl2;
00523
00524 if (stack_pointer < 2
00525 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
00526 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
00527 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
00528 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
00529
00530 abort ();
00531
00532 flush_quick_stack ();
00533 decl1 = find_stack_slot (stack_pointer - 1, type1);
00534 decl2 = find_stack_slot (stack_pointer - 2, type2);
00535 temp = copy_to_reg (DECL_RTL (decl1));
00536 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
00537 emit_move_insn (DECL_RTL (decl2), temp);
00538 stack_type_map[stack_pointer - 1] = type2;
00539 stack_type_map[stack_pointer - 2] = type1;
00540 }
00541
00542 static void
00543 java_stack_dup (size, offset)
00544 int size, offset;
00545 {
00546 int low_index = stack_pointer - size - offset;
00547 int dst_index;
00548 if (low_index < 0)
00549 error ("stack underflow - dup* operation");
00550
00551 flush_quick_stack ();
00552
00553 stack_pointer += size;
00554 dst_index = stack_pointer;
00555
00556 for (dst_index = stack_pointer; --dst_index >= low_index; )
00557 {
00558 tree type;
00559 int src_index = dst_index - size;
00560 if (src_index < low_index)
00561 src_index = dst_index + size + offset;
00562 type = stack_type_map [src_index];
00563 if (type == TYPE_SECOND)
00564 {
00565 if (src_index <= low_index)
00566
00567 abort ();
00568
00569 stack_type_map[dst_index] = type;
00570 src_index--; dst_index--;
00571 type = stack_type_map[src_index];
00572 if (! TYPE_IS_WIDE (type))
00573 abort ();
00574 }
00575 else if (TYPE_IS_WIDE (type))
00576 abort ();
00577
00578 if (src_index != dst_index)
00579 {
00580 tree src_decl = find_stack_slot (src_index, type);
00581 tree dst_decl = find_stack_slot (dst_index, type);
00582 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
00583 stack_type_map[dst_index] = type;
00584 }
00585 }
00586 }
00587
00588
00589
00590
00591 static void
00592 build_java_athrow (node)
00593 tree node;
00594 {
00595 tree call;
00596
00597 call = build (CALL_EXPR,
00598 void_type_node,
00599 build_address_of (throw_node),
00600 build_tree_list (NULL_TREE, node),
00601 NULL_TREE);
00602 TREE_SIDE_EFFECTS (call) = 1;
00603 expand_expr_stmt (call);
00604 java_stack_pop (stack_pointer);
00605 }
00606
00607
00608
00609 static void
00610 build_java_jsr (target_pc, return_pc)
00611 int target_pc, return_pc;
00612 {
00613 tree where = lookup_label (target_pc);
00614 tree ret = lookup_label (return_pc);
00615 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
00616 push_value (ret_label);
00617 flush_quick_stack ();
00618 emit_jump (label_rtx (where));
00619 expand_label (ret);
00620 if (instruction_bits [return_pc] & BCODE_VERIFIED)
00621 load_type_state (ret);
00622 }
00623
00624 static void
00625 build_java_ret (location)
00626 tree location;
00627 {
00628 expand_computed_goto (location);
00629 }
00630
00631
00632
00633 tree
00634 decode_newarray_type (atype)
00635 int atype;
00636 {
00637 switch (atype)
00638 {
00639 case 4: return boolean_type_node;
00640 case 5: return char_type_node;
00641 case 6: return float_type_node;
00642 case 7: return double_type_node;
00643 case 8: return byte_type_node;
00644 case 9: return short_type_node;
00645 case 10: return int_type_node;
00646 case 11: return long_type_node;
00647 default: return NULL_TREE;
00648 }
00649 }
00650
00651
00652
00653 int
00654 encode_newarray_type (type)
00655 tree type;
00656 {
00657 if (type == boolean_type_node)
00658 return 4;
00659 else if (type == char_type_node)
00660 return 5;
00661 else if (type == float_type_node)
00662 return 6;
00663 else if (type == double_type_node)
00664 return 7;
00665 else if (type == byte_type_node)
00666 return 8;
00667 else if (type == short_type_node)
00668 return 9;
00669 else if (type == int_type_node)
00670 return 10;
00671 else if (type == long_type_node)
00672 return 11;
00673 else
00674 abort ();
00675 }
00676
00677
00678
00679
00680 static tree
00681 build_java_throw_out_of_bounds_exception (index)
00682 tree index;
00683 {
00684 tree node = build (CALL_EXPR, int_type_node,
00685 build_address_of (soft_badarrayindex_node),
00686 build_tree_list (NULL_TREE, index), NULL_TREE);
00687 TREE_SIDE_EFFECTS (node) = 1;
00688 return (node);
00689 }
00690
00691
00692
00693
00694 tree
00695 build_java_array_length_access (node)
00696 tree node;
00697 {
00698 tree type = TREE_TYPE (node);
00699 tree array_type = TREE_TYPE (type);
00700 HOST_WIDE_INT length;
00701
00702 if (!is_array_type_p (type))
00703 abort ();
00704
00705 length = java_array_type_length (type);
00706 if (length >= 0)
00707 return build_int_2 (length, 0);
00708
00709 node = build (COMPONENT_REF, int_type_node,
00710 build_java_indirect_ref (array_type, node,
00711 flag_check_references),
00712 lookup_field (&array_type, get_identifier ("length")));
00713 IS_ARRAY_LENGTH_ACCESS (node) = 1;
00714 return node;
00715 }
00716
00717
00718
00719
00720
00721 tree
00722 java_check_reference (expr, check)
00723 tree expr;
00724 int check;
00725 {
00726 if (!flag_syntax_only && check)
00727 {
00728 tree cond;
00729 expr = save_expr (expr);
00730 cond = build (COND_EXPR, void_type_node,
00731 build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
00732 build (CALL_EXPR, void_type_node,
00733 build_address_of (soft_nullpointer_node),
00734 NULL_TREE, NULL_TREE),
00735 empty_stmt_node);
00736 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
00737 }
00738
00739 return expr;
00740 }
00741
00742
00743
00744 tree
00745 build_java_indirect_ref (type, expr, check)
00746 tree type;
00747 tree expr;
00748 int check;
00749 {
00750 return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
00751 }
00752
00753
00754
00755
00756
00757
00758 tree
00759 build_java_arrayaccess (array, type, index)
00760 tree array, type, index;
00761 {
00762 tree node, throw = NULL_TREE;
00763 tree data_field;
00764 tree ref;
00765 tree array_type = TREE_TYPE (TREE_TYPE (array));
00766
00767 if (flag_bounds_check)
00768 {
00769
00770
00771
00772
00773
00774 tree test;
00775 tree len = build_java_array_length_access (array);
00776 TREE_TYPE (len) = unsigned_int_type_node;
00777 test = fold (build (GE_EXPR, boolean_type_node,
00778 convert (unsigned_int_type_node, index),
00779 len));
00780 if (! integer_zerop (test))
00781 {
00782 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
00783 build_java_throw_out_of_bounds_exception (index));
00784
00785 TREE_SIDE_EFFECTS( throw ) = 1;
00786 }
00787 }
00788
00789
00790
00791 if (throw != NULL_TREE)
00792 index = build (COMPOUND_EXPR, int_type_node, throw, index);
00793
00794 data_field = lookup_field (&array_type, get_identifier ("data"));
00795
00796 ref = build (COMPONENT_REF, TREE_TYPE (data_field),
00797 build_java_indirect_ref (array_type, array,
00798 flag_check_references),
00799 data_field);
00800
00801 node = build (ARRAY_REF, type, ref, index);
00802 return node;
00803 }
00804
00805
00806
00807
00808
00809 tree
00810 build_java_arraystore_check (array, object)
00811 tree array;
00812 tree object;
00813 {
00814 tree check, element_type, source;
00815 tree array_type_p = TREE_TYPE (array);
00816 tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));
00817
00818 if (! is_array_type_p (array_type_p))
00819 abort ();
00820
00821
00822 element_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
00823
00824 if (TREE_CODE (element_type) != TYPE_DECL
00825 || TREE_CODE (object_type) != TYPE_DECL)
00826 abort ();
00827
00828 if (!flag_store_check)
00829 return build1 (NOP_EXPR, array_type_p, array);
00830
00831
00832
00833
00834
00835 if (element_type == object_type
00836 && (TYPE_ARRAY_P (TREE_TYPE (element_type))
00837 || CLASS_FINAL (element_type)))
00838 return build1 (NOP_EXPR, array_type_p, array);
00839
00840
00841 if (TREE_CODE (object) == SAVE_EXPR)
00842 source = TREE_OPERAND (object, 0);
00843 else
00844 source = object;
00845
00846
00847 if (TREE_CODE (source) == ARRAY_REF)
00848 {
00849 tree target;
00850 source = TREE_OPERAND (source, 0);
00851 source = TREE_OPERAND (source, 0);
00852 source = TREE_OPERAND (source, 0);
00853 if (TREE_CODE (source) == SAVE_EXPR)
00854 source = TREE_OPERAND (source, 0);
00855
00856 target = array;
00857 if (TREE_CODE (target) == SAVE_EXPR)
00858 target = TREE_OPERAND (target, 0);
00859
00860 if (source == target)
00861 return build1 (NOP_EXPR, array_type_p, array);
00862 }
00863
00864
00865 check = build (CALL_EXPR, void_type_node,
00866 build_address_of (soft_checkarraystore_node),
00867 tree_cons (NULL_TREE, array,
00868 build_tree_list (NULL_TREE, object)),
00869 NULL_TREE);
00870 TREE_SIDE_EFFECTS (check) = 1;
00871
00872 return check;
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882 static tree
00883 build_java_check_indexed_type (array_node, indexed_type)
00884 tree array_node;
00885 tree indexed_type;
00886 {
00887 tree elt_type;
00888
00889 if (!is_array_type_p (TREE_TYPE (array_node)))
00890 abort ();
00891
00892 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
00893
00894 if (indexed_type == ptr_type_node )
00895 return promote_type (elt_type);
00896
00897
00898 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
00899 return boolean_type_node;
00900
00901 if (indexed_type != elt_type )
00902 abort ();
00903 else
00904 return indexed_type;
00905 }
00906
00907
00908
00909
00910
00911 tree
00912 build_newarray (atype_value, length)
00913 int atype_value;
00914 tree length;
00915 {
00916 tree type_arg;
00917
00918 tree prim_type = decode_newarray_type (atype_value);
00919 tree type
00920 = build_java_array_type (prim_type,
00921 host_integerp (length, 0) == INTEGER_CST
00922 ? tree_low_cst (length, 0) : -1);
00923
00924
00925
00926
00927 if (flag_emit_class_files)
00928 type_arg = build_int_2 (atype_value, 0);
00929 else
00930 type_arg = build_class_ref (prim_type);
00931
00932 return build (CALL_EXPR, promote_type (type),
00933 build_address_of (soft_newarray_node),
00934 tree_cons (NULL_TREE,
00935 type_arg,
00936 build_tree_list (NULL_TREE, length)),
00937 NULL_TREE);
00938 }
00939
00940
00941
00942
00943 tree
00944 build_anewarray (class_type, length)
00945 tree class_type;
00946 tree length;
00947 {
00948 tree type
00949 = build_java_array_type (class_type,
00950 host_integerp (length, 0)
00951 ? tree_low_cst (length, 0) : -1);
00952
00953 return build (CALL_EXPR, promote_type (type),
00954 build_address_of (soft_anewarray_node),
00955 tree_cons (NULL_TREE, length,
00956 tree_cons (NULL_TREE, build_class_ref (class_type),
00957 build_tree_list (NULL_TREE,
00958 null_pointer_node))),
00959 NULL_TREE);
00960 }
00961
00962
00963
00964 tree
00965 build_new_array (type, length)
00966 tree type;
00967 tree length;
00968 {
00969 if (JPRIMITIVE_TYPE_P (type))
00970 return build_newarray (encode_newarray_type (type), length);
00971 else
00972 return build_anewarray (TREE_TYPE (type), length);
00973 }
00974
00975
00976
00977
00978
00979 static void
00980 expand_java_multianewarray (class_type, ndim)
00981 tree class_type;
00982 int ndim;
00983 {
00984 int i;
00985 tree args = build_tree_list( NULL_TREE, null_pointer_node );
00986
00987 for( i = 0; i < ndim; i++ )
00988 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
00989
00990 push_value (build (CALL_EXPR,
00991 promote_type (class_type),
00992 build_address_of (soft_multianewarray_node),
00993 tree_cons (NULL_TREE, build_class_ref (class_type),
00994 tree_cons (NULL_TREE,
00995 build_int_2 (ndim, 0), args )),
00996 NULL_TREE));
00997 }
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 static void
01010 expand_java_arraystore (rhs_type_node)
01011 tree rhs_type_node;
01012 {
01013 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
01014 && TYPE_PRECISION (rhs_type_node) <= 32) ?
01015 int_type_node : rhs_type_node);
01016 tree index = pop_value (int_type_node);
01017 tree array = pop_value (ptr_type_node);
01018
01019 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
01020
01021 flush_quick_stack ();
01022
01023 index = save_expr (index);
01024 array = save_expr (array);
01025
01026 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
01027 {
01028 tree check = build_java_arraystore_check (array, rhs_node);
01029 expand_expr_stmt (check);
01030 }
01031
01032 expand_assignment (build_java_arrayaccess (array,
01033 rhs_type_node,
01034 index),
01035 rhs_node, 0, 0);
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045 static void
01046 expand_java_arrayload (lhs_type_node )
01047 tree lhs_type_node;
01048 {
01049 tree load_node;
01050 tree index_node = pop_value (int_type_node);
01051 tree array_node = pop_value (ptr_type_node);
01052
01053 index_node = save_expr (index_node);
01054 array_node = save_expr (array_node);
01055 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
01056
01057 load_node = build_java_arrayaccess (array_node,
01058 lhs_type_node,
01059 index_node);
01060
01061 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
01062 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
01063 push_value (load_node);
01064 }
01065
01066
01067
01068
01069 static void
01070 expand_java_array_length ()
01071 {
01072 tree array = pop_value (ptr_type_node);
01073 tree length = build_java_array_length_access (array);
01074
01075 push_value (length);
01076 }
01077
01078
01079
01080
01081 static tree
01082 build_java_monitor (call, object)
01083 tree call;
01084 tree object;
01085 {
01086 return (build (CALL_EXPR,
01087 void_type_node,
01088 build_address_of (call),
01089 build_tree_list (NULL_TREE, object),
01090 NULL_TREE));
01091 }
01092
01093
01094
01095 static void
01096 expand_java_pushc (ival, type)
01097 int ival;
01098 tree type;
01099 {
01100 tree value;
01101 if (type == ptr_type_node && ival == 0)
01102 value = null_pointer_node;
01103 else if (type == int_type_node || type == long_type_node)
01104 {
01105 value = build_int_2 (ival, ival < 0 ? -1 : 0);
01106 TREE_TYPE (value) = type;
01107 }
01108 else if (type == float_type_node || type == double_type_node)
01109 {
01110 REAL_VALUE_TYPE x;
01111 #ifdef REAL_ARITHMETIC
01112 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
01113 #else
01114 x = ival;
01115 #endif
01116 value = build_real (type, x);
01117 }
01118 else
01119 abort ();
01120
01121 push_value (value);
01122 }
01123
01124 static void
01125 expand_java_return (type)
01126 tree type;
01127 {
01128 if (type == void_type_node)
01129 expand_null_return ();
01130 else
01131 {
01132 tree retval = pop_value (type);
01133 tree res = DECL_RESULT (current_function_decl);
01134 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
01135
01136
01137
01138
01139
01140 if (INT_TYPE_SIZE < 32
01141 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
01142 < GET_MODE_SIZE (TYPE_MODE (type))))
01143 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
01144
01145 TREE_SIDE_EFFECTS (retval) = 1;
01146 expand_return (retval);
01147 }
01148 }
01149
01150 static void
01151 expand_load_internal (index, type, pc)
01152 int index;
01153 tree type;
01154 int pc;
01155 {
01156 tree copy;
01157 tree var = find_local_variable (index, type, pc);
01158
01159
01160
01161
01162
01163
01164
01165 copy = build_decl (VAR_DECL, NULL_TREE, type);
01166 DECL_CONTEXT (copy) = current_function_decl;
01167 layout_decl (copy, 0);
01168 DECL_REGISTER (copy) = 1;
01169 expand_decl (copy);
01170 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
01171 DECL_INITIAL (copy) = var;
01172 expand_decl_init (copy);
01173 push_value (copy);
01174 }
01175
01176 tree
01177 build_address_of (value)
01178 tree value;
01179 {
01180 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
01181 }
01182
01183 bool class_has_finalize_method (type)
01184 tree type;
01185 {
01186 tree super = CLASSTYPE_SUPER (type);
01187
01188 if (super == NULL_TREE)
01189 return false;
01190
01191 else
01192 return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
01193 }
01194
01195 static void
01196 expand_java_NEW (type)
01197 tree type;
01198 {
01199 tree alloc_node;
01200
01201 alloc_node = (class_has_finalize_method (type) ? alloc_object_node
01202 : alloc_no_finalizer_node);
01203 if (! CLASS_LOADED_P (type))
01204 load_class (type, 1);
01205 safe_layout_class (type);
01206 push_value (build (CALL_EXPR, promote_type (type),
01207 build_address_of (alloc_node),
01208 tree_cons (NULL_TREE, build_class_ref (type),
01209 build_tree_list (NULL_TREE,
01210 size_in_bytes (type))),
01211 NULL_TREE));
01212 }
01213
01214
01215
01216
01217 tree
01218 build_get_class (value)
01219 tree value;
01220 {
01221 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
01222 tree vtable_field = lookup_field (&object_type_node,
01223 get_identifier ("vtable"));
01224 return build (COMPONENT_REF, class_ptr_type,
01225 build1 (INDIRECT_REF, dtable_type,
01226 build (COMPONENT_REF, dtable_ptr_type,
01227 build_java_indirect_ref (object_type_node, value,
01228 flag_check_references),
01229 vtable_field)),
01230 class_field);
01231 }
01232
01233
01234
01235
01236
01237 tree
01238 build_instanceof (value, type)
01239 tree value, type;
01240 {
01241 tree expr;
01242 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
01243 tree valtype = TREE_TYPE (TREE_TYPE (value));
01244 tree valclass = TYPE_NAME (valtype);
01245 tree klass;
01246
01247
01248
01249 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
01250 {
01251 load_class (type, 1);
01252 safe_layout_class (type);
01253 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
01254 return error_mark_node;
01255 }
01256 klass = TYPE_NAME (type);
01257
01258 if (type == object_type_node || inherits_from_p (valtype, type))
01259 {
01260
01261
01262
01263 expr = build (COND_EXPR, itype,
01264 value,
01265 boolean_true_node, boolean_false_node);
01266 }
01267 else if (! TYPE_ARRAY_P (type)
01268 && ! TYPE_ARRAY_P (valtype)
01269 && DECL_P (klass) && DECL_P (valclass)
01270 && ! CLASS_INTERFACE (valclass)
01271 && ! CLASS_INTERFACE (klass)
01272 && ! inherits_from_p (type, valtype)
01273 && (CLASS_FINAL (klass)
01274 || ! inherits_from_p (valtype, type)))
01275 {
01276
01277
01278 expr = boolean_false_node;
01279 }
01280 else if (DECL_P (klass) && CLASS_FINAL (klass))
01281 {
01282 tree save = save_expr (value);
01283 expr = build (COND_EXPR, itype,
01284 save,
01285 build (EQ_EXPR, itype,
01286 build_get_class (save),
01287 build_class_ref (type)),
01288 boolean_false_node);
01289 }
01290 else
01291 {
01292 expr = build (CALL_EXPR, itype,
01293 build_address_of (soft_instanceof_node),
01294 tree_cons (NULL_TREE, value,
01295 build_tree_list (NULL_TREE,
01296 build_class_ref (type))),
01297 NULL_TREE);
01298 }
01299 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
01300 return expr;
01301 }
01302
01303 static void
01304 expand_java_INSTANCEOF (type)
01305 tree type;
01306 {
01307 tree value = pop_value (object_ptr_type_node);
01308 value = build_instanceof (value, type);
01309 push_value (value);
01310 }
01311
01312 static void
01313 expand_java_CHECKCAST (type)
01314 tree type;
01315 {
01316 tree value = pop_value (ptr_type_node);
01317 value = build (CALL_EXPR, promote_type (type),
01318 build_address_of (soft_checkcast_node),
01319 tree_cons (NULL_TREE, build_class_ref (type),
01320 build_tree_list (NULL_TREE, value)),
01321 NULL_TREE);
01322 push_value (value);
01323 }
01324
01325 static void
01326 expand_iinc (local_var_index, ival, pc)
01327 unsigned int local_var_index;
01328 int ival;
01329 int pc;
01330 {
01331 tree local_var, res;
01332 tree constant_value;
01333
01334 flush_quick_stack ();
01335 local_var = find_local_variable (local_var_index, int_type_node, pc);
01336 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
01337 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
01338 expand_assignment (local_var, res, 0, 0);
01339 }
01340
01341
01342 tree
01343 build_java_soft_divmod (op, type, op1, op2)
01344 enum tree_code op;
01345 tree type, op1, op2;
01346 {
01347 tree call = NULL;
01348 tree arg1 = convert (type, op1);
01349 tree arg2 = convert (type, op2);
01350
01351 if (type == int_type_node)
01352 {
01353 switch (op)
01354 {
01355 case TRUNC_DIV_EXPR:
01356 call = soft_idiv_node;
01357 break;
01358 case TRUNC_MOD_EXPR:
01359 call = soft_irem_node;
01360 break;
01361 default:
01362 break;
01363 }
01364 }
01365 else if (type == long_type_node)
01366 {
01367 switch (op)
01368 {
01369 case TRUNC_DIV_EXPR:
01370 call = soft_ldiv_node;
01371 break;
01372 case TRUNC_MOD_EXPR:
01373 call = soft_lrem_node;
01374 break;
01375 default:
01376 break;
01377 }
01378 }
01379
01380 if (! call)
01381 abort ();
01382
01383 call = build (CALL_EXPR, type,
01384 build_address_of (call),
01385 tree_cons (NULL_TREE, arg1,
01386 build_tree_list (NULL_TREE, arg2)),
01387 NULL_TREE);
01388
01389 return call;
01390 }
01391
01392 tree
01393 build_java_binop (op, type, arg1, arg2)
01394 enum tree_code op;
01395 tree type, arg1, arg2;
01396 {
01397 tree mask;
01398 switch (op)
01399 {
01400 case URSHIFT_EXPR:
01401 {
01402 tree u_type = unsigned_type (type);
01403 arg1 = convert (u_type, arg1);
01404 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
01405 return convert (type, arg1);
01406 }
01407 case LSHIFT_EXPR:
01408 case RSHIFT_EXPR:
01409 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
01410 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
01411 break;
01412
01413 case COMPARE_L_EXPR:
01414 case COMPARE_G_EXPR:
01415 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
01416 {
01417 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
01418 boolean_type_node, arg1, arg2));
01419 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
01420 tree second_compare = fold (build (COND_EXPR, int_type_node,
01421 ifexp2, integer_zero_node,
01422 op == COMPARE_L_EXPR
01423 ? integer_minus_one_node
01424 : integer_one_node));
01425 return fold (build (COND_EXPR, int_type_node, ifexp1,
01426 op == COMPARE_L_EXPR ? integer_one_node
01427 : integer_minus_one_node,
01428 second_compare));
01429 }
01430 case COMPARE_EXPR:
01431 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
01432 {
01433 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
01434 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
01435 tree second_compare = fold ( build (COND_EXPR, int_type_node,
01436 ifexp2, integer_one_node,
01437 integer_zero_node));
01438 return fold (build (COND_EXPR, int_type_node,
01439 ifexp1, integer_minus_one_node, second_compare));
01440 }
01441 case TRUNC_DIV_EXPR:
01442 case TRUNC_MOD_EXPR:
01443 if (TREE_CODE (type) == REAL_TYPE
01444 && op == TRUNC_MOD_EXPR)
01445 {
01446 tree call;
01447 if (type != double_type_node)
01448 {
01449 arg1 = convert (double_type_node, arg1);
01450 arg2 = convert (double_type_node, arg2);
01451 }
01452 call = build (CALL_EXPR, double_type_node,
01453 build_address_of (soft_fmod_node),
01454 tree_cons (NULL_TREE, arg1,
01455 build_tree_list (NULL_TREE, arg2)),
01456 NULL_TREE);
01457 if (type != double_type_node)
01458 call = convert (type, call);
01459 return call;
01460 }
01461
01462 if (TREE_CODE (type) == INTEGER_TYPE
01463 && flag_use_divide_subroutine
01464 && ! flag_syntax_only)
01465 return build_java_soft_divmod (op, type, arg1, arg2);
01466
01467 break;
01468 default: ;
01469 }
01470 return fold (build (op, type, arg1, arg2));
01471 }
01472
01473 static void
01474 expand_java_binop (type, op)
01475 tree type; enum tree_code op;
01476 {
01477 tree larg, rarg;
01478 tree ltype = type;
01479 tree rtype = type;
01480 switch (op)
01481 {
01482 case LSHIFT_EXPR:
01483 case RSHIFT_EXPR:
01484 case URSHIFT_EXPR:
01485 rtype = int_type_node;
01486 rarg = pop_value (rtype);
01487 break;
01488 default:
01489 rarg = pop_value (rtype);
01490 }
01491 larg = pop_value (ltype);
01492 push_value (build_java_binop (op, type, larg, rarg));
01493 }
01494
01495
01496
01497
01498
01499
01500
01501
01502 tree
01503 lookup_field (typep, name)
01504 tree *typep;
01505 tree name;
01506 {
01507 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
01508 {
01509 load_class (*typep, 1);
01510 safe_layout_class (*typep);
01511 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
01512 return error_mark_node;
01513 }
01514 do
01515 {
01516 tree field, basetype_vec;
01517 tree save_field;
01518 int n, i;
01519
01520 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
01521 if (DECL_NAME (field) == name)
01522 return field;
01523
01524
01525 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
01526 n = TREE_VEC_LENGTH (basetype_vec);
01527 save_field = NULL_TREE;
01528 for (i = 0; i < n; i++)
01529 {
01530 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
01531 if ((field = lookup_field (&t, name)))
01532 {
01533 if (save_field == field)
01534 continue;
01535 if (save_field == NULL_TREE)
01536 save_field = field;
01537 else
01538 {
01539 tree i1 = DECL_CONTEXT (save_field);
01540 tree i2 = DECL_CONTEXT (field);
01541 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
01542 IDENTIFIER_POINTER (name),
01543 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
01544 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
01545 return error_mark_node;
01546 }
01547 }
01548 }
01549
01550 if (save_field != NULL_TREE)
01551 return save_field;
01552
01553 *typep = CLASSTYPE_SUPER (*typep);
01554 } while (*typep);
01555 return NULL_TREE;
01556 }
01557
01558
01559
01560
01561
01562 tree
01563 build_field_ref (self_value, self_class, name)
01564 tree self_value, self_class, name;
01565 {
01566 tree base_class = self_class;
01567 tree field_decl = lookup_field (&base_class, name);
01568 if (field_decl == NULL_TREE)
01569 {
01570 error ("field `%s' not found", IDENTIFIER_POINTER (name));
01571 return error_mark_node;
01572 }
01573 if (self_value == NULL_TREE)
01574 {
01575 return build_static_field_ref (field_decl);
01576 }
01577 else
01578 {
01579 int check = (flag_check_references
01580 && ! (DECL_P (self_value)
01581 && DECL_NAME (self_value) == this_identifier_node));
01582
01583 tree base_handle_type = promote_type (base_class);
01584 if (base_handle_type != TREE_TYPE (self_value))
01585 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
01586 #ifdef JAVA_USE_HANDLES
01587 self_value = unhand_expr (self_value);
01588 #endif
01589 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
01590 self_value, check);
01591 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
01592 self_value, field_decl));
01593 }
01594 }
01595
01596 tree
01597 lookup_label (pc)
01598 int pc;
01599 {
01600 tree name;
01601 char buf[32];
01602 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
01603 name = get_identifier (buf);
01604 if (IDENTIFIER_LOCAL_VALUE (name))
01605 return IDENTIFIER_LOCAL_VALUE (name);
01606 else
01607 {
01608
01609 tree decl = create_label_decl (name);
01610 LABEL_PC (decl) = pc;
01611 label_rtx (decl);
01612 return pushdecl (decl);
01613 }
01614 }
01615
01616
01617
01618
01619 tree
01620 generate_name ()
01621 {
01622 static int l_number = 0;
01623 char buff [32];
01624 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
01625 l_number++;
01626 return get_identifier (buff);
01627 }
01628
01629 tree
01630 create_label_decl (name)
01631 tree name;
01632 {
01633 tree decl;
01634 decl = build_decl (LABEL_DECL, name,
01635 TREE_TYPE (return_address_type_node));
01636 DECL_CONTEXT (decl) = current_function_decl;
01637 DECL_IGNORED_P (decl) = 1;
01638 return decl;
01639 }
01640
01641
01642 char *instruction_bits;
01643
01644 static void
01645 note_label (current_pc, target_pc)
01646 int current_pc ATTRIBUTE_UNUSED, target_pc;
01647 {
01648 lookup_label (target_pc);
01649 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
01650 }
01651
01652
01653
01654
01655 static void
01656 expand_compare (condition, value1, value2, target_pc)
01657 enum tree_code condition;
01658 tree value1, value2;
01659 int target_pc;
01660 {
01661 tree target = lookup_label (target_pc);
01662 tree cond = fold (build (condition, boolean_type_node, value1, value2));
01663 expand_start_cond (truthvalue_conversion (cond), 0);
01664 expand_goto (target);
01665 expand_end_cond ();
01666 }
01667
01668
01669
01670 static void
01671 expand_test (condition, type, target_pc)
01672 enum tree_code condition;
01673 tree type;
01674 int target_pc;
01675 {
01676 tree value1, value2;
01677 flush_quick_stack ();
01678 value1 = pop_value (type);
01679 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
01680 expand_compare (condition, value1, value2, target_pc);
01681 }
01682
01683
01684
01685 static void
01686 expand_cond (condition, type, target_pc)
01687 enum tree_code condition;
01688 tree type;
01689 int target_pc;
01690 {
01691 tree value1, value2;
01692 flush_quick_stack ();
01693
01694 value2 = pop_value (type);
01695 value1 = pop_value (type);
01696
01697 expand_compare (condition, value1, value2, target_pc);
01698 }
01699
01700 static void
01701 expand_java_goto (target_pc)
01702 int target_pc;
01703 {
01704 tree target_label = lookup_label (target_pc);
01705 flush_quick_stack ();
01706 expand_goto (target_label);
01707 }
01708
01709 #if 0
01710 static void
01711 expand_java_call (target_pc, return_address)
01712 int target_pc, return_address;
01713 {
01714 tree target_label = lookup_label (target_pc);
01715 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
01716 push_value (value);
01717 flush_quick_stack ();
01718 expand_goto (target_label);
01719 }
01720
01721 static void
01722 expand_java_ret (return_address)
01723 tree return_address ATTRIBUTE_UNUSED;
01724 {
01725 warning ("ret instruction not implemented");
01726 #if 0
01727 tree target_label = lookup_label (target_pc);
01728 flush_quick_stack ();
01729 expand_goto (target_label);
01730 #endif
01731 }
01732 #endif
01733
01734 static tree
01735 pop_arguments (arg_types)
01736 tree arg_types;
01737 {
01738 if (arg_types == end_params_node)
01739 return NULL_TREE;
01740 if (TREE_CODE (arg_types) == TREE_LIST)
01741 {
01742 tree tail = pop_arguments (TREE_CHAIN (arg_types));
01743 tree type = TREE_VALUE (arg_types);
01744 tree arg = pop_value (type);
01745 if (PROMOTE_PROTOTYPES
01746 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
01747 && INTEGRAL_TYPE_P (type))
01748 arg = convert (integer_type_node, arg);
01749 return tree_cons (NULL_TREE, arg, tail);
01750 }
01751 abort ();
01752 }
01753
01754
01755
01756
01757
01758 tree
01759 build_class_init (clas, expr)
01760 tree clas, expr;
01761 {
01762 tree init;
01763 struct init_test_hash_entry *ite;
01764 if (inherits_from_p (current_class, clas))
01765 return expr;
01766
01767 if (always_initialize_class_p)
01768 {
01769 init = build (CALL_EXPR, void_type_node,
01770 build_address_of (soft_initclass_node),
01771 build_tree_list (NULL_TREE, build_class_ref (clas)),
01772 NULL_TREE);
01773 TREE_SIDE_EFFECTS (init) = 1;
01774 }
01775 else
01776 {
01777 ite = (struct init_test_hash_entry *)
01778 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
01779 (const hash_table_key) clas,
01780 TRUE, NULL);
01781
01782 if (ite->init_test_decl == 0)
01783 {
01784
01785
01786 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
01787 boolean_type_node);
01788 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (ite->init_test_decl);
01789 LOCAL_CLASS_INITIALIZATION_FLAG (ite->init_test_decl) = 1;
01790 DECL_CONTEXT (ite->init_test_decl) = current_function_decl;
01791 DECL_FUNCTION_INIT_TEST_CLASS (ite->init_test_decl) = clas;
01792
01793
01794 if (!STATIC_CLASS_INIT_OPT_P ())
01795 DECL_BIT_INDEX(ite->init_test_decl) = -1;
01796 }
01797
01798 init = build (CALL_EXPR, void_type_node,
01799 build_address_of (soft_initclass_node),
01800 build_tree_list (NULL_TREE, build_class_ref (clas)),
01801 NULL_TREE);
01802 TREE_SIDE_EFFECTS (init) = 1;
01803 init = build (COND_EXPR, void_type_node,
01804 build (EQ_EXPR, boolean_type_node,
01805 ite->init_test_decl, boolean_false_node),
01806 init, integer_zero_node);
01807 TREE_SIDE_EFFECTS (init) = 1;
01808 init = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
01809 build (MODIFY_EXPR, boolean_type_node,
01810 ite->init_test_decl, boolean_true_node));
01811 TREE_SIDE_EFFECTS (init) = 1;
01812 }
01813
01814 if (expr != NULL_TREE)
01815 {
01816 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
01817 TREE_SIDE_EFFECTS (expr) = 1;
01818 return expr;
01819 }
01820 return init;
01821 }
01822
01823 tree
01824 build_known_method_ref (method, method_type, self_type,
01825 method_signature, arg_list)
01826 tree method, method_type ATTRIBUTE_UNUSED, self_type,
01827 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
01828 {
01829 tree func;
01830 if (is_compiled_class (self_type))
01831 {
01832 make_decl_rtl (method, NULL);
01833 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
01834 }
01835 else
01836 {
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846 int method_index = 0;
01847 tree meth;
01848 tree ref = build_class_ref (self_type);
01849 ref = build1 (INDIRECT_REF, class_type_node, ref);
01850 if (ncode_ident == NULL_TREE)
01851 ncode_ident = get_identifier ("ncode");
01852 if (methods_ident == NULL_TREE)
01853 methods_ident = get_identifier ("methods");
01854 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
01855 lookup_field (&class_type_node, methods_ident));
01856 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
01857 ; meth = TREE_CHAIN (meth))
01858 {
01859 if (method == meth)
01860 break;
01861 if (meth == NULL_TREE)
01862 fatal_error ("method '%s' not found in class",
01863 IDENTIFIER_POINTER (DECL_NAME (method)));
01864 method_index++;
01865 }
01866 method_index *= int_size_in_bytes (method_type_node);
01867 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
01868 ref, build_int_2 (method_index, 0)));
01869 ref = build1 (INDIRECT_REF, method_type_node, ref);
01870 func = build (COMPONENT_REF, nativecode_ptr_type_node,
01871 ref,
01872 lookup_field (&method_type_node, ncode_ident));
01873 }
01874 return func;
01875 }
01876
01877 tree
01878 invoke_build_dtable (is_invoke_interface, arg_list)
01879 int is_invoke_interface;
01880 tree arg_list;
01881 {
01882 tree dtable, objectref;
01883
01884 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
01885
01886
01887
01888
01889 objectref = (is_invoke_interface
01890 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
01891 object_type_node : TREE_VALUE (arg_list));
01892
01893 if (dtable_ident == NULL_TREE)
01894 dtable_ident = get_identifier ("vtable");
01895 dtable = build_java_indirect_ref (object_type_node, objectref,
01896 flag_check_references);
01897 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
01898 lookup_field (&object_type_node, dtable_ident));
01899
01900 return dtable;
01901 }
01902
01903
01904
01905
01906
01907 int
01908 get_offset_table_index (method)
01909 tree method;
01910 {
01911 int i = 1;
01912 tree method_list;
01913
01914 if (otable_methods == NULL_TREE)
01915 {
01916 otable_methods = build_tree_list (method, method);
01917 return 1;
01918 }
01919
01920 method_list = otable_methods;
01921
01922 while (1)
01923 {
01924 if (TREE_VALUE (method_list) == method)
01925 return i;
01926 i++;
01927 if (TREE_CHAIN (method_list) == NULL_TREE)
01928 break;
01929 else
01930 method_list = TREE_CHAIN (method_list);
01931 }
01932
01933 TREE_CHAIN (method_list) = build_tree_list (method, method);
01934 return i;
01935 }
01936
01937 tree
01938 build_invokevirtual (dtable, method)
01939 tree dtable, method;
01940 {
01941 tree func;
01942 tree nativecode_ptr_ptr_type_node
01943 = build_pointer_type (nativecode_ptr_type_node);
01944 tree method_index;
01945 tree otable_index;
01946
01947 if (flag_indirect_dispatch)
01948 {
01949 otable_index = build_int_2 (get_offset_table_index (method), 0);
01950 method_index = build (ARRAY_REF, integer_type_node, otable_decl,
01951 otable_index);
01952 }
01953 else
01954 {
01955 method_index = convert (sizetype, DECL_VINDEX (method));
01956
01957 if (TARGET_VTABLE_USES_DESCRIPTORS)
01958
01959 method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
01960 else
01961
01962 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
01963
01964 method_index = size_binop (MULT_EXPR, method_index,
01965 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
01966
01967 if (TARGET_VTABLE_USES_DESCRIPTORS)
01968 method_index = size_binop (MULT_EXPR, method_index,
01969 size_int (TARGET_VTABLE_USES_DESCRIPTORS));
01970 }
01971
01972 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
01973 convert (nativecode_ptr_ptr_type_node, method_index)));
01974
01975 if (TARGET_VTABLE_USES_DESCRIPTORS)
01976 func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
01977 else
01978 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
01979
01980 return func;
01981 }
01982
01983 tree
01984 build_invokeinterface (dtable, method)
01985 tree dtable, method;
01986 {
01987 static tree class_ident = NULL_TREE;
01988 tree lookup_arg;
01989 tree interface;
01990 tree idx;
01991 tree meth;
01992 tree otable_index;
01993 int i;
01994
01995
01996
01997
01998
01999 if (class_ident == NULL_TREE)
02000 {
02001 class_ident = get_identifier ("class");
02002 ggc_add_tree_root (&class_ident, 1);
02003 }
02004
02005 dtable = build_java_indirect_ref (dtable_type, dtable, flag_check_references);
02006 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
02007 lookup_field (&dtable_type, class_ident));
02008
02009 interface = DECL_CONTEXT (method);
02010 layout_class_methods (interface);
02011
02012 if (flag_indirect_dispatch)
02013 {
02014 otable_index = build_int_2 (get_offset_table_index (method), 0);
02015 idx = build (ARRAY_REF, integer_type_node, otable_decl, otable_index);
02016 }
02017 else
02018 {
02019 i = 1;
02020 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
02021 {
02022 if (meth == method)
02023 {
02024 idx = build_int_2 (i, 0);
02025 break;
02026 }
02027 if (meth == NULL_TREE)
02028 abort ();
02029 }
02030 }
02031
02032 lookup_arg = tree_cons (NULL_TREE, dtable,
02033 tree_cons (NULL_TREE, build_class_ref (interface),
02034 build_tree_list (NULL_TREE, idx)));
02035
02036 return build (CALL_EXPR, ptr_type_node,
02037 build_address_of (soft_lookupinterfacemethod_node),
02038 lookup_arg, NULL_TREE);
02039 }
02040
02041
02042
02043
02044
02045
02046 static void
02047 expand_invoke (opcode, method_ref_index, nargs)
02048 int opcode;
02049 int method_ref_index;
02050 int nargs ATTRIBUTE_UNUSED;
02051 {
02052 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
02053 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
02054 tree self_type = get_class_constant
02055 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
02056 const char *const self_name
02057 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
02058 tree call, func, method, arg_list, method_type;
02059 tree check = NULL_TREE;
02060
02061 if (! CLASS_LOADED_P (self_type))
02062 {
02063 load_class (self_type, 1);
02064 safe_layout_class (self_type);
02065 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
02066 fatal_error ("failed to find class '%s'", self_name);
02067 }
02068 layout_class_methods (self_type);
02069
02070 if (ID_INIT_P (method_name))
02071 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
02072 method_signature);
02073 else
02074 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
02075 method_name, method_signature);
02076 if (method == NULL_TREE)
02077 {
02078 error ("class '%s' has no method named '%s' matching signature '%s'",
02079 self_name,
02080 IDENTIFIER_POINTER (method_name),
02081 IDENTIFIER_POINTER (method_signature));
02082 }
02083
02084 else if (opcode == OPCODE_invokestatic)
02085 {
02086 if (!METHOD_STATIC (method))
02087 {
02088 error ("invokestatic on non static method");
02089 method = NULL_TREE;
02090 }
02091 else if (METHOD_ABSTRACT (method))
02092 {
02093 error ("invokestatic on abstract method");
02094 method = NULL_TREE;
02095 }
02096 }
02097 else
02098 {
02099 if (METHOD_STATIC (method))
02100 {
02101 error ("invoke[non-static] on static method");
02102 method = NULL_TREE;
02103 }
02104 }
02105
02106 if (method == NULL_TREE)
02107 {
02108 method_type = get_type_from_signature (method_signature);
02109 pop_arguments (TYPE_ARG_TYPES (method_type));
02110 if (opcode != OPCODE_invokestatic)
02111 pop_type (self_type);
02112 method_type = promote_type (TREE_TYPE (method_type));
02113 push_value (convert (method_type, integer_zero_node));
02114 return;
02115 }
02116
02117 method_type = TREE_TYPE (method);
02118 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
02119 flush_quick_stack ();
02120
02121 func = NULL_TREE;
02122 if (opcode == OPCODE_invokestatic)
02123 func = build_known_method_ref (method, method_type, self_type,
02124 method_signature, arg_list);
02125 else if (opcode == OPCODE_invokespecial
02126 || (opcode == OPCODE_invokevirtual
02127 && (METHOD_PRIVATE (method)
02128 || METHOD_FINAL (method)
02129 || CLASS_FINAL (TYPE_NAME (self_type)))))
02130 {
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140 tree save_arg = save_expr (TREE_VALUE (arg_list));
02141 TREE_VALUE (arg_list) = save_arg;
02142 check = java_check_reference (save_arg, ! DECL_INIT_P (method));
02143 func = build_known_method_ref (method, method_type, self_type,
02144 method_signature, arg_list);
02145 }
02146 else
02147 {
02148 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
02149 arg_list);
02150 if (opcode == OPCODE_invokevirtual)
02151 func = build_invokevirtual (dtable, method);
02152 else
02153 func = build_invokeinterface (dtable, method);
02154 }
02155 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
02156
02157 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
02158 TREE_SIDE_EFFECTS (call) = 1;
02159 call = check_for_builtin (method, call);
02160
02161 if (check != NULL_TREE)
02162 {
02163 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
02164 TREE_SIDE_EFFECTS (call) = 1;
02165 }
02166
02167 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
02168 expand_expr_stmt (call);
02169 else
02170 {
02171 push_value (call);
02172 flush_quick_stack ();
02173 }
02174 }
02175
02176
02177
02178
02179 tree
02180 build_jni_stub (method)
02181 tree method;
02182 {
02183 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
02184 tree jni_func_type, tem;
02185 tree env_var, res_var = NULL_TREE, block;
02186 tree method_args, res_type;
02187 tree meth_var;
02188
02189 tree klass = DECL_CONTEXT (method);
02190 int from_class = ! CLASS_FROM_SOURCE_P (klass);
02191 klass = build_class_ref (klass);
02192
02193 if (! METHOD_NATIVE (method) || ! flag_jni)
02194 abort ();
02195
02196 DECL_ARTIFICIAL (method) = 1;
02197 DECL_EXTERNAL (method) = 0;
02198
02199 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
02200 DECL_CONTEXT (env_var) = method;
02201
02202 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
02203 {
02204 res_var = build_decl (VAR_DECL, get_identifier ("res"),
02205 TREE_TYPE (TREE_TYPE (method)));
02206 DECL_CONTEXT (res_var) = method;
02207 TREE_CHAIN (env_var) = res_var;
02208 }
02209
02210 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
02211 TREE_STATIC (meth_var) = 1;
02212 TREE_PUBLIC (meth_var) = 0;
02213 DECL_EXTERNAL (meth_var) = 0;
02214 DECL_CONTEXT (meth_var) = method;
02215 DECL_ARTIFICIAL (meth_var) = 1;
02216 DECL_INITIAL (meth_var) = null_pointer_node;
02217 TREE_USED (meth_var) = 1;
02218 chainon (env_var, meth_var);
02219 layout_decl (meth_var, 0);
02220 make_decl_rtl (meth_var, NULL);
02221 rest_of_decl_compilation (meth_var, NULL, 0, 0);
02222
02223
02224
02225 if (from_class)
02226 method_args = DECL_ARGUMENTS (method);
02227 else
02228 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
02229 block = build_block (env_var, NULL_TREE, NULL_TREE,
02230 method_args, NULL_TREE);
02231 TREE_SIDE_EFFECTS (block) = 1;
02232
02233
02234 if (from_class)
02235 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
02236
02237
02238 body = build (MODIFY_EXPR, ptr_type_node, env_var,
02239 build (CALL_EXPR, ptr_type_node,
02240 build_address_of (soft_getjnienvnewframe_node),
02241 build_tree_list (NULL_TREE, klass),
02242 NULL_TREE));
02243 CAN_COMPLETE_NORMALLY (body) = 1;
02244
02245
02246
02247
02248 args = NULL_TREE;
02249 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
02250 args = tree_cons (NULL_TREE, tem, args);
02251 args = nreverse (args);
02252 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
02253
02254
02255
02256
02257 if (METHOD_STATIC (method))
02258 {
02259 args = tree_cons (NULL_TREE, klass, args);
02260 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
02261 }
02262
02263
02264 args = tree_cons (NULL_TREE, env_var, args);
02265 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
02266
02267
02268
02269
02270 method_sig = build_java_signature (TREE_TYPE (method));
02271 lookup_arg =
02272 build_tree_list (NULL_TREE,
02273 build_utf8_ref (unmangle_classname
02274 (IDENTIFIER_POINTER (method_sig),
02275 IDENTIFIER_LENGTH (method_sig))));
02276 tem = DECL_NAME (method);
02277 lookup_arg
02278 = tree_cons (NULL_TREE, klass,
02279 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
02280
02281 jni_func_type
02282 = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
02283 arg_types));
02284
02285 jnifunc = build (COND_EXPR, ptr_type_node,
02286 meth_var, meth_var,
02287 build (MODIFY_EXPR, ptr_type_node,
02288 meth_var,
02289 build (CALL_EXPR, ptr_type_node,
02290 build_address_of (soft_lookupjnimethod_node),
02291 lookup_arg, NULL_TREE)));
02292
02293
02294
02295 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
02296 build1 (NOP_EXPR, jni_func_type, jnifunc),
02297 args, NULL_TREE);
02298
02299
02300
02301 if (res_var != NULL_TREE)
02302 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
02303 res_var, call);
02304
02305 TREE_SIDE_EFFECTS (call) = 1;
02306 CAN_COMPLETE_NORMALLY (call) = 1;
02307
02308 body = build (COMPOUND_EXPR, void_type_node, body, call);
02309 TREE_SIDE_EFFECTS (body) = 1;
02310
02311
02312 call = build (CALL_EXPR, ptr_type_node,
02313 build_address_of (soft_jnipopsystemframe_node),
02314 build_tree_list (NULL_TREE, env_var),
02315 NULL_TREE);
02316 TREE_SIDE_EFFECTS (call) = 1;
02317 CAN_COMPLETE_NORMALLY (call) = 1;
02318 body = build (COMPOUND_EXPR, void_type_node, body, call);
02319 TREE_SIDE_EFFECTS (body) = 1;
02320
02321
02322
02323
02324 if (from_class)
02325 {
02326 res_type = void_type_node;
02327 if (res_var != NULL_TREE)
02328 {
02329 tree drt;
02330 if (! DECL_RESULT (method))
02331 abort ();
02332
02333
02334
02335
02336 drt = TREE_TYPE (DECL_RESULT (method));
02337 if (drt != TREE_TYPE (res_var))
02338 res_var = build1 (CONVERT_EXPR, drt, res_var);
02339 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
02340 TREE_SIDE_EFFECTS (res_var) = 1;
02341 }
02342 }
02343 else
02344 {
02345
02346 res_type = NULL_TREE;
02347 }
02348 body = build (COMPOUND_EXPR, void_type_node, body,
02349 build1 (RETURN_EXPR, res_type, res_var));
02350 TREE_SIDE_EFFECTS (body) = 1;
02351
02352 BLOCK_EXPR_BODY (block) = body;
02353 return block;
02354 }
02355
02356
02357
02358
02359
02360
02361 static void
02362 expand_java_field_op (is_static, is_putting, field_ref_index)
02363 int is_static;
02364 int is_putting;
02365 int field_ref_index;
02366 {
02367 tree self_type =
02368 get_class_constant (current_jcf,
02369 COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
02370 field_ref_index));
02371 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
02372 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
02373 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool,
02374 field_ref_index);
02375 tree field_type = get_type_from_signature (field_signature);
02376 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
02377 tree field_ref;
02378 int is_error = 0;
02379 tree field_decl = lookup_field (&self_type, field_name);
02380 if (field_decl == error_mark_node)
02381 {
02382 is_error = 1;
02383 }
02384 else if (field_decl == NULL_TREE)
02385 {
02386 error ("missing field '%s' in '%s'",
02387 IDENTIFIER_POINTER (field_name), self_name);
02388 is_error = 1;
02389 }
02390 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
02391 {
02392 error ("mismatching signature for field '%s' in '%s'",
02393 IDENTIFIER_POINTER (field_name), self_name);
02394 is_error = 1;
02395 }
02396 field_ref = is_static ? NULL_TREE : pop_value (self_type);
02397 if (is_error)
02398 {
02399 if (! is_putting)
02400 push_value (convert (field_type, integer_zero_node));
02401 flush_quick_stack ();
02402 return;
02403 }
02404
02405 field_ref = build_field_ref (field_ref, self_type, field_name);
02406 if (is_static)
02407 field_ref = build_class_init (self_type, field_ref);
02408 if (is_putting)
02409 {
02410 flush_quick_stack ();
02411 if (FIELD_FINAL (field_decl))
02412 {
02413 if (DECL_CONTEXT (field_decl) != current_class)
02414 error_with_decl (field_decl,
02415 "assignment to final field `%s' not in field's class");
02416 else if (FIELD_STATIC (field_decl))
02417 {
02418 if (!DECL_CLINIT_P (current_function_decl))
02419 warning_with_decl (field_decl,
02420 "assignment to final static field `%s' not in class initializer");
02421 }
02422 else
02423 {
02424 tree cfndecl_name = DECL_NAME (current_function_decl);
02425 if (! DECL_CONSTRUCTOR_P (current_function_decl)
02426 && !ID_FINIT_P (cfndecl_name))
02427 warning_with_decl (field_decl, "assignment to final field `%s' not in constructor");
02428 }
02429 }
02430 expand_assignment (field_ref, new_value, 0, 0);
02431 }
02432 else
02433 push_value (field_ref);
02434 }
02435
02436 void
02437 load_type_state (label)
02438 tree label;
02439 {
02440 int i;
02441 tree vec = LABEL_TYPE_STATE (label);
02442 int cur_length = TREE_VEC_LENGTH (vec);
02443 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
02444 for (i = 0; i < cur_length; i++)
02445 type_map [i] = TREE_VEC_ELT (vec, i);
02446 }
02447
02448
02449
02450
02451
02452 static tree
02453 case_identity (t, v)
02454 tree t __attribute__ ((__unused__));
02455 tree v;
02456 {
02457 return v;
02458 }
02459
02460
02461
02462 static tree
02463 get_primitive_array_vtable (tree elt)
02464 {
02465 tree r;
02466 if (elt == boolean_type_node)
02467 r = boolean_array_vtable;
02468 else if (elt == byte_type_node)
02469 r = byte_array_vtable;
02470 else if (elt == char_type_node)
02471 r = char_array_vtable;
02472 else if (elt == short_type_node)
02473 r = short_array_vtable;
02474 else if (elt == int_type_node)
02475 r = int_array_vtable;
02476 else if (elt == long_type_node)
02477 r = long_array_vtable;
02478 else if (elt == float_type_node)
02479 r = float_array_vtable;
02480 else if (elt == double_type_node)
02481 r = double_array_vtable;
02482 else
02483 abort ();
02484 return build_address_of (r);
02485 }
02486
02487 struct rtx_def *
02488 java_lang_expand_expr (exp, target, tmode, modifier)
02489 register tree exp;
02490 rtx target;
02491 enum machine_mode tmode;
02492 enum expand_modifier modifier;
02493 {
02494 tree current;
02495
02496 switch (TREE_CODE (exp))
02497 {
02498 case NEW_ARRAY_INIT:
02499 {
02500 rtx tmp;
02501 tree array_type = TREE_TYPE (TREE_TYPE (exp));
02502 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
02503 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
02504 HOST_WIDE_INT ilength = java_array_type_length (array_type);
02505 tree length = build_int_2 (ilength, 0);
02506 tree init = TREE_OPERAND (exp, 0);
02507 tree array_decl;
02508
02509
02510 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
02511 && JPRIMITIVE_TYPE_P (element_type))
02512 {
02513 tree temp, value, init_decl;
02514 struct rtx_def *r;
02515 START_RECORD_CONSTRUCTOR (temp, object_type_node);
02516 PUSH_FIELD_VALUE (temp, "vtable",
02517 get_primitive_array_vtable (element_type));
02518 if (! flag_hash_synchronization)
02519 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
02520 FINISH_RECORD_CONSTRUCTOR (temp);
02521 START_RECORD_CONSTRUCTOR (value, array_type);
02522 PUSH_SUPER_VALUE (value, temp);
02523 PUSH_FIELD_VALUE (value, "length", length);
02524 PUSH_FIELD_VALUE (value, "data", init);
02525 FINISH_RECORD_CONSTRUCTOR (value);
02526
02527 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
02528 pushdecl_top_level (init_decl);
02529 TREE_STATIC (init_decl) = 1;
02530 DECL_INITIAL (init_decl) = value;
02531 DECL_IGNORED_P (init_decl) = 1;
02532 TREE_READONLY (init_decl) = 1;
02533
02534 if (flag_hash_synchronization && POINTER_SIZE < 64)
02535 DECL_ALIGN (init_decl) = 64;
02536 rest_of_decl_compilation (init_decl, NULL, 1, 0);
02537 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
02538 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
02539 r = expand_expr (init, target, tmode, modifier);
02540 return r;
02541 }
02542
02543 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
02544 expand_decl (array_decl);
02545 tmp = expand_assignment (array_decl,
02546 build_new_array (element_type, length),
02547 1, 0);
02548 if (TREE_CONSTANT (init)
02549 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
02550 {
02551 tree init_decl;
02552 init_decl = build_decl (VAR_DECL, generate_name (),
02553 TREE_TYPE (init));
02554 pushdecl_top_level (init_decl);
02555 TREE_STATIC (init_decl) = 1;
02556 DECL_INITIAL (init_decl) = init;
02557 DECL_IGNORED_P (init_decl) = 1;
02558 TREE_READONLY (init_decl) = 1;
02559 rest_of_decl_compilation (init_decl, NULL, 1, 0);
02560 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
02561 init = init_decl;
02562 }
02563 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
02564 build_java_indirect_ref (array_type,
02565 array_decl, flag_check_references),
02566 data_fld), init, 0, 0);
02567 return tmp;
02568 }
02569 case BLOCK:
02570 if (BLOCK_EXPR_BODY (exp))
02571 {
02572 tree local;
02573 tree body = BLOCK_EXPR_BODY (exp);
02574
02575
02576 int found_class_initialization_flag = 0;
02577
02578 pushlevel (2);
02579 expand_start_bindings (0);
02580 local = BLOCK_EXPR_DECLS (exp);
02581 while (local)
02582 {
02583 tree next = TREE_CHAIN (local);
02584 found_class_initialization_flag +=
02585 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
02586 layout_decl (local, 0);
02587 expand_decl (pushdecl (local));
02588 local = next;
02589 }
02590
02591
02592 if (! always_initialize_class_p
02593 && current_function_decl
02594 && found_class_initialization_flag)
02595 hash_traverse
02596 (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
02597 emit_init_test_initialization, NULL);
02598
02599
02600 while (TREE_CODE (body) == COMPOUND_EXPR)
02601 {
02602 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
02603 emit_queue ();
02604 body = TREE_OPERAND (body, 1);
02605 }
02606 expand_expr (body, const0_rtx, VOIDmode, 0);
02607 emit_queue ();
02608 expand_end_bindings (getdecls (), 1, 0);
02609 poplevel (1, 1, 0);
02610 return const0_rtx;
02611 }
02612 return const0_rtx;
02613
02614 case CASE_EXPR:
02615 {
02616 tree duplicate;
02617 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
02618 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
02619 &duplicate) == 2)
02620 {
02621 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
02622 parse_error_context
02623 (wfl_operator, "Duplicate case label: `%s'",
02624 print_int_node (TREE_OPERAND (exp, 0)));
02625 }
02626 return const0_rtx;
02627 }
02628
02629 case DEFAULT_EXPR:
02630 pushcase (NULL_TREE, 0,
02631 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
02632 return const0_rtx;
02633
02634 case SWITCH_EXPR:
02635 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
02636 expand_expr_stmt (TREE_OPERAND (exp, 1));
02637 expand_end_case (TREE_OPERAND (exp, 0));
02638 return const0_rtx;
02639
02640 case TRY_EXPR:
02641
02642
02643
02644 expand_eh_region_start ();
02645 expand_expr_stmt (TREE_OPERAND (exp, 0));
02646 expand_start_all_catch ();
02647
02648
02649 for (current = TREE_OPERAND (exp, 1); current;
02650 current = TREE_CHAIN (current))
02651 {
02652 tree catch = TREE_OPERAND (current, 0);
02653 tree decl = BLOCK_EXPR_DECLS (catch);
02654 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
02655
02656 expand_start_catch (type);
02657 expand_expr_stmt (TREE_OPERAND (current, 0));
02658 expand_end_catch ();
02659 }
02660 expand_end_all_catch ();
02661 return const0_rtx;
02662
02663 case JAVA_EXC_OBJ_EXPR:
02664 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
02665 target, tmode, modifier);
02666
02667 default:
02668 internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
02669 }
02670 }
02671
02672
02673
02674
02675 void
02676 note_instructions (jcf, method)
02677 JCF *jcf;
02678 tree method;
02679 {
02680 int PC;
02681 unsigned char* byte_ops;
02682 long length = DECL_CODE_LENGTH (method);
02683
02684 int saw_index;
02685 jint INT_temp;
02686
02687 #undef RET
02688 #undef AND
02689 #undef PTR
02690 #define BCODE byte_ops
02691 #define BYTE_type_node byte_type_node
02692 #define SHORT_type_node short_type_node
02693 #define INT_type_node int_type_node
02694 #define LONG_type_node long_type_node
02695 #define CHAR_type_node char_type_node
02696 #define PTR_type_node ptr_type_node
02697 #define FLOAT_type_node float_type_node
02698 #define DOUBLE_type_node double_type_node
02699 #define VOID_type_node void_type_node
02700 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
02701 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
02702 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
02703 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
02704
02705 #define CHECK_PC_IN_RANGE(PC) ((void)1)
02706
02707 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
02708 byte_ops = jcf->read_ptr;
02709 instruction_bits = xrealloc (instruction_bits, length + 1);
02710 memset (instruction_bits, 0, length + 1);
02711
02712
02713 for (PC = 0; PC < length;)
02714 {
02715 int oldpc = PC;
02716 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
02717 switch (byte_ops[PC++])
02718 {
02719 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
02720 case OPCODE: \
02721 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
02722 break;
02723
02724 #define NOTE_LABEL(PC) note_label(oldpc, PC)
02725
02726 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
02727 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
02728 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
02729 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE)
02730 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE)
02731 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE)
02732 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE)
02733 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE)
02734
02735 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
02736 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
02737 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
02738 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
02739 #define PRE_SPECIAL_ENTER(IGNORE)
02740 #define PRE_SPECIAL_EXIT(IGNORE)
02741 #define PRE_SPECIAL_THROW(IGNORE)
02742 #define PRE_SPECIAL_BREAK(IGNORE)
02743
02744
02745 #define PRE_SPECIAL_WIDE(IGNORE) \
02746 { \
02747 int modified_opcode = IMMEDIATE_u1; \
02748 if (modified_opcode == OPCODE_iinc) \
02749 { \
02750 (void) IMMEDIATE_u2; \
02751 (void) IMMEDIATE_s2; \
02752 } \
02753 else \
02754 { \
02755 (void) IMMEDIATE_u2; \
02756 } \
02757 }
02758
02759 #define PRE_IMPL(IGNORE1, IGNORE2)
02760
02761 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE)
02762
02763 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE)
02764 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
02765 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
02766 #define PRE_ARRAY_LOAD(TYPE)
02767 #define PRE_ARRAY_STORE(TYPE)
02768 #define PRE_ARRAY_LENGTH(TYPE)
02769 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
02770 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
02771 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
02772 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
02773
02774 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
02775 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
02776 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
02777 saw_index = 0; INT_temp = (OPERAND_VALUE); \
02778 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
02779 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
02780 saw_index = 0; INT_temp = (OPERAND_VALUE); \
02781 NOTE_LABEL (PC); \
02782 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
02783
02784 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
02785
02786 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
02787 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
02788
02789 #define PRE_LOOKUP_SWITCH \
02790 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
02791 NOTE_LABEL (default_offset+oldpc); \
02792 if (npairs >= 0) \
02793 while (--npairs >= 0) { \
02794 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
02795 jint offset = IMMEDIATE_s4; \
02796 NOTE_LABEL (offset+oldpc); } \
02797 }
02798
02799 #define PRE_TABLE_SWITCH \
02800 { jint default_offset = IMMEDIATE_s4; \
02801 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
02802 NOTE_LABEL (default_offset+oldpc); \
02803 if (low <= high) \
02804 while (low++ <= high) { \
02805 jint offset = IMMEDIATE_s4; \
02806 NOTE_LABEL (offset+oldpc); } \
02807 }
02808
02809 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
02810 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
02811 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
02812 (void)(IMMEDIATE_u2); \
02813 PC += 2 * IS_INTERFACE ;
02814
02815 #include "javaop.def"
02816 #undef JAVAOP
02817 }
02818 }
02819 }
02820
02821 void
02822 expand_byte_code (jcf, method)
02823 JCF *jcf;
02824 tree method;
02825 {
02826 int PC;
02827 int i;
02828 const unsigned char *linenumber_pointer;
02829 int dead_code_index = -1;
02830 unsigned char* byte_ops;
02831 long length = DECL_CODE_LENGTH (method);
02832
02833 stack_pointer = 0;
02834 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
02835 byte_ops = jcf->read_ptr;
02836
02837
02838
02839 linenumber_pointer = linenumber_table;
02840 for (i = 0; i < linenumber_count; i++)
02841 {
02842 int pc = GET_u2 (linenumber_pointer);
02843 linenumber_pointer += 4;
02844 if (pc >= length)
02845 warning ("invalid PC in line number table");
02846 else
02847 {
02848 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
02849 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
02850 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
02851 }
02852 }
02853
02854 if (! verify_jvm_instructions (jcf, byte_ops, length))
02855 return;
02856
02857
02858 linenumber_pointer = linenumber_table;
02859 for (PC = 0; PC < length;)
02860 {
02861 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
02862 {
02863 tree label = lookup_label (PC);
02864 flush_quick_stack ();
02865 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
02866 expand_label (label);
02867 if (LABEL_VERIFIED (label) || PC == 0)
02868 load_type_state (label);
02869 }
02870
02871 if (! (instruction_bits [PC] & BCODE_VERIFIED))
02872 {
02873 if (dead_code_index == -1)
02874 {
02875
02876
02877
02878
02879 dead_code_index = PC;
02880 }
02881
02882
02883 byte_ops[PC] = 0x0;
02884 }
02885 else
02886 {
02887 if (dead_code_index != -1)
02888 {
02889
02890 warning ("unreachable bytecode from %d to before %d",
02891 dead_code_index, PC);
02892 dead_code_index = -1;
02893 }
02894 }
02895
02896
02897
02898
02899
02900
02901 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
02902 {
02903 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
02904 || GET_u2 (linenumber_pointer) != PC)
02905 linenumber_pointer = linenumber_table;
02906 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
02907 {
02908 int pc = GET_u2 (linenumber_pointer);
02909 linenumber_pointer += 4;
02910 if (pc == PC)
02911 {
02912 lineno = GET_u2 (linenumber_pointer - 2);
02913 emit_line_note (input_filename, lineno);
02914 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
02915 break;
02916 }
02917 }
02918 }
02919 maybe_pushlevels (PC);
02920 PC = process_jvm_instruction (PC, byte_ops, length);
02921 maybe_poplevels (PC);
02922 }
02923
02924 if (dead_code_index != -1)
02925 {
02926
02927 warning ("unreachable bytecode from %d to the end of the method",
02928 dead_code_index);
02929 }
02930 }
02931
02932 static void
02933 java_push_constant_from_pool (jcf, index)
02934 JCF *jcf;
02935 int index;
02936 {
02937 tree c;
02938 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
02939 {
02940 tree name;
02941 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
02942 index = alloc_name_constant (CONSTANT_String, name);
02943 c = build_ref_from_constant_pool (index);
02944 TREE_TYPE (c) = promote_type (string_type_node);
02945 }
02946 else
02947 c = get_constant (jcf, index);
02948 push_value (c);
02949 }
02950
02951 int
02952 process_jvm_instruction (PC, byte_ops, length)
02953 int PC;
02954 const unsigned char* byte_ops;
02955 long length ATTRIBUTE_UNUSED;
02956 {
02957 const char *opname;
02958 int oldpc = PC;
02959
02960
02961
02962 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
02963 {
02964 tree type = pop_type (ptr_type_node);
02965 push_value (build (JAVA_EXC_OBJ_EXPR, type));
02966 }
02967
02968 switch (byte_ops[PC++])
02969 {
02970 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
02971 case OPCODE: \
02972 opname = #OPNAME; \
02973 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
02974 break;
02975
02976 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
02977 { \
02978 int saw_index = 0; \
02979 int index = OPERAND_VALUE; \
02980 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
02981 }
02982
02983 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
02984 { \
02985 \
02986 int opvalue = OPERAND_VALUE; \
02987 build_java_jsr (oldpc + opvalue, PC); \
02988 }
02989
02990
02991 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
02992 { int saw_index = 0; int ival = (OPERAND_VALUE); \
02993 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
02994 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
02995
02996
02997 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
02998 expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
02999
03000
03001 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
03002 { \
03003 \
03004 int opvalue = OPERAND_VALUE; \
03005 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
03006 }
03007
03008 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
03009 expand_java_return (OPERAND_TYPE##_type_node)
03010
03011 #define REM_EXPR TRUNC_MOD_EXPR
03012 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
03013 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
03014
03015 #define FIELD(IS_STATIC, IS_PUT) \
03016 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
03017
03018 #define TEST(OPERAND_TYPE, CONDITION) \
03019 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
03020
03021 #define COND(OPERAND_TYPE, CONDITION) \
03022 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
03023
03024 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
03025 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
03026
03027 #define BRANCH_GOTO(OPERAND_VALUE) \
03028 expand_java_goto (oldpc + OPERAND_VALUE)
03029
03030 #define BRANCH_CALL(OPERAND_VALUE) \
03031 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
03032
03033 #if 0
03034 #define BRANCH_RETURN(OPERAND_VALUE) \
03035 { \
03036 tree type = OPERAND_TYPE##_type_node; \
03037 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
03038 expand_java_ret (value); \
03039 }
03040 #endif
03041
03042 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
03043 fprintf (stderr, "%3d: %s ", oldpc, opname); \
03044 fprintf (stderr, "(not implemented)\n")
03045 #define NOT_IMPL1(OPERAND_VALUE) \
03046 fprintf (stderr, "%3d: %s ", oldpc, opname); \
03047 fprintf (stderr, "(not implemented)\n")
03048
03049 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
03050
03051 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
03052
03053 #define STACK_POP(COUNT) java_stack_pop (COUNT)
03054
03055 #define STACK_SWAP(COUNT) java_stack_swap()
03056
03057 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
03058 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
03059 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
03060
03061 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
03062 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
03063
03064 #define LOOKUP_SWITCH \
03065 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
03066 tree selector = pop_value (INT_type_node); \
03067 tree duplicate, label; \
03068 tree type = TREE_TYPE (selector); \
03069 flush_quick_stack (); \
03070 expand_start_case (0, selector, type, "switch statement");\
03071 while (--npairs >= 0) \
03072 { \
03073 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
03074 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
03075 TREE_TYPE (value) = type; \
03076 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
03077 pushcase (value, convert, label, &duplicate); \
03078 expand_java_goto (oldpc + offset); \
03079 } \
03080 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
03081 pushcase (NULL_TREE, 0, label, &duplicate); \
03082 expand_java_goto (oldpc + default_offset); \
03083 expand_end_case (selector); \
03084 }
03085
03086 #define TABLE_SWITCH \
03087 { jint default_offset = IMMEDIATE_s4; \
03088 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
03089 tree selector = pop_value (INT_type_node); \
03090 tree duplicate, label; \
03091 tree type = TREE_TYPE (selector); \
03092 flush_quick_stack (); \
03093 expand_start_case (0, selector, type, "switch statement");\
03094 for (; low <= high; low++) \
03095 { \
03096 jint offset = IMMEDIATE_s4; \
03097 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
03098 TREE_TYPE (value) = type; \
03099 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
03100 pushcase (value, convert, label, &duplicate); \
03101 expand_java_goto (oldpc + offset); \
03102 } \
03103 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
03104 pushcase (NULL_TREE, 0, label, &duplicate); \
03105 expand_java_goto (oldpc + default_offset); \
03106 expand_end_case (selector); \
03107 }
03108
03109 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
03110 { int opcode = byte_ops[PC-1]; \
03111 int method_ref_index = IMMEDIATE_u2; \
03112 int nargs; \
03113 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
03114 else nargs = -1; \
03115 expand_invoke (opcode, method_ref_index, nargs); \
03116 }
03117
03118
03119 #define OBJECT(TYPE, OP) \
03120 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
03121
03122 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
03123
03124 #define ARRAY_LOAD(OPERAND_TYPE) \
03125 { \
03126 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
03127 }
03128
03129 #define ARRAY_STORE(OPERAND_TYPE) \
03130 { \
03131 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
03132 }
03133
03134 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
03135 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
03136 #define ARRAY_NEW_PTR() \
03137 push_value (build_anewarray (get_class_constant (current_jcf, \
03138 IMMEDIATE_u2), \
03139 pop_value (int_type_node)));
03140 #define ARRAY_NEW_NUM() \
03141 { \
03142 int atype = IMMEDIATE_u1; \
03143 push_value (build_newarray (atype, pop_value (int_type_node)));\
03144 }
03145 #define ARRAY_NEW_MULTI() \
03146 { \
03147 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
03148 int ndims = IMMEDIATE_u1; \
03149 expand_java_multianewarray( class, ndims ); \
03150 }
03151
03152 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
03153 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
03154 pop_value (OPERAND_TYPE##_type_node))));
03155
03156 #define CONVERT2(FROM_TYPE, TO_TYPE) \
03157 { \
03158 push_value (build1 (NOP_EXPR, int_type_node, \
03159 (convert (TO_TYPE##_type_node, \
03160 pop_value (FROM_TYPE##_type_node))))); \
03161 }
03162
03163 #define CONVERT(FROM_TYPE, TO_TYPE) \
03164 { \
03165 push_value (convert (TO_TYPE##_type_node, \
03166 pop_value (FROM_TYPE##_type_node))); \
03167 }
03168
03169
03170
03171 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
03172 { \
03173 tree decl, value; \
03174 int var = OPVALUE; \
03175 tree type = OPTYPE; \
03176 value = pop_value (type); \
03177 type = TREE_TYPE (value); \
03178 decl = find_local_variable (var, type, oldpc); \
03179 set_local_type (var, type ); \
03180 expand_assignment (decl, value, 0, 0); \
03181 }
03182
03183 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
03184 { \
03185 \
03186 int opvalue = OPERAND_VALUE; \
03187 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
03188 }
03189
03190 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
03191 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
03192
03193 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
03194 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
03195
03196 #define MONITOR_OPERATION(call) \
03197 { \
03198 tree o = pop_value (ptr_type_node); \
03199 tree c; \
03200 flush_quick_stack (); \
03201 c = build_java_monitor (call, o); \
03202 TREE_SIDE_EFFECTS (c) = 1; \
03203 expand_expr_stmt (c); \
03204 }
03205
03206 #define SPECIAL_IINC(IGNORED) \
03207 { \
03208 unsigned int local_var_index = IMMEDIATE_u1; \
03209 int ival = IMMEDIATE_s1; \
03210 expand_iinc(local_var_index, ival, oldpc); \
03211 }
03212
03213 #define SPECIAL_WIDE(IGNORED) \
03214 { \
03215 int modified_opcode = IMMEDIATE_u1; \
03216 unsigned int local_var_index = IMMEDIATE_u2; \
03217 switch (modified_opcode) \
03218 { \
03219 case OPCODE_iinc: \
03220 { \
03221 int ival = IMMEDIATE_s2; \
03222 expand_iinc (local_var_index, ival, oldpc); \
03223 break; \
03224 } \
03225 case OPCODE_iload: \
03226 case OPCODE_lload: \
03227 case OPCODE_fload: \
03228 case OPCODE_dload: \
03229 case OPCODE_aload: \
03230 { \
03231 \
03232 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
03233 break; \
03234 } \
03235 case OPCODE_istore: \
03236 case OPCODE_lstore: \
03237 case OPCODE_fstore: \
03238 case OPCODE_dstore: \
03239 case OPCODE_astore: \
03240 { \
03241 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
03242 break; \
03243 } \
03244 default: \
03245 error ("unrecogized wide sub-instruction"); \
03246 } \
03247 }
03248
03249 #define SPECIAL_THROW(IGNORED) \
03250 build_java_athrow (pop_value (throwable_type_node))
03251
03252 #define SPECIAL_BREAK NOT_IMPL1
03253 #define IMPL NOT_IMPL
03254
03255 #include "javaop.def"
03256 #undef JAVAOP
03257 default:
03258 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
03259 }
03260 return PC;
03261 }
03262
03263
03264
03265
03266 static unsigned char
03267 peek_opcode_at_pc (jcf, code_offset, pc)
03268 JCF *jcf;
03269 int code_offset, pc;
03270 {
03271 unsigned char opcode;
03272 long absolute_offset = (long)JCF_TELL (jcf);
03273
03274 JCF_SEEK (jcf, code_offset);
03275 opcode = jcf->read_ptr [pc];
03276 JCF_SEEK (jcf, absolute_offset);
03277 return opcode;
03278 }
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304 int
03305 maybe_adjust_start_pc (jcf, code_offset, start_pc, slot)
03306 struct JCF *jcf;
03307 int code_offset, start_pc, slot;
03308 {
03309 int first, index, opcode;
03310 int pc, insn_pc;
03311 int wide_found = 0;
03312
03313 if (!start_pc)
03314 return start_pc;
03315
03316 first = index = -1;
03317
03318
03319 for (pc = start_pc-1; pc; pc--)
03320 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
03321 break;
03322 insn_pc = pc;
03323
03324
03325 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
03326 if (opcode == OPCODE_wide)
03327 {
03328 wide_found = 1;
03329 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
03330 }
03331
03332 switch (opcode)
03333 {
03334 case OPCODE_astore_0:
03335 case OPCODE_astore_1:
03336 case OPCODE_astore_2:
03337 case OPCODE_astore_3:
03338 first = OPCODE_astore_0;
03339 break;
03340
03341 case OPCODE_istore_0:
03342 case OPCODE_istore_1:
03343 case OPCODE_istore_2:
03344 case OPCODE_istore_3:
03345 first = OPCODE_istore_0;
03346 break;
03347
03348 case OPCODE_lstore_0:
03349 case OPCODE_lstore_1:
03350 case OPCODE_lstore_2:
03351 case OPCODE_lstore_3:
03352 first = OPCODE_lstore_0;
03353 break;
03354
03355 case OPCODE_fstore_0:
03356 case OPCODE_fstore_1:
03357 case OPCODE_fstore_2:
03358 case OPCODE_fstore_3:
03359 first = OPCODE_fstore_0;
03360 break;
03361
03362 case OPCODE_dstore_0:
03363 case OPCODE_dstore_1:
03364 case OPCODE_dstore_2:
03365 case OPCODE_dstore_3:
03366 first = OPCODE_dstore_0;
03367 break;
03368
03369 case OPCODE_astore:
03370 case OPCODE_istore:
03371 case OPCODE_lstore:
03372 case OPCODE_fstore:
03373 case OPCODE_dstore:
03374 index = peek_opcode_at_pc (jcf, code_offset, pc);
03375 if (wide_found)
03376 {
03377 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
03378 index = (other << 8) + index;
03379 }
03380 break;
03381 }
03382
03383
03384
03385 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
03386 start_pc = insn_pc;
03387
03388 return start_pc;
03389 }
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409 tree
03410 force_evaluation_order (node)
03411 tree node;
03412 {
03413 if (flag_syntax_only)
03414 return node;
03415 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
03416 {
03417 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
03418 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
03419 }
03420 else if (TREE_CODE (node) == CALL_EXPR
03421 || TREE_CODE (node) == NEW_CLASS_EXPR
03422 || (TREE_CODE (node) == COMPOUND_EXPR
03423 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
03424 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
03425 {
03426 tree arg, cmp;
03427
03428 if (!TREE_OPERAND (node, 1))
03429 return node;
03430
03431 arg = node;
03432
03433
03434 if (TREE_CODE (node) == COMPOUND_EXPR)
03435 arg = TREE_OPERAND (node, 0);
03436
03437 arg = TREE_OPERAND (arg, 1);
03438
03439
03440 if (TREE_CODE (arg) != TREE_LIST)
03441 abort ();
03442
03443
03444 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
03445 {
03446 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
03447 cmp = (cmp == NULL_TREE ? saved :
03448 build (COMPOUND_EXPR, void_type_node, cmp, saved));
03449 TREE_VALUE (arg) = saved;
03450 }
03451
03452 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
03453 TREE_SIDE_EFFECTS (cmp) = 1;
03454
03455 if (cmp)
03456 {
03457 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
03458 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
03459 TREE_SIDE_EFFECTS (cmp) = 1;
03460 node = cmp;
03461 }
03462 }
03463 return node;
03464 }
03465
03466
03467
03468
03469 static bool
03470 emit_init_test_initialization (entry, key)
03471 struct hash_entry *entry;
03472 hash_table_key key ATTRIBUTE_UNUSED;
03473 {
03474 struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
03475 tree klass = build_class_ref ((tree) entry->key);
03476 tree rhs;
03477
03478
03479
03480
03481 if (DECL_INITIAL (ite->init_test_decl) == boolean_true_node)
03482 rhs = boolean_true_node;
03483
03484
03485
03486
03487 else
03488 rhs = build (GE_EXPR, boolean_type_node,
03489 build (COMPONENT_REF, byte_type_node,
03490 build1 (INDIRECT_REF, class_type_node, klass),
03491 lookup_field (&class_type_node,
03492 get_identifier ("state"))),
03493 build_int_2 (JV_STATE_DONE, 0));
03494
03495 expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
03496 ite->init_test_decl, rhs));
03497 return true;
03498 }