summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authorJemma Issroff <jemmaissroff@gmail.com>2023-08-28 16:55:58 -0400
committerGitHub <noreply@github.com>2023-08-28 13:55:58 -0700
commit3b815ed7da8261f45b84dcde2c900934f7379dac (patch)
tree84bf9e833e4a572c43d87b545df1d5aba0cbb19b /iseq.c
parentf726ad97406dc1c3bccfe74a53931552b9db755f (diff)
Add yarp/yarp_compiler.c (#8042)
* Add yarp/yarp_compiler.c as stencil for compiling YARP This commit adds yarp/yarp_compiler.c, and changes the sync script to ensure that yarp/yarp_compiler.c will not get overwritten * [Misc #119772] Create and expose RubyVM::InstructionSequence.compile_yarp This commit creates the stencil for a compile_yarp function, which we will continue to fill out. It allows us to check the output of compiled YARP code against compiled code without using YARP.
Notes
Notes: Merged-By: jemmaissroff
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/iseq.c b/iseq.c
index 80bd280a14..0b7ea138fa 100644
--- a/iseq.c
+++ b/iseq.c
@@ -43,6 +43,9 @@
#include "builtin.h"
#include "insns.inc"
#include "insns_info.inc"
+#include "yarp/yarp.h"
+
+VALUE rb_iseq_compile_yarp_node(rb_iseq_t * iseq, const yp_node_t * yarp_pointer);
VALUE rb_cISeq;
static VALUE iseqw_new(const rb_iseq_t *iseq);
@@ -1326,7 +1329,7 @@ rb_iseqw_new(const rb_iseq_t *iseq)
static VALUE
iseqw_s_compile(int argc, VALUE *argv, VALUE self)
{
- VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;
+ VALUE src, file = Qnil, path = Qnil, line = Qnil, opt = Qnil;
int i;
i = rb_scan_args(argc, argv, "1*:", &src, NULL, &opt);
@@ -1348,6 +1351,67 @@ iseqw_s_compile(int argc, VALUE *argv, VALUE self)
return iseqw_new(rb_iseq_compile_with_option(src, file, path, line, opt));
}
+static VALUE
+iseqw_s_compile_yarp(int argc, VALUE *argv, VALUE self)
+{
+ VALUE src, file = Qnil, path = Qnil, line = Qnil, opt = Qnil;
+ int i;
+
+ i = rb_scan_args(argc, argv, "1*:", &src, NULL, &opt);
+ if (i > 4+NIL_P(opt)) rb_error_arity(argc, 1, 5);
+ switch (i) {
+ case 5: opt = argv[--i];
+ case 4: line = argv[--i];
+ case 3: path = argv[--i];
+ case 2: file = argv[--i];
+ }
+
+ if (NIL_P(file)) file = rb_fstring_lit("<compiled>");
+ if (NIL_P(path)) path = file;
+ if (NIL_P(line)) line = INT2FIX(1);
+
+ Check_Type(path, T_STRING);
+ Check_Type(file, T_STRING);
+
+ rb_iseq_t *iseq = iseq_alloc();
+
+ yp_parser_t parser;
+ size_t len = RSTRING_LEN(src);
+ VALUE name = rb_fstring_lit("<compiled>");
+
+ yp_parser_init(&parser, RSTRING_PTR(src), len, "");
+
+ yp_node_t *node = yp_parse(&parser);
+
+ int first_lineno = NUM2INT(line);
+ yp_line_column_t start_loc = yp_newline_list_line_column(&parser.newline_list, node->location.start);
+ yp_line_column_t end_loc = yp_newline_list_line_column(&parser.newline_list, node->location.end);
+
+ 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;
+
+ int node_id = 0;
+
+ rb_iseq_t *parent = NULL;
+ enum rb_iseq_type iseq_type = ISEQ_TYPE_TOP;
+ rb_compile_option_t option;
+
+ make_compile_option(&option, opt);
+
+ prepare_iseq_build(iseq, name, file, path, first_lineno, &node_location, node_id,
+ parent, 0, (enum rb_iseq_type)iseq_type, Qnil, &option);
+
+ rb_iseq_compile_yarp_node(iseq, node);
+
+ yp_node_destroy(&parser, node);
+ yp_parser_free(&parser);
+
+ return iseqw_new(iseq);
+}
+
/*
* call-seq:
* InstructionSequence.compile_file(file[, options]) -> iseq
@@ -3920,6 +3984,7 @@ Init_ISeq(void)
(void)iseq_s_load;
rb_define_singleton_method(rb_cISeq, "compile", iseqw_s_compile, -1);
+ rb_define_singleton_method(rb_cISeq, "compile_yarp", iseqw_s_compile_yarp, -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);