[ruby-cvs:78792] 85a337f986 (master): Kernel#lambda: return forwarded block as non-lambda proc
"Alan Wu" <[email protected]> Sat, 21 Dec 2019 23:09:06 +0900 (JST)
| Newsgroups | gmane.comp.lang.ruby.cvs |
|---|---|
| Message-ID | <[email protected]> |
Alan Wu 2019-07-14 01:04:01 +0900 (Sun, 14 Jul 2019)
New Revision: 85a337f986
https://github.com/ruby/ruby/commit/85a337f986
Log:
Kernel#lambda: return forwarded block as non-lambda proc
Before this commit, Kernel#lambda can't tell the difference between a
directly passed literal block and one passed with an ampersand.
A block passed with an ampersand is semantically speaking already a
non-lambda proc. When Kernel#lambda receives a non-lambda proc, it
should simply return it.
Implementation wise, when the VM calls a method with a literal block, it
places the code for the block on the calling control frame and passes a
pointer (block handler) to the callee. Before this commit, the VM
forwards block arguments by simply forwarding the block handler, which
leaves the slot for block code unused when a control frame forwards its
block argument. I use the vacant space to indicate that a frame has
forwarded its block argument and inspect that in Kernel#lambda to detect
forwarded blocks.
This is a very ad-hoc solution and relies *heavily* on the way block
passing works in the VM. However, it's the most self-contained solution
I have.
[Bug #15620]
Modified files:
proc.c
test/ruby/test_lambda.rb
vm_args.c
vm_core.h