diff options
author | Kevin Newton <[email protected]> | 2024-08-29 09:24:01 -0400 |
---|---|---|
committer | Kevin Newton <[email protected]> | 2024-08-29 10:29:34 -0400 |
commit | 14bb376b79ca9140bfd36dbbad06be045f31f92e () | |
tree | 7a2bffc436024aba71d9f34cf040df6f85406e64 /prism_compile.c | |
parent | 6b08a50a62f3575be4f7f4aeac0d416b8d3cd7c1 (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.c | 130 |
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; } |