Add parse.y implementation

This commit is contained in:
Aaron Patterson 2025-04-07 15:09:16 -07:00 committed by Aaron Patterson
parent 3552d446ca
commit f15d85f086

View File

@ -9380,6 +9380,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
INIT_ANCHOR(recv);
INIT_ANCHOR(args);
#if OPT_SUPPORT_JOKE
if (nd_type_p(node, NODE_VCALL)) {
ID id_bitblt;
@ -9475,6 +9476,17 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
}
ADD_SEQ(ret, recv);
bool inline_new = ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction &&
mid == rb_intern("new") &&
parent_block == NULL &&
!(flag & VM_CALL_ARGS_BLOCKARG);
if (inline_new) {
ADD_INSN(ret, node, putnil);
ADD_INSN(ret, node, swap);
}
ADD_SEQ(ret, args);
debugp_param("call args argc", argc);
@ -9491,7 +9503,36 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
if ((flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT) && !(flag & VM_CALL_KW_SPLAT_MUT)) {
ADD_INSN(ret, line_node, splatkw);
}
LABEL *not_basic_new = NEW_LABEL(nd_line(node));
LABEL *not_basic_new_finish = NEW_LABEL(nd_line(node));
if (inline_new) {
// Jump unless the receiver uses the "basic" implementation of "new"
VALUE ci;
if (flag & VM_CALL_FORWARDING) {
ci = (VALUE)new_callinfo(iseq, mid, NUM2INT(argc) + 1, flag, keywords, 0);
}
else {
ci = (VALUE)new_callinfo(iseq, mid, NUM2INT(argc), flag, keywords, 0);
}
ADD_INSN2(ret, node, opt_new, ci, not_basic_new);
LABEL_REF(not_basic_new);
// optimized path
ADD_SEND_R(ret, line_node, rb_intern("initialize"), argc, parent_block, INT2FIX(flag | VM_CALL_FCALL), keywords);
ADD_INSNL(ret, line_node, jump, not_basic_new_finish);
ADD_LABEL(ret, not_basic_new);
// Fall back to normal send
ADD_SEND_R(ret, line_node, mid, argc, parent_block, INT2FIX(flag), keywords);
ADD_INSN(ret, line_node, swap);
ADD_LABEL(ret, not_basic_new_finish);
ADD_INSN(ret, line_node, pop);
} else {
ADD_SEND_R(ret, line_node, mid, argc, parent_block, INT2FIX(flag), keywords);
}
qcall_branch_end(iseq, ret, else_label, branches, node, line_node);
if (popped) {