Visitar URL original
Convert block-pass arguments in the direct keyword call path by sferik · Pull Request #9840 · jruby/jruby · GitHub
Skip to content

Convert block-pass arguments in the direct keyword call path - #9840

Merged
headius merged 1 commit into
jruby:masterfrom
sferik:jit-keywords-block-pass
Oct 20, 2026
Merged

headius merged 1 commit into
jruby:masterfrom
sferik:jit-keywords-block-pass

Conversation

@sferik

@sferik sferik commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Fixes #9820.

The direct keyword-argument path in compileCallWithKeywords pushed a block-pass argument, like &:read or &pr, as the raw object, and then told the call site it was a Block. The JVM rejected the class with VerifyError: Bad type on operand stack, so any method containing a call like IO.popen(cmd, err: [:child, :out], &:read) stayed interpreted.

The argument is now converted with getBlockFromObject, which is what the normal call path does. That handles symbols, procs, method objects and nil, and passes the method's own block through unchanged, which is why foo(a: 1, &block) already worked.

This was the most common failure in the compile check from #9821: 96 methods and blocks in the stdlib, ruby/spec and the MRI tests, including Bundler::GemHelper#sh_with_status. After this change, the stdlib has none left.

The new spec passes a symbol, a proc, nil and a method object alongside keyword arguments, with and without positional arguments and inside a block, and checks that each block actually reaches the method. It fails in JIT mode before this change and passes in all four modes after it. I also checked the forms from the issue with the real JIT, and they compile and give the same results as CRuby.

compileCallWithKeywords pushed a block-pass argument, like &:to_s or
&pr, as the raw object and passed it where the call site expects a
Block. The JVM rejected the class with VerifyError: Bad type on operand
stack, so any method with a call like IO.popen(cmd, err: [:child, :out],
&:read) stayed interpreted.

Convert the argument with getBlockFromObject, as the normal call path
does. That also handles the method's own block, which is already a
Block.

Fixes jruby#9820
@sferik
sferik force-pushed the jit-keywords-block-pass branch from f9015f5 to afa4115 Compare October 20, 2026 02:21

@headius headius left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely a change made to block pass conversion sometime after keywords were pulled out as a separate piece of logic. The IR has gone through some changes that likely removed an implicit block conversion call and this branch was never updated.

Can't currently track down exactly why this is doing the wrong thing, but it's a simple fix and looks good.

@headius headius added this to the JRuby 10.1.3.0 milestone Oct 20, 2026
@headius
headius merged commit b0330e1 into jruby:master Oct 20, 2026
135 checks passed
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.

JIT emits invalid bytecode for a call with keyword arguments and a block-pass argument (VerifyError)

2 participants