summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-02-07 23:25:33 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-05 22:11:20 -0800
commitd11f960fb0243f2285f7f476c8b0fd244bbbdfc5 (patch)
treee02f87d7caf86ba3e4b845927091a77832568c55 /lib
parent5a1cee1d965301b05e9d2d85b0ee39ef3c6757f7 (diff)
downloadruby-d11f960fb0243f2285f7f476c8b0fd244bbbdfc5.tar.gz
Implement non-embedded ivars
Diffstat (limited to 'lib')
-rw-r--r--lib/ruby_vm/mjit/c_pointer.rb11
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb12
2 files changed, 14 insertions, 9 deletions
diff --git a/lib/ruby_vm/mjit/c_pointer.rb b/lib/ruby_vm/mjit/c_pointer.rb
index c91f6f646b..73cf267482 100644
--- a/lib/ruby_vm/mjit/c_pointer.rb
+++ b/lib/ruby_vm/mjit/c_pointer.rb
@@ -135,12 +135,13 @@ module RubyVM::MJIT
define_singleton_method(:sizeof) { sizeof }
# Part of Struct's offsetof implementation
- define_singleton_method(:offsetof) do |*fields|
- if fields.size == 1
- 0
- else
- raise NotImplementedError
+ define_singleton_method(:offsetof) do |field, *fields|
+ member = members.fetch(field)
+ offset = 0
+ unless fields.empty?
+ offset += member.offsetof(*fields)
end
+ offset
end
define_method(:initialize) do |addr|
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index 5852c28deb..285ba41102 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -575,7 +575,7 @@ module RubyVM::MJIT
case C.BUILTIN_TYPE(comptime_obj)
when C.T_OBJECT
- # This is the only supported case for now
+ # This is the only supported case for now (ROBJECT_IVPTR)
else
asm.incr_counter(:getivar_not_t_object)
return CantCompile
@@ -593,13 +593,17 @@ module RubyVM::MJIT
index = C.rb_shape_get_iv_index(shape_id, ivar_id)
if index
+ # See 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)])
- val_opnd = :rax
else
- asm.incr_counter(:getivar_too_complex)
- return CantCompile
+ # Pull out an ivar table on heap
+ asm.mov(:rax, [:rax, C.RObject.offsetof(:as, :heap, :ivptr)])
+ # Read the table
+ asm.mov(:rax, [:rax, index * C.VALUE.size])
end
+ val_opnd = :rax
else
val_opnd = Qnil
end