mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix Ractor.make_shareable changing locals for Procs
env_copy() uses rb_ary_delete_at() with a loop counting up while iterating through the list of read only locals. rb_ary_delete_at() can shift elements in the array to an index lesser than the loop index, causing locals to be missed and set to Qfalse in the returned environment. Iterate through the locals in reverse instead, this way the shifting never happens for locals that are yet to be visited and we process all the locals in the array. [Bug #18023]
This commit is contained in:
parent
d53493715c
commit
7622819147
Notes:
git
2021-10-07 04:39:02 +09:00
Merged: https://github.com/ruby/ruby/pull/4940 Merged-By: XrXr
2 changed files with 23 additions and 1 deletions
|
@ -187,6 +187,28 @@ assert_equal '[:ok, :ok, :ok]', %q{
|
|||
}.map(&:take)
|
||||
}
|
||||
|
||||
# Ractor.make_shareable issue for locals in proc [Bug #18023]
|
||||
assert_equal '[:a, :b, :c, :d, :e]', %q{
|
||||
v1, v2, v3, v4, v5 = :a, :b, :c, :d, :e
|
||||
closure = Proc.new { [v1, v2, v3, v4, v5] }
|
||||
|
||||
Ractor.make_shareable(closure).call
|
||||
}
|
||||
|
||||
# Ractor.make_shareable issue for locals in proc [Bug #18023]
|
||||
assert_equal '[:a, :b, :c, :d, :e, :f, :g]', %q{
|
||||
a = :a
|
||||
closure = -> {
|
||||
b, c, d = :b, :c, :d
|
||||
-> {
|
||||
e, f, g = :e, :f, :g
|
||||
-> { [a, b, c, d, e, f, g] }
|
||||
}.call
|
||||
}.call
|
||||
|
||||
Ractor.make_shareable(closure).call
|
||||
}
|
||||
|
||||
###
|
||||
###
|
||||
# Ractor still has several memory corruption so skip huge number of tests
|
||||
|
|
2
vm.c
2
vm.c
|
@ -1006,7 +1006,7 @@ env_copy(const VALUE *src_ep, VALUE read_only_variables)
|
|||
volatile VALUE prev_env = Qnil;
|
||||
|
||||
if (read_only_variables) {
|
||||
for (int i=0; i<RARRAY_LENINT(read_only_variables); i++) {
|
||||
for (int i=RARRAY_LENINT(read_only_variables)-1; i>=0; i--) {
|
||||
ID id = SYM2ID(rb_str_intern(RARRAY_AREF(read_only_variables, i)));
|
||||
|
||||
for (unsigned int j=0; j<src_env->iseq->body->local_table_size; j++) {
|
||||
|
|
Loading…
Reference in a new issue