summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2025-08-26 19:05:57 +0900
committerYusuke Endoh <mame@ruby-lang.org>2025-08-28 12:44:29 +0900
commited8fe53e80e16f9bff592333a3082981f39216e1 (patch)
tree7ea069596d503333c0cb0fb52764fb3ca468db23
parent2ccb2de677849732181224cb9fd1a831dbaac4c0 (diff)
Allow to get a NODE_SCOPE node of dummy stack frame of ArgumentError
Previously, it was not possible to obtain a node of the callee's `Thread::Backtrace::Location` for cases like "wrong number of arguments" by using `RubyVM::AST.of`. This change allows that retrieval. This is preparation for [Feature #21543].
-rw-r--r--test/ruby/test_ast.rb44
-rw-r--r--vm_backtrace.c4
2 files changed, 46 insertions, 2 deletions
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index f5c4b8d6b9..ef078c3575 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -365,6 +365,50 @@ class TestAst < Test::Unit::TestCase
assert_equal node.node_id, node_id
end
+ def add(x, y)
+ end
+
+ def test_node_id_for_backtrace_location_of_method_definition
+ omit if ParserSupport.prism_enabled?
+
+ begin
+ add(1)
+ rescue ArgumentError => exc
+ loc = exc.backtrace_locations.first
+ node_id = RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc)
+ node = RubyVM::AbstractSyntaxTree.of(method(:add))
+ assert_equal node.node_id, node_id
+ end
+ end
+
+ def test_node_id_for_backtrace_location_of_lambda
+ omit if ParserSupport.prism_enabled?
+
+ v = -> {}
+ begin
+ v.call(1)
+ rescue ArgumentError => exc
+ loc = exc.backtrace_locations.first
+ node_id = RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc)
+ node = RubyVM::AbstractSyntaxTree.of(v)
+ assert_equal node.node_id, node_id
+ end
+ end
+
+ def test_node_id_for_backtrace_location_of_lambda_method
+ omit if ParserSupport.prism_enabled?
+
+ v = lambda {}
+ begin
+ v.call(1)
+ rescue ArgumentError => exc
+ loc = exc.backtrace_locations.first
+ node_id = RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc)
+ node = RubyVM::AbstractSyntaxTree.of(v)
+ assert_equal node.node_id, node_id
+ end
+ end
+
def test_node_id_for_backtrace_location_raises_argument_error
bug19262 = '[ruby-core:111435]'
diff --git a/vm_backtrace.c b/vm_backtrace.c
index 12e4b771e2..cc8607b2d7 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -44,7 +44,7 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
}
if (lineno) *lineno = ISEQ_BODY(iseq)->location.first_lineno;
#ifdef USE_ISEQ_NODE_ID
- if (node_id) *node_id = -1;
+ if (node_id) *node_id = ISEQ_BODY(iseq)->location.node_id;
#endif
return 1;
}
@@ -400,7 +400,7 @@ location_path_m(VALUE self)
static int
location_node_id(rb_backtrace_location_t *loc)
{
- if (loc->iseq && loc->pc) {
+ if (loc->iseq) {
return calc_node_id(loc->iseq, loc->pc);
}
return -1;