Fix Module#const_source_location for autoload constants with direct requires
If an autoload exists for a constant, but the path for the autoload was required, const_source_location would return [false, 0] instead of the actual file and line. This fixes it by setting the appropriate file and line in rb_const_set, and saving the file and line in const_tbl_update before they get reset by current_autoload_data. Fixes [Bug #18624]
This commit is contained in:
parent
653e517eef
commit
c85d1cda86
Notes:
git
2022-06-07 03:13:14 +09:00
@ -443,6 +443,23 @@ p Foo::Bar
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_source_location_after_require
|
||||||
|
bug = "Bug18624"
|
||||||
|
Dir.mktmpdir('autoload') do |tmpdir|
|
||||||
|
path = "#{tmpdir}/test-#{bug}.rb"
|
||||||
|
File.write(path, "C::#{bug} = __FILE__\n")
|
||||||
|
assert_separately(%W[-I #{tmpdir}], "#{<<-"begin;"}\n#{<<-"end;"}")
|
||||||
|
begin;
|
||||||
|
class C; end
|
||||||
|
C.autoload(:Bug18624, #{path.dump})
|
||||||
|
require #{path.dump}
|
||||||
|
assert_equal [#{path.dump}, 1], C.const_source_location(#{bug.dump})
|
||||||
|
assert_equal #{path.dump}, C.const_get(#{bug.dump})
|
||||||
|
assert_equal [#{path.dump}, 1], C.const_source_location(#{bug.dump})
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_no_memory_leak
|
def test_no_memory_leak
|
||||||
assert_no_memory_leak([], '', "#{<<~"begin;"}\n#{<<~'end;'}", 'many autoloads', timeout: 60)
|
assert_no_memory_leak([], '', "#{<<~"begin;"}\n#{<<~'end;'}", 'many autoloads', timeout: 60)
|
||||||
begin;
|
begin;
|
||||||
|
@ -3264,6 +3264,7 @@ const_set(VALUE klass, ID id, VALUE val)
|
|||||||
.value = val, .flag = CONST_PUBLIC,
|
.value = val, .flag = CONST_PUBLIC,
|
||||||
/* fill the rest with 0 */
|
/* fill the rest with 0 */
|
||||||
};
|
};
|
||||||
|
ac.file = rb_source_location(&ac.line);
|
||||||
const_tbl_update(&ac, false);
|
const_tbl_update(&ac, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3337,6 +3338,8 @@ const_tbl_update(struct autoload_const *ac, int autoload_force)
|
|||||||
ce = (rb_const_entry_t *)value;
|
ce = (rb_const_entry_t *)value;
|
||||||
if (ce->value == Qundef) {
|
if (ce->value == Qundef) {
|
||||||
RUBY_ASSERT_CRITICAL_SECTION_ENTER();
|
RUBY_ASSERT_CRITICAL_SECTION_ENTER();
|
||||||
|
VALUE file = ac->file;
|
||||||
|
int line = ac->line;
|
||||||
struct autoload_data *ele = autoload_data_for_named_constant(klass, id, &ac);
|
struct autoload_data *ele = autoload_data_for_named_constant(klass, id, &ac);
|
||||||
|
|
||||||
if (!autoload_force && ele) {
|
if (!autoload_force && ele) {
|
||||||
@ -3350,8 +3353,8 @@ const_tbl_update(struct autoload_const *ac, int autoload_force)
|
|||||||
autoload_delete(klass, id);
|
autoload_delete(klass, id);
|
||||||
ce->flag = visibility;
|
ce->flag = visibility;
|
||||||
RB_OBJ_WRITE(klass, &ce->value, val);
|
RB_OBJ_WRITE(klass, &ce->value, val);
|
||||||
RB_OBJ_WRITE(klass, &ce->file, ac->file);
|
RB_OBJ_WRITE(klass, &ce->file, file);
|
||||||
ce->line = ac->line;
|
ce->line = line;
|
||||||
}
|
}
|
||||||
RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
|
RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user