diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2022-11-15 00:11:44 -0800 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2022-11-15 00:34:00 -0800 |
commit | 1a9e87fe3a0bb8a4a16e34997371b1823557202d (patch) | |
tree | a4c01edd23fa8dc91a3002fba3516b0818f40122 /lib | |
parent | f500ca9b8a62599433f7087fe1da30ec16e3564c (diff) | |
download | ruby-1a9e87fe3a0bb8a4a16e34997371b1823557202d.tar.gz |
MJIT: Fix vm_cc_cme(cc).def.type to use bit field
access properly. Because the libclang node had two children, it wasn't
handled well by the pattern matching for the bit field case.
In addition to that, this bit field has a non-1 width. Because we're
returning true/false for a width-1 bit field, I added another behavior
that works like a char value for bit fields with width 2-8.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mjit/c_pointer.rb | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/mjit/c_pointer.rb b/lib/mjit/c_pointer.rb index 7f64a8ac8f..7dd836f1c9 100644 --- a/lib/mjit/c_pointer.rb +++ b/lib/mjit/c_pointer.rb @@ -282,12 +282,17 @@ module RubyVM::MJIT # Dereference def * - if @width != 1 - raise NotImplementedError.new("Non-1 width is not implemented yet") + if @width == 1 + byte = Fiddle::Pointer.new(@addr)[0, Fiddle::SIZEOF_CHAR].unpack('c').first + bit = (1 & (byte >> @offset)) + bit == 1 + elsif @width <= 8 && @offset == 0 + byte = Fiddle::Pointer.new(@addr)[0, Fiddle::SIZEOF_CHAR].unpack('c').first + bitmask = @width.times.map { |i| 1 << i }.sum + byte & bitmask + else + raise NotImplementedError.new("not-implemented bit field access: width=#{@width} offset=#{@offset}") end - byte = Fiddle::Pointer.new(@addr)[0, Fiddle::SIZEOF_CHAR].unpack('c').first - bit = 1 & (byte >> @offset) - bit == 1 end # @param width [Integer] |