[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
This commit is contained in:
Jemma Issroff 2023-11-20 15:40:35 -05:00
Родитель f9628fb4be
Коммит b913626bea
2 изменённых файлов: 45 добавлений и 3 удалений

Просмотреть файл

@ -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: {

Просмотреть файл

@ -268,6 +268,28 @@ module Prism
def test_LocalVariableWriteNode
assert_prism_eval("pit = 1")
assert_prism_eval(<<-CODE)
a = 0
[].each do
a = 1
end
a
CODE
assert_prism_eval(<<-CODE)
a = 1
d = 1
[1].each do
b = 2
a = 2
[2].each do
c = 3
d = 4
a = 2
end
end
[a, d]
CODE
end
def test_MatchWriteNode