diff options
| author | Takashi Kokubun <takashikkbn@gmail.com> | 2023-08-10 20:08:29 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-10 23:08:29 -0400 |
| commit | 654b64822395ead530ac3ecae318197be85c8b52 (patch) | |
| tree | b579540aeb587b889fb202024a91c56f6e6815d3 | |
| parent | b7453b91dc1e5adc9d5ebe15c644cf5e0a54e3ac (diff) | |
YJIT: Implement checkmatch instruction (#8203)
Notes
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
| -rw-r--r-- | vm_insnhelper.c | 6 | ||||
| -rw-r--r-- | yjit/bindgen/src/main.rs | 1 | ||||
| -rw-r--r-- | yjit/src/codegen.rs | 28 | ||||
| -rw-r--r-- | yjit/src/cruby_bindings.inc.rs | 4 |
4 files changed, 39 insertions, 0 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 5cbd47d78b..7ee8fd2cbf 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -5233,6 +5233,12 @@ vm_check_match(rb_execution_context_t *ec, VALUE target, VALUE pattern, rb_num_t } } +VALUE +rb_vm_check_match(rb_execution_context_t *ec, VALUE target, VALUE pattern, rb_num_t flag) +{ + return vm_check_match(ec, target, pattern, flag); +} + static VALUE vm_check_keyword(lindex_t bits, lindex_t idx, const VALUE *ep) { diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 8a187bf674..6b6337d541 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -292,6 +292,7 @@ fn main() { .allowlist_type("rb_builtin_attr") .allowlist_type("ruby_tag_type") .allowlist_type("ruby_vm_throw_flags") + .allowlist_type("vm_check_match_type") // From yjit.c .allowlist_function("rb_iseq_(get|set)_yjit_payload") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index b3139253ad..1baa5edd64 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -1901,6 +1901,33 @@ fn gen_putstring( Some(KeepCompiling) } +fn gen_checkmatch( + jit: &mut JITState, + asm: &mut Assembler, + _ocb: &mut OutlinedCb, +) -> Option<CodegenStatus> { + let flag = jit.get_arg(0).as_u32(); + + // rb_vm_check_match is not leaf unless flag is VM_CHECKMATCH_TYPE_WHEN. + // See also: leafness_of_checkmatch() and check_match() + if flag != VM_CHECKMATCH_TYPE_WHEN { + jit_prepare_routine_call(jit, asm); + } + + let pattern = asm.stack_pop(1); + let target = asm.stack_pop(1); + + extern "C" { + fn rb_vm_check_match(ec: EcPtr, target: VALUE, pattern: VALUE, num: u32) -> VALUE; + } + let result = asm.ccall(rb_vm_check_match as *const u8, vec![EC, target, pattern, flag.into()]); + + let stack_ret = asm.stack_push(Type::Unknown); + asm.mov(stack_ret, result); + + Some(KeepCompiling) +} + // Push Qtrue or Qfalse depending on whether the given keyword was supplied by // the caller fn gen_checkkeyword( @@ -8300,6 +8327,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> { YARVINSN_expandarray => Some(gen_expandarray), YARVINSN_defined => Some(gen_defined), YARVINSN_definedivar => Some(gen_definedivar), + YARVINSN_checkmatch => Some(gen_checkmatch), YARVINSN_checkkeyword => Some(gen_checkkeyword), YARVINSN_concatstrings => Some(gen_concatstrings), YARVINSN_getinstancevariable => Some(gen_getinstancevariable), diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 73dad6d2fb..1d0704073d 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -768,6 +768,10 @@ impl rb_proc_t { __bindgen_bitfield_unit } } +pub const VM_CHECKMATCH_TYPE_WHEN: vm_check_match_type = 1; +pub const VM_CHECKMATCH_TYPE_CASE: vm_check_match_type = 2; +pub const VM_CHECKMATCH_TYPE_RESCUE: vm_check_match_type = 3; +pub type vm_check_match_type = u32; pub const VM_SPECIAL_OBJECT_VMCORE: vm_special_object_type = 1; pub const VM_SPECIAL_OBJECT_CBASE: vm_special_object_type = 2; pub const VM_SPECIAL_OBJECT_CONST_BASE: vm_special_object_type = 3; |
