RJIT: Implement getspecial insn
This commit is contained in:
parent
93e05aaa74
commit
dc28ccbb6d
@ -18,7 +18,7 @@ module RubyVM::RJIT
|
|||||||
asm.incr_counter(:rjit_insns_count)
|
asm.incr_counter(:rjit_insns_count)
|
||||||
asm.comment("Insn: #{insn.name}")
|
asm.comment("Insn: #{insn.name}")
|
||||||
|
|
||||||
# 76/102
|
# 77/102
|
||||||
case insn.name
|
case insn.name
|
||||||
when :nop then nop(jit, ctx, asm)
|
when :nop then nop(jit, ctx, asm)
|
||||||
when :getlocal then getlocal(jit, ctx, asm)
|
when :getlocal then getlocal(jit, ctx, asm)
|
||||||
@ -26,7 +26,7 @@ module RubyVM::RJIT
|
|||||||
when :getblockparam then getblockparam(jit, ctx, asm)
|
when :getblockparam then getblockparam(jit, ctx, asm)
|
||||||
# setblockparam
|
# setblockparam
|
||||||
when :getblockparamproxy then getblockparamproxy(jit, ctx, asm)
|
when :getblockparamproxy then getblockparamproxy(jit, ctx, asm)
|
||||||
# getspecial
|
when :getspecial then getspecial(jit, ctx, asm)
|
||||||
# setspecial
|
# setspecial
|
||||||
when :getinstancevariable then getinstancevariable(jit, ctx, asm)
|
when :getinstancevariable then getinstancevariable(jit, ctx, asm)
|
||||||
when :setinstancevariable then setinstancevariable(jit, ctx, asm)
|
when :setinstancevariable then setinstancevariable(jit, ctx, asm)
|
||||||
@ -301,7 +301,72 @@ module RubyVM::RJIT
|
|||||||
EndBlock
|
EndBlock
|
||||||
end
|
end
|
||||||
|
|
||||||
# getspecial
|
# @param jit [RubyVM::RJIT::JITState]
|
||||||
|
# @param ctx [RubyVM::RJIT::Context]
|
||||||
|
# @param asm [RubyVM::RJIT::Assembler]
|
||||||
|
def getspecial(jit, ctx, asm)
|
||||||
|
# This takes two arguments, key and type
|
||||||
|
# key is only used when type == 0
|
||||||
|
# A non-zero type determines which type of backref to fetch
|
||||||
|
#rb_num_t key = jit.jit_get_arg(0);
|
||||||
|
rtype = jit.operand(1)
|
||||||
|
|
||||||
|
if rtype == 0
|
||||||
|
# not yet implemented
|
||||||
|
return CantCompile;
|
||||||
|
elsif rtype & 0x01 != 0
|
||||||
|
# Fetch a "special" backref based on a char encoded by shifting by 1
|
||||||
|
|
||||||
|
# Can raise if matchdata uninitialized
|
||||||
|
jit_prepare_routine_call(jit, ctx, asm)
|
||||||
|
|
||||||
|
# call rb_backref_get()
|
||||||
|
asm.comment('rb_backref_get')
|
||||||
|
asm.call(C.rb_backref_get)
|
||||||
|
|
||||||
|
asm.mov(C_ARGS[0], C_RET) # backref
|
||||||
|
case [rtype >> 1].pack('c')
|
||||||
|
in ?&
|
||||||
|
asm.comment("rb_reg_last_match")
|
||||||
|
asm.call(C.rb_reg_last_match)
|
||||||
|
in ?`
|
||||||
|
asm.comment("rb_reg_match_pre")
|
||||||
|
asm.call(C.rb_reg_match_pre)
|
||||||
|
in ?'
|
||||||
|
asm.comment("rb_reg_match_post")
|
||||||
|
asm.call(C.rb_reg_match_post)
|
||||||
|
in ?+
|
||||||
|
asm.comment("rb_reg_match_last")
|
||||||
|
asm.call(C.rb_reg_match_last)
|
||||||
|
end
|
||||||
|
|
||||||
|
stack_ret = ctx.stack_push
|
||||||
|
asm.mov(stack_ret, C_RET)
|
||||||
|
|
||||||
|
KeepCompiling
|
||||||
|
else
|
||||||
|
# Fetch the N-th match from the last backref based on type shifted by 1
|
||||||
|
|
||||||
|
# Can raise if matchdata uninitialized
|
||||||
|
jit_prepare_routine_call(jit, ctx, asm)
|
||||||
|
|
||||||
|
# call rb_backref_get()
|
||||||
|
asm.comment('rb_backref_get')
|
||||||
|
asm.call(C.rb_backref_get)
|
||||||
|
|
||||||
|
# rb_reg_nth_match((int)(type >> 1), backref);
|
||||||
|
asm.comment('rb_reg_nth_match')
|
||||||
|
asm.mov(C_ARGS[0], rtype >> 1)
|
||||||
|
asm.mov(C_ARGS[1], C_RET) # backref
|
||||||
|
asm.call(C.rb_reg_nth_match)
|
||||||
|
|
||||||
|
stack_ret = ctx.stack_push
|
||||||
|
asm.mov(stack_ret, C_RET)
|
||||||
|
|
||||||
|
KeepCompiling
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# setspecial
|
# setspecial
|
||||||
|
|
||||||
# @param jit [RubyVM::RJIT::JITState]
|
# @param jit [RubyVM::RJIT::JITState]
|
||||||
|
24
rjit_c.rb
24
rjit_c.rb
@ -465,6 +465,10 @@ module RubyVM::RJIT # :nodoc: all
|
|||||||
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_store) }
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_store) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def C.rb_backref_get
|
||||||
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_backref_get) }
|
||||||
|
end
|
||||||
|
|
||||||
def C.rb_ec_ary_new_from_values
|
def C.rb_ec_ary_new_from_values
|
||||||
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ec_ary_new_from_values) }
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ec_ary_new_from_values) }
|
||||||
end
|
end
|
||||||
@ -537,6 +541,26 @@ module RubyVM::RJIT # :nodoc: all
|
|||||||
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_obj_is_kind_of) }
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_obj_is_kind_of) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def C.rb_reg_last_match
|
||||||
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_last_match) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def C.rb_reg_match_last
|
||||||
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_match_last) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def C.rb_reg_match_post
|
||||||
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_match_post) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def C.rb_reg_match_pre
|
||||||
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_match_pre) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def C.rb_reg_nth_match
|
||||||
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_nth_match) }
|
||||||
|
end
|
||||||
|
|
||||||
def C.rb_str_concat_literals
|
def C.rb_str_concat_literals
|
||||||
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_concat_literals) }
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_concat_literals) }
|
||||||
end
|
end
|
||||||
|
@ -518,6 +518,12 @@ generator = BindingGenerator.new(
|
|||||||
rjit_record_exit_stack
|
rjit_record_exit_stack
|
||||||
rb_ivar_defined
|
rb_ivar_defined
|
||||||
rb_vm_throw
|
rb_vm_throw
|
||||||
|
rb_backref_get
|
||||||
|
rb_reg_last_match
|
||||||
|
rb_reg_match_pre
|
||||||
|
rb_reg_match_post
|
||||||
|
rb_reg_match_last
|
||||||
|
rb_reg_nth_match
|
||||||
],
|
],
|
||||||
types: %w[
|
types: %w[
|
||||||
CALL_DATA
|
CALL_DATA
|
||||||
|
Loading…
x
Reference in New Issue
Block a user