Allow lambdas that don't access self to be made shareable
This commit allows lambdas that don't access self to be "made shareable" regardless of the shareability of self.
For example, the following code used to produce a lambda that was not shareable:
class Foo
def make_block; lambda { 1234 }; end
end
Ractor.make_shareable(Foo.new.make_block) # exception
This lambda was not allowed to be shareable because it could possibly access self which is an unfrozen instance of Foo. However, we know by looking at the code that it doesn't access the instance of Foo, so I think we should lift this restriction.
Upon calling make_shareable, this change scans the instructions of the block looking for particular instructions that access self. If it sees any of those instructions, then we use the default behavior (checking sharability of self). If we don't see those instructions, then we'll allow the lambda to be shareable.
For example, this is shareable:
def make_block
foo = 123
lambda { foo }
end
But these are not shareable:
def make_block
lambda { @foo }
end
def make_block
lambda { @foo = 1 }
end
def make_block
lambda { eval("123") }
end
[Feature #21033]