diff --git a/compile.c b/compile.c index fd8c26cad5a1b7..88b6719b62debe 100644 --- a/compile.c +++ b/compile.c @@ -1442,7 +1442,7 @@ new_insn_body(rb_iseq_t *iseq, const NODE *const line_node, enum ruby_vminsn_typ } static const struct rb_callinfo * -new_callinfo(rb_iseq_t *iseq, ID mid, int argc, unsigned int flag, struct rb_callinfo_kwarg *kw_arg, int has_blockiseq) +new_callinfo(rb_iseq_t *iseq, ID mid, int argc, unsigned int flag, const struct rb_callinfo_kwarg *kw_arg, int has_blockiseq) { VM_ASSERT(argc >= 0); @@ -3933,12 +3933,16 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) switch (vm_ci_mid(ci)) { case idNew: iobj->insn_id = BIN(opt_new); + fprintf(stderr, "operand_size = %d\n", iobj->operand_size); // TODO: add a second call_data for `#initialize` + // + // const struct rb_callinfo * new_ci = (struct rb_callinfo *)iobj->operands[0]; + iobj->operands[1] = (VALUE)new_callinfo(iseq, idInitialize, vm_ci_argc(ci), vm_ci_flag(ci) | VM_CALL_FCALL, vm_ci_kwarg(ci), FALSE); break; default: iobj->insn_id = BIN(opt_send_without_block); + iobj->operand_size = insn_len(iobj->insn_id) - 1; } - iobj->operand_size = insn_len(iobj->insn_id) - 1; } } #undef SP_INSN diff --git a/defs/id.def b/defs/id.def index 2ddde7be70702a..f9912dd9110d5e 100644 --- a/defs/id.def +++ b/defs/id.def @@ -5,6 +5,7 @@ firstline, predefined = __LINE__+1, %[\ hash freeze nil? + new inspect intern object_id diff --git a/insns.def b/insns.def index 124448e30cebea..fa1f417b8dbfc9 100644 --- a/insns.def +++ b/insns.def @@ -831,7 +831,7 @@ opt_send_without_block /* Invoke constructor */ DEFINE_INSN opt_new -(CALL_DATA cd) +(CALL_DATA cd, CALL_DATA cd_initialize) (...) (VALUE val) // attr bool handles_sp = true; @@ -842,20 +842,24 @@ opt_new val = vm_opt_new_alloc(GET_ISEQ(), recv, cd); if (val != Qundef) { + TOPN(vm_ci_argc(cd->ci)) = val; fprintf(stderr, "opt!\n"); - // TODO: call initialize (need a second CALL_DATA). + if (vm_sendish(ec, GET_CFP(), cd_initialize, VM_BLOCK_HANDLER_NONE, mexp_search_method) == Qundef) { + val = Qundef; + } } - else { + + if (val == Qundef) { fprintf(stderr, "de-opt!\n"); - } - VALUE bh = VM_BLOCK_HANDLER_NONE; - val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); - JIT_EXEC(ec, val); + VALUE bh = VM_BLOCK_HANDLER_NONE; + val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); + JIT_EXEC(ec, val); - if (val == Qundef) { - RESTORE_REGS(); - NEXT_INSN(); + if (val == Qundef) { + RESTORE_REGS(); + NEXT_INSN(); + } } }