[前][次][番号順一覧][スレッド一覧]

ruby-changes:73699

From: Takashi <ko1@a...>
Date: Fri, 23 Sep 2022 06:45:09 +0900 (JST)
Subject: [ruby-changes:73699] 0c9dc01a2a (master): Skip struct fields whose output differs

https://git.ruby-lang.org/ruby.git/commit/?id=0c9dc01a2a

From 0c9dc01a2a9a082843b287d30a18c6c67d79de51 Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Thu, 22 Sep 2022 22:32:49 +0900
Subject: Skip struct fields whose output differs

across different environments
---
 lib/mjit/c_type.rb   |  4 ++--
 mjit_c.rb            |  3 ---
 tool/mjit/bindgen.rb | 32 ++++++++++++++++----------------
 3 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/lib/mjit/c_type.rb b/lib/mjit/c_type.rb
index 8ccdfcc4d3..9e45d8d41c 100644
--- a/lib/mjit/c_type.rb
+++ b/lib/mjit/c_type.rb
@@ -46,9 +46,9 @@ module RubyVM::MJIT https://github.com/ruby/ruby/blob/trunk/lib/mjit/c_type.rb#L46
         new(Fiddle::Importer.parse_ctype(ctype))
       end
 
-      def self.find(size, unsigned)
+      def self.find(size, signed)
         fiddle_type = TYPE_MAP.fetch(size)
-        fiddle_type = -fiddle_type if unsigned
+        fiddle_type = -fiddle_type unless signed
         new(fiddle_type)
       end
 
diff --git a/mjit_c.rb b/mjit_c.rb
index 5c84b10331..6b316860be 100644
--- a/mjit_c.rb
+++ b/mjit_c.rb
@@ -372,14 +372,12 @@ module RubyVM::MJIT https://github.com/ruby/ruby/blob/trunk/mjit_c.rb#L372
       errinfo: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), errinfo)")],
       passed_block_handler: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), passed_block_handler)")],
       raised_flag: [CType::Immediate.parse("uint8_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), raised_flag)")],
-      method_missing_reason: [self.method_missing_reason, nil],
       private_const_reference: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), private_const_reference)")],
       machine: [CType::Struct.new(
         "", Primitive.cexpr!("SIZEOF(((struct rb_execution_context_struct *)NULL)->machine)"),
         stack_start: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_start)")],
         stack_end: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_end)")],
         stack_maxsize: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_maxsize)")],
-        regs: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, regs)")],
       ), Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), machine)")],
     )
   end
@@ -454,7 +452,6 @@ module RubyVM::MJIT https://github.com/ruby/ruby/blob/trunk/mjit_c.rb#L452
       jit_func: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), jit_func)")],
       total_calls: [CType::Immediate.parse("unsigned long"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), total_calls)")],
       jit_unit: [CType::Pointer.new { self.rb_mjit_unit }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), jit_unit)")],
-      yjit_payload: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), yjit_payload)")],
     )
   end
 
diff --git a/tool/mjit/bindgen.rb b/tool/mjit/bindgen.rb
index d6431f8c40..56369c2d98 100755
--- a/tool/mjit/bindgen.rb
+++ b/tool/mjit/bindgen.rb
@@ -12,20 +12,9 @@ unless build_dir = ARGV.first https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L12
   abort "Usage: #{$0} BUILD_DIR"
 end
 
-if Fiddle::SIZEOF_VOIDP == 8
-  arch_bits = 64
-else
-  arch_bits = 32
-end
-
 # Help ffi-clang find libclang
-if arch_bits == 64
-  # apt install libclang1
-  ENV['LIBCLANG'] ||= Dir.glob("/lib/#{RUBY_PLATFORM}-gnu/libclang-*.so*").grep_v(/-cpp/).sort.last
-else
-  # apt install libclang1:i386
-  ENV['LIBCLANG'] ||= Dir.glob("/lib/i386-linux-gnu/libclang-*.so*").sort.last
-end
+# Hint: apt install libclang1
+ENV['LIBCLANG'] ||= Dir.glob("/lib/#{RUBY_PLATFORM}-gnu/libclang-*.so*").grep_v(/-cpp/).sort.last
 require 'ffi/clang'
 
 class Node < Struct.new(
@@ -116,14 +105,16 @@ class BindingGenerator https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L105
   # @param ints [Array<String>]
   # @param types [Array<String>]
   # @param dynamic_types [Array<String>] #ifdef-dependent immediate types, which need Primitive.cexpr! for type detection
+  # @param skip_fields [Hash{ Symbol => Array<String> }] Struct fields that are skipped from bindgen
   # @param ruby_fields [Hash{ Symbol => Array<String> }] Struct VALUE fields that are considered Ruby objects
-  def initialize(src_path:, uses:, ints:, types:, dynamic_types:, ruby_fields:)
+  def initialize(src_path:, uses:, ints:, types:, dynamic_types:, skip_fields:, ruby_fields:)
     @preamble, @postamble = split_ambles(src_path)
     @src = String.new
     @uses = uses.sort
     @ints = ints.sort
     @types = types.sort
     @dynamic_types = dynamic_types.sort
+    @skip_fields = skip_fields.transform_keys(&:to_s)
     @ruby_fields = ruby_fields.transform_keys(&:to_s)
     @references = Set.new
   end
@@ -209,12 +200,16 @@ class BindingGenerator https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L200
       buf << "  \"#{node.spelling}\", Primitive.cexpr!(\"SIZEOF(#{sizeof_type || node.type})\"),\n"
       bit_fields_end = node.children.index { |c| c.bitwidth == -1 } || node.children.size # first non-bit field index
       node.children.each_with_index do |child, i|
+        skip_type = sizeof_type&.gsub(/\(\(struct ([^\)]+) \*\)NULL\)->/, '\1.') || node.spelling
+        next if @skip_fields.fetch(skip_type, []).include?(child.spelling)
         field_builder = proc do |field, type|
           if node.kind == :struct
             to_ruby = @ruby_fields.fetch(node.spelling, []).include?(field)
             if child.bitwidth > 0
-              # give up offsetof calculation for non-leading bit fields
-              offsetof = (i < bit_fields_end ? node.offsetof.fetch(field) : nil).inspect
+              if bit_fields_end <= i # give up offsetof calculation for non-leading bit fields
+                raise "non-leading bit fields are not supported. consider including '#{field}' in skip_fields."
+              end
+              offsetof = node.offsetof.fetch(field)
             else
               off_type = sizeof_type || "(*((#{node.type} *)NULL))"
               offsetof = "Primitive.cexpr!(\"OFFSETOF(#{off_type}, #{field})\")"
@@ -380,6 +375,11 @@ generator = BindingGenerator.new( https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L375
   dynamic_types: %w[
     VALUE
   ],
+  skip_fields: {
+    'rb_execution_context_struct.machine': %w[regs], # differs between macOS and Linux
+    rb_execution_context_struct: %w[method_missing_reason], # non-leading bit fields not supported
+    rb_iseq_constant_body: %w[yjit_payload], # conditionally defined
+  },
   ruby_fields: {
     rb_iseq_location_struct: %w[
       base_label
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]