1
0
Fork 0
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:
Alan Wu 2021-10-06 15:38:33 -04:00 committed by GitHub
parent d53493715c
commit 7622819147
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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

View file

@ -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
View file

@ -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++) {