summaryrefslogtreecommitdiff
path: root/prism_compile.c
diff options
context:
space:
mode:
authorKevin Newton <[email protected]>2024-08-29 09:24:01 -0400
committerKevin Newton <[email protected]>2024-08-29 10:29:34 -0400
commit14bb376b79ca9140bfd36dbbad06be045f31f92e ()
tree7a2bffc436024aba71d9f34cf040df6f85406e64 /prism_compile.c
parent6b08a50a62f3575be4f7f4aeac0d416b8d3cd7c1 (diff)
[PRISM] Copy the rest of the setup_args_dup_rest_p function
Notes: Merged: https://.com/ruby/ruby/pull/11496
-rw-r--r--prism_compile.c130
1 files changed, 84 insertions, 46 deletions
@@ -1801,61 +1801,99 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
return orig_argc;
}
-static bool
-pm_setup_args_dup_rest_p(const pm_node_t *node) {
- switch(PM_NODE_TYPE(node)) {
- case PM_CALL_NODE:
- return true;
- default:
return false;
}
}
-// Compile the argument parts of a call
static int
pm_setup_args(const pm_arguments_node_t *arguments_node, const pm_node_t *block, int *flags, struct rb_callinfo_kwarg **kw_arg, rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node, const pm_node_location_t *node_location)
{
VALUE dup_rest = Qtrue;
- if (arguments_node != NULL) {
- size_t arg_size = arguments_node->arguments.size;
- const pm_node_list_t *args = &arguments_node->arguments;
- // Calls like foo(1, *f, **hash) that use splat and kwsplat
- // could be eligible for eliding duping the rest array (dup_reset=false).
- if (arg_size >= 2
- && PM_NODE_FLAG_P(arguments_node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT)
- && !PM_NODE_FLAG_P(arguments_node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS)
- && PM_NODE_TYPE_P(args->nodes[arg_size - 1], PM_KEYWORD_HASH_NODE)) {
- dup_rest = Qfalse;
-
- const pm_keyword_hash_node_t *keyword_arg = (const pm_keyword_hash_node_t *) args->nodes[arg_size - 1];
- const pm_node_list_t *elements = &keyword_arg->elements;
-
- if (PM_NODE_TYPE_P(elements->nodes[0], PM_ASSOC_NODE)) {
- const pm_assoc_node_t *assoc = (const pm_assoc_node_t *) elements->nodes[0];
-
- if (pm_setup_args_dup_rest_p(assoc->value)) {
- dup_rest = Qtrue;
- }
- }
-
- if (PM_NODE_TYPE_P(elements->nodes[0], PM_ASSOC_SPLAT_NODE)) {
- const pm_assoc_splat_node_t *assoc = (const pm_assoc_splat_node_t *) elements->nodes[0];
- if (assoc->value && pm_setup_args_dup_rest_p(assoc->value)) {
- dup_rest = Qtrue;
- }
}
}
}
VALUE initial_dup_rest = dup_rest;
if (block && PM_NODE_TYPE_P(block, PM_BLOCK_ARGUMENT_NODE)) {
// We compile the `&block_arg` expression first and stitch it later
// since the nature of the expression influences whether splat should
// duplicate the array.
bool regular_block_arg = true;
DECL_ANCHOR(block_arg);
INIT_ANCHOR(block_arg);
pm_compile_node(iseq, block, block_arg, false, scope_node);
@@ -1869,26 +1907,26 @@ pm_setup_args(const pm_arguments_node_t *arguments_node, const pm_node_t *block,
if (iobj->insn_id == BIN(getblockparam)) {
iobj->insn_id = BIN(getblockparamproxy);
}
// Allow splat without duplication for simple one-instruction
- // block arguments like `&arg`. It is known that this optimization
- // can be too aggressive in some cases. See [Bug #16504].
regular_block_arg = false;
}
}
- int argc = pm_setup_args_core(arguments_node, block, flags, regular_block_arg, kw_arg, &dup_rest, iseq, ret, scope_node, node_location);
-
- if (*flags & VM_CALL_ARGS_SPLAT && dup_rest != initial_dup_rest) {
- *flags |= VM_CALL_ARGS_SPLAT_MUT;
- }
-
PUSH_SEQ(ret, block_arg);
-
- return argc;
}
- int argc = pm_setup_args_core(arguments_node, block, flags, false, kw_arg, &dup_rest, iseq, ret, scope_node, node_location);
-
if (*flags & VM_CALL_ARGS_SPLAT && dup_rest != initial_dup_rest) {
*flags |= VM_CALL_ARGS_SPLAT_MUT;
}