зеркало из https://github.com/github/ruby.git
Implement attr_reader
This commit is contained in:
Родитель
e6354d5e9b
Коммит
ecae1cd74e
|
@ -859,7 +859,7 @@ module RubyVM::MJIT
|
|||
# @param jit [RubyVM::MJIT::JITState]
|
||||
# @param ctx [RubyVM::MJIT::Context]
|
||||
# @param asm [RubyVM::MJIT::Assembler]
|
||||
def jit_getivar(jit, ctx, asm, comptime_obj, ivar_id)
|
||||
def jit_getivar(jit, ctx, asm, comptime_obj, ivar_id, obj_opnd = nil)
|
||||
side_exit = side_exit(jit, ctx)
|
||||
starting_ctx = ctx.dup # copy for jit_chain_guard
|
||||
|
||||
|
@ -868,7 +868,11 @@ module RubyVM::MJIT
|
|||
asm.incr_counter(:getivar_special_const)
|
||||
return CantCompile
|
||||
end
|
||||
asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)])
|
||||
if obj_opnd.nil? # getivar
|
||||
asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)])
|
||||
else # attr_reader
|
||||
asm.mov(:rax, obj_opnd)
|
||||
end
|
||||
guard_object_is_heap(asm, :rax, counted_exit(side_exit, :getivar_not_heap))
|
||||
|
||||
case C.BUILTIN_TYPE(comptime_obj)
|
||||
|
@ -891,7 +895,7 @@ module RubyVM::MJIT
|
|||
|
||||
index = C.rb_shape_get_iv_index(shape_id, ivar_id)
|
||||
if index
|
||||
# See ROBJECT_IVPTR
|
||||
asm.comment('ROBJECT_IVPTR')
|
||||
if C.FL_TEST_RAW(comptime_obj, C.ROBJECT_EMBED)
|
||||
# Access embedded array
|
||||
asm.mov(:rax, [:rax, C.RObject.offsetof(:as, :ary) + (index * C.VALUE.size)])
|
||||
|
@ -906,6 +910,9 @@ module RubyVM::MJIT
|
|||
val_opnd = Qnil
|
||||
end
|
||||
|
||||
if obj_opnd
|
||||
ctx.stack_pop # pop receiver for attr_reader
|
||||
end
|
||||
stack_opnd = ctx.stack_push
|
||||
asm.mov(stack_opnd, val_opnd)
|
||||
|
||||
|
@ -981,14 +988,14 @@ module RubyVM::MJIT
|
|||
# Invalidate on redefinition (part of vm_search_method_fastpath)
|
||||
@invariants.assume_method_lookup_stable(jit, cme)
|
||||
|
||||
jit_call_method_each_type(jit, ctx, asm, ci, argc, flags, cme)
|
||||
jit_call_method_each_type(jit, ctx, asm, ci, argc, flags, cme, comptime_recv, recv_opnd)
|
||||
end
|
||||
|
||||
# vm_call_method_each_type
|
||||
# @param jit [RubyVM::MJIT::JITState]
|
||||
# @param ctx [RubyVM::MJIT::Context]
|
||||
# @param asm [RubyVM::MJIT::Assembler]
|
||||
def jit_call_method_each_type(jit, ctx, asm, ci, argc, flags, cme)
|
||||
def jit_call_method_each_type(jit, ctx, asm, ci, argc, flags, cme, comptime_recv, recv_opnd)
|
||||
case cme.def.type
|
||||
when C.VM_METHOD_TYPE_ISEQ
|
||||
jit_call_iseq_setup(jit, ctx, asm, ci, cme, flags, argc)
|
||||
|
@ -1000,8 +1007,7 @@ module RubyVM::MJIT
|
|||
asm.incr_counter(:send_attrset)
|
||||
return CantCompile
|
||||
when C.VM_METHOD_TYPE_IVAR
|
||||
asm.incr_counter(:send_ivar)
|
||||
return CantCompile
|
||||
jit_call_ivar(jit, ctx, asm, ci, cme, flags, argc, comptime_recv, recv_opnd)
|
||||
# when C.VM_METHOD_TYPE_MISSING
|
||||
when C.VM_METHOD_TYPE_BMETHOD
|
||||
asm.incr_counter(:send_bmethod)
|
||||
|
@ -1046,6 +1052,9 @@ module RubyVM::MJIT
|
|||
end
|
||||
|
||||
# vm_call_iseq_setup_normal (vm_call_iseq_setup_2 -> vm_call_iseq_setup_normal)
|
||||
# @param jit [RubyVM::MJIT::JITState]
|
||||
# @param ctx [RubyVM::MJIT::Context]
|
||||
# @param asm [RubyVM::MJIT::Assembler]
|
||||
def jit_call_iseq_setup_normal(jit, ctx, asm, ci, cme, flags, argc, iseq)
|
||||
# Save caller SP and PC before pushing a callee frame for backtrace and side exits
|
||||
asm.comment('save SP to caller CFP')
|
||||
|
@ -1062,6 +1071,36 @@ module RubyVM::MJIT
|
|||
jit_push_frame(jit, ctx, asm, ci, cme, flags, argc, iseq, frame_type, next_pc)
|
||||
end
|
||||
|
||||
# vm_call_ivar
|
||||
# @param jit [RubyVM::MJIT::JITState]
|
||||
# @param ctx [RubyVM::MJIT::Context]
|
||||
# @param asm [RubyVM::MJIT::Assembler]
|
||||
def jit_call_ivar(jit, ctx, asm, ci, cme, flags, argc, comptime_recv, recv_opnd)
|
||||
if flags & C.VM_CALL_ARGS_SPLAT != 0
|
||||
asm.incr_counter(:send_ivar_splat)
|
||||
return CantCompile
|
||||
end
|
||||
|
||||
if argc != 0
|
||||
asm.incr_counter(:send_ivar_arity)
|
||||
return CantCompile
|
||||
end
|
||||
|
||||
if flags & C.VM_CALL_OPT_SEND != 0
|
||||
asm.incr_counter(:send_ivar_opt_send)
|
||||
return CantCompile
|
||||
end
|
||||
|
||||
ivar_id = cme.def.body.attr.id
|
||||
|
||||
if flags & C.VM_CALL_OPT_SEND != 0
|
||||
asm.incr_counter(:send_ivar_blockarg)
|
||||
return CantCompile
|
||||
end
|
||||
|
||||
jit_getivar(jit, ctx, asm, comptime_recv, ivar_id, recv_opnd)
|
||||
end
|
||||
|
||||
# vm_push_frame
|
||||
#
|
||||
# Frame structure:
|
||||
|
|
7
mjit_c.h
7
mjit_c.h
|
@ -119,7 +119,6 @@ MJIT_RUNTIME_COUNTERS(
|
|||
send_tailcall,
|
||||
send_not_implemented_type,
|
||||
send_cfunc,
|
||||
send_ivar,
|
||||
send_attrset,
|
||||
send_bmethod,
|
||||
send_alias,
|
||||
|
@ -127,6 +126,12 @@ MJIT_RUNTIME_COUNTERS(
|
|||
send_zsuper,
|
||||
send_refined,
|
||||
|
||||
send_ivar,
|
||||
send_ivar_splat,
|
||||
send_ivar_arity,
|
||||
send_ivar_opt_send,
|
||||
send_ivar_blockarg,
|
||||
|
||||
send_guard_nil,
|
||||
send_guard_true,
|
||||
send_guard_false,
|
||||
|
|
30
mjit_c.rb
30
mjit_c.rb
|
@ -395,6 +395,10 @@ module RubyVM::MJIT # :nodoc: all
|
|||
Primitive.cexpr! %q{ UINT2NUM(VM_CALL_KW_SPLAT_bit) }
|
||||
end
|
||||
|
||||
def C.VM_CALL_OPT_SEND
|
||||
Primitive.cexpr! %q{ UINT2NUM(VM_CALL_OPT_SEND) }
|
||||
end
|
||||
|
||||
def C.VM_CALL_TAILCALL
|
||||
Primitive.cexpr! %q{ UINT2NUM(VM_CALL_TAILCALL) }
|
||||
end
|
||||
|
@ -499,6 +503,10 @@ module RubyVM::MJIT # :nodoc: all
|
|||
@IC ||= self.iseq_inline_constant_cache
|
||||
end
|
||||
|
||||
def C.ID
|
||||
@ID ||= CType::Immediate.parse("unsigned long")
|
||||
end
|
||||
|
||||
def C.IVC
|
||||
@IVC ||= self.iseq_inline_iv_cache_entry
|
||||
end
|
||||
|
@ -856,6 +864,14 @@ module RubyVM::MJIT # :nodoc: all
|
|||
@rb_iseq_t ||= self.rb_iseq_struct
|
||||
end
|
||||
|
||||
def C.rb_method_attr_t
|
||||
@rb_method_attr_t ||= CType::Struct.new(
|
||||
"rb_method_attr_struct", Primitive.cexpr!("SIZEOF(struct rb_method_attr_struct)"),
|
||||
id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_method_attr_struct *)NULL)), id)")],
|
||||
location: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_method_attr_struct *)NULL)), location)")],
|
||||
)
|
||||
end
|
||||
|
||||
def C.rb_method_definition_struct
|
||||
@rb_method_definition_struct ||= CType::Struct.new(
|
||||
"rb_method_definition_struct", Primitive.cexpr!("SIZEOF(struct rb_method_definition_struct)"),
|
||||
|
@ -917,13 +933,17 @@ module RubyVM::MJIT # :nodoc: all
|
|||
send_tailcall: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_tailcall)")],
|
||||
send_not_implemented_type: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_not_implemented_type)")],
|
||||
send_cfunc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_cfunc)")],
|
||||
send_ivar: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar)")],
|
||||
send_attrset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_attrset)")],
|
||||
send_bmethod: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_bmethod)")],
|
||||
send_alias: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_alias)")],
|
||||
send_optimized: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized)")],
|
||||
send_zsuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_zsuper)")],
|
||||
send_refined: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_refined)")],
|
||||
send_ivar: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar)")],
|
||||
send_ivar_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_splat)")],
|
||||
send_ivar_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_arity)")],
|
||||
send_ivar_opt_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_opt_send)")],
|
||||
send_ivar_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_blockarg)")],
|
||||
send_guard_nil: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_guard_nil)")],
|
||||
send_guard_true: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_guard_true)")],
|
||||
send_guard_false: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_guard_false)")],
|
||||
|
@ -996,10 +1016,6 @@ module RubyVM::MJIT # :nodoc: all
|
|||
CType::Bool.new
|
||||
end
|
||||
|
||||
def C.ID
|
||||
CType::Stub.new(:ID)
|
||||
end
|
||||
|
||||
def C.rb_thread_struct
|
||||
CType::Stub.new(:rb_thread_struct)
|
||||
end
|
||||
|
@ -1088,10 +1104,6 @@ module RubyVM::MJIT # :nodoc: all
|
|||
CType::Stub.new(:rb_method_cfunc_t)
|
||||
end
|
||||
|
||||
def C.rb_method_attr_t
|
||||
CType::Stub.new(:rb_method_attr_t)
|
||||
end
|
||||
|
||||
def C.rb_method_alias_t
|
||||
CType::Stub.new(:rb_method_alias_t)
|
||||
end
|
||||
|
|
|
@ -376,6 +376,7 @@ generator = BindingGenerator.new(
|
|||
VM_CALL_KW_SPLAT_bit
|
||||
VM_CALL_TAILCALL
|
||||
VM_CALL_TAILCALL_bit
|
||||
VM_CALL_OPT_SEND
|
||||
VM_ENV_FLAG_LOCAL
|
||||
VM_FRAME_MAGIC_METHOD
|
||||
VM_METHOD_TYPE_CFUNC
|
||||
|
@ -407,6 +408,7 @@ generator = BindingGenerator.new(
|
|||
types: %w[
|
||||
CALL_DATA
|
||||
IC
|
||||
ID
|
||||
IVC
|
||||
RB_BUILTIN
|
||||
RBasic
|
||||
|
@ -442,6 +444,7 @@ generator = BindingGenerator.new(
|
|||
rb_serial_t
|
||||
rb_shape
|
||||
rb_shape_t
|
||||
rb_method_attr_t
|
||||
],
|
||||
dynamic_types: %w[
|
||||
VALUE
|
||||
|
|
Загрузка…
Ссылка в новой задаче