summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-22 14:55:32 +0000
committershirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-22 14:55:32 +0000
commit97ecab7b34aaf58f472254356afcd3d529e57401 (patch)
tree7a5cb8ba32676645eeaf973e3b65f2be493c1c4c
parentff6c50709c7f8ee6ce81963864598223fc07f40d (diff)
Fix cache validity check of require
* array.c (rb_ary_shared_with_p): fix cache validity check. If #pop or #shift has been called against $: or $", the array will be still shared with the snapshot. We check array length for cache validity. [ruby-core:49518] [Bug #7383] * test/ruby/test_require.rb (TestRequire#test_require_with_array_pop, TestRequire#test_require_with_array_shift): add tests for above. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37808 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--array.c11
-rw-r--r--test/ruby/test_require.rb31
3 files changed, 50 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 72d0a40204..3b99737a4b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Thu Nov 22 23:45:18 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
+
+ * array.c (rb_ary_shared_with_p): fix cache validity check.
+ If #pop or #shift has been called against $: or $", the array will
+ be still shared with the snapshot. We check array length for cache
+ validity.
+ [ruby-core:49518] [Bug #7383]
+
+ * test/ruby/test_require.rb
+ (TestRequire#test_require_with_array_pop,
+ TestRequire#test_require_with_array_shift): add tests for above.
+
Thu Nov 22 21:48:48 2012 NAKAMURA Usaku <usa@ruby-lang.org>
* common.mk, win32/Makefile.sub (probes.dmyh): now be made in current
diff --git a/array.c b/array.c
index bbe9f60e40..3e617f55aa 100644
--- a/array.c
+++ b/array.c
@@ -351,13 +351,16 @@ rb_ary_frozen_p(VALUE ary)
e.g. rb_ary_replace) and check later whether the array has been
modified from the snapshot. The snapshot is cheap, though if
something does modify the array it will pay the cost of copying
- it. */
+ it. If Array#pop or Array#shift has been called, the array will
+ be still shared with the snapshot, but the array length will
+ differ. */
VALUE
rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
{
- if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1)
- && !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2)
- && RARRAY(ary1)->as.heap.aux.shared == RARRAY(ary2)->as.heap.aux.shared) {
+ if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
+ !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
+ RARRAY(ary1)->as.heap.aux.shared == RARRAY(ary2)->as.heap.aux.shared &&
+ RARRAY(ary1)->as.heap.len == RARRAY(ary2)->as.heap.len) {
return Qtrue;
}
return Qfalse;
diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb
index 36d7c788bf..d3cae1e01c 100644
--- a/test/ruby/test_require.rb
+++ b/test/ruby/test_require.rb
@@ -545,4 +545,35 @@ class TestRequire < Test::Unit::TestCase
}
}
end
+
+ def assert_require_with_shared_array_modified(add, del)
+ bug7383 = '[ruby-core:49518]'
+ Dir.mktmpdir {|tmp|
+ Dir.chdir(tmp) {
+ open("foo.rb", "w") {}
+ Dir.mkdir("a")
+ open(File.join("a", "bar.rb"), "w") {}
+ assert_in_out_err([], <<-INPUT, %w(:ok), [], bug7383)
+ $:.#{add} "#{tmp}"
+ $:.#{add} "#{tmp}/a"
+ require "foo"
+ $:.#{del}
+ # Expanded load path cache should be rebuilt.
+ begin
+ require "bar"
+ rescue LoadError
+ p :ok
+ end
+ INPUT
+ }
+ }
+ end
+
+ def test_require_with_array_pop
+ assert_require_with_shared_array_modified("push", "pop")
+ end
+
+ def test_require_with_array_shift
+ assert_require_with_shared_array_modified("unshift", "shift")
+ end
end