Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PRISM] Add debug info for frozen strings #10399

Merged
merged 1 commit into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 33 additions & 6 deletions prism_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,23 @@ pm_source_file_value(const pm_source_file_node_t *node, const pm_scope_node_t *s
}
}

/**
* Return a static literal string, optionally with attached debugging
* information.
*/
static VALUE
pm_static_literal_string(rb_iseq_t *iseq, VALUE string, int line_number)
{
if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX(line_number));
rb_ivar_set(string, id_debug_created_info, rb_obj_freeze(debug_info));
return rb_str_freeze(string);
}
else {
return rb_fstring(string);
}
}

/**
* Certain nodes can be compiled literally. This function returns the literal
* value described by the given node. For example, an array node with all static
Expand Down Expand Up @@ -603,8 +620,11 @@ pm_static_literal_value(rb_iseq_t *iseq, const pm_node_t *node, const pm_scope_n
const pm_interpolated_regular_expression_node_t *cast = (const pm_interpolated_regular_expression_node_t *) node;
return parse_regexp_concat(iseq, scope_node, (const pm_node_t *) cast, &cast->parts);
}
case PM_INTERPOLATED_STRING_NODE:
return pm_static_literal_concat(&((const pm_interpolated_string_node_t *) node)->parts, scope_node, true);
case PM_INTERPOLATED_STRING_NODE: {
VALUE string = pm_static_literal_concat(&((const pm_interpolated_string_node_t *) node)->parts, scope_node, false);
int line_number = pm_node_line_number(scope_node->parser, node);
return pm_static_literal_string(iseq, string, line_number);
}
case PM_INTERPOLATED_SYMBOL_NODE: {
const pm_interpolated_symbol_node_t *cast = (const pm_interpolated_symbol_node_t *) node;
VALUE string = pm_static_literal_concat(&cast->parts, scope_node, true);
Expand All @@ -631,8 +651,11 @@ pm_static_literal_value(rb_iseq_t *iseq, const pm_node_t *node, const pm_scope_n
}
case PM_SOURCE_LINE_NODE:
return INT2FIX(pm_node_line_number(scope_node->parser, node));
case PM_STRING_NODE:
return rb_fstring(parse_string_encoded(scope_node, node, &((pm_string_node_t *)node)->unescaped));
case PM_STRING_NODE: {
VALUE string = parse_string_encoded(scope_node, node, &((const pm_string_node_t *) node)->unescaped);
int line_number = pm_node_line_number(scope_node->parser, node);
return pm_static_literal_string(iseq, string, line_number);
}
case PM_SYMBOL_NODE:
return ID2SYM(parse_string_symbol(scope_node, (const pm_symbol_node_t *) node));
case PM_TRUE_NODE:
Expand Down Expand Up @@ -4308,7 +4331,10 @@ pm_compile_case_node_dispatch(rb_iseq_t *iseq, VALUE dispatch, const pm_node_t *
break;
case PM_STRING_NODE: {
const pm_string_node_t *cast = (const pm_string_node_t *) node;
key = rb_fstring(parse_string_encoded(scope_node, node, &cast->unescaped));
VALUE string = parse_string_encoded(scope_node, node, &cast->unescaped);

int line_number = pm_node_line_number(scope_node->parser, node);
key = pm_static_literal_string(iseq, string, line_number);
break;
}
default:
Expand Down Expand Up @@ -8140,7 +8166,8 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// ^^^^^
if (!popped) {
const pm_string_node_t *cast = (const pm_string_node_t *) node;
VALUE value = rb_fstring(parse_string_encoded(scope_node, node, &cast->unescaped));
VALUE value = parse_string_encoded(scope_node, node, &cast->unescaped);
value = pm_static_literal_string(iseq, value, location.line);

if (PM_NODE_FLAG_P(node, PM_STRING_FLAGS_FROZEN)) {
PUSH_INSN1(ret, location, putobject, value);
Expand Down
3 changes: 0 additions & 3 deletions spec/prism.mspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# frozen_string_literal: true

## Command line
MSpec.register(:exclude, "The --debug flag produces debugging info on attempted frozen string modification")

## Language
MSpec.register(:exclude, "The BEGIN keyword runs multiple begins in FIFO order")
MSpec.register(:exclude, "Executing break from within a block works when passing through a super call")
Expand Down