зеркало из https://github.com/github/ruby.git
Store depth offset inside the scope node.
Instead of incrementing the depth using call by reference as we're recursing up the stack we could instead store an offset for each known scope where we know the depth is going to represented differently in the Prism ast.
This commit is contained in:
Родитель
a1647c460f
Коммит
57782d3d47
|
@ -689,7 +689,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, int *depth)
|
||||
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
|
||||
|
@ -701,8 +701,7 @@ 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
|
||||
(*depth)++;
|
||||
return pm_lookup_local_index_any_scope(iseq, scope_node->previous, constant_id, depth);
|
||||
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;
|
||||
|
@ -723,14 +722,14 @@ pm_lookup_local_index(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_
|
|||
}
|
||||
|
||||
static int
|
||||
pm_lookup_local_index_with_depth(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id, int *depth)
|
||||
pm_lookup_local_index_with_depth(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id, uint32_t depth)
|
||||
{
|
||||
for(int i = 0; i < *depth; i++) {
|
||||
for(uint32_t i = 0; i < depth; i++) {
|
||||
scope_node = scope_node->previous;
|
||||
iseq = (rb_iseq_t *)ISEQ_BODY(iseq)->parent_iseq;
|
||||
}
|
||||
|
||||
return pm_lookup_local_index_any_scope(iseq, scope_node, constant_id, depth);
|
||||
return pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
|
||||
}
|
||||
|
||||
// This returns the CRuby ID which maps to the pm_constant_id_t
|
||||
|
@ -1337,8 +1336,10 @@ pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_
|
|||
scope->parameters = NULL;
|
||||
scope->body = NULL;
|
||||
scope->constants = NULL;
|
||||
scope->local_depth_offset = 0;
|
||||
if (previous) {
|
||||
scope->constants = previous->constants;
|
||||
scope->local_depth_offset = previous->local_depth_offset;
|
||||
}
|
||||
scope->index_lookup_table = NULL;
|
||||
|
||||
|
@ -1368,6 +1369,7 @@ pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_
|
|||
case PM_ENSURE_NODE: {
|
||||
pm_ensure_node_t *cast = (pm_ensure_node_t *)node;
|
||||
scope->body = (pm_node_t *)cast->statements;
|
||||
scope->local_depth_offset += 1;
|
||||
break;
|
||||
}
|
||||
case PM_FOR_NODE: {
|
||||
|
@ -3049,9 +3051,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
LABEL *end_label = NEW_LABEL(lineno);
|
||||
|
||||
pm_constant_id_t constant_id = local_variable_and_write_node->name;
|
||||
int *depth = (int *)&local_variable_and_write_node->depth;
|
||||
int depth = local_variable_and_write_node->depth + scope_node->local_depth_offset;
|
||||
int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
|
||||
ADD_GETLOCAL(ret, &dummy_line_node, local_index, *depth);
|
||||
ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
|
||||
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
|
@ -3063,7 +3065,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, local_index, *depth);
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
|
||||
ADD_LABEL(ret, end_label);
|
||||
|
||||
return;
|
||||
|
@ -3073,9 +3075,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
|
||||
pm_constant_id_t constant_id = local_variable_operator_write_node->name;
|
||||
|
||||
int *depth = (int *)&local_variable_operator_write_node->depth;
|
||||
int depth = local_variable_operator_write_node->depth + scope_node->local_depth_offset;
|
||||
int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
|
||||
ADD_GETLOCAL(ret, &dummy_line_node, local_index, *depth);
|
||||
ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
|
||||
|
||||
PM_COMPILE_NOT_POPPED(local_variable_operator_write_node->value);
|
||||
ID method_id = pm_constant_id_lookup(scope_node, local_variable_operator_write_node->operator);
|
||||
|
@ -3085,7 +3087,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, local_index, *depth);
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -3099,9 +3101,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
ADD_INSNL(ret, &dummy_line_node, branchunless, set_label);
|
||||
|
||||
pm_constant_id_t constant_id = local_variable_or_write_node->name;
|
||||
int *depth = (int *)&local_variable_or_write_node->depth;
|
||||
int depth = local_variable_or_write_node->depth + scope_node->local_depth_offset;
|
||||
int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
|
||||
ADD_GETLOCAL(ret, &dummy_line_node, local_index, *depth);
|
||||
ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
|
||||
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
|
@ -3114,7 +3116,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, local_index, *depth);
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
|
||||
ADD_LABEL(ret, end_label);
|
||||
|
||||
return;
|
||||
|
@ -3123,9 +3125,8 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
pm_local_variable_read_node_t *local_read_node = (pm_local_variable_read_node_t *) node;
|
||||
|
||||
if (!popped) {
|
||||
int *depth = (int *)&local_read_node->depth;
|
||||
int index = pm_lookup_local_index_with_depth(iseq, scope_node, local_read_node->name, depth);
|
||||
ADD_GETLOCAL(ret, &dummy_line_node, index, *depth);
|
||||
int index = pm_lookup_local_index_with_depth(iseq, scope_node, local_read_node->name, local_read_node->depth);
|
||||
ADD_GETLOCAL(ret, &dummy_line_node, index, local_read_node->depth + scope_node->local_depth_offset);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -3133,10 +3134,9 @@ 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 depth = 0;
|
||||
int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id, &depth);
|
||||
int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
|
||||
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, index, depth);
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->depth + scope_node->local_depth_offset);
|
||||
return;
|
||||
}
|
||||
case PM_LOCAL_VARIABLE_WRITE_NODE: {
|
||||
|
@ -3147,10 +3147,9 @@ 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 depth = 0;
|
||||
int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id, &depth);
|
||||
int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
|
||||
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, index, depth);
|
||||
ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->depth + scope_node->local_depth_offset);
|
||||
return;
|
||||
}
|
||||
case PM_MATCH_LAST_LINE_NODE: {
|
||||
|
|
|
@ -13,6 +13,11 @@ typedef struct pm_scope_node {
|
|||
|
||||
ID *constants;
|
||||
st_table *index_lookup_table;
|
||||
|
||||
// Some locals are defined at higher scopes than they are used. We can use
|
||||
// this offset to control which parent scopes local table we should be
|
||||
// referencing from the current scope.
|
||||
unsigned int local_depth_offset;
|
||||
} pm_scope_node_t;
|
||||
|
||||
void pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, pm_parser_t *parser);
|
||||
|
|
|
@ -737,6 +737,16 @@ module Prism
|
|||
end
|
||||
a + b + c
|
||||
CODE
|
||||
assert_prism_eval(<<~CODE)
|
||||
foo = 1
|
||||
begin
|
||||
ensure
|
||||
begin
|
||||
ensure
|
||||
foo.nil?
|
||||
end
|
||||
end
|
||||
CODE
|
||||
end
|
||||
|
||||
def test_NextNode
|
||||
|
|
Загрузка…
Ссылка в новой задаче