summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2024-08-28 18:30:21 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2024-08-28 19:27:15 -0400
commitfe440c59679b0475ad7b566b5680fdb9998207f7 (patch)
tree15f53ea64404407177265b5dbb2cc617b4f8bc8a
parent3fa5b4be195a84391e7cbde88b4c7d2e6fcf0e7c (diff)
[PRISM] Use node flags for dup_rest detection instead of looping
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/11489
-rw-r--r--prism_compile.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/prism_compile.c b/prism_compile.c
index 94a42e7ddd..c1562bcd2a 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -1823,35 +1823,27 @@ pm_setup_args(const pm_arguments_node_t *arguments_node, const pm_node_t *block,
// 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_TYPE_P(args->nodes[arg_size - 2], PM_SPLAT_NODE)
+ && 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)) {
- // Reject calls that have more than one splat.
dup_rest = Qfalse;
- for (size_t i = 0; i < arg_size - 2; i++) {
- if (PM_NODE_TYPE_P(args->nodes[i], PM_SPLAT_NODE)) {
- dup_rest = Qtrue;
- break;
- }
- }
- if (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;
+ 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_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_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 (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;
- }
+ if (assoc->value && pm_setup_args_dup_rest_p(assoc->value)) {
+ dup_rest = Qtrue;
}
}
}