From 47ff4a165802236ae951c39fda1adf2887ad75b1 Mon Sep 17 00:00:00 2001 From: Matt Valentine-House Date: Mon, 8 Jan 2024 13:31:29 +0000 Subject: [PATCH] [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 --- prism_compile.c | 19 ++++++++++++------- 1 file 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: {