[PRISM] Correctly hook up line numbers for eval

This commit is contained in:
Kevin Newton 2024-02-14 14:17:32 -05:00
parent 1d3b306753
commit 9933377c34
16 changed files with 133 additions and 139 deletions

11
iseq.c
View File

@ -1002,8 +1002,10 @@ pm_iseq_new_with_opt(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpa
if (!option) option = &COMPILE_OPTION_DEFAULT; if (!option) option = &COMPILE_OPTION_DEFAULT;
pm_location_t *location = &node->base.location; pm_location_t *location = &node->base.location;
pm_line_column_t start = pm_newline_list_line_column(&node->parser->newline_list, location->start); int32_t start_line = node->parser->start_line;
pm_line_column_t end = pm_newline_list_line_column(&node->parser->newline_list, location->end);
pm_line_column_t start = pm_newline_list_line_column(&node->parser->newline_list, location->start, start_line);
pm_line_column_t end = pm_newline_list_line_column(&node->parser->newline_list, location->end, start_line);
rb_code_location_t code_location = (rb_code_location_t) { rb_code_location_t code_location = (rb_code_location_t) {
.beg_pos = { .lineno = (int) start.line, .column = (int) start.column }, .beg_pos = { .lineno = (int) start.line, .column = (int) start.column },
@ -1232,8 +1234,9 @@ pm_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, V
StringValueCStr(file); StringValueCStr(file);
pm_parse_result_t result = { 0 }; pm_parse_result_t result = { 0 };
VALUE error; pm_options_line_set(&result.options, NUM2INT(line));
VALUE error;
if (RB_TYPE_P(src, T_FILE)) { if (RB_TYPE_P(src, T_FILE)) {
VALUE filepath = rb_io_path(src); VALUE filepath = rb_io_path(src);
error = pm_parse_file(&result, filepath); error = pm_parse_file(&result, filepath);
@ -1635,6 +1638,8 @@ iseqw_s_compile_file_prism(int argc, VALUE *argv, VALUE self)
VALUE v = rb_vm_push_frame_fname(ec, file); VALUE v = rb_vm_push_frame_fname(ec, file);
pm_parse_result_t result = { 0 }; pm_parse_result_t result = { 0 };
result.options.line = 1;
VALUE error = pm_parse_file(&result, file); VALUE error = pm_parse_file(&result, file);
if (error == Qnil) { if (error == Qnil) {

2
load.c
View File

@ -745,6 +745,8 @@ load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
if (*rb_ruby_prism_ptr()) { if (*rb_ruby_prism_ptr()) {
pm_parse_result_t result = { 0 }; pm_parse_result_t result = { 0 };
result.options.line = 1;
VALUE error = pm_parse_file(&result, fname); VALUE error = pm_parse_file(&result, fname);
if (error == Qnil) { if (error == Qnil) {

View File

@ -18115,7 +18115,7 @@ typedef struct {
pm_diagnostic_t *error; pm_diagnostic_t *error;
/** The start line of the diagnostic message. */ /** The start line of the diagnostic message. */
uint32_t line; int32_t line;
/** The column start of the diagnostic message. */ /** The column start of the diagnostic message. */
uint32_t column_start; uint32_t column_start;
@ -18147,12 +18147,13 @@ typedef struct {
#define PM_COLOR_RESET "\033[0m" #define PM_COLOR_RESET "\033[0m"
static inline pm_error_t * static inline pm_error_t *
pm_parser_errors_format_sort(const pm_list_t *error_list, const pm_newline_list_t *newline_list) { pm_parser_errors_format_sort(const pm_parser_t *parser, const pm_list_t *error_list, const pm_newline_list_t *newline_list) {
pm_error_t *errors = calloc(error_list->size, sizeof(pm_error_t)); pm_error_t *errors = calloc(error_list->size, sizeof(pm_error_t));
int32_t start_line = parser->start_line;
for (pm_diagnostic_t *error = (pm_diagnostic_t *) error_list->head; error != NULL; error = (pm_diagnostic_t *) error->node.next) { for (pm_diagnostic_t *error = (pm_diagnostic_t *) error_list->head; error != NULL; error = (pm_diagnostic_t *) error->node.next) {
pm_line_column_t start = pm_newline_list_line_column(newline_list, error->location.start); pm_line_column_t start = pm_newline_list_line_column(newline_list, error->location.start, start_line);
pm_line_column_t end = pm_newline_list_line_column(newline_list, error->location.end); pm_line_column_t end = pm_newline_list_line_column(newline_list, error->location.end, start_line);
// We're going to insert this error into the array in sorted order. We // We're going to insert this error into the array in sorted order. We
// do this by finding the first error that has a line number greater // do this by finding the first error that has a line number greater
@ -18163,8 +18164,8 @@ pm_parser_errors_format_sort(const pm_list_t *error_list, const pm_newline_list_
(index < error_list->size) && (index < error_list->size) &&
(errors[index].error != NULL) && (errors[index].error != NULL) &&
( (
(errors[index].line < ((uint32_t) start.line)) || (errors[index].line < start.line) ||
(errors[index].line == ((uint32_t) start.line) && errors[index].column_start < ((uint32_t) start.column)) ((errors[index].line == start.line) && (errors[index].column_start < start.column))
) )
) index++; ) index++;
@ -18177,18 +18178,18 @@ pm_parser_errors_format_sort(const pm_list_t *error_list, const pm_newline_list_
// Finally, we'll insert the error into the array. // Finally, we'll insert the error into the array.
uint32_t column_end; uint32_t column_end;
if (start.line == end.line) { if (start.line == end.line) {
column_end = (uint32_t) end.column; column_end = end.column;
} else { } else {
column_end = (uint32_t) (newline_list->offsets[start.line] - newline_list->offsets[start.line - 1] - 1); column_end = (uint32_t) (newline_list->offsets[start.line - start_line + 1] - newline_list->offsets[start.line - start_line] - 1);
} }
// Ensure we have at least one column of error. // Ensure we have at least one column of error.
if (((uint32_t) start.column) == column_end) column_end++; if (start.column == column_end) column_end++;
errors[index] = (pm_error_t) { errors[index] = (pm_error_t) {
.error = error, .error = error,
.line = (uint32_t) start.line, .line = start.line,
.column_start = (uint32_t) start.column, .column_start = start.column,
.column_end = column_end .column_end = column_end
}; };
} }
@ -18197,17 +18198,19 @@ pm_parser_errors_format_sort(const pm_list_t *error_list, const pm_newline_list_
} }
static inline void static inline void
pm_parser_errors_format_line(const pm_parser_t *parser, const pm_newline_list_t *newline_list, const char *number_prefix, size_t line, pm_buffer_t *buffer) { pm_parser_errors_format_line(const pm_parser_t *parser, const pm_newline_list_t *newline_list, const char *number_prefix, int32_t line, pm_buffer_t *buffer) {
const uint8_t *start = &parser->start[newline_list->offsets[line - 1]]; size_t index = (size_t) (line - parser->start_line);
const uint8_t *start = &parser->start[newline_list->offsets[index]];
const uint8_t *end; const uint8_t *end;
if (line >= newline_list->size) { if (index >= newline_list->size - 1) {
end = parser->end; end = parser->end;
} else { } else {
end = &parser->start[newline_list->offsets[line]]; end = &parser->start[newline_list->offsets[index + 1]];
} }
pm_buffer_append_format(buffer, number_prefix, (uint32_t) line); pm_buffer_append_format(buffer, number_prefix, line);
pm_buffer_append_string(buffer, (const char *) start, (size_t) (end - start)); pm_buffer_append_string(buffer, (const char *) start, (size_t) (end - start));
if (end == parser->end && end[-1] != '\n') { if (end == parser->end && end[-1] != '\n') {
@ -18225,25 +18228,26 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
// First, we're going to sort all of the errors by line number using an // First, we're going to sort all of the errors by line number using an
// insertion sort into a newly allocated array. // insertion sort into a newly allocated array.
const int32_t start_line = parser->start_line;
const pm_newline_list_t *newline_list = &parser->newline_list; const pm_newline_list_t *newline_list = &parser->newline_list;
pm_error_t *errors = pm_parser_errors_format_sort(error_list, newline_list); pm_error_t *errors = pm_parser_errors_format_sort(parser, error_list, newline_list);
// Now we're going to determine how we're going to format line numbers and // Now we're going to determine how we're going to format line numbers and
// blank lines based on the maximum number of digits in the line numbers // blank lines based on the maximum number of digits in the line numbers
// that are going to be displayed. // that are going to be displayed.
pm_error_format_t error_format; pm_error_format_t error_format;
size_t max_line_number = errors[error_list->size - 1].line; int32_t max_line_number = errors[error_list->size - 1].line - start_line;
if (max_line_number < 10) { if (max_line_number < 10) {
if (colorize) { if (colorize) {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%1" PRIu32 " | " PM_COLOR_RESET, .number_prefix = PM_COLOR_GRAY "%1" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET, .blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
.divider = PM_COLOR_GRAY " ~~~~~" PM_COLOR_RESET "\n" .divider = PM_COLOR_GRAY " ~~~~~" PM_COLOR_RESET "\n"
}; };
} else { } else {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = "%1" PRIu32 " | ", .number_prefix = "%1" PRIi32 " | ",
.blank_prefix = " | ", .blank_prefix = " | ",
.divider = " ~~~~~\n" .divider = " ~~~~~\n"
}; };
@ -18251,13 +18255,13 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
} else if (max_line_number < 100) { } else if (max_line_number < 100) {
if (colorize) { if (colorize) {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%2" PRIu32 " | " PM_COLOR_RESET, .number_prefix = PM_COLOR_GRAY "%2" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET, .blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
.divider = PM_COLOR_GRAY " ~~~~~~" PM_COLOR_RESET "\n" .divider = PM_COLOR_GRAY " ~~~~~~" PM_COLOR_RESET "\n"
}; };
} else { } else {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = "%2" PRIu32 " | ", .number_prefix = "%2" PRIi32 " | ",
.blank_prefix = " | ", .blank_prefix = " | ",
.divider = " ~~~~~~\n" .divider = " ~~~~~~\n"
}; };
@ -18265,13 +18269,13 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
} else if (max_line_number < 1000) { } else if (max_line_number < 1000) {
if (colorize) { if (colorize) {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%3" PRIu32 " | " PM_COLOR_RESET, .number_prefix = PM_COLOR_GRAY "%3" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET, .blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
.divider = PM_COLOR_GRAY " ~~~~~~~" PM_COLOR_RESET "\n" .divider = PM_COLOR_GRAY " ~~~~~~~" PM_COLOR_RESET "\n"
}; };
} else { } else {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = "%3" PRIu32 " | ", .number_prefix = "%3" PRIi32 " | ",
.blank_prefix = " | ", .blank_prefix = " | ",
.divider = " ~~~~~~~\n" .divider = " ~~~~~~~\n"
}; };
@ -18279,13 +18283,13 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
} else if (max_line_number < 10000) { } else if (max_line_number < 10000) {
if (colorize) { if (colorize) {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%4" PRIu32 " | " PM_COLOR_RESET, .number_prefix = PM_COLOR_GRAY "%4" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET, .blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
.divider = PM_COLOR_GRAY " ~~~~~~~~" PM_COLOR_RESET "\n" .divider = PM_COLOR_GRAY " ~~~~~~~~" PM_COLOR_RESET "\n"
}; };
} else { } else {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = "%4" PRIu32 " | ", .number_prefix = "%4" PRIi32 " | ",
.blank_prefix = " | ", .blank_prefix = " | ",
.divider = " ~~~~~~~~\n" .divider = " ~~~~~~~~\n"
}; };
@ -18293,13 +18297,13 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
} else { } else {
if (colorize) { if (colorize) {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%5" PRIu32 " | " PM_COLOR_RESET, .number_prefix = PM_COLOR_GRAY "%5" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET, .blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
.divider = PM_COLOR_GRAY " ~~~~~~~~" PM_COLOR_RESET "\n" .divider = PM_COLOR_GRAY " ~~~~~~~~" PM_COLOR_RESET "\n"
}; };
} else { } else {
error_format = (pm_error_format_t) { error_format = (pm_error_format_t) {
.number_prefix = "%5" PRIu32 " | ", .number_prefix = "%5" PRIi32 " | ",
.blank_prefix = " | ", .blank_prefix = " | ",
.divider = " ~~~~~~~~\n" .divider = " ~~~~~~~~\n"
}; };
@ -18314,7 +18318,7 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
// the source before the error to give some context. We'll be careful not to // the source before the error to give some context. We'll be careful not to
// display the same line twice in case the errors are close enough in the // display the same line twice in case the errors are close enough in the
// source. // source.
uint32_t last_line = 0; int32_t last_line = 0;
const pm_encoding_t *encoding = parser->encoding; const pm_encoding_t *encoding = parser->encoding;
for (size_t index = 0; index < error_list->size; index++) { for (size_t index = 0; index < error_list->size; index++) {
@ -18360,7 +18364,7 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
pm_buffer_append_string(buffer, error_format.blank_prefix, error_format.blank_prefix_length); pm_buffer_append_string(buffer, error_format.blank_prefix, error_format.blank_prefix_length);
size_t column = 0; size_t column = 0;
const uint8_t *start = &parser->start[newline_list->offsets[error->line - 1]]; const uint8_t *start = &parser->start[newline_list->offsets[error->line - start_line]];
while (column < error->column_end) { while (column < error->column_end) {
if (column < error->column_start) { if (column < error->column_start) {
@ -18384,7 +18388,7 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
// Here we determine how many lines of padding to display after the // Here we determine how many lines of padding to display after the
// error, depending on where the next error is in source. // error, depending on where the next error is in source.
last_line = error->line; last_line = error->line;
size_t next_line = (index == error_list->size - 1) ? newline_list->size : errors[index + 1].line; int32_t next_line = (index == error_list->size - 1) ? ((int32_t) newline_list->size) : errors[index + 1].line;
if (next_line - last_line > 1) { if (next_line - last_line > 1) {
pm_buffer_append_string(buffer, " ", 2); pm_buffer_append_string(buffer, " ", 2);

View File

@ -38,9 +38,9 @@ prettyprint_source(pm_buffer_t *output_buffer, const uint8_t *source, size_t len
static inline void static inline void
prettyprint_location(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_location_t *location) { prettyprint_location(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_location_t *location) {
pm_line_column_t start = pm_newline_list_line_column(&parser->newline_list, location->start); pm_line_column_t start = pm_newline_list_line_column(&parser->newline_list, location->start, parser->start_line);
pm_line_column_t end = pm_newline_list_line_column(&parser->newline_list, location->end); pm_line_column_t end = pm_newline_list_line_column(&parser->newline_list, location->end, parser->start_line);
pm_buffer_append_format(output_buffer, "(%lu,%lu)-(%lu,%lu)", (unsigned long) start.line, (unsigned long) start.column, (unsigned long) end.line, (unsigned long) end.column); pm_buffer_append_format(output_buffer, "(%" PRIi32 ",%" PRIu32 ")-(%" PRIi32 ",%" PRIu32 ")", start.line, start.column, end.line, end.column);
} }
static inline void static inline void

View File

@ -51,7 +51,7 @@ pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor) {
* are returned. * are returned.
*/ */
pm_line_column_t pm_line_column_t
pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor) { pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line) {
assert(cursor >= list->start); assert(cursor >= list->start);
size_t offset = (size_t) (cursor - list->start); size_t offset = (size_t) (cursor - list->start);
@ -62,7 +62,7 @@ pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor
size_t mid = left + (right - left) / 2; size_t mid = left + (right - left) / 2;
if (list->offsets[mid] == offset) { if (list->offsets[mid] == offset) {
return ((pm_line_column_t) { mid + 1, 0 }); return ((pm_line_column_t) { ((int32_t) mid) + start_line, 0 });
} }
if (list->offsets[mid] < offset) { if (list->offsets[mid] < offset) {
@ -72,7 +72,10 @@ pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor
} }
} }
return ((pm_line_column_t) { left, offset - list->offsets[left - 1] }); return ((pm_line_column_t) {
.line = ((int32_t) left) + start_line - 1,
.column = (uint32_t) (offset - list->offsets[left - 1])
});
} }
/** /**

View File

@ -44,10 +44,10 @@ typedef struct {
*/ */
typedef struct { typedef struct {
/** The line number. */ /** The line number. */
size_t line; int32_t line;
/** The column number. */ /** The column number. */
size_t column; uint32_t column;
} pm_line_column_t; } pm_line_column_t;
/** /**
@ -79,9 +79,10 @@ bool pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor);
* *
* @param list The list to search. * @param list The list to search.
* @param cursor A pointer to the offset to search for. * @param cursor A pointer to the offset to search for.
* @param start_line The line to start counting from.
* @return The line and column of the given offset. * @return The line and column of the given offset.
*/ */
pm_line_column_t pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor); pm_line_column_t pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line);
/** /**
* Free the internal memory allocated for the newline list. * Free the internal memory allocated for the newline list.

View File

@ -93,10 +93,14 @@
#define PM_CONSTANT_POW ((pm_constant_id_t)(idPow | PM_SPECIAL_CONSTANT_FLAG)) #define PM_CONSTANT_POW ((pm_constant_id_t)(idPow | PM_SPECIAL_CONSTANT_FLAG))
static int static int
pm_line_number(const pm_parser_t *parser, const pm_node_t *node) pm_location_line_number(const pm_parser_t *parser, const pm_location_t *location) {
return (int) pm_newline_list_line_column(&parser->newline_list, location->start, parser->start_line).line;
}
static int
pm_node_line_number(const pm_parser_t *parser, const pm_node_t *node)
{ {
pm_line_column_t line_column = pm_newline_list_line_column(&parser->newline_list, node->location.start); return (int) pm_newline_list_line_column(&parser->newline_list, node->location.start, parser->start_line).line;
return (int) line_column.line;
} }
static VALUE static VALUE
@ -431,11 +435,8 @@ pm_static_literal_value(const pm_node_t *node, const pm_scope_node_t *scope_node
pm_source_file_node_t *cast = (pm_source_file_node_t *)node; pm_source_file_node_t *cast = (pm_source_file_node_t *)node;
return cast->filepath.length ? parse_string(&cast->filepath, scope_node->parser) : rb_fstring_lit("<compiled>"); return cast->filepath.length ? parse_string(&cast->filepath, scope_node->parser) : rb_fstring_lit("<compiled>");
} }
case PM_SOURCE_LINE_NODE: { case PM_SOURCE_LINE_NODE:
int source_line = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; return INT2FIX(pm_node_line_number(scope_node->parser, node));
// TODO: Incorporate options which allow for passing a line number
return INT2FIX(source_line);
}
case PM_STRING_NODE: case PM_STRING_NODE:
return parse_string_encoded(node, &((pm_string_node_t *)node)->unescaped, scope_node->parser); return parse_string_encoded(node, &((pm_string_node_t *)node)->unescaped, scope_node->parser);
case PM_SYMBOL_NODE: case PM_SYMBOL_NODE:
@ -484,11 +485,8 @@ pm_line_node(pm_line_node_t *line_node, const pm_scope_node_t *scope_node, const
// First, clear out the pointer. // First, clear out the pointer.
memset(line_node, 0, sizeof(pm_line_node_t)); memset(line_node, 0, sizeof(pm_line_node_t));
// Next, retrieve the line and column information from prism.
pm_line_column_t line_column = pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start);
// Next, use the line number for the dummy node. // Next, use the line number for the dummy node.
int lineno = (int) line_column.line; int lineno = pm_node_line_number(scope_node->parser, node);
nd_set_line(&line_node->node, lineno); nd_set_line(&line_node->node, lineno);
nd_set_node_id(&line_node->node, lineno); nd_set_node_id(&line_node->node, lineno);
@ -502,7 +500,7 @@ pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_no
static void static void
pm_compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_node_t *cond, LABEL *then_label, LABEL *else_label, bool popped, pm_scope_node_t *scope_node) pm_compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_node_t *cond, LABEL *then_label, LABEL *else_label, bool popped, pm_scope_node_t *scope_node)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, cond->location.start).line; int lineno = pm_node_line_number(scope_node->parser, cond);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
DECL_ANCHOR(seq); DECL_ANCHOR(seq);
@ -580,7 +578,7 @@ static void
pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_node_t *cond, pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_node_t *cond,
LABEL *then_label, LABEL *else_label, bool popped, pm_scope_node_t *scope_node) LABEL *then_label, LABEL *else_label, bool popped, pm_scope_node_t *scope_node)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, cond->location.start).line; int lineno = pm_node_line_number(scope_node->parser, cond);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
again: again:
@ -1338,7 +1336,7 @@ pm_setup_args(const pm_arguments_node_t *arguments_node, const pm_node_t *block,
static void static void
pm_compile_index_operator_write_node(pm_scope_node_t *scope_node, const pm_index_operator_write_node_t *node, rb_iseq_t *iseq, LINK_ANCHOR *const ret, bool popped) pm_compile_index_operator_write_node(pm_scope_node_t *scope_node, const pm_index_operator_write_node_t *node, rb_iseq_t *iseq, LINK_ANCHOR *const ret, bool popped)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->base.location.start).line; int lineno = pm_node_line_number(scope_node->parser, (const pm_node_t *) node);
const NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); const NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
if (!popped) { if (!popped) {
@ -1458,7 +1456,7 @@ pm_compile_index_operator_write_node(pm_scope_node_t *scope_node, const pm_index
static void static void
pm_compile_index_control_flow_write_node(pm_scope_node_t *scope_node, const pm_node_t *node, const pm_node_t *receiver, const pm_arguments_node_t *arguments, const pm_node_t *block, const pm_node_t *value, rb_iseq_t *iseq, LINK_ANCHOR *const ret, bool popped) pm_compile_index_control_flow_write_node(pm_scope_node_t *scope_node, const pm_node_t *node, const pm_node_t *receiver, const pm_arguments_node_t *arguments, const pm_node_t *block, const pm_node_t *value, rb_iseq_t *iseq, LINK_ANCHOR *const ret, bool popped)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; int lineno = pm_node_line_number(scope_node->parser, node);
const NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); const NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
if (!popped) { if (!popped) {
@ -2958,11 +2956,10 @@ pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *con
static void static void
pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, ID method_id, LABEL *start) pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, ID method_id, LABEL *start)
{ {
const pm_parser_t *parser = scope_node->parser; const pm_location_t *message_loc = &call_node->message_loc;
const uint8_t *call_start = call_node->message_loc.start; if (message_loc->start == NULL) message_loc = &call_node->base.location;
if (call_start == NULL) call_start = call_node->base.location.start;
int lineno = (int) pm_newline_list_line_column(&parser->newline_list, call_start).line; int lineno = pm_location_line_number(scope_node->parser, message_loc);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
LABEL *else_label = NEW_LABEL(lineno); LABEL *else_label = NEW_LABEL(lineno);
@ -2982,11 +2979,9 @@ pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *c
if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) { if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) {
// Scope associated with the block // Scope associated with the block
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init(call_node->block, &next_scope_node, scope_node, parser); pm_scope_node_init(call_node->block, &next_scope_node, scope_node, scope_node->parser);
int block_lineno = (int) pm_newline_list_line_column(&parser->newline_list, call_node->block->location.start).line;
block_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, block_lineno);
block_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, pm_node_line_number(scope_node->parser, call_node->block));
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
if (ISEQ_BODY(block_iseq)->catch_table) { if (ISEQ_BODY(block_iseq)->catch_table) {
@ -3201,7 +3196,7 @@ pm_compile_destructured_param_locals(const pm_multi_target_node_t *node, st_tabl
static inline void static inline void
pm_compile_destructured_param_write(rb_iseq_t *iseq, const pm_required_parameter_node_t *node, LINK_ANCHOR *const ret, const pm_scope_node_t *scope_node) pm_compile_destructured_param_write(rb_iseq_t *iseq, const pm_required_parameter_node_t *node, LINK_ANCHOR *const ret, const pm_scope_node_t *scope_node)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->base.location.start).line; int lineno = pm_node_line_number(scope_node->parser, (const pm_node_t *) node);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
pm_local_index_t index = pm_lookup_local_index(iseq, scope_node, node->name, 0); pm_local_index_t index = pm_lookup_local_index(iseq, scope_node, node->name, 0);
@ -3219,7 +3214,7 @@ pm_compile_destructured_param_write(rb_iseq_t *iseq, const pm_required_parameter
static void static void
pm_compile_destructured_param_writes(rb_iseq_t *iseq, const pm_multi_target_node_t *node, LINK_ANCHOR *const ret, const pm_scope_node_t *scope_node) pm_compile_destructured_param_writes(rb_iseq_t *iseq, const pm_multi_target_node_t *node, LINK_ANCHOR *const ret, const pm_scope_node_t *scope_node)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->base.location.start).line; int lineno = pm_node_line_number(scope_node->parser, (const pm_node_t *) node);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
bool has_rest = (node->rest && PM_NODE_TYPE_P(node->rest, PM_SPLAT_NODE) && (((pm_splat_node_t *) node->rest)->expression) != NULL); bool has_rest = (node->rest && PM_NODE_TYPE_P(node->rest, PM_SPLAT_NODE) && (((pm_splat_node_t *) node->rest)->expression) != NULL);
@ -3415,7 +3410,7 @@ pm_compile_multi_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR
static void static void
pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const parents, LINK_ANCHOR *const writes, LINK_ANCHOR *const cleanup, pm_scope_node_t *scope_node, pm_multi_target_state_t *state) pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const parents, LINK_ANCHOR *const writes, LINK_ANCHOR *const cleanup, pm_scope_node_t *scope_node, pm_multi_target_state_t *state)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; int lineno = pm_node_line_number(scope_node->parser, node);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
switch (PM_NODE_TYPE(node)) { switch (PM_NODE_TYPE(node)) {
@ -3629,7 +3624,7 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
static size_t static size_t
pm_compile_multi_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const parents, LINK_ANCHOR *const writes, LINK_ANCHOR *const cleanup, pm_scope_node_t *scope_node, pm_multi_target_state_t *state) pm_compile_multi_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const parents, LINK_ANCHOR *const writes, LINK_ANCHOR *const cleanup, pm_scope_node_t *scope_node, pm_multi_target_state_t *state)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; int lineno = pm_node_line_number(scope_node->parser, node);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
const pm_node_list_t *lefts; const pm_node_list_t *lefts;
@ -3720,7 +3715,7 @@ pm_compile_multi_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR
static void static void
pm_compile_for_node_index(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node) pm_compile_for_node_index(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; int lineno = pm_node_line_number(scope_node->parser, node);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
switch (PM_NODE_TYPE(node)) { switch (PM_NODE_TYPE(node)) {
@ -3824,7 +3819,7 @@ pm_compile_rescue(rb_iseq_t *iseq, pm_begin_node_t *begin_node, LINK_ANCHOR *con
&rescue_scope_node, &rescue_scope_node,
rb_str_concat(rb_str_new2("rescue in "), ISEQ_BODY(iseq)->location.label), rb_str_concat(rb_str_new2("rescue in "), ISEQ_BODY(iseq)->location.label),
ISEQ_TYPE_RESCUE, ISEQ_TYPE_RESCUE,
pm_line_number(parser, (const pm_node_t *) begin_node->rescue_clause) pm_node_line_number(parser, (const pm_node_t *) begin_node->rescue_clause)
); );
pm_scope_node_destroy(&rescue_scope_node); pm_scope_node_destroy(&rescue_scope_node);
@ -3899,7 +3894,7 @@ pm_compile_ensure(rb_iseq_t *iseq, pm_begin_node_t *begin_node, LINK_ANCHOR *con
&next_scope_node, &next_scope_node,
rb_str_concat(rb_str_new2("ensure in "), ISEQ_BODY(iseq)->location.label), rb_str_concat(rb_str_new2("ensure in "), ISEQ_BODY(iseq)->location.label),
ISEQ_TYPE_ENSURE, ISEQ_TYPE_ENSURE,
pm_line_number(parser, (const pm_node_t *) begin_node->ensure_clause) pm_node_line_number(parser, (const pm_node_t *) begin_node->ensure_clause)
); );
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -3985,7 +3980,7 @@ pm_opt_aset_with_p(const rb_iseq_t *iseq, const pm_call_node_t *node)
static void static void
pm_compile_constant_read(rb_iseq_t *iseq, VALUE name, const pm_location_t *name_loc, LINK_ANCHOR *const ret, const pm_scope_node_t *scope_node) pm_compile_constant_read(rb_iseq_t *iseq, VALUE name, const pm_location_t *name_loc, LINK_ANCHOR *const ret, const pm_scope_node_t *scope_node)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, name_loc->start).line; int lineno = pm_location_line_number(scope_node->parser, name_loc);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) { if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
@ -4045,7 +4040,7 @@ pm_constant_path_parts(const pm_node_t *node, const pm_scope_node_t *scope_node)
static void static void
pm_compile_constant_path(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const prefix, LINK_ANCHOR *const body, bool popped, pm_scope_node_t *scope_node) pm_compile_constant_path(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const prefix, LINK_ANCHOR *const body, bool popped, pm_scope_node_t *scope_node)
{ {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; int lineno = pm_node_line_number(scope_node->parser, node);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
switch (PM_NODE_TYPE(node)) { switch (PM_NODE_TYPE(node)) {
@ -4141,7 +4136,8 @@ pm_compile_case_node_dispatch(VALUE dispatch, const pm_node_t *node, LABEL *labe
static void static void
pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node) pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node)
{ {
const pm_line_column_t location = pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start); const pm_parser_t *parser = scope_node->parser;
const pm_line_column_t location = pm_newline_list_line_column(&parser->newline_list, node->location.start, parser->start_line);
int lineno = (int) location.line; int lineno = (int) location.line;
if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_NEWLINE) && ISEQ_COMPILE_DATA(iseq)->last_line != lineno) { if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_NEWLINE) && ISEQ_COMPILE_DATA(iseq)->last_line != lineno) {
@ -4163,8 +4159,8 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
const pm_alias_global_variable_node_t *cast = (const pm_alias_global_variable_node_t *) node; const pm_alias_global_variable_node_t *cast = (const pm_alias_global_variable_node_t *) node;
PUSH_INSN1(ret, location, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); PUSH_INSN1(ret, location, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
PUSH_INSN1(ret, location, putobject, ID2SYM(parse_location_symbol(&cast->new_name->location, scope_node->parser))); PUSH_INSN1(ret, location, putobject, ID2SYM(parse_location_symbol(&cast->new_name->location, parser)));
PUSH_INSN1(ret, location, putobject, ID2SYM(parse_location_symbol(&cast->old_name->location, scope_node->parser))); PUSH_INSN1(ret, location, putobject, ID2SYM(parse_location_symbol(&cast->old_name->location, parser)));
PUSH_SEND(ret, location, id_core_set_variable_alias, INT2FIX(2)); PUSH_SEND(ret, location, id_core_set_variable_alias, INT2FIX(2));
if (popped) PUSH_INSN(ret, location, pop); if (popped) PUSH_INSN(ret, location, pop);
@ -4480,7 +4476,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
switch (method_id) { switch (method_id) {
case idUMinus: { case idUMinus: {
if (pm_opt_str_freeze_p(iseq, call_node)) { if (pm_opt_str_freeze_p(iseq, call_node)) {
VALUE value = rb_fstring(parse_string_encoded(call_node->receiver, &((const pm_string_node_t * )call_node->receiver)->unescaped, scope_node->parser)); VALUE value = rb_fstring(parse_string_encoded(call_node->receiver, &((const pm_string_node_t * )call_node->receiver)->unescaped, parser));
ADD_INSN2(ret, &dummy_line_node, opt_str_uminus, value, new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE)); ADD_INSN2(ret, &dummy_line_node, opt_str_uminus, value, new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
return; return;
} }
@ -4488,7 +4484,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
} }
case idFreeze: { case idFreeze: {
if (pm_opt_str_freeze_p(iseq, call_node)) { if (pm_opt_str_freeze_p(iseq, call_node)) {
VALUE value = rb_fstring(parse_string_encoded(call_node->receiver, &((const pm_string_node_t * )call_node->receiver)->unescaped, scope_node->parser)); VALUE value = rb_fstring(parse_string_encoded(call_node->receiver, &((const pm_string_node_t * )call_node->receiver)->unescaped, parser));
ADD_INSN2(ret, &dummy_line_node, opt_str_freeze, value, new_callinfo(iseq, idFreeze, 0, 0, NULL, FALSE)); ADD_INSN2(ret, &dummy_line_node, opt_str_freeze, value, new_callinfo(iseq, idFreeze, 0, 0, NULL, FALSE));
return; return;
} }
@ -4497,7 +4493,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
case idAREF: { case idAREF: {
if (pm_opt_aref_with_p(iseq, call_node)) { if (pm_opt_aref_with_p(iseq, call_node)) {
const pm_string_node_t *string = (const pm_string_node_t *) ((const pm_arguments_node_t *) call_node->arguments)->arguments.nodes[0]; const pm_string_node_t *string = (const pm_string_node_t *) ((const pm_arguments_node_t *) call_node->arguments)->arguments.nodes[0];
VALUE value = rb_fstring(parse_string_encoded((const pm_node_t *) string, &string->unescaped, scope_node->parser)); VALUE value = rb_fstring(parse_string_encoded((const pm_node_t *) string, &string->unescaped, parser));
PM_COMPILE_NOT_POPPED(call_node->receiver); PM_COMPILE_NOT_POPPED(call_node->receiver);
ADD_INSN2(ret, &dummy_line_node, opt_aref_with, value, new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE)); ADD_INSN2(ret, &dummy_line_node, opt_aref_with, value, new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
@ -4512,7 +4508,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
case idASET: { case idASET: {
if (pm_opt_aset_with_p(iseq, call_node)) { if (pm_opt_aset_with_p(iseq, call_node)) {
const pm_string_node_t *string = (const pm_string_node_t *) ((const pm_arguments_node_t *) call_node->arguments)->arguments.nodes[0]; const pm_string_node_t *string = (const pm_string_node_t *) ((const pm_arguments_node_t *) call_node->arguments)->arguments.nodes[0];
VALUE value = rb_fstring(parse_string_encoded((const pm_node_t *) string, &string->unescaped, scope_node->parser)); VALUE value = rb_fstring(parse_string_encoded((const pm_node_t *) string, &string->unescaped, parser));
PM_COMPILE_NOT_POPPED(call_node->receiver); PM_COMPILE_NOT_POPPED(call_node->receiver);
PM_COMPILE_NOT_POPPED(((const pm_arguments_node_t *) call_node->arguments)->arguments.nodes[1]); PM_COMPILE_NOT_POPPED(((const pm_arguments_node_t *) call_node->arguments)->arguments.nodes[1]);
@ -4633,7 +4629,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
const pm_when_node_t *clause = (const pm_when_node_t *) conditions->nodes[clause_index]; const pm_when_node_t *clause = (const pm_when_node_t *) conditions->nodes[clause_index];
const pm_node_list_t *conditions = &clause->conditions; const pm_node_list_t *conditions = &clause->conditions;
int clause_lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, clause->base.location.start).line; int clause_lineno = pm_node_line_number(parser, (const pm_node_t *) clause);
LABEL *label = NEW_LABEL(clause_lineno); LABEL *label = NEW_LABEL(clause_lineno);
ADD_LABEL(body_seq, label); ADD_LABEL(body_seq, label);
@ -4659,9 +4655,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
ADD_INSNL(cond_seq, &dummy_line_node, branchif, label); ADD_INSNL(cond_seq, &dummy_line_node, branchif, label);
} }
else { else {
int condition_lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, condition->location.start).line; LABEL *next_label = NEW_LABEL(pm_node_line_number(parser, condition));
LABEL *next_label = NEW_LABEL(condition_lineno);
pm_compile_branch_condition(iseq, cond_seq, condition, label, next_label, false, scope_node); pm_compile_branch_condition(iseq, cond_seq, condition, label, next_label, false, scope_node);
ADD_LABEL(cond_seq, next_label); ADD_LABEL(cond_seq, next_label);
} }
@ -4732,7 +4726,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
else { else {
if (PM_NODE_TYPE_P(condition, PM_STRING_NODE)) { if (PM_NODE_TYPE_P(condition, PM_STRING_NODE)) {
const pm_string_node_t *string = (const pm_string_node_t *) condition; const pm_string_node_t *string = (const pm_string_node_t *) condition;
VALUE value = rb_fstring(parse_string_encoded((const pm_node_t *) string, &string->unescaped, scope_node->parser)); VALUE value = rb_fstring(parse_string_encoded((const pm_node_t *) string, &string->unescaped, parser));
ADD_INSN1(cond_seq, &dummy_line_node, putobject, value); ADD_INSN1(cond_seq, &dummy_line_node, putobject, value);
} }
else { else {
@ -4961,7 +4955,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
VALUE class_name = rb_str_freeze(rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(class_id))); VALUE class_name = rb_str_freeze(rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(class_id)));
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init((pm_node_t *)class_node, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t *)class_node, &next_scope_node, scope_node, parser);
const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(&next_scope_node, class_name, ISEQ_TYPE_CLASS, lineno); const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(&next_scope_node, class_name, ISEQ_TYPE_CLASS, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -5100,7 +5094,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN1(ret, &dummy_line_node, opt_getconstant_path, parts); ADD_INSN1(ret, &dummy_line_node, opt_getconstant_path, parts);
} }
else { else {
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; int lineno = pm_node_line_number(parser, node);
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
DECL_ANCHOR(prefix); DECL_ANCHOR(prefix);
@ -5375,7 +5369,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
ID method_name = pm_constant_id_lookup(scope_node, def_node->name); ID method_name = pm_constant_id_lookup(scope_node, def_node->name);
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init((pm_node_t *)def_node, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t *)def_node, &next_scope_node, scope_node, parser);
rb_iseq_t *method_iseq = NEW_ISEQ(&next_scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno); rb_iseq_t *method_iseq = NEW_ISEQ(&next_scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -5483,7 +5477,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// Next, create the new scope that is going to contain the block that // Next, create the new scope that is going to contain the block that
// will be passed to the each method. // will be passed to the each method.
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init((pm_node_t *) cast, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t *) cast, &next_scope_node, scope_node, parser);
const rb_iseq_t *child_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); const rb_iseq_t *child_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -5539,7 +5533,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
if (forwarding_super_node->block) { if (forwarding_super_node->block) {
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init((pm_node_t *)forwarding_super_node->block, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t *)forwarding_super_node->block, &next_scope_node, scope_node, parser);
block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -5772,7 +5766,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
return; return;
} }
case PM_IF_NODE: { case PM_IF_NODE: {
const int line = (int)pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; const int line = pm_node_line_number(parser, node);
pm_if_node_t *if_node = (pm_if_node_t *)node; pm_if_node_t *if_node = (pm_if_node_t *)node;
pm_statements_node_t *node_body = if_node->statements; pm_statements_node_t *node_body = if_node->statements;
pm_node_t *node_else = if_node->consequent; pm_node_t *node_else = if_node->consequent;
@ -5934,7 +5928,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
int ic_index = ISEQ_BODY(iseq)->ise_size++; int ic_index = ISEQ_BODY(iseq)->ise_size++;
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init((pm_node_t*)node, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t*)node, &next_scope_node, scope_node, parser);
block_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); block_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -6012,10 +6006,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
const pm_lambda_node_t *cast = (const pm_lambda_node_t *) node; const pm_lambda_node_t *cast = (const pm_lambda_node_t *) node;
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init(node, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init(node, &next_scope_node, scope_node, parser);
int opening_lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, cast->opening_loc.start).line;
int opening_lineno = pm_location_line_number(parser, &cast->opening_loc);
const rb_iseq_t *block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, opening_lineno); const rb_iseq_t *block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, opening_lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -6127,7 +6120,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
if (!popped) { if (!popped) {
pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node; pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node;
VALUE regex_str = parse_string(&cast->unescaped, scope_node->parser); VALUE regex_str = parse_string(&cast->unescaped, parser);
VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), pm_reg_flags(node)); VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), pm_reg_flags(node));
ADD_INSN1(ret, &dummy_line_node, putobject, regex); ADD_INSN1(ret, &dummy_line_node, putobject, regex);
@ -6321,7 +6314,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
VALUE module_name = rb_str_freeze(rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(module_id))); VALUE module_name = rb_str_freeze(rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(module_id)));
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init((pm_node_t *)module_node, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t *)module_node, &next_scope_node, scope_node, parser);
const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(&next_scope_node, module_name, ISEQ_TYPE_CLASS, lineno); const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(&next_scope_node, module_name, ISEQ_TYPE_CLASS, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -6547,7 +6540,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block; const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init(node, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init(node, &next_scope_node, scope_node, parser);
child_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); child_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -6674,7 +6667,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
if (!popped) { if (!popped) {
pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node; pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node;
VALUE regex = pm_new_regex(cast, scope_node->parser); VALUE regex = pm_new_regex(cast, parser);
ADD_INSN1(ret, &dummy_line_node, putobject, regex); ADD_INSN1(ret, &dummy_line_node, putobject, regex);
} }
@ -6779,13 +6772,13 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node;
pm_scope_node_t rescue_scope_node; pm_scope_node_t rescue_scope_node;
pm_scope_node_init((pm_node_t *) cast, &rescue_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t *) cast, &rescue_scope_node, scope_node, parser);
rb_iseq_t *rescue_iseq = NEW_CHILD_ISEQ( rb_iseq_t *rescue_iseq = NEW_CHILD_ISEQ(
&rescue_scope_node, &rescue_scope_node,
rb_str_concat(rb_str_new2("rescue in "), ISEQ_BODY(iseq)->location.label), rb_str_concat(rb_str_new2("rescue in "), ISEQ_BODY(iseq)->location.label),
ISEQ_TYPE_RESCUE, ISEQ_TYPE_RESCUE,
pm_line_number(scope_node->parser, cast->rescue_expression) pm_node_line_number(parser, cast->rescue_expression)
); );
pm_scope_node_destroy(&rescue_scope_node); pm_scope_node_destroy(&rescue_scope_node);
@ -7470,7 +7463,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
RUBY_ASSERT(0 < maximum && maximum <= 9); RUBY_ASSERT(0 < maximum && maximum <= 9);
for (int i = 0; i < maximum; i++, local_index++) { for (int i = 0; i < maximum; i++, local_index++) {
const uint8_t param_name[] = { '_', '1' + i }; const uint8_t param_name[] = { '_', '1' + i };
pm_constant_id_t constant_id = pm_constant_pool_find(&scope_node->parser->constant_pool, param_name, 2); pm_constant_id_t constant_id = pm_constant_pool_find(&parser->constant_pool, param_name, 2);
RUBY_ASSERT(constant_id && "parser should fill in any gaps in numbered parameters"); RUBY_ASSERT(constant_id && "parser should fill in any gaps in numbered parameters");
pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node); pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
} }
@ -7650,7 +7643,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// We create another ScopeNode from the statements within the PostExecutionNode // We create another ScopeNode from the statements within the PostExecutionNode
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init((pm_node_t *)post_execution_node->statements, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t *)post_execution_node->statements, &next_scope_node, scope_node, parser);
const rb_iseq_t *block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(body->parent_iseq), ISEQ_TYPE_BLOCK, lineno); const rb_iseq_t *block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(body->parent_iseq), ISEQ_TYPE_BLOCK, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -7753,7 +7746,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_singleton_class_node_t *singleton_class_node = (pm_singleton_class_node_t *)node; pm_singleton_class_node_t *singleton_class_node = (pm_singleton_class_node_t *)node;
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init((pm_node_t *)singleton_class_node, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init((pm_node_t *)singleton_class_node, &next_scope_node, scope_node, parser);
const rb_iseq_t *singleton_class = NEW_ISEQ(&next_scope_node, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, lineno); const rb_iseq_t *singleton_class = NEW_ISEQ(&next_scope_node, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
@ -7829,7 +7822,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
case PM_STRING_NODE: { case PM_STRING_NODE: {
if (!popped) { if (!popped) {
pm_string_node_t *cast = (pm_string_node_t *) node; pm_string_node_t *cast = (pm_string_node_t *) node;
VALUE value = parse_string_encoded(node, &cast->unescaped, scope_node->parser); VALUE value = parse_string_encoded(node, &cast->unescaped, parser);
value = rb_fstring(value); value = rb_fstring(value);
if (node->flags & PM_STRING_FLAGS_FROZEN) { if (node->flags & PM_STRING_FLAGS_FROZEN) {
ADD_INSN1(ret, &dummy_line_node, putobject, value); ADD_INSN1(ret, &dummy_line_node, putobject, value);
@ -7859,7 +7852,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
if (super_node->block && PM_NODE_TYPE_P(super_node->block, PM_BLOCK_NODE)) { if (super_node->block && PM_NODE_TYPE_P(super_node->block, PM_BLOCK_NODE)) {
pm_scope_node_t next_scope_node; pm_scope_node_t next_scope_node;
pm_scope_node_init(super_node->block, &next_scope_node, scope_node, scope_node->parser); pm_scope_node_init(super_node->block, &next_scope_node, scope_node, parser);
parent_block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); parent_block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
} }
@ -7912,7 +7905,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
return; return;
} }
case PM_UNLESS_NODE: { case PM_UNLESS_NODE: {
const int line = (int)pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; const int line = pm_node_line_number(parser, node);
pm_unless_node_t *unless_node = (pm_unless_node_t *)node; pm_unless_node_t *unless_node = (pm_unless_node_t *)node;
pm_node_t *node_body = (pm_node_t *)(unless_node->statements); pm_node_t *node_body = (pm_node_t *)(unless_node->statements);
pm_statements_node_t *node_else = NULL; pm_statements_node_t *node_else = NULL;
@ -7948,7 +7941,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
} }
case PM_X_STRING_NODE: { case PM_X_STRING_NODE: {
pm_x_string_node_t *cast = (pm_x_string_node_t *) node; pm_x_string_node_t *cast = (pm_x_string_node_t *) node;
VALUE value = parse_string_encoded(node, &cast->unescaped, scope_node->parser); VALUE value = parse_string_encoded(node, &cast->unescaped, parser);
PM_PUTSELF; PM_PUTSELF;
ADD_INSN1(ret, &dummy_line_node, putobject, value); ADD_INSN1(ret, &dummy_line_node, putobject, value);
@ -8043,11 +8036,11 @@ pm_parse_result_free(pm_parse_result_t *result)
static bool static bool
pm_parse_input_error_utf8_p(const pm_parser_t *parser, const pm_location_t *location) pm_parse_input_error_utf8_p(const pm_parser_t *parser, const pm_location_t *location)
{ {
const pm_line_column_t start_location = pm_newline_list_line_column(&parser->newline_list, location->start); const size_t start_line = pm_newline_list_line_column(&parser->newline_list, location->start, 1).line;
const pm_line_column_t end_location = pm_newline_list_line_column(&parser->newline_list, location->end); const size_t end_line = pm_newline_list_line_column(&parser->newline_list, location->end, 1).line;
const uint8_t *start = parser->start + parser->newline_list.offsets[start_location.line - 1]; const uint8_t *start = parser->start + parser->newline_list.offsets[start_line - 1];
const uint8_t *end = ((end_location.line == parser->newline_list.size) ? parser->end : (parser->start + parser->newline_list.offsets[end_location.line])); const uint8_t *end = ((end_line == parser->newline_list.size) ? parser->end : (parser->start + parser->newline_list.offsets[end_line]));
size_t width; size_t width;
while (start < end) { while (start < end) {
@ -8097,7 +8090,7 @@ pm_parse_input_error(const pm_parse_result_t *result)
for (const pm_diagnostic_t *error = head; error != NULL; error = (pm_diagnostic_t *) error->node.next) { for (const pm_diagnostic_t *error = head; error != NULL; error = (pm_diagnostic_t *) error->node.next) {
if (error != head) pm_buffer_append_byte(&buffer, '\n'); if (error != head) pm_buffer_append_byte(&buffer, '\n');
pm_buffer_append_format(&buffer, "%.*s:%" PRIu32 ": %s", (int) pm_string_length(filepath), pm_string_source(filepath), (uint32_t) pm_newline_list_line_column(&result->parser.newline_list, error->location.start).line, error->message); pm_buffer_append_format(&buffer, "%.*s:%" PRIi32 ": %s", (int) pm_string_length(filepath), pm_string_source(filepath), (int32_t) pm_location_line_number(&result->parser, &error->location), error->message);
} }
} }
@ -8134,7 +8127,7 @@ pm_parse_input(pm_parse_result_t *result, VALUE filepath)
const char *warning_filepath = (const char *) pm_string_source(&result->parser.filepath); const char *warning_filepath = (const char *) pm_string_source(&result->parser.filepath);
for (warning = (pm_diagnostic_t *) result->parser.warning_list.head; warning != NULL; warning = (pm_diagnostic_t *) warning->node.next) { for (warning = (pm_diagnostic_t *) result->parser.warning_list.head; warning != NULL; warning = (pm_diagnostic_t *) warning->node.next) {
int line = (int) pm_newline_list_line_column(&result->parser.newline_list, warning->location.start).line; int line = pm_location_line_number(&result->parser, &warning->location);
if (warning->level == PM_WARNING_LEVEL_VERBOSE) { if (warning->level == PM_WARNING_LEVEL_VERBOSE) {
rb_compile_warning(warning_filepath, line, "%s", warning->message); rb_compile_warning(warning_filepath, line, "%s", warning->message);

5
ruby.c
View File

@ -2347,6 +2347,8 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
if (dump & (DUMP_BIT(prism_parsetree))) { if (dump & (DUMP_BIT(prism_parsetree))) {
pm_parse_result_t result = { 0 }; pm_parse_result_t result = { 0 };
result.options.line = 1;
VALUE error; VALUE error;
if (strcmp(opt->script, "-") == 0) { if (strcmp(opt->script, "-") == 0) {
@ -2413,7 +2415,10 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
if ((*rb_ruby_prism_ptr())) { if ((*rb_ruby_prism_ptr())) {
ruby_opt_init(opt); ruby_opt_init(opt);
pm_parse_result_t result = { 0 }; pm_parse_result_t result = { 0 };
result.options.line = 1;
VALUE error; VALUE error;
if (strcmp(opt->script, "-") == 0) { if (strcmp(opt->script, "-") == 0) {

View File

@ -1 +0,0 @@
exclude(:test_redefinition_mismatch, "incorrect line number")

View File

@ -1,6 +0,0 @@
exclude(:test_with_filename_and_safe_level, "incorrect line number")
exclude(:test_with_filename_lineno, "incorrect line number")
exclude(:test_with_filename, "incorrect line number")
exclude(:test_with_location, "incorrect line number")
exclude(:test_without_filename_with_safe_level, "incorrect line number")
exclude(:test_without_filename, "incorrect line number")

View File

@ -1,6 +0,0 @@
exclude(:test_def_method_with_fname, "incorrect line number")
exclude(:test_def_method_without_filename, "incorrect line number")
exclude(:test_eval_input_with_exception, "incorrect line number")
exclude(:test_keep_lineno, "incorrect line number")
exclude(:test_multi_line_comment_lineno, "incorrect line number")
exclude(:test_multi_line_comment_lineno, "incorrect line number")

View File

@ -1,5 +0,0 @@
exclude(:test_def_method_with_fname, "unknown")
exclude(:test_def_method_without_filename, "unknown")
exclude(:test_keep_lineno, "unknown")
exclude(:test_multi_line_comment_lineno, "unknown")
exclude(:test_require_nonascii_path_shift_jis, "unknown")

View File

@ -1,3 +1,2 @@
exclude(:test_eval_ascii_incompatible, "incorrect encoding") exclude(:test_eval_ascii_incompatible, "incorrect encoding")
exclude(:test_eval_location_binding, "incorrect line number")
exclude(:test_file_encoding, "incorrect encoding") exclude(:test_file_encoding, "incorrect encoding")

View File

@ -1 +0,0 @@
exclude(:test_redefinition_mismatch, "unknown")

View File

@ -2,7 +2,6 @@ exclude(:test_assign_in_conditional, "missing warning")
exclude(:test_here_document, "incorrect heredoc") exclude(:test_here_document, "incorrect heredoc")
exclude(:test_literal_in_conditional, "missing warning") exclude(:test_literal_in_conditional, "missing warning")
exclude(:test_magic_comment, "incorrect encoding") exclude(:test_magic_comment, "incorrect encoding")
exclude(:test_negative_line_number, "incorrect line number")
exclude(:test_nonascii_const_set, "incorrect encoding") exclude(:test_nonascii_const_set, "incorrect encoding")
exclude(:test_nonascii_constant, "incorrect encoding") exclude(:test_nonascii_constant, "incorrect encoding")
exclude(:test_question, "missing warning") exclude(:test_question, "missing warning")

View File

@ -1661,6 +1661,7 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line,
} }
pm_parse_result_t result = { 0 }; pm_parse_result_t result = { 0 };
pm_options_line_set(&result.options, line);
// Cout scopes, one for each parent iseq, plus one for our local scope // Cout scopes, one for each parent iseq, plus one for our local scope
int scopes_count = 0; int scopes_count = 0;
@ -1698,6 +1699,7 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line,
pm_parse_result_free(&result); pm_parse_result_free(&result);
rb_exc_raise(error); rb_exc_raise(error);
} }
// Create one scope node for each scope passed in, initialize the local // Create one scope node for each scope passed in, initialize the local
// lookup table with all the local variable information attached to the // lookup table with all the local variable information attached to the
// scope used by the parser. // scope used by the parser.
@ -1706,7 +1708,7 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line,
for (int scopes_index = 0; scopes_index < scopes_count; scopes_index++) { for (int scopes_index = 0; scopes_index < scopes_count; scopes_index++) {
pm_scope_node_t *parent_scope = ruby_xcalloc(1, sizeof(pm_scope_node_t)); pm_scope_node_t *parent_scope = ruby_xcalloc(1, sizeof(pm_scope_node_t));
if (parent_scope == NULL) abort(); RUBY_ASSERT(parent_scope != NULL);
pm_options_scope_t *options_scope = &result.options.scopes[scopes_count - scopes_index - 1]; pm_options_scope_t *options_scope = &result.options.scopes[scopes_count - scopes_index - 1];
parent_scope->parser = &result.parser; parent_scope->parser = &result.parser;