[前][次][番号順一覧][スレッド一覧]

ruby-changes:69441

From: Yusuke <ko1@a...>
Date: Tue, 26 Oct 2021 01:58:15 +0900 (JST)
Subject: [ruby-changes:69441] 09fa773e04 (master): ast.c: Use kept script_lines data instead of re-opening the source file (#5019)

https://git.ruby-lang.org/ruby.git/commit/?id=09fa773e04

From 09fa773e04f183e5eb685f07e174efa2cf77f9dc Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@r...>
Date: Tue, 26 Oct 2021 01:58:01 +0900
Subject: ast.c: Use kept script_lines data instead of re-opening the source
 file (#5019)

ast.c: Use kept script_lines data instead of re-open the source file
---
 ast.c          |  9 +++++----
 internal/vm.h  |  2 +-
 parse.y        |  1 +
 vm_backtrace.c | 22 +++++++++++-----------
 4 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/ast.c b/ast.c
index 84e5fdcecc8..96116d43eba 100644
--- a/ast.c
+++ b/ast.c
@@ -195,12 +195,12 @@ script_lines(VALUE path) https://github.com/ruby/ruby/blob/trunk/ast.c#L195
 static VALUE
 ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script_lines)
 {
-    VALUE path, node, lines;
+    VALUE path, node, lines = Qnil;
     int node_id;
 
     if (rb_frame_info_p(body)) {
-        rb_frame_info_get(body, &path, &node_id);
-        if (NIL_P(path)) return Qnil;
+        rb_frame_info_get(body, &path, &lines, &node_id);
+        if (NIL_P(path) && NIL_P(lines)) return Qnil;
     }
     else {
         const rb_iseq_t *iseq = NULL;
@@ -220,10 +220,11 @@ ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script https://github.com/ruby/ruby/blob/trunk/ast.c#L220
             rb_raise(rb_eArgError, "cannot get AST for method defined in eval");
         }
         path = rb_iseq_path(iseq);
+        lines = iseq->body->variable.script_lines;
         node_id = iseq->body->location.node_id;
     }
 
-    if (!NIL_P(lines = script_lines(path))) {
+    if (!NIL_P(lines) || !NIL_P(lines = script_lines(path))) {
         node = rb_ast_parse_array(lines, keep_script_lines);
     }
     else if (RSTRING_LEN(path) == 2 && memcmp(RSTRING_PTR(path), "-e", 2) == 0) {
diff --git a/internal/vm.h b/internal/vm.h
index 8893d70cd48..e902a814114 100644
--- a/internal/vm.h
+++ b/internal/vm.h
@@ -111,7 +111,7 @@ VALUE rb_backtrace_to_str_ary(VALUE obj); https://github.com/ruby/ruby/blob/trunk/internal/vm.h#L111
 VALUE rb_backtrace_to_location_ary(VALUE obj);
 void rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output);
 int rb_frame_info_p(VALUE obj);
-void rb_frame_info_get(VALUE obj, VALUE *path, int *node_id);
+void rb_frame_info_get(VALUE obj, VALUE *path, VALUE *script_lines, int *node_id);
 
 MJIT_SYMBOL_EXPORT_BEGIN
 VALUE rb_ec_backtrace_object(const struct rb_execution_context_struct *ec);
diff --git a/parse.y b/parse.y
index 2ec9d7770cb..5948f6e2f63 100644
--- a/parse.y
+++ b/parse.y
@@ -6414,6 +6414,7 @@ lex_getline(struct parser_params *p) https://github.com/ruby/ruby/blob/trunk/parse.y#L6414
     VALUE line = (*p->lex.gets)(p, p->lex.input);
     if (NIL_P(line)) return line;
     must_be_ascii_compatible(line);
+    if (RB_OBJ_FROZEN(line)) line = rb_str_dup(line); // needed for RubyVM::AST.of because script_lines in iseq is deep-frozen
 #ifndef RIPPER
     if (p->debug_lines) {
 	rb_enc_associate(line, p->enc);
diff --git a/vm_backtrace.c b/vm_backtrace.c
index 8294d218a4a..f2e9bed6bac 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -283,19 +283,16 @@ location_base_label_m(VALUE self) https://github.com/ruby/ruby/blob/trunk/vm_backtrace.c#L283
     return location_base_label(location_ptr(self));
 }
 
-static VALUE
-location_path(rb_backtrace_location_t *loc)
+static const rb_iseq_t *
+location_iseq(rb_backtrace_location_t *loc)
 {
     switch (loc->type) {
       case LOCATION_TYPE_ISEQ:
-        return rb_iseq_path(loc->iseq);
+        return loc->iseq;
       case LOCATION_TYPE_CFUNC:
-        if (loc->iseq) {
-            return rb_iseq_path(loc->iseq);
-	}
-	return Qnil;
+        return loc->iseq;
       default:
-	rb_bug("location_path: unreachable");
+	rb_bug("location_iseq: unreachable");
 	UNREACHABLE;
     }
 }
@@ -313,7 +310,8 @@ location_path(rb_backtrace_location_t *loc) https://github.com/ruby/ruby/blob/trunk/vm_backtrace.c#L310
 static VALUE
 location_path_m(VALUE self)
 {
-    return location_path(location_ptr(self));
+    const rb_iseq_t *iseq = location_iseq(location_ptr(self));
+    return iseq ? rb_iseq_path(iseq) : Qnil;
 }
 
 #ifdef USE_ISEQ_NODE_ID
@@ -336,11 +334,13 @@ location_node_id(rb_backtrace_location_t *loc) https://github.com/ruby/ruby/blob/trunk/vm_backtrace.c#L334
 #endif
 
 void
-rb_frame_info_get(VALUE obj, VALUE *path, int *node_id)
+rb_frame_info_get(VALUE obj, VALUE *path, VALUE *script_lines, int *node_id)
 {
 #ifdef USE_ISEQ_NODE_ID
     rb_backtrace_location_t *loc = location_ptr(obj);
-    *path = location_path(loc);
+    const rb_iseq_t *iseq = location_iseq(loc);
+    *path = iseq ? rb_iseq_path(iseq) : Qnil;
+    *script_lines = iseq ? iseq->body->variable.script_lines : Qnil;
     *node_id = location_node_id(loc);
 #else
     *path = Qnil;
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]