YJIT: Implement codegen for Kernel#block_given? (#7202)
This commit is contained in:
parent
2181a66374
commit
2a0bf269c9
Notes:
git
2023-01-31 15:11:31 +00:00
Merged-By: maximecb <maximecb@ruby-lang.org>
@ -118,7 +118,7 @@ module Kernel
|
|||||||
# 2.then.detect(&:odd?) # => nil
|
# 2.then.detect(&:odd?) # => nil
|
||||||
#
|
#
|
||||||
def then
|
def then
|
||||||
unless Primitive.block_given_p
|
unless block_given?
|
||||||
return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
|
return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
|
||||||
end
|
end
|
||||||
yield(self)
|
yield(self)
|
||||||
@ -142,7 +142,7 @@ module Kernel
|
|||||||
# then {|response| JSON.parse(response) }
|
# then {|response| JSON.parse(response) }
|
||||||
#
|
#
|
||||||
def yield_self
|
def yield_self
|
||||||
unless Primitive.block_given_p
|
unless block_given?
|
||||||
return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
|
return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
|
||||||
end
|
end
|
||||||
yield(self)
|
yield(self)
|
||||||
@ -178,7 +178,7 @@ module Kernel
|
|||||||
# puts enum.next
|
# puts enum.next
|
||||||
# } #=> :ok
|
# } #=> :ok
|
||||||
def loop
|
def loop
|
||||||
unless Primitive.block_given_p
|
unless block_given?
|
||||||
return enum_for(:loop) { Float::INFINITY }
|
return enum_for(:loop) { Float::INFINITY }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
6
object.c
6
object.c
@ -569,12 +569,6 @@ rb_obj_size(VALUE self, VALUE args, VALUE obj)
|
|||||||
return LONG2FIX(1);
|
return LONG2FIX(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
|
||||||
block_given_p(rb_execution_context_t *ec, VALUE self)
|
|
||||||
{
|
|
||||||
return RBOOL(rb_block_given_p());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* :nodoc:
|
* :nodoc:
|
||||||
*--
|
*--
|
||||||
|
@ -4380,6 +4380,36 @@ fn jit_obj_respond_to(
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn jit_rb_f_block_given_p(
|
||||||
|
jit: &mut JITState,
|
||||||
|
ctx: &mut Context,
|
||||||
|
asm: &mut Assembler,
|
||||||
|
_ocb: &mut OutlinedCb,
|
||||||
|
_ci: *const rb_callinfo,
|
||||||
|
_cme: *const rb_callable_method_entry_t,
|
||||||
|
_block: Option<IseqPtr>,
|
||||||
|
_argc: i32,
|
||||||
|
_known_recv_class: *const VALUE,
|
||||||
|
) -> bool {
|
||||||
|
asm.comment("block_given?");
|
||||||
|
|
||||||
|
// Same as rb_vm_frame_block_handler
|
||||||
|
let ep_opnd = gen_get_lep(jit, asm);
|
||||||
|
let block_handler = asm.load(
|
||||||
|
Opnd::mem(64, ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL)
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.stack_pop(1);
|
||||||
|
let out_opnd = ctx.stack_push(Type::UnknownImm);
|
||||||
|
|
||||||
|
// Return `block_handler != VM_BLOCK_HANDLER_NONE`
|
||||||
|
asm.cmp(block_handler, VM_BLOCK_HANDLER_NONE.into());
|
||||||
|
let block_given = asm.csel_ne(Qtrue.into(), Qfalse.into());
|
||||||
|
asm.mov(out_opnd, block_given);
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn jit_thread_s_current(
|
fn jit_thread_s_current(
|
||||||
_jit: &mut JITState,
|
_jit: &mut JITState,
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
@ -7513,6 +7543,7 @@ impl CodegenGlobals {
|
|||||||
self.yjit_reg_method(rb_cString, "+@", jit_rb_str_uplus);
|
self.yjit_reg_method(rb_cString, "+@", jit_rb_str_uplus);
|
||||||
|
|
||||||
self.yjit_reg_method(rb_mKernel, "respond_to?", jit_obj_respond_to);
|
self.yjit_reg_method(rb_mKernel, "respond_to?", jit_obj_respond_to);
|
||||||
|
self.yjit_reg_method(rb_mKernel, "block_given?", jit_rb_f_block_given_p);
|
||||||
|
|
||||||
// Thread.current
|
// Thread.current
|
||||||
self.yjit_reg_method(
|
self.yjit_reg_method(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user