summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Valentine-House <matt@eightbitraptor.com>2024-01-08 13:31:29 +0000
committerMatt Valentine-House <matt@eightbitraptor.com>2024-01-08 19:55:26 +0000
commit47ff4a165802236ae951c39fda1adf2887ad75b1 (patch)
tree189b61d4e31cacfb926d945a2f36f0be101c3579
parent94a98ce632eec8faba16355676d9d56313d6b381 (diff)
[PRISM] Blocks should track the found local depth
Rather than rely purely on local depth offset. This is because we can't assume a specific depth offset for all variable accesses happening within a block in the same way that we can for rescue/ensure/for or other nodes that push scopes. This is because block parameters are defined in the scope level, so we always need to start from the top most scope and walk backwards. Fixes ruby/prism@2053
-rw-r--r--prism_compile.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/prism_compile.c b/prism_compile.c
index e9c65329a3..1df2ccf8b2 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -760,7 +760,7 @@ pm_interpolated_node_compile(pm_node_list_t *parts, rb_iseq_t *iseq, NODE dummy_
// It also takes a pointer to depth, and increments depth appropriately
// according to the depth of the local
static int
-pm_lookup_local_index_any_scope(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id)
+pm_lookup_local_index_any_scope(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id, int *found_depth)
{
if (!scope_node) {
// We have recursed up all scope nodes
@@ -772,7 +772,10 @@ pm_lookup_local_index_any_scope(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm
if (!st_lookup(scope_node->index_lookup_table, constant_id, &local_index)) {
// Local does not exist at this level, continue recursing up
- return pm_lookup_local_index_any_scope(iseq, scope_node->previous, constant_id);
+ if (found_depth) {
+ (*found_depth)++;
+ }
+ return pm_lookup_local_index_any_scope(iseq, scope_node->previous, constant_id, found_depth);
}
return scope_node->local_table_for_iseq_size - (int)local_index;
@@ -798,7 +801,7 @@ pm_lookup_local_index_with_depth(rb_iseq_t *iseq, pm_scope_node_t *scope_node, p
iseq = (rb_iseq_t *)ISEQ_BODY(iseq)->parent_iseq;
}
- return pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
+ return pm_lookup_local_index_any_scope(iseq, scope_node, constant_id, NULL);
}
// This returns the CRuby ID which maps to the pm_constant_id_t
@@ -4679,9 +4682,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_local_variable_target_node_t *local_write_node = (pm_local_variable_target_node_t *) node;
pm_constant_id_t constant_id = local_write_node->name;
- int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
+ int found_depth = 0;
+ int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id, &found_depth);
- ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->depth + scope_node->local_depth_offset);
+ ADD_SETLOCAL(ret, &dummy_line_node, index, found_depth);
return;
}
case PM_LOCAL_VARIABLE_WRITE_NODE: {
@@ -4692,9 +4696,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_constant_id_t constant_id = local_write_node->name;
- int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
+ int found_depth = 0;
+ int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id, &found_depth);
- ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->depth + scope_node->local_depth_offset);
+ ADD_SETLOCAL(ret, &dummy_line_node, index, found_depth);
return;
}
case PM_MATCH_LAST_LINE_NODE: {