Skip to content

Make Kernel#lambda return non-lambda when block is not literal - #2288

Closed
XrXr wants to merge 1 commit into
ruby:masterfrom
XrXr:block-pass-lambda-two-four
Closed

Make Kernel#lambda return non-lambda when block is not literal#2288
XrXr wants to merge 1 commit into
ruby:masterfrom
XrXr:block-pass-lambda-two-four

Conversation

@XrXr

@XrXr XrXr commented Jul 12, 2019

Copy link
Copy Markdown
Member

This restores the behavior of Kernel#lambda from Ruby 2.4.x
when it receives a non literal block.

Semantically speaking, once a literal block is passed into a method
which takes an ampersand argument, the block becomes a non-lambda
Proc object. When Kernel#lambda recieves a non-lambda proc,
it is supposed to simply return it.

Because of lazy proc allocation, Kernel#lambda wasn't able to tell
the difference between a literal block and a block that has passed
through an ampersand argument and is semantically supposed to be
a Proc object.

This commit uses a new pointer tag, 0x2, to indicate that a block
has passed through an ampersand argument. In all other regards,
this block handler tag is the same as block_handler_type_iseq.
I then use this new tag in Kernel#lambda to implement the
2.4.x spec.

Bug #15620

This restores the behavior of Kernel#lambda from Ruby 2.4.x
when it receives a non literal block.

Semantically speaking, once a literal block is passed into a method
which takes an ampersand argument, the block becomes a non-lambda
Proc object. When Kernel#lambda recieves a non-lambda proc,
it is supposed to simply return it.

Because of lazy proc allocation, Kernel#lambda wasn't able to tell
the difference between a literal block and a block that has passed
through an ampersand argument and is semantically supposed to be
a Proc object.

This commit uses a new pointer tag, `0x2`, to indicate that a block
has passed through an ampersand argument. In all other regards,
this block handler tag is the same as `block_handler_type_iseq`.
I then use this new tag in Kernel#lambda to implement the
2.4.x spec.

[Bug ruby#15620]
@XrXr

XrXr commented Jul 12, 2019

Copy link
Copy Markdown
Member Author

@ko1 Question: You seem to have picked 0x01 and 0x03 intentionally. Are there any issues with using 0x 2 as a tag? I think 0x02 makes the pointer look like a float to the GC. Could that cause problems?

I ran tests with VM_CHECK_MODE=1 things seem okay.

EDIT: ah, it looks like I messed something up for 32-bit platforms.

@XrXr

XrXr commented Jul 13, 2019

Copy link
Copy Markdown
Member Author

😬 it looks like 0x02 conflicts with RUBY_SYMBOL_FLAG on 32 bit platforms. I ran out of bits to use for tagging it looks like. Sorry about the noise.

@XrXr XrXr closed this Jul 13, 2019
@XrXr
XrXr deleted the block-pass-lambda-two-four branch July 14, 2019 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant