aboutsummaryrefslogtreecommitdiffstats
path: root/iseq.c
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2023-11-09 02:39:12 -0500
committerJemma Issroff <jemmaissroff@gmail.com>2023-11-20 12:45:29 -0800
commit323bec6295e46a6f4926e742f7444fc54924b527 (patch)
tree3f768d659a4976cf314394b30e57c90c1d2f0bcb /iseq.c
parent2796e4ece24f62f7d952a894097726b85bbd6fc8 (diff)
downloadruby-323bec6295e46a6f4926e742f7444fc54924b527.tar.gz
RubyVM::InstructionSequence.compile_file_prism
* Provide a new API compile_file_prism which mirrors compile_file but uses prism to parse/compile. * Provide the ability to run test-all with RUBY_ISEQ_DUMP_DEBUG set to "prism". If it is, we'll use the new compile_file_prism API to load iseqs during the test run.
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c107
1 files changed, 66 insertions, 41 deletions
diff --git a/iseq.c b/iseq.c
index bc292859f3..03c7623b3c 100644
--- a/iseq.c
+++ b/iseq.c
@@ -943,6 +943,20 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea
VALUE rb_iseq_compile_prism_node(rb_iseq_t * iseq, pm_scope_node_t *scope_node, pm_parser_t *parser);
+/**
+ * Initialize an rb_code_location_t with a prism location.
+ */
+static void
+pm_code_location(rb_code_location_t *code_location, const pm_newline_list_t *newline_list, const pm_location_t *location) {
+ pm_line_column_t start = pm_newline_list_line_column(newline_list, location->start);
+ pm_line_column_t end = pm_newline_list_line_column(newline_list, location->end);
+
+ *code_location = (rb_code_location_t) {
+ .beg_pos = { .lineno = (int) start.line, .column = (int) start.column },
+ .end_pos = { .lineno = (int) end.line, .column = (int) end.column }
+ };
+}
+
rb_iseq_t *
pm_iseq_new_with_opt(pm_scope_node_t *scope_node, pm_parser_t *parser, VALUE name, VALUE path, VALUE realpath,
int first_lineno, const rb_iseq_t *parent, int isolated_depth,
@@ -950,31 +964,17 @@ pm_iseq_new_with_opt(pm_scope_node_t *scope_node, pm_parser_t *parser, VALUE nam
{
rb_iseq_t *iseq = iseq_alloc();
VALUE script_lines = Qnil;
- rb_code_location_t code_loc;
-
if (!option) option = &COMPILE_OPTION_DEFAULT;
- pm_line_column_t start_line_col = pm_newline_list_line_column(&parser->newline_list, scope_node->base.location.start);
- pm_line_column_t end_line_col = pm_newline_list_line_column(&parser->newline_list, scope_node->base.location.end);
-
- code_loc = (rb_code_location_t) {
- .beg_pos = {
- .lineno = (int) start_line_col.line,
- .column = (int) start_line_col.column
- },
- .end_pos = {
- .lineno = (int) end_line_col.line,
- .column = (int) end_line_col.column
- },
- };
+ rb_code_location_t code_location;
+ pm_code_location(&code_location, &parser->newline_list, &scope_node->base.location);
// TODO: node_id
int node_id = -1;
- prepare_iseq_build(iseq, name, path, realpath, first_lineno, &code_loc, node_id,
+ prepare_iseq_build(iseq, name, path, realpath, first_lineno, &code_location, node_id,
parent, isolated_depth, type, script_lines, option);
rb_iseq_compile_prism_node(iseq, scope_node, parser);
-
finish_iseq_build(iseq);
return iseq_translate(iseq);
@@ -1391,6 +1391,24 @@ iseqw_s_compile(int argc, VALUE *argv, VALUE self)
return iseqw_new(rb_iseq_compile_with_option(src, file, path, line, opt));
}
+static void
+iseqw_s_compile_prism_compile(pm_parser_t *parser, VALUE opt, rb_iseq_t *iseq, VALUE file, VALUE path, int first_lineno) {
+ pm_node_t *node = pm_parse(parser);
+ rb_code_location_t code_location;
+ pm_code_location(&code_location, &parser->newline_list, &node->location);
+
+ rb_compile_option_t option;
+ make_compile_option(&option, opt);
+ prepare_iseq_build(iseq, rb_fstring_lit("<compiled>"), file, path, first_lineno, &code_location, -1, NULL, 0, ISEQ_TYPE_TOP, Qnil, &option);
+
+ pm_scope_node_t scope_node;
+ pm_scope_node_init(node, &scope_node, NULL, parser);
+ rb_iseq_compile_prism_node(iseq, &scope_node, parser);
+
+ finish_iseq_build(iseq);
+ pm_node_destroy(parser, node);
+}
+
static VALUE
iseqw_s_compile_prism(int argc, VALUE *argv, VALUE self)
{
@@ -1413,44 +1431,50 @@ iseqw_s_compile_prism(int argc, VALUE *argv, VALUE self)
Check_Type(path, T_STRING);
Check_Type(file, T_STRING);
- rb_iseq_t *iseq = iseq_alloc();
- int start_line = NUM2INT(line);
-
pm_options_t options = { 0 };
pm_options_filepath_set(&options, RSTRING_PTR(file));
+
+ int start_line = NUM2INT(line);
pm_options_line_set(&options, start_line);
pm_parser_t parser;
pm_parser_init(&parser, (const uint8_t *) RSTRING_PTR(src), RSTRING_LEN(src), &options);
- pm_node_t *node = pm_parse(&parser);
- pm_line_column_t start_loc = pm_newline_list_line_column(&parser.newline_list, node->location.start);
- pm_line_column_t end_loc = pm_newline_list_line_column(&parser.newline_list, node->location.end);
+ rb_iseq_t *iseq = iseq_alloc();
+ iseqw_s_compile_prism_compile(&parser, opt, iseq, file, path, start_line);
+ pm_parser_free(&parser);
+ pm_options_free(&options);
- rb_code_location_t node_location;
- node_location.beg_pos.lineno = (int) start_loc.line;
- node_location.beg_pos.column = (int) start_loc.column;
- node_location.end_pos.lineno = (int) end_loc.line;
- node_location.end_pos.column = (int) end_loc.column;
+ return iseqw_new(iseq);
+}
- int node_id = 0;
- rb_iseq_t *parent = NULL;
- enum rb_iseq_type iseq_type = ISEQ_TYPE_TOP;
- rb_compile_option_t option;
+static VALUE
+iseqw_s_compile_file_prism(int argc, VALUE *argv, VALUE self)
+{
+ VALUE file = Qnil, opt = Qnil;
+ int i;
- make_compile_option(&option, opt);
+ i = rb_scan_args(argc, argv, "1*:", &file, NULL, &opt);
+ if (i > 1+NIL_P(opt)) rb_error_arity(argc, 1, 5);
+ switch (i) {
+ case 2: opt = argv[--i];
+ }
+ FilePathValue(file);
+ file = rb_fstring(file); /* rb_io_t->pathv gets frozen anyways */
- VALUE name = rb_fstring_lit("<compiled>");
- prepare_iseq_build(iseq, name, file, path, start_line, &node_location, node_id,
- parent, 0, (enum rb_iseq_type)iseq_type, Qnil, &option);
+ pm_string_t input;
+ pm_string_mapped_init(&input, RSTRING_PTR(file));
- pm_scope_node_t scope_node;
- pm_scope_node_init(node, &scope_node, NULL, &parser);
- rb_iseq_compile_prism_node(iseq, &scope_node, &parser);
+ pm_options_t options = { 0 };
+ pm_options_filepath_set(&options, RSTRING_PTR(file));
- finish_iseq_build(iseq);
- pm_node_destroy(&parser, node);
+ pm_parser_t parser;
+ pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
+
+ rb_iseq_t *iseq = iseq_alloc();
+ iseqw_s_compile_prism_compile(&parser, opt, iseq, file, rb_realpath_internal(Qnil, file, 1), 1);
pm_parser_free(&parser);
+ pm_string_free(&input);
pm_options_free(&options);
return iseqw_new(iseq);
@@ -4029,6 +4053,7 @@ Init_ISeq(void)
rb_define_singleton_method(rb_cISeq, "compile", iseqw_s_compile, -1);
rb_define_singleton_method(rb_cISeq, "compile_prism", iseqw_s_compile_prism, -1);
+ rb_define_singleton_method(rb_cISeq, "compile_file_prism", iseqw_s_compile_file_prism, -1);
rb_define_singleton_method(rb_cISeq, "new", iseqw_s_compile, -1);
rb_define_singleton_method(rb_cISeq, "compile_file", iseqw_s_compile_file, -1);
rb_define_singleton_method(rb_cISeq, "compile_option", iseqw_s_compile_option_get, 0);