summaryrefslogtreecommitdiff
path: root/ast.c
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2021-06-08 17:34:08 +0900
committerYusuke Endoh <mame@ruby-lang.org>2021-06-18 03:35:38 +0900
commitdfba87cd622f9699f54d1d0b8c057deb428874b6 (patch)
treebd07194e1c0dc96cd517cbf1e3c37389e5d48614 /ast.c
parentea6062898ad0d66ede0a1866028c0605c357e2cb (diff)
Make it possible to get AST::Node from Thread::Backtrace::Location
RubyVM::AST.of(Thread::Backtrace::Location) returns a node that corresponds to the location. Typically, the node is a method call, but not always. This change also includes iseq's dump/load support of node_ids for each instructions.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4558
Diffstat (limited to 'ast.c')
-rw-r--r--ast.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/ast.c b/ast.c
index 78de316c61..04ba3c987f 100644
--- a/ast.c
+++ b/ast.c
@@ -197,23 +197,26 @@ ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE save_script
{
VALUE path, node, lines;
int node_id;
- const rb_iseq_t *iseq = NULL;
- if (rb_obj_is_proc(body)) {
- iseq = vm_proc_iseq(body);
-
- if (!rb_obj_is_iseq((VALUE)iseq)) {
- iseq = NULL;
- }
+ if (rb_frame_info_p(body)) {
+ rb_frame_info_get(body, &path, &node_id);
+ if (NIL_P(path)) return Qnil;
}
else {
- iseq = rb_method_iseq(body);
- }
+ const rb_iseq_t *iseq = NULL;
+
+ if (rb_obj_is_proc(body)) {
+ iseq = vm_proc_iseq(body);
- if (!iseq) return Qnil;
+ if (!rb_obj_is_iseq((VALUE)iseq)) return Qnil;
+ }
+ else {
+ iseq = rb_method_iseq(body);
+ }
+ path = rb_iseq_path(iseq);
+ node_id = iseq->body->location.node_id;
+ }
- path = rb_iseq_path(iseq);
- node_id = iseq->body->location.node_id;
if (!NIL_P(lines = script_lines(path))) {
node = rb_ast_parse_array(lines, save_script_lines);
}