From 06b62cbbdd560c6210d48a50ba99cfdc2f110dfe Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 20 Jan 2023 10:57:23 -0800 Subject: [PATCH] Add `offsetof` so we can get the offset of members I want to get the offset of fields inside structs, but I don't want to instantiate the struct. I need to embed the offsets inside machine code, and I can't get the offsets without calling `new` on the struct. This commit adds an `offset` method so you can get the offset of a member without instantiating anything. You can do: ```ruby C.rb_control_frame_t.offsetof(:sp) #=> 8 ``` I don't think this implementation is perfect, you can only get immediate fields. But it is better than nothing! --- lib/ruby_vm/mjit/c_pointer.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/ruby_vm/mjit/c_pointer.rb b/lib/ruby_vm/mjit/c_pointer.rb index a92c2140ae..de45c171c3 100644 --- a/lib/ruby_vm/mjit/c_pointer.rb +++ b/lib/ruby_vm/mjit/c_pointer.rb @@ -54,6 +54,12 @@ module RubyVM::MJIT # :nodoc: all # Return the size of this type define_singleton_method(:sizeof) { sizeof } + # Get the offset of a member named +name+ + define_singleton_method(:offsetof) { |name| + _, offset = members.fetch(name) + offset / 8 + } + define_method(:initialize) do |addr = nil| if addr.nil? # TODO: get rid of this feature later addr = Fiddle.malloc(sizeof)