📄 expr.c
字号:
expand_assignment (field_ref, new_value, 0, 0); } else push_value (field_ref);}treebuild_primtype_type_ref (self_name) char *self_name;{ char *class_name = self_name+10; tree typ; if (strncmp(class_name, "Byte", 4) == 0) typ = byte_type_node; else if (strncmp(class_name, "Short", 5) == 0) typ = short_type_node; else if (strncmp(class_name, "Integer", 7) == 0) typ = int_type_node; else if (strncmp(class_name, "Long", 4) == 0) typ = long_type_node; else if (strncmp(class_name, "Float", 5) == 0) typ = float_type_node; else if (strncmp(class_name, "Double", 6) == 0) typ = double_type_node; else if (strncmp(class_name, "Boolean", 7) == 0) typ = boolean_type_node; else if (strncmp(class_name, "Char", 4) == 0) typ = char_type_node; else if (strncmp(class_name, "Void", 4) == 0) typ = void_type_node; else typ = NULL_TREE; if (typ != NULL_TREE) return build_class_ref (typ); else return NULL_TREE;}voidload_type_state (label) tree label;{ int i; tree vec = LABEL_TYPE_STATE (label); int cur_length = TREE_VEC_LENGTH (vec); stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl); for (i = 0; i < cur_length; i++) type_map [i] = TREE_VEC_ELT (vec, i);}/* Do the expansion of a Java switch. With Gcc, switches are front-end dependant things, but they rely on gcc routines. This function is placed here because it uses things defined locally in parse.y. */static treecase_identity (t, v) tree t __attribute__ ((__unused__)); tree v;{ return v;}struct rtx_def *java_lang_expand_expr (exp, target, tmode, modifier) register tree exp; rtx target; enum machine_mode tmode; enum expand_modifier modifier;{ tree current; switch (TREE_CODE (exp)) { case NEW_ARRAY_INIT: { rtx tmp; tree array_type = TREE_TYPE (TREE_TYPE (exp)); tree element_type = TYPE_ARRAY_ELEMENT (array_type); tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type))); HOST_WIDE_INT ilength = java_array_type_length (array_type); tree length = build_int_2 (ilength, 0); tree init = TREE_OPERAND (exp, 0); tree array_decl;#if 0 /* Enable this once we can set the vtable field statically. FIXME */ if (TREE_CONSTANT (init) && TREE_STATIC (exp) && JPRIMITIVE_TYPE_P (element_type)) { tree temp, value, init_decl; START_RECORD_CONSTRUCTOR (temp, object_type_node); PUSH_FIELD_VALUE (temp, "vtable", null_pointer_node /* FIXME */ ); PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node); FINISH_RECORD_CONSTRUCTOR (temp); START_RECORD_CONSTRUCTOR (value, array_type); PUSH_SUPER_VALUE (value, temp); PUSH_FIELD_VALUE (value, "length", length); PUSH_FIELD_VALUE (value, "data", init); FINISH_RECORD_CONSTRUCTOR (value); init_decl = build_decl (VAR_DECL, generate_name (), array_type); pushdecl_top_level (init_decl); TREE_STATIC (init_decl) = 1; DECL_INITIAL (init_decl) = value; DECL_IGNORED_P (init_decl) = 1; TREE_READONLY (init_decl) = 1; make_decl_rtl (init_decl, NULL, 1); init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl); return expand_expr (init, target, tmode, modifier); }#endif array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp)); expand_decl (array_decl); tmp = expand_assignment (array_decl, build_new_array (element_type, length), 1, 0); if (TREE_CONSTANT (init) && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type)) { tree init_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (init)); pushdecl_top_level (init_decl); TREE_STATIC (init_decl) = 1; DECL_INITIAL (init_decl) = init; DECL_IGNORED_P (init_decl) = 1; TREE_READONLY (init_decl) = 1; make_decl_rtl (init_decl, NULL, 1); init = init_decl; } expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld), build1 (INDIRECT_REF, array_type, array_decl), data_fld), init, 0, 0); return tmp; } case BLOCK: if (BLOCK_EXPR_BODY (exp)) { tree local; tree body = BLOCK_EXPR_BODY (exp); struct rtx_def *to_return; pushlevel (2); /* 2 and above */ expand_start_bindings (0); local = BLOCK_EXPR_DECLS (exp); while (local) { tree next = TREE_CHAIN (local); layout_decl (local, 0); expand_decl (pushdecl (local)); local = next; } /* Avoid deep recursion for long block. */ while (TREE_CODE (body) == COMPOUND_EXPR) { expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0); emit_queue (); body = TREE_OPERAND (body, 1); } to_return = expand_expr (body, target, tmode, modifier); poplevel (1, 1, 0); expand_end_bindings (getdecls (), 1, 0); return to_return; } break; case CASE_EXPR: { tree duplicate; if (pushcase (TREE_OPERAND (exp, 0), case_identity, build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), &duplicate) == 2) { EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp); parse_error_context (wfl_operator, "Duplicate case label: `%s'", print_int_node (TREE_OPERAND (exp, 0))); } return const0_rtx; } case DEFAULT_EXPR: pushcase (NULL_TREE, 0, build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL); return const0_rtx; case SWITCH_EXPR: expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch"); expand_expr_stmt (TREE_OPERAND (exp, 1)); expand_end_case (TREE_OPERAND (exp, 0)); return const0_rtx; case TRY_EXPR: /* We expand a try[-catch] block */ /* Expand the try block */ expand_eh_region_start (); expand_expr_stmt (TREE_OPERAND (exp, 0)); expand_start_all_catch (); /* Expand all catch clauses (EH handlers) */ for (current = TREE_OPERAND (exp, 1); current; current = TREE_CHAIN (current)) { tree type; tree catch = TREE_OPERAND (current, 0); tree decl = BLOCK_EXPR_DECLS (catch); type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE); start_catch_handler (prepare_eh_table_type (type)); expand_expr_stmt (TREE_OPERAND (current, 0)); expand_resume_after_catch (); end_catch_handler (); } expand_end_all_catch (); break; default: fatal ("Can't expand '%s' tree - java_lang_expand_expr", tree_code_name [TREE_CODE (exp)]); }}voidexpand_byte_code (jcf, method) JCF *jcf; tree method;{ int PC; int i; int saw_index; unsigned char *linenumber_pointer; int dead_code_index = -1;#undef RET /* Defined by config/i386/i386.h */#undef AND /* Causes problems with opcodes for iand and land. */#undef PTR#define BCODE byte_ops#define BYTE_type_node byte_type_node#define SHORT_type_node short_type_node#define INT_type_node int_type_node#define LONG_type_node long_type_node#define CHAR_type_node char_type_node#define PTR_type_node ptr_type_node#define FLOAT_type_node float_type_node#define DOUBLE_type_node double_type_node#define VOID_type_node void_type_node jint INT_temp; unsigned char* byte_ops; long length = DECL_CODE_LENGTH (method); stack_pointer = 0; JCF_SEEK (jcf, DECL_CODE_OFFSET (method)); byte_ops = jcf->read_ptr;#define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)#define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)#define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)#define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)#define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */ instruction_bits = oballoc (length + 1); bzero (instruction_bits, length + 1); /* We make an initial pass of the line number table, to note which instructions have associated line number entries. */ linenumber_pointer = linenumber_table; for (i = 0; i < linenumber_count; i++) { int pc = GET_u2 (linenumber_pointer); linenumber_pointer += 4; if (pc >= length) warning ("invalid PC in line number table"); else { if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0) instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS; instruction_bits[pc] |= BCODE_HAS_LINENUMBER; } } /* Do a preliminary pass. * This figures out which PC can be the targets of jumps. */ for (PC = 0; PC < length;) { int oldpc = PC; /* PC at instruction start. */ instruction_bits [PC] |= BCODE_INSTRUCTION_START; switch (byte_ops[PC++]) {#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \ case OPCODE: \ PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \ break;#define NOTE_LABEL(PC) note_label(oldpc, PC)#define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);#define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);#define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);#define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */#define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */#define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */#define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */#define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */#define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \ PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)#define PRE_SPECIAL_IINC(OPERAND_TYPE) \ ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)#define PRE_SPECIAL_ENTER(IGNORE) /* nothing */#define PRE_SPECIAL_EXIT(IGNORE) /* nothing */#define PRE_SPECIAL_THROW(IGNORE) /* nothing */#define PRE_SPECIAL_BREAK(IGNORE) /* nothing *//* two forms of wide instructions */#define PRE_SPECIAL_WIDE(IGNORE) \ { \ int modified_opcode = IMMEDIATE_u1; \ if (modified_opcode == OPCODE_iinc) \ { \ (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \ (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \ } \ else \ { \ (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \ } \ }/* nothing */ /* XXX JH */#define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */#define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */#define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */#define PRE_ARRAY(OPERAND_TYPE, SUBOP) \ PRE_ARRAY_##SUBOP(OPERAND_TYPE)#define PRE_ARRAY_LOAD(TYPE) /* nothing */#define PRE_ARRAY_STORE(TYPE) /* nothing */#define PRE_ARRAY_LENGTH(TYPE) /* nothing */#define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE#define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)#define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)#define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)#define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)#define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)#define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \ saw_index = 0; INT_temp = (OPERAND_VALUE); \ if (!saw_index) NOTE_LABEL(oldpc + INT_temp);#define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \ saw_index = 0; INT_temp = (OPERAND_VALUE); \ if (!saw_index) NOTE_LABEL(oldpc + INT_temp);#define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)#define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \ PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH#define PRE_LOOKUP_SWITCH \ { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \ NOTE_LABEL (default_offset+oldpc); \ if (npairs >= 0) \ while (--npairs >= 0) { \ jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \ jint offset = IMMEDIATE_s4; \ NOTE_LABEL (offset+oldpc); } \ }#define PRE_TABLE_SWITCH \ { jint default_offset = IMMEDIATE_s4; \ jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \ NOTE_LABEL (default_offset+oldpc); \ if (low <= high) \ while (low++ <= high) { \ jint offset = IMMEDIATE_s4; \ NOTE_LABEL (offset+oldpc); } \ }#define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);#define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);#define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \ (void)(IMMEDIATE_u2); \ PC += 2 * IS_INTERFACE /* for invokeinterface */;#include "javaop.def"#undef JAVAOP } } /* for */ if (! verify_jvm_instructions (jcf, byte_ops, length)) return; /* Translate bytecodes to rtl instructions. */ linenumber_pointer = linenumber_table; for (PC = 0; PC < length;) { if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0) { tree label = lookup_label (PC); flush_quick_stack (); if ((instruction_bits [PC] & BCODE_TARGET) != 0) expand_label (label); if (LABEL_VERIFIED (label) || PC == 0) load_type_state (label); } if (! (instruction_bits [PC] & BCODE_VERIFIED)) { if (dead_code_index == -1) { /* This is the start of a region of unreachable bytecodes. They still need to be processed in order for EH ranges to get handled correctly. However, we can simply replace these bytecodes with nops. */ dead_code_index = PC; } /* Turn this bytecode into a nop. */ byte_ops[PC] = 0x0; } else { if (dead_code_index != -1) { /* We've just reached the end of a region of dead code. */ warning ("Unreachable bytecode from %d to before %d.", dead_code_index, PC); dead_code_index = -1; } } /* Handle possible line number entry for this PC. This code handles out-of-order and multiple linenumbers per PC, but is optimized f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -