merge revision(s) dd80d9b089: [Backport #20997]

YJIT: Filter `&` calls from specialized C method codegen

	Evident with the crash reported in [Bug #20997], the C replacement
	codegen functions aren't authored to handle block arguments (nor
	should they because the extra code from the complexity defeats
	optimization). Filter sites with VM_CALL_ARGS_BLOCKARG.
This commit is contained in:
nagachika 2025-01-25 14:51:31 +09:00
parent 97243cc9c7
commit 7c0c2df9b4
3 changed files with 11 additions and 3 deletions

View file

@ -3520,3 +3520,11 @@ assert_equal 'ok', %q{
cw(4)
}
assert_normal_exit %{
class Bug20997
def foo(&) = self.class.name(&)
new.foo
end
}

View file

@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 6
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 251
#define RUBY_PATCHLEVEL 252
#include "ruby/version.h"
#include "ruby/internal/abi.h"

View file

@ -4584,8 +4584,8 @@ fn gen_send_cfunc(
return CantCompile;
}
// Delegate to codegen for C methods if we have it.
if kw_arg.is_null() && flags & VM_CALL_OPT_SEND == 0 && flags & VM_CALL_ARGS_SPLAT == 0 && (cfunc_argc == -1 || argc == cfunc_argc) {
// Delegate to codegen for C methods if we have it and the callsite is simple enough.
if kw_arg.is_null() && flags & VM_CALL_OPT_SEND == 0 && flags & VM_CALL_ARGS_SPLAT == 0 && flags & VM_CALL_ARGS_BLOCKARG == 0 && (cfunc_argc == -1 || argc == cfunc_argc) {
let codegen_p = lookup_cfunc_codegen(unsafe { (*cme).def });
let expected_stack_after = ctx.get_stack_size() as i32 - argc;
if let Some(known_cfunc_codegen) = codegen_p {