Skip to content

Commit

Permalink
[PRISM] Add anon KW args to the block local table
Browse files Browse the repository at this point in the history
  • Loading branch information
eightbitraptor authored and jemmaissroff committed Dec 14, 2023
1 parent e51f9e9 commit a10c11a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
16 changes: 14 additions & 2 deletions prism_compile.c
Expand Up @@ -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);

Expand All @@ -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: {
Expand Down Expand Up @@ -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 &&
Expand Down Expand Up @@ -4761,18 +4769,22 @@ 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);
}

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(...)
Expand Down
1 change: 1 addition & 0 deletions test/ruby/test_compile_prism.rb
Expand Up @@ -1632,6 +1632,7 @@ def test_FowardingParameterNode

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
Expand Down

0 comments on commit a10c11a

Please sign in to comment.