summaryrefslogtreecommitdiff
path: root/lib/ruby_vm
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-12 22:07:02 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-12 22:07:02 -0700
commit330086d3f6d0f05ef6ccdf1e512c19e94e7104f3 (patch)
tree19b027a15f3596b0e936b451d296cf7727e36c7d /lib/ruby_vm
parent3938efa70f5e1f69d588c2b7552335176180cbbb (diff)
RJIT: Implement definedivar
Diffstat (limited to 'lib/ruby_vm')
-rw-r--r--lib/ruby_vm/rjit/insn_compiler.rb37
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb
index c23c55e5f0..50cafb2b92 100644
--- a/lib/ruby_vm/rjit/insn_compiler.rb
+++ b/lib/ruby_vm/rjit/insn_compiler.rb
@@ -18,7 +18,7 @@ module RubyVM::RJIT
asm.incr_counter(:rjit_insns_count)
asm.comment("Insn: #{insn.name}")
- # 72/101
+ # 73/102
case insn.name
when :nop then nop(jit, ctx, asm)
when :getlocal then getlocal(jit, ctx, asm)
@@ -64,6 +64,7 @@ module RubyVM::RJIT
when :setn then setn(jit, ctx, asm)
when :adjuststack then adjuststack(jit, ctx, asm)
when :defined then defined(jit, ctx, asm)
+ when :definedvar then definedivar(jit, ctx, asm)
# checkmatch
# checkkeyword
# checktype
@@ -1038,6 +1039,40 @@ module RubyVM::RJIT
KeepCompiling
end
+ # @param jit [RubyVM::RJIT::JITState]
+ # @param ctx [RubyVM::RJIT::Context]
+ # @param asm [RubyVM::RJIT::Assembler]
+ def definedivar(jit, ctx, asm)
+ ivar_name = jit.operand(0)
+ pushval = jit.operand(2)
+
+ # Get the receiver
+ asm.mov(:rcx, [CFP, C.rb_control_frame_t.offsetof(:self)])
+
+ # Save the PC and SP because the callee may allocate
+ # Note that this modifies REG_SP, which is why we do it first
+ jit_prepare_routine_call(jit, ctx, asm) # clobbers :rax
+
+ # Call rb_ivar_defined(recv, ivar_name)
+ asm.mov(C_ARGS[0], :rcx)
+ asm.mov(C_ARGS[1], ivar_name)
+ asm.call(C.rb_ivar_defined)
+
+ # if (rb_ivar_defined(recv, ivar_name)) {
+ # val = pushval;
+ # }
+ asm.test(C_RET, 255)
+ asm.mov(:rax, Qnil)
+ asm.mov(:rcx, pushval)
+ asm.cmovnz(:rax, :rcx)
+
+ # Push the return value onto the stack
+ stack_ret = ctx.stack_push
+ asm.mov(stack_ret, :rax)
+
+ KeepCompiling
+ end
+
# checkmatch
# checkkeyword
# checktype