[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