summaryrefslogtreecommitdiff
path: root/vm_eval.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2021-05-21 11:01:06 -0700
committerJeremy Evans <code@jeremyevans.net>2021-07-29 13:51:03 -0700
commit64ac984129a7a4645efe5ac57c168ef880b479b2 (patch)
tree3d5aa171e3e63e39b9b8d4ab4425d01894880f02 /vm_eval.c
parent6998d758248d778fa95b008c78d05473e48b8428 (diff)
Make RubyVM::AbstractSyntaxTree.of raise for method/proc created in eval
This changes Thread::Location::Backtrace#absolute_path to return nil for methods/procs defined in eval. If the realpath of an iseq is nil, that indicates it was defined in eval, in which case you cannot use RubyVM::AbstractSyntaxTree.of. Fixes [Bug #16983] Co-authored-by: Koichi Sasada <ko1@atdot.net>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4519
Diffstat (limited to 'vm_eval.c')
-rw-r--r--vm_eval.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/vm_eval.c b/vm_eval.c
index bc40c15b6c..19ba6dd96b 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -1661,13 +1661,15 @@ rb_each(VALUE obj)
}
void rb_parser_warn_location(VALUE, int);
+
+static VALUE eval_default_path;
+
static const rb_iseq_t *
eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
const struct rb_block *base_block)
{
const VALUE parser = rb_parser_new();
const rb_iseq_t *const parent = vm_block_iseq(base_block);
- VALUE realpath = Qnil;
rb_iseq_t *iseq = NULL;
rb_ast_t *ast;
int isolated_depth = 0;
@@ -1694,10 +1696,14 @@ eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
if (fname != Qundef) {
if (!NIL_P(fname)) fname = rb_fstring(fname);
- realpath = fname;
}
else {
fname = rb_fstring_lit("(eval)");
+ if (!eval_default_path) {
+ eval_default_path = rb_fstring_lit("(eval)");
+ rb_gc_register_mark_object(eval_default_path);
+ }
+ fname = eval_default_path;
}
rb_parser_set_context(parser, parent, FALSE);
@@ -1705,7 +1711,7 @@ eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
if (ast->body.root) {
iseq = rb_iseq_new_eval(&ast->body,
parent->body->location.label,
- fname, realpath, INT2FIX(line),
+ fname, Qnil, INT2FIX(line),
parent, isolated_depth);
}
rb_ast_dispose(ast);
@@ -2590,7 +2596,18 @@ rb_current_realfilepath(void)
const rb_execution_context_t *ec = GET_EC();
rb_control_frame_t *cfp = ec->cfp;
cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
- if (cfp != 0) return rb_iseq_realpath(cfp->iseq);
+ if (cfp != NULL) {
+ VALUE path = rb_iseq_realpath(cfp->iseq);
+ if (RTEST(path)) return path;
+ // eval context
+ path = rb_iseq_path(cfp->iseq);
+ if (path == eval_default_path) {
+ return Qnil;
+ }
+ else {
+ return path;
+ }
+ }
return Qnil;
}