[PRISM] Compile YieldNode with different arguments
This commit is contained in:
parent
cb70994b0e
commit
2760f23774
@ -836,6 +836,38 @@ pm_compile_call_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
pm_compile_index_write_nodes_add_send(bool popped, LINK_ANCHOR *const ret, rb_iseq_t *iseq, NODE dummy_line_node, VALUE argc, int flag, int block_offset)
|
||||
{
|
||||
if (!popped) {
|
||||
ADD_INSN1(ret, &dummy_line_node, setn, FIXNUM_INC(argc, 2 + block_offset));
|
||||
}
|
||||
|
||||
if (flag & VM_CALL_ARGS_SPLAT) {
|
||||
ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(1));
|
||||
if (block_offset > 0) {
|
||||
ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(3));
|
||||
PM_SWAP;
|
||||
PM_POP;
|
||||
}
|
||||
ADD_INSN(ret, &dummy_line_node, concatarray);
|
||||
if (block_offset > 0) {
|
||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(3));
|
||||
PM_POP;
|
||||
}
|
||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, argc, INT2FIX(flag));
|
||||
}
|
||||
else {
|
||||
if (block_offset > 0) {
|
||||
PM_SWAP;
|
||||
}
|
||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag));
|
||||
}
|
||||
|
||||
PM_POP;
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
pm_setup_args(pm_arguments_node_t *arguments_node, int *flags, struct rb_callinfo_kwarg **kw_arg, rb_iseq_t *iseq, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, pm_parser_t *parser)
|
||||
{
|
||||
@ -907,12 +939,14 @@ pm_setup_args(pm_arguments_node_t *arguments_node, int *flags, struct rb_callinf
|
||||
else {
|
||||
PM_SWAP;
|
||||
}
|
||||
|
||||
*flags |= VM_CALL_KW_SPLAT_MUT;
|
||||
}
|
||||
|
||||
pm_assoc_splat_node_t *assoc_splat = (pm_assoc_splat_node_t *)cur_node;
|
||||
PM_COMPILE_NOT_POPPED(assoc_splat->value);
|
||||
|
||||
*flags |= VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT;
|
||||
*flags |= VM_CALL_KW_SPLAT;
|
||||
|
||||
if (len > 1) {
|
||||
ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_kwd, INT2FIX(2));
|
||||
@ -996,38 +1030,6 @@ pm_setup_args(pm_arguments_node_t *arguments_node, int *flags, struct rb_callinf
|
||||
return orig_argc;
|
||||
}
|
||||
|
||||
static void
|
||||
pm_compile_index_write_nodes_add_send(bool popped, LINK_ANCHOR *const ret, rb_iseq_t *iseq, NODE dummy_line_node, VALUE argc, int flag, int block_offset)
|
||||
{
|
||||
if (!popped) {
|
||||
ADD_INSN1(ret, &dummy_line_node, setn, FIXNUM_INC(argc, 2 + block_offset));
|
||||
}
|
||||
|
||||
if (flag & VM_CALL_ARGS_SPLAT) {
|
||||
ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(1));
|
||||
if (block_offset > 0) {
|
||||
ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(3));
|
||||
PM_SWAP;
|
||||
PM_POP;
|
||||
}
|
||||
ADD_INSN(ret, &dummy_line_node, concatarray);
|
||||
if (block_offset > 0) {
|
||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(3));
|
||||
PM_POP;
|
||||
}
|
||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, argc, INT2FIX(flag));
|
||||
}
|
||||
else {
|
||||
if (block_offset > 0) {
|
||||
PM_SWAP;
|
||||
}
|
||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag));
|
||||
}
|
||||
|
||||
PM_POP;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
pm_compile_index_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t *value, pm_arguments_node_t *arguments, pm_node_t *block, LINK_ANCHOR *const ret, rb_iseq_t *iseq, int lineno, const uint8_t * src, bool popped, pm_scope_node_t *scope_node, pm_parser_t *parser)
|
||||
{
|
||||
@ -4042,18 +4044,16 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
||||
case PM_YIELD_NODE: {
|
||||
pm_yield_node_t *yield_node = (pm_yield_node_t *)node;
|
||||
|
||||
unsigned int flag = 0;
|
||||
int flags = 0;
|
||||
struct rb_callinfo_kwarg *keywords = NULL;
|
||||
|
||||
int argc = 0;
|
||||
|
||||
if (yield_node->arguments) {
|
||||
PM_COMPILE_NOT_POPPED((pm_node_t *)yield_node->arguments);
|
||||
|
||||
argc = (int) yield_node->arguments->arguments.size;
|
||||
argc = pm_setup_args(yield_node->arguments, &flags, &keywords, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
|
||||
}
|
||||
|
||||
ADD_INSN1(ret, &dummy_line_node, invokeblock, new_callinfo(iseq, 0, argc, flag, keywords, FALSE));
|
||||
ADD_INSN1(ret, &dummy_line_node, invokeblock, new_callinfo(iseq, 0, argc, flags, keywords, FALSE));
|
||||
|
||||
PM_POP_IF_POPPED;
|
||||
|
||||
|
@ -841,6 +841,7 @@ module Prism
|
||||
def test_YieldNode
|
||||
assert_prism_eval("def prism_test_yield_node; yield; end")
|
||||
assert_prism_eval("def prism_test_yield_node; yield 1, 2; end")
|
||||
assert_prism_eval("def prism_test_yield_node; yield **kw if condition; end")
|
||||
|
||||
# Test case where there's a call directly after the yield call
|
||||
assert_prism_eval("def prism_test_yield_node; yield; 1; end")
|
||||
|
Loading…
x
Reference in New Issue
Block a user