Project

General

Profile

Bug #4379 » final_eval_location.patch

This passes rubyspec while the above does not. Ensures __FILE__ == eval("__FILE__", binding) - quix (James M. Lawrence), 02/09/2011 06:57 AM

View differences:

vm_eval.c
}
static VALUE
eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *volatile file, volatile int line)
eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *volatile file, volatile int line, volatile int is_user_file)
{
int state;
VALUE result = Qundef;
......
if (rb_obj_is_kind_of(scope, rb_cBinding)) {
GetBindingPtr(scope, bind);
envval = bind->env;
if (strcmp(file, "(eval)") == 0 && bind->filename != Qnil) {
if (!is_user_file && strcmp(file, "(eval)") == 0 && bind->filename != Qnil) {
file = RSTRING_PTR(bind->filename);
line = bind->line_no;
}
......
if (state) {
if (state == TAG_RAISE) {
VALUE errinfo = th->errinfo;
if (strcmp(file, "(eval)") == 0) {
if (!is_user_file && strcmp(file, "(eval)") == 0) {
VALUE mesg, errat, bt2;
extern VALUE rb_get_backtrace(VALUE info);
ID id_mesg;
......
}
static VALUE
eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line)
eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line, int is_user_file)
{
return eval_string_with_cref(self, src, scope, 0, file, line);
return eval_string_with_cref(self, src, scope, 0, file, line, is_user_file);
}
/*
......
VALUE src, scope, vfile, vline;
const char *file = "(eval)";
int line = 1;
int is_user_file = FALSE;
rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
if (rb_safe_level() >= 4) {
......
}
if (argc >= 3) {
StringValue(vfile);
is_user_file = TRUE;
}
if (argc >= 4) {
line = NUM2INT(vline);
......
if (!NIL_P(vfile))
file = RSTRING_PTR(vfile);
return eval_string(self, src, scope, file, line);
return eval_string(self, src, scope, file, line, is_user_file);
}
VALUE
rb_eval_string(const char *str)
{
return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1, FALSE);
}
VALUE
......
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0);
val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0, FALSE);
}
POP_TAG();
......
/* string eval under the class/module context */
static VALUE
eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line, int is_user_file)
{
NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC, NULL);
......
SafeStringValue(src);
}
return eval_string_with_cref(self, src, Qnil, cref, file, line);
return eval_string_with_cref(self, src, Qnil, cref, file, line, is_user_file);
}
static VALUE
specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
{
int is_user_file = FALSE;
if (rb_block_given_p()) {
if (argc > 0) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
......
line = NUM2INT(argv[2]);
if (argc > 1) {
file = StringValuePtr(argv[1]);
is_user_file = TRUE;
}
}
return eval_under(klass, self, argv[0], file, line);
return eval_under(klass, self, argv[0], file, line, is_user_file);
}
}
(4-4/4)