📄 kaffe.def
字号:
end_sync();}define_insn_finidefine_insn(JSR){ check_pcidx (0); idx = (int16)((getpc(0) << 8) | getpc(1)); trace_jcode ("jsr %ld\n", (long) (pc + idx)); push(1); move_label_const(stack(0), reference_code_label(npc)); begin_sync(); branch_a(reference_code_label(pc+idx)); end_sync();}define_insn_finidefine_insn(RET){ check_pc (0); idx = (uint8)getpc(0); trace_jcode ("ret %d\n", idx); check_local_ref(idx); begin_sync(); branch_indirect(stored_code_label(local(idx))); end_sync();}define_insn_finidefine_insn(TABLESWITCH){ /* * ..., index -> ... */ check_stack_int(0); npc = (pc + 1 + 3) & -4; low = (int32)((getcode(npc+4) << 24) | (getcode(npc+5) << 16) | (getcode(npc+6) << 8) | getcode(npc+7)); high = (int32)((getcode(npc+8) << 24) | (getcode(npc+9) << 16) | (getcode(npc+10) << 8) | getcode(npc+11)); npc = npc + 12; trace_jcode ("tableswitch %d %d\n", low, high); end_sub_block(); cbranch_int_const_lt(stack(0), low, reference_label(TABLESWITCH, 8)); cbranch_int_const_le(stack(0), high, reference_label(TABLESWITCH, 7)); start_sub_block(); set_label(TABLESWITCH, 8); move_int_const(stack(0), low-3); /* Position at default entry */ end_sub_block(); start_sub_block(); set_label(TABLESWITCH, 7); if (low != 0) { start_sub_block(); sub_int_const(stack(0), stack(0), low); end_sub_block(); } lshl_int_const(stack(0), stack(0), switchtable_shift); slot_alloctmp(tmp2); move_label_const(tmp2, reference_table_label(9)); add_ref(stack(0), tmp2, stack(0)); slot_freetmp(tmp2); load_code_ref(stack(0), stack(0)); end_sub_block(); branch_indirect(table_code_label(stack(0))); pop(1);#if defined(TRANSLATOR) { build_code_ref(&getcode(npc-12), pc); /* Default entry */ build_code_ref(&getcode(npc-12), pc); /* Dummy */ build_code_ref(&getcode(npc-12), pc); /* Dummy */ set_label(TABLESWITCH, 9); for (idx = 0; idx < high-low+1; idx++) { build_code_ref(&getcode(npc + (idx << switchtable_shift)), pc); } }#endif adjustpc((4 - (pc % 4)) + 12 + (high - low + 1) * 4);}define_insn_finidefine_insn(LOOKUPSWITCH){ /* * ..., key -> ... */ check_stack_int(0); npc = (pc + 1 + 3) & -4; idx = (int32)((getcode(npc+4) << 24) | (getcode(npc+5) << 16) | (getcode(npc+6) << 8) | getcode(npc+7)); trace_jcode ("lookupswitch %d\n", idx); slot_alloctmp(mtable); slot_alloctmp(tmp); move_label_const(tmp, reference_table_label(7)); if (idx != 0) { slot_alloctmp(tmp2); move_ref(tmp2, tmp); add_ref_const(tmp, tmp, idx * switchpair_size); end_sub_block(); set_label(LOOKUPSWITCH, 5); start_sub_block(); load_key(mtable, tmp); end_sub_block(); cbranch_int_eq(mtable, stack(0), reference_label(LOOKUPSWITCH, 6)); start_sub_block(); add_ref_const(tmp, tmp, -switchpair_size); end_sub_block(); cbranch_ref_ne(tmp, tmp2, reference_label(LOOKUPSWITCH, 5)); slot_freetmp(tmp2); start_sub_block(); add_ref_const(tmp, tmp, -switchpair_addr); end_sub_block(); set_label(LOOKUPSWITCH, 6); start_sub_block(); add_ref_const(tmp, tmp, switchpair_addr); } load_code_ref(tmp, tmp); end_sub_block(); branch_indirect(table_code_label(tmp)); pop(1); slot_freetmp(mtable); slot_freetmp(tmp);#if defined(TRANSLATOR) { set_label(LOOKUPSWITCH, 7); build_code_ref(&getcode(npc), pc); build_key(&getcode(npc)); /* Dummy key */ for (low = 1; low <= idx; low++) { build_key(&getcode(npc + (low * switchpair_size))); build_code_ref(&getcode(npc + (low * switchpair_size) + switchpair_addr), pc); } }#endif adjustpc((4 - (pc % 4)) + (idx + 1) * 8);}define_insn_finidefine_insn(IRETURN){ trace_jcode ("ireturn\n"); check_stack_int(0); monitor_exit(); exit_method(); returnarg_int(rstack(0)); ret();}define_insn_finidefine_insn(LRETURN){ trace_jcode ("lreturn\n"); check_stack_long(0); monitor_exit(); exit_method(); returnarg_long(rstack_long(0)); ret();}define_insn_finidefine_insn(FRETURN){ trace_jcode ("freturn\n"); check_stack_float(0); monitor_exit(); exit_method(); returnarg_float(rstack_float(0)); ret();}define_insn_finidefine_insn(DRETURN){ trace_jcode ("dreturn\n"); check_stack_double(0); monitor_exit(); exit_method(); returnarg_double(rstack_double(0)); ret();}define_insn_finidefine_insn(ARETURN){ trace_jcode ("areturn\n"); check_stack_ref(0); monitor_exit(); exit_method(); returnarg_ref(rstack_ref(0)); ret();}define_insn_finidefine_insn(RETURN){ trace_jcode ("return\n"); monitor_exit(); exit_method(); ret();}define_insn_fini/* * This macro initialises the static data associated with a class. */#define INIT_STATIC_CLASS(c) \ if (c != 0 && c->state != CSTATE_COMPLETE) { \ softcall_initialise_class(c); \ }define_insn(GETSTATIC){ /* * ... -> ..., value */ check_pcidx (0); idx = (uint16)((getpc(0) << 8) | getpc(1)); trace_jcode ("getstatic %d\n", idx); get_static_field_info_noerror(idx); if (field_class() == 0) { softcall_nosuchclass(field_classname()); switch (field_sig()->data[0]) { case 'J': case 'D': push(2); break; default: push(1); break; } break; } INIT_STATIC_CLASS(field_class()); if (field_field() == 0) { softcall_nosuchfield(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': push(2); break; default: push(1); break; } } else if (!(field_field()->accflags & ACC_STATIC)) { softcall_incompatibleclasschange(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': push(2); break; default: push(1); break; } } else if (!checkFieldAccess(current_class(), field_class(), field_field())) { softcall_illegalaccess(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': push(2); break; default: push(1); break; } } /* Use the proper load to increase the chances of the translator getting data in the right type of register. */ else if (!FIELD_ISPRIM(field_field())) { push(1); load_addr_ref(stack(0), FIELD_ADDRESS(field_field())); } else switch (CLASS_PRIM_SIG(FIELD_TYPE(field_field()))) { case 'I': push(1); load_addr_int(stack(0), FIELD_ADDRESS(field_field())); break; case 'S': push(1); load_addr_short(stack(0), FIELD_ADDRESS(field_field())); break; case 'B': case 'Z': push(1); load_addr_byte(stack(0), FIELD_ADDRESS(field_field())); break; case 'C': push(1); load_addr_char(stack(0), FIELD_ADDRESS(field_field())); break; case 'F': push(1); load_addr_float(stack(0), FIELD_ADDRESS(field_field())); break; case 'J': push(2); load_addr_long(stack_long(0), FIELD_ADDRESS(field_field())); break; case 'D': push(2); load_addr_double(stack_double(0), FIELD_ADDRESS(field_field())); break; default: KAFFEVM_ABORT(); }}define_insn_finidefine_insn(PUTSTATIC){ /* * ..., value -> ... */ check_pcidx (0); idx = (uint16)((getpc(0) << 8) | getpc(1)); trace_jcode ("putstatic %d\n", idx); get_static_field_info_noerror(idx); if (field_class() == 0) { softcall_nosuchclass(field_classname()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(2); break; default: pop(1); break; } break; } INIT_STATIC_CLASS(field_class()); if (field_field() == 0) { softcall_nosuchfield(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(2); break; default: pop(1); break; } } else if (!(field_field()->accflags & ACC_STATIC)) { softcall_incompatibleclasschange(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(2); break; default: pop(1); break; } } else if (((field_field()->accflags & ACC_FINAL) && (field_class() != current_class() || current_class()->state != CSTATE_DOING_INIT )) || !checkFieldAccess(current_class(), field_class(), field_field())) { softcall_illegalaccess(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(2); break; default: pop(1); break; } } else if (!FIELD_ISPRIM(field_field())) { SOFT_ADDREFERENCE_STATIC(field_statics(), stack(0)); store_addr_ref(FIELD_ADDRESS(field_field()), stack(0)); pop(1); } else switch (CLASS_PRIM_SIG(FIELD_TYPE(field_field()))) { case 'I': store_addr_int(FIELD_ADDRESS(field_field()), stack(0)); pop(1); break; case 'S': store_addr_short(FIELD_ADDRESS(field_field()), stack(0)); pop(1); break; case 'B': case 'Z': store_addr_byte(FIELD_ADDRESS(field_field()), stack(0)); pop(1); break; case 'C': store_addr_char(FIELD_ADDRESS(field_field()), stack(0)); pop(1); break; case 'F': store_addr_float(FIELD_ADDRESS(field_field()), stack(0)); pop(1); break; case 'J': store_addr_long(FIELD_ADDRESS(field_field()), stack_long(0)); pop(2); break; case 'D': store_addr_double(FIELD_ADDRESS(field_field()), stack_double(0)); pop(2); break; default: KAFFEVM_ABORT(); }}define_insn_finidefine_insn(GETFIELD){ /* * ..., obj-ref -> ..., value */ check_pcidx (0); check_stack_ref(0); check_null(GETFIELD, stack(0), 34); idx = (uint16)((getpc(0) << 8) | getpc(1)); trace_jcode ("getfield %d\n", idx); get_field_info(idx); /* If field not found we put an exception down */ if (field_field() == 0) { softcall_nosuchfield(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(1); break; default: break; } } else if (field_field()->accflags & ACC_STATIC) { softcall_incompatibleclasschange(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(1); break; default: break; } } else if (!checkFieldAccess(current_class(), field_class(), field_field())) { softcall_illegalaccess(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(1); break; default: break; } } /* Use the proper load to increase the chances of the translator getting data in the right type of register. */ else if (!FIELD_ISPRIM(field_field())) { load_offset_ref(stack(0), rstack(0), FIELD_BOFFSET(field_field())); } else switch (CLASS_PRIM_SIG(FIELD_TYPE(field_field()))) { case 'I': load_offset_int(stack(0), rstack(0), FIELD_BOFFSET(field_field())); break; case 'S': load_offset_short(stack(0), rstack(0), FIELD_BOFFSET(field_field())); break; case 'B': case 'Z': load_offset_byte(stack(0), rstack(0), FIELD_BOFFSET(field_field())); break; case 'C': load_offset_char(stack(0), rstack(0), FIELD_BOFFSET(field_field())); break; case 'F': load_offset_float(stack(0), stack(0), FIELD_BOFFSET(field_field())); break; case 'J': load_offset_long(stack_long(-1), stack(0), FIELD_BOFFSET(field_field())); push(1); break; case 'D': load_offset_double(stack_double(-1), stack(0), FIELD_BOFFSET(field_field())); push(1); break; default: KAFFEVM_ABORT(); }}define_insn_finidefine_insn(PUTFIELD){ /* * ..., obj-ref, value -> ... */ check_pcidx (0); idx = (uint16)((getpc(0) << 8) | getpc(1)); trace_jcode ("putfield %d\n", idx); get_field_info(idx); if (field_field() == 0) { softcall_nosuchfield(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(3); break; default: pop(2); break; } } else if (field_field()->accflags & ACC_STATIC) { softcall_incompatibleclasschange(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(3); break; default: pop(2); break; } } else if (((field_field()->accflags & ACC_FINAL) && (field_class() != current_class() )) || !checkFieldAccess(current_class(), field_class(), field_field())) { softcall_illegalaccess(field_classname(), field_name()); switch (field_sig()->data[0]) { case 'J': case 'D': pop(3); break; default: pop(2); break; } } /* Use the proper store to increase the chances of the translator having the data in the right type of register already. */ else if (!FIELD_ISPRIM(field_field())) { check_stack_ref(1); check_null(PUTFIELD, rstack(1), 35); SOFT_ADDREFERENCE(rstack(1), rstack(0)); store_offset_ref(rstack(1), FIELD_BOFFSET(field_field()), rstack(0)); pop(2); } else switch (CLASS_PRIM_SIG(FIELD_TYPE(field_field()))) { case 'I': check_stack_ref(1); check_null(PUTFIELD, stack(1), 36); store_offset_int(stack(1), FIELD_BOFFSET(field_field()), stack(0)); pop(2); break; case 'S': check_stack_ref(1); check_null(PUTFIELD, stack(1), 37); store_offset_short(stack(1), FIELD_BOFFSET(field_field()), stack(0)); pop(2); break; case 'B': case 'Z': check_stack_ref(1); check_null(PUTFIELD, stack(1), 38); store_offset_byte(stack(1), FIELD_BOFFSET(field_field()), stack(0)); pop(2); break; case 'C': check_stack_ref(1); check_null(PUTFIELD, stack(1), 39); store_offset_char(stack(1), FIELD_BOFFSET(field_field()), stack(0)); pop(2); break; case 'F': check_stack_ref(1); check_null(PUTFIELD, stack(1), 40); store_offset_float(stack(1), FIELD_BOFFSET(field_field()), stack(0)); pop(2); break; case 'J': check_stack_ref(2); check_null(PUTFIELD, stack(2), 41); store_offset_long(stack(2), FIELD_BOFFSET(field_field()), stack_long(0)); pop(3); break; case 'D': check_stack_ref(2); check_null(PUTFIELD, stack(2), 42); store_offset_double(stack(2), FIELD_BOFFSET(field_field()), stack_double(0)); pop(3); break; default: KAFFEVM_ABORT(); }}define_insn_fini#define METHOD_RETURN_VALUE() \do { \ /* Store the return type (if necessary) */ \ switch (low) { \ case 'V': \ break; \ case 'L': \ case '[': \ push(1); \ return_ref(stack(0)); \ break; \ case 'I': \ case 'Z': \ case 'S': \ case 'B': \ case 'C': \ push(1); \ return_int(stack(0)); \ break; \ case 'F': \ push(1); \ return_float(stack(0)); \ break; \ case 'J': \ push(2); \ return_long(stack_long(0)); \ break; \ case 'D': \ push(2); \ return_double(stack_double(0)); \ break; \ default: \ KAFFEVM_ABORT(); \ } \} while (0)define_insn(INVOKEVIRTUAL){ /* * ..., obj, ..args.., -> ... */ check_pcidx (0); idx = (uint16)((getpc(0) << 8) | getpc(1)); trace_jcode ("invokevirtual %d\n", idx); get_method_info_noerror(idx); /* If class doesn't exist, call 'NoSuchClassError' */ if (method_class() == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -