aboutsummaryrefslogtreecommitdiffstats
path: root/prism_compile.c
diff options
context:
space:
mode:
authorJemma Issroff <jemmaissroff@gmail.com>2023-11-20 15:40:35 -0500
committerJemma Issroff <jemmaissroff@gmail.com>2023-11-20 13:48:46 -0800
commitb913626bea138908102cb6b2c9a6bf9438428c76 (patch)
treea68a2db930c7665212223ea6b8f4acad4e6c79cf /prism_compile.c
parentf9628fb4be1c5eb5a652a6c3d3d97530bdcc76a5 (diff)
downloadruby-b913626bea138908102cb6b2c9a6bf9438428c76.tar.gz
[PRISM] Fix LocalVariableWriteNodes within blocks
Prior to this commit, we weren't recursing up scopes to look for the local definition. With this commit, we do so, fixing local writes within blocks
Diffstat (limited to 'prism_compile.c')
-rw-r--r--prism_compile.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/prism_compile.c b/prism_compile.c
index f4fda7e183..ed171c4584 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -685,6 +685,26 @@ pm_interpolated_node_compile(pm_node_list_t *parts, rb_iseq_t *iseq, NODE dummy_
}
}
+// This recurses through scopes and finds the local index at any scope leve
+static int
+pm_lookup_local_index_any_scope(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id)
+{
+ if (!scope_node) {
+ // We have recursed up all scope nodes
+ // and have not found the local yet
+ rb_bug("This local does not exist");
+ }
+
+ st_data_t local_index;
+
+ 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);
+ }
+
+ return (int)scope_node->index_lookup_table->num_entries - (int)local_index;
+}
+
static int
pm_lookup_local_index(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id)
{
@@ -2866,7 +2886,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
for (size_t index = 0; index < local_write_node->depth; index++) scope_node = scope_node->previous;
int index = pm_lookup_local_index(iseq, scope_node, constant_id);
- ADD_SETLOCAL(ret, &dummy_line_node, (int)index, local_write_node->depth);
+ ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->depth);
return;
}
case PM_LOCAL_VARIABLE_WRITE_NODE: {
@@ -2876,9 +2896,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
PM_DUP_UNLESS_POPPED;
pm_constant_id_t constant_id = local_write_node->name;
- int index = pm_lookup_local_index(iseq, scope_node, constant_id);
+ int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
- ADD_SETLOCAL(ret, &dummy_line_node, (int)index, local_write_node->depth);
+ ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->depth);
return;
}
case PM_MATCH_LAST_LINE_NODE: {