summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Valentine-House <matt@eightbitraptor.com>2023-12-13 14:40:34 +0000
committerJemma Issroff <jemmaissroff@gmail.com>2023-12-14 07:01:19 -0500
commita10c11a66bae7ec4bfb56d0ccfe74a0c6681fc77 (patch)
tree7176f5c84520bc2f6f67eb2375974f255c8e4f09
parente51f9e9f75cc1dde9234836fa92077d71b3c5141 (diff)
[PRISM] Add anon KW args to the block local table
-rw-r--r--prism_compile.c16
-rw-r--r--test/ruby/test_compile_prism.rb1
2 files changed, 15 insertions, 2 deletions
diff --git a/prism_compile.c b/prism_compile.c
index 768a02757a..610e5b4fcf 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -4427,6 +4427,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_node_list_t *posts_list = NULL;
pm_node_list_t *requireds_list = NULL;
pm_node_list_t *block_locals = NULL;
+ pm_node_t *block_param_keyword_rest = NULL;
struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
@@ -4436,6 +4437,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_block_parameters_node_t *block_parameters_node = (pm_block_parameters_node_t *)scope_node->parameters;
parameters_node = block_parameters_node->parameters;
block_locals = &block_parameters_node->locals;
+ if (parameters_node) {
+ block_param_keyword_rest = parameters_node->keyword_rest;
+ }
break;
}
case PM_PARAMETERS_NODE: {
@@ -4508,6 +4512,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
}
+ if (block_param_keyword_rest) {
+ table_size++;
+ }
+
// When we have a `...` as the keyword_rest, it's a forwarding_parameter_node and
// we need to leave space for 2 more locals on the locals table (`*` and `&`)
if (parameters_node && parameters_node->keyword_rest &&
@@ -4761,6 +4769,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
// ^^^
case PM_KEYWORD_REST_PARAMETER_NODE: {
+ pm_keyword_rest_parameter_node_t *kw_rest_node = (pm_keyword_rest_parameter_node_t *)parameters_node->keyword_rest;
if (!body->param.flags.has_kw) {
body->param.keyword = keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
}
@@ -4768,11 +4777,14 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
keyword->rest_start = local_index;
body->param.flags.has_kwrest = true;
- pm_constant_id_t constant_id = ((pm_keyword_rest_parameter_node_t *)parameters_node->keyword_rest)->name;
+ pm_constant_id_t constant_id = kw_rest_node->name;
if (constant_id) {
pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- local_index++;
}
+ else {
+ local_table_for_iseq->ids[local_index] = idPow;
+ }
+ local_index++;
break;
}
// def foo(...)
diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb
index 0c95f1b194..6a942cfff1 100644
--- a/test/ruby/test_compile_prism.rb
+++ b/test/ruby/test_compile_prism.rb
@@ -1632,6 +1632,7 @@ module Prism
def test_KeywordRestParameterNode
assert_prism_eval("def prism_test_keyword_rest_parameter_node(a, **b); end")
+ assert_prism_eval("Object.tap { |**| }")
end
def test_NoKeywordsParameterNode