From f4b299a1ed036234c0144797acba555c9feb3c6e Mon Sep 17 00:00:00 2001 From: Matt Valentine-House Date: Mon, 15 Jan 2024 20:59:11 +0000 Subject: [PATCH] Bind index & depth together into pm_local_index_t --- prism_compile.c | 59 +++++++++++++++++++++++++++---------------------- prism_compile.h | 12 ++++++++++ 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/prism_compile.c b/prism_compile.c index 1ef8ff637b..9d92017beb 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -813,15 +813,20 @@ pm_lookup_local_index_any_scope(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm return scope_node->local_table_for_iseq_size - (int)local_index; } -static int +static pm_local_index_t 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) { + pm_local_index_t lindex = {0}; + 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, NULL); + lindex.level = (int)depth; + lindex.index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id, NULL); + + return lindex; } // This returns the CRuby ID which maps to the pm_constant_id_t @@ -2117,7 +2122,7 @@ pm_compile_pattern(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t // of a pattern. For example, foo in bar. This results in the value // being matched being written to that local variable. pm_local_variable_target_node_t *cast = (pm_local_variable_target_node_t *) node; - int index = pm_lookup_local_index_with_depth(iseq, scope_node, cast->name, 0); + pm_local_index_t index = pm_lookup_local_index_with_depth(iseq, scope_node, cast->name, cast->depth); // If this local variable is being written from within an alternation // pattern, then it cannot actually be added to the local table since @@ -2133,7 +2138,7 @@ pm_compile_pattern(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t } } - ADD_SETLOCAL(ret, &line.node, index, (int) cast->depth); + ADD_SETLOCAL(ret, &line.node, index.index, index.level); ADD_INSNL(ret, &line.node, jump, matched_label); break; } @@ -4887,8 +4892,8 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_constant_id_t constant_id = local_variable_and_write_node->name; 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); + pm_local_index_t local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth); + ADD_GETLOCAL(ret, &dummy_line_node, local_index.index, local_index.level); PM_DUP_UNLESS_POPPED; @@ -4900,7 +4905,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.index, local_index.level); ADD_LABEL(ret, end_label); return; @@ -4911,8 +4916,8 @@ 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 = 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); + pm_local_index_t local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth); + ADD_GETLOCAL(ret, &dummy_line_node, local_index.index, local_index.level); 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); @@ -4922,7 +4927,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.index, local_index.level); return; } @@ -4937,8 +4942,8 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_constant_id_t constant_id = local_variable_or_write_node->name; 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); + pm_local_index_t local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth); + ADD_GETLOCAL(ret, &dummy_line_node, local_index.index, local_index.level); PM_DUP_UNLESS_POPPED; @@ -4951,7 +4956,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.index, local_index.level); ADD_LABEL(ret, end_label); return; @@ -4960,8 +4965,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 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); + pm_local_index_t 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.index, local_read_node->depth + scope_node->local_depth_offset); } return; } @@ -5125,12 +5130,12 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_TARGET_NODE)); pm_local_variable_target_node_t *local_target = (pm_local_variable_target_node_t *) target; - int index = pm_lookup_local_index_with_depth(iseq, scope_node, local_target->name, 0); + pm_local_index_t index = pm_lookup_local_index_with_depth(iseq, scope_node, local_target->name, local_target->depth); ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(scope_node, local_target->name))); ADD_SEND(ret, &dummy_line_node, idAREF, INT2FIX(1)); ADD_LABEL(ret, fail_label); - ADD_SETLOCAL(ret, &dummy_line_node, index, (int) local_target->depth); + ADD_SETLOCAL(ret, &dummy_line_node, index.index, index.level); PM_POP_IF_POPPED; return; } @@ -5142,14 +5147,14 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_TARGET_NODE)); pm_local_variable_target_node_t *local_target = (pm_local_variable_target_node_t *) target; - int index = pm_lookup_local_index_with_depth(iseq, scope_node, local_target->name, 0); + pm_local_index_t index = pm_lookup_local_index_with_depth(iseq, scope_node, local_target->name, local_target->depth); if (((size_t) targets_index) < (targets_count - 1)) { PM_DUP; } ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(scope_node, local_target->name))); ADD_SEND(ret, &dummy_line_node, idAREF, INT2FIX(1)); - ADD_SETLOCAL(ret, &dummy_line_node, index, (int) local_target->depth); + ADD_SETLOCAL(ret, &dummy_line_node, index.index, index.level); } // Since we matched successfully, now we'll jump to the end. @@ -5165,10 +5170,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_TARGET_NODE)); pm_local_variable_target_node_t *local_target = (pm_local_variable_target_node_t *) target; - int index = pm_lookup_local_index_with_depth(iseq, scope_node, local_target->name, 0); + pm_local_index_t index = pm_lookup_local_index_with_depth(iseq, scope_node, local_target->name, local_target->depth); PM_PUTNIL; - ADD_SETLOCAL(ret, &dummy_line_node, index, (int) local_target->depth); + ADD_SETLOCAL(ret, &dummy_line_node, index.index, index.level); } // Finally, we can push the end label for either case. @@ -5202,9 +5207,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_REQUIRED_PARAMETER_NODE: { pm_required_parameter_node_t *required_parameter_node = (pm_required_parameter_node_t *)node; - int index = pm_lookup_local_index_with_depth(iseq, scope_node, required_parameter_node->name, 0); + pm_local_index_t index = pm_lookup_local_index_with_depth(iseq, scope_node, required_parameter_node->name, 0); - ADD_SETLOCAL(ret, &dummy_line_node, index, 0); + ADD_SETLOCAL(ret, &dummy_line_node, index.index, index.level); return; } case PM_MULTI_TARGET_NODE: { @@ -5463,9 +5468,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_optional_parameter_node_t *optional_parameter_node = (pm_optional_parameter_node_t *)node; PM_COMPILE_NOT_POPPED(optional_parameter_node->value); - int index = pm_lookup_local_index_with_depth(iseq, scope_node, optional_parameter_node->name, 0); + pm_local_index_t index = pm_lookup_local_index_with_depth(iseq, scope_node, optional_parameter_node->name, 0); - ADD_SETLOCAL(ret, &dummy_line_node, index, 0); + ADD_SETLOCAL(ret, &dummy_line_node, index.index, index.level); return; } @@ -6414,12 +6419,12 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, PM_NODE_TYPE_P(value, PM_RANGE_NODE)) { LABEL *end_label = NEW_LABEL(nd_line(&dummy_line_node)); - int index = pm_lookup_local_index_with_depth(iseq, scope_node, name, 0); + pm_local_index_t index = pm_lookup_local_index_with_depth(iseq, scope_node, name, 0); int kw_bits_idx = table_size - body->param.keyword->bits_start; ADD_INSN2(ret, &dummy_line_node, checkkeyword, INT2FIX(kw_bits_idx + VM_ENV_DATA_SIZE - 1), INT2FIX(i)); ADD_INSNL(ret, &dummy_line_node, branchif, end_label); PM_COMPILE(value); - ADD_SETLOCAL(ret, &dummy_line_node, index, 0); + ADD_SETLOCAL(ret, &dummy_line_node, index.index, index.level); ADD_LABEL(ret, end_label); } diff --git a/prism_compile.h b/prism_compile.h index ed0c7b4c91..0b3a6fb826 100644 --- a/prism_compile.h +++ b/prism_compile.h @@ -1,5 +1,17 @@ #include "prism/prism.h" +/** + * the getlocal and setlocal instructions require two parameters. level is how + * many hops up the iseq stack one needs to go before finding the correct local + * table. The index is the index in that table where our variable is. + * + * Because these are always calculated and used together, we'll bind them + * together as a tuple. + */ +typedef struct pm_local_index_struct { + int index, level; +} pm_local_index_t; + // ScopeNodes are helper nodes, and will never be part of the AST. We manually // declare them here to avoid generating them. typedef struct pm_scope_node {