ruby-changes:62381
From: nagachika <ko1@a...>
Date: Thu, 23 Jul 2020 17:47:28 +0900 (JST)
Subject: [ruby-changes:62381] c65aae118c (ruby_2_7): merge revision(s) 927308108cced69cae478798004524b9a5d2f252: [Backport #16764]
https://git.ruby-lang.org/ruby.git/commit/?id=c65aae118c From c65aae118ccff86096b9983641b371491bc23434 Mon Sep 17 00:00:00 2001 From: nagachika <nagachika@r...> Date: Thu, 23 Jul 2020 17:47:12 +0900 Subject: merge revision(s) 927308108cced69cae478798004524b9a5d2f252: [Backport #16764] Fix source location of autoloaded constant [Bug #16764] diff --git a/test/ruby/test_autoload.rb b/test/ruby/test_autoload.rb index 2e53c92..171dbb6 100644 --- a/test/ruby/test_autoload.rb +++ b/test/ruby/test_autoload.rb @@ -425,6 +425,19 @@ p Foo::Bar https://github.com/ruby/ruby/blob/trunk/test/ruby/test_autoload.rb#L425 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| diff --git a/variable.c b/variable.c index 42c4cb7..3146168 100644 --- a/variable.c +++ b/variable.c @@ -1802,8 +1802,10 @@ struct autoload_const { https://github.com/ruby/ruby/blob/trunk/variable.c#L1802 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 */ @@ -1872,6 +1874,7 @@ autoload_c_compact(void *ptr) https://github.com/ruby/ruby/blob/trunk/variable.c#L1874 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 @@ -1882,6 +1885,7 @@ autoload_c_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/variable.c#L1885 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 @@ -2768,11 +2772,11 @@ rb_const_set(VALUE klass, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L2772 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); } /* @@ -2837,10 +2841,17 @@ const_tbl_update(struct autoload_const *ac) https://github.com/ruby/ruby/blob/trunk/variable.c#L2841 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 */ - autoload_delete(klass, id); + 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); diff --git a/version.h b/version.h index a0b6e42..269f278 100644 --- a/version.h +++ b/version.h @@ -2,7 +2,7 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L2 # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 1 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 106 +#define RUBY_PATCHLEVEL 107 #define RUBY_RELEASE_YEAR 2020 #define RUBY_RELEASE_MONTH 7 -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/