diff options
Diffstat (limited to 'prism_compile.c')
-rw-r--r-- | prism_compile.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/prism_compile.c b/prism_compile.c index 4350a346e3..ba59e6f04d 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -2925,42 +2925,53 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_MULTI_TARGET_NODE: { pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node; - for (size_t index = 0; index < cast->lefts.size; index++) { - PM_COMPILE(cast->lefts.nodes[index]); + + if (cast->lefts.size) { + int flag = (int) (bool) cast->rights.size; + ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(cast->lefts.size), INT2FIX(flag)); + for (size_t index = 0; index < cast->lefts.size; index++) { + PM_COMPILE_NOT_POPPED(cast->lefts.nodes[index]); + } + } + + if (cast->rights.size) { + ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(cast->rights.size), INT2FIX(2)); + for (size_t index = 0; index < cast->rights.size; index++) { + PM_COMPILE_NOT_POPPED(cast->rights.nodes[index]); + } } return; } case PM_MULTI_WRITE_NODE: { pm_multi_write_node_t *multi_write_node = (pm_multi_write_node_t *)node; - pm_node_list_t *node_list = &multi_write_node->lefts; + pm_node_list_t *lefts = &multi_write_node->lefts; + pm_node_list_t *rights = &multi_write_node->rights; // pre-process the left hand side of multi-assignments. uint8_t pushed = 0; - for (size_t index = 0; index < node_list->size; index++) { - pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, node_list->nodes[index], ret, scope_node, pushed, false); + for (size_t index = 0; index < lefts->size; index++) { + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, lefts->nodes[index], ret, scope_node, pushed, false); } PM_COMPILE_NOT_POPPED(multi_write_node->value); - - // TODO: int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00); - int flag = 0x00; - PM_DUP_UNLESS_POPPED; - ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(node_list->size), INT2FIX(flag)); - for (size_t index = 0; index < node_list->size; index++) { - pm_node_t *considered_node = node_list->nodes[index]; + if (lefts->size) { + ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(lefts->size), INT2FIX((int) (bool) rights->size)); + for (size_t index = 0; index < lefts->size; index++) { + pm_node_t *considered_node = lefts->nodes[index]; - if (PM_NODE_TYPE_P(considered_node, PM_CONSTANT_PATH_TARGET_NODE) && pushed > 0) { - pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) considered_node; - ID name = pm_constant_id_lookup(scope_node, ((pm_constant_read_node_t * ) cast->child)->name); + if (PM_NODE_TYPE_P(considered_node, PM_CONSTANT_PATH_TARGET_NODE) && pushed > 0) { + pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) considered_node; + ID name = pm_constant_id_lookup(scope_node, ((pm_constant_read_node_t * ) cast->child)->name); - pushed -= 2; + pushed -= 2; - ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(pushed)); - ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(name)); - } else { - PM_COMPILE(node_list->nodes[index]); + ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(pushed)); + ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(name)); + } else { + PM_COMPILE(lefts->nodes[index]); + } } } @@ -2971,6 +2982,23 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } } + if (multi_write_node->rest) { + RUBY_ASSERT(PM_NODE_TYPE_P(multi_write_node->rest, PM_SPLAT_NODE)); + + pm_splat_node_t *rest_splat = ((pm_splat_node_t *)multi_write_node->rest); + if (rest_splat->expression) { + ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(0), INT2FIX(1)); + PM_COMPILE(rest_splat->expression); + } + } + + if (rights->size) { + ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(rights->size), INT2FIX(2)); + for (size_t index = 0; index < rights->size; index++) { + PM_COMPILE(rights->nodes[index]); + } + } + return; } case PM_NEXT_NODE: { |