зеркало из https://github.com/github/ruby.git
Fix source location of autoloaded constant [Bug #16764]
This commit is contained in:
Родитель
ce60821387
Коммит
927308108c
|
@ -427,6 +427,19 @@ p Foo::Bar
|
|||
end
|
||||
end
|
||||
|
||||
def test_source_location
|
||||
klass = self.class
|
||||
bug = "Bug16764"
|
||||
Dir.mktmpdir('autoload') do |tmpdir|
|
||||
path = "#{tmpdir}/test-#{bug}.rb"
|
||||
File.write(path, "#{klass}::#{bug} = __FILE__\n")
|
||||
klass.autoload(:Bug16764, path)
|
||||
assert_equal [__FILE__, __LINE__-1], klass.const_source_location(bug)
|
||||
assert_equal path, klass.const_get(bug)
|
||||
assert_equal [path, 1], klass.const_source_location(bug)
|
||||
end
|
||||
end
|
||||
|
||||
def test_no_leak
|
||||
assert_no_memory_leak([], '', <<~'end;', 'many autoloads', timeout: 60)
|
||||
200000.times do |i|
|
||||
|
|
25
variable.c
25
variable.c
|
@ -1807,8 +1807,10 @@ struct autoload_const {
|
|||
VALUE mod;
|
||||
VALUE ad; /* autoload_data_i */
|
||||
VALUE value;
|
||||
VALUE file;
|
||||
ID id;
|
||||
rb_const_flag_t flag;
|
||||
int line;
|
||||
};
|
||||
|
||||
/* always on stack, no need to mark */
|
||||
|
@ -1877,6 +1879,7 @@ autoload_c_compact(void *ptr)
|
|||
ac->mod = rb_gc_location(ac->mod);
|
||||
ac->ad = rb_gc_location(ac->ad);
|
||||
ac->value = rb_gc_location(ac->value);
|
||||
ac->file = rb_gc_location(ac->file);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1887,6 +1890,7 @@ autoload_c_mark(void *ptr)
|
|||
rb_gc_mark_movable(ac->mod);
|
||||
rb_gc_mark_movable(ac->ad);
|
||||
rb_gc_mark_movable(ac->value);
|
||||
rb_gc_mark_movable(ac->file);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2772,11 +2776,11 @@ rb_const_set(VALUE klass, ID id, VALUE val)
|
|||
setup_const_entry(ce, klass, val, CONST_PUBLIC);
|
||||
}
|
||||
else {
|
||||
struct autoload_const ac;
|
||||
ac.mod = klass;
|
||||
ac.id = id;
|
||||
ac.value = val;
|
||||
ac.flag = CONST_PUBLIC;
|
||||
struct autoload_const ac = {
|
||||
.mod = klass, .id = id,
|
||||
.value = val, .flag = CONST_PUBLIC,
|
||||
/* fill the rest with 0 */
|
||||
};
|
||||
const_tbl_update(&ac);
|
||||
}
|
||||
/*
|
||||
|
@ -2841,10 +2845,17 @@ const_tbl_update(struct autoload_const *ac)
|
|||
rb_clear_constant_cache();
|
||||
|
||||
ac->value = val; /* autoload_i is non-WB-protected */
|
||||
return;
|
||||
ac->file = rb_source_location(&ac->line);
|
||||
}
|
||||
/* otherwise, allow to override */
|
||||
else {
|
||||
/* otherwise autoloaded constant, allow to override */
|
||||
autoload_delete(klass, id);
|
||||
ce->flag = visibility;
|
||||
RB_OBJ_WRITE(klass, &ce->value, val);
|
||||
RB_OBJ_WRITE(klass, &ce->file, ac->file);
|
||||
ce->line = ac->line;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
VALUE name = QUOTE_ID(id);
|
||||
|
|
Загрузка…
Ссылка в новой задаче