aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2022-11-15 00:11:44 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2022-11-15 00:34:00 -0800
commit1a9e87fe3a0bb8a4a16e34997371b1823557202d (patch)
treea4c01edd23fa8dc91a3002fba3516b0818f40122 /lib
parentf500ca9b8a62599433f7087fe1da30ec16e3564c (diff)
downloadruby-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.rb15
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]