summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2024-01-23 13:13:56 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2024-01-24 12:04:44 -0800
commit03f76f098ada081c8ce1db25ddc9b9fc21608877 (patch)
tree40f22afe8e874de8a5705fcf7283b6f7661bfb4b
parent29c3ec3d49ad66c4ec9ea13735481cca598bcbcd (diff)
Fix repeated optional _ parameters
Ensure there is enough space in the local table for repeated optional parameters. Co-Authored-By: Matt Valentine-House <matt@eightbitraptor.com>
-rw-r--r--prism_compile.c25
-rw-r--r--test/ruby/test_compile_prism.rb4
2 files changed, 27 insertions, 2 deletions
diff --git a/prism_compile.c b/prism_compile.c
index 4e2984c065..4e54a494d8 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -6341,6 +6341,19 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
}
+ // Ensure there is enough room in the local table for any
+ // parameters that have been repeated
+ // ex: def underscore_parameters(_, _ = 1, _ = 2); _; end
+ // ^^^^^^^^^^^^
+ if (optionals_list && optionals_list->size) {
+ for (size_t i = 0; i < optionals_list->size; i++) {
+ pm_node_t * node = optionals_list->nodes[i];
+ if (PM_NODE_FLAG_P(node, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) {
+ table_size++;
+ }
+ }
+ }
+
// If we have an anonymous "rest" node, we'll need to increase the local
// table size to take it in to account.
// def m(foo, *, bar)
@@ -6457,8 +6470,16 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
body->param.flags.has_opt = true;
for (size_t i = 0; i < optionals_list->size; i++, local_index++) {
- pm_constant_id_t name = ((pm_optional_parameter_node_t *)optionals_list->nodes[i])->name;
- pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
+ pm_node_t * node = optionals_list->nodes[i];
+ pm_constant_id_t name = ((pm_optional_parameter_node_t *)node)->name;
+
+ if (PM_NODE_FLAG_P(node, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) {
+ ID local = pm_constant_id_lookup(scope_node, name);
+ local_table_for_iseq->ids[local_index] = local;
+ }
+ else {
+ pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
+ }
}
}
diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb
index bccc4d4695..e5401fab9d 100644
--- a/test/ruby/test_compile_prism.rb
+++ b/test/ruby/test_compile_prism.rb
@@ -1545,6 +1545,10 @@ a
CODE
end
+ def test_repeated_optional_underscore
+ assert_prism_eval("def self.m(a, _, _, _ = 1, _ = 2, b); end; method(:m).parameters")
+ end
+
def test_repeated_required_underscore
assert_prism_eval("def self.m(a, _, _, b); end; method(:m).parameters")
end