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

ruby-changes:73692

From: Takashi <ko1@a...>
Date: Fri, 23 Sep 2022 06:45:03 +0900 (JST)
Subject: [ruby-changes:73692] 334b8bd459 (master): Mix manual and auto-generated C APIs

https://git.ruby-lang.org/ruby.git/commit/?id=334b8bd459

From 334b8bd4596cd2fff737f4ced2f2bdf1d7f82679 Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Sun, 18 Sep 2022 23:17:22 +0900
Subject: Mix manual and auto-generated C APIs

---
 mjit_compiler.rb                 | 118 -------------------------------------
 tool/mjit/bindgen.rb             |  31 +++++++---
 tool/ruby_vm/views/mjit_c.rb.erb | 124 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+), 125 deletions(-)

diff --git a/mjit_compiler.rb b/mjit_compiler.rb
index 4996e773dc..0a558f67e4 100644
--- a/mjit_compiler.rb
+++ b/mjit_compiler.rb
@@ -14,124 +14,6 @@ if RubyVM::MJIT.enabled? https://github.com/ruby/ruby/blob/trunk/mjit_compiler.rb#L14
     require 'mjit/c_32'
   end
 
-  class << RubyVM::MJIT::C
-    def ROBJECT_EMBED_LEN_MAX
-      Primitive.cexpr! 'INT2NUM(RBIMPL_EMBED_LEN_MAX_OF(VALUE))'
-    end
-
-    def cdhash_to_hash(cdhash_addr)
-      Primitive.cdhash_to_hash(cdhash_addr)
-    end
-
-    def builtin_compiler(f, bf, index, stack_size, builtin_inline_p)
-      Primitive.builtin_compile(f, bf.to_i, index, stack_size, builtin_inline_p)
-    end
-
-    def has_cache_for_send(cc, insn)
-      Primitive.has_cache_for_send(cc.to_i, insn)
-    end
-
-    def rb_iseq_check(iseq)
-      _iseq_addr = iseq.to_i
-      iseq_addr = Primitive.cexpr! 'PTR2NUM((VALUE)rb_iseq_check((rb_iseq_t *)NUM2PTR(_iseq_addr)))'
-      rb_iseq_t.new(iseq_addr)
-    end
-
-    def rb_iseq_path(iseq)
-      _iseq_addr = iseq.to_i
-      Primitive.cexpr! 'rb_iseq_path((rb_iseq_t *)NUM2PTR(_iseq_addr))'
-    end
-
-    def vm_ci_argc(ci)
-      _ci_addr = ci.to_i
-      Primitive.cexpr! 'UINT2NUM(vm_ci_argc((CALL_INFO)NUM2PTR(_ci_addr)))'
-    end
-
-    def vm_ci_flag(ci)
-      _ci_addr = ci.to_i
-      Primitive.cexpr! 'UINT2NUM(vm_ci_flag((CALL_INFO)NUM2PTR(_ci_addr)))'
-    end
-
-    def rb_splat_or_kwargs_p(ci)
-      _ci_addr = ci.to_i
-      Primitive.cexpr! 'RBOOL(rb_splat_or_kwargs_p((CALL_INFO)NUM2PTR(_ci_addr)))'
-    end
-
-    def fastpath_applied_iseq_p(ci, cc, iseq)
-      _ci_addr = ci.to_i
-      _cc_addr = cc.to_i
-      _iseq_addr = iseq.to_i
-      Primitive.cexpr! 'RBOOL(fastpath_applied_iseq_p((CALL_INFO)NUM2PTR(_ci_addr), (CALL_CACHE)NUM2PTR(_cc_addr), (rb_iseq_t *)NUM2PTR(_iseq_addr)))'
-    end
-
-    def mjit_opts
-      addr = Primitive.cexpr! 'PTR2NUM((VALUE)&mjit_opts)'
-      mjit_options.new(addr)
-    end
-
-    def mjit_call_attribute_sp_inc(insn, operands)
-      _operands_addr = operands.to_i
-      Primitive.cexpr! 'LONG2NUM(mjit_call_attribute_sp_inc(NUM2INT(insn), (VALUE *)NUM2PTR(_operands_addr)))'
-    end
-
-    def mjit_capture_cc_entries(compiled_body, captured_body)
-      _compiled_body_addr = compiled_body.to_i
-      _captured_body_addr = captured_body.to_i
-      Primitive.cexpr! 'INT2NUM(mjit_capture_cc_entries((struct rb_iseq_constant_body *)NUM2PTR(_compiled_body_addr), (struct rb_iseq_constant_body *)NUM2PTR(_captured_body_addr)))'
-    end
-
-    #const struct rb_iseq_constant_body *body, union iseq_inline_storage_entry *is_entries
-    def mjit_capture_is_entries(body, is_entries)
-      _body_addr = body.to_i
-      _is_entries_addr = is_entries.to_i
-      Primitive.cstmt! %{
-        mjit_capture_is_entries((struct rb_iseq_constant_body *)NUM2PTR(_body_addr), (union iseq_inline_storage_entry *)NUM2PTR(_is_entries_addr));
-        return Qnil;
-      }
-    end
-
-    # Convert encoded VM pointers to insn BINs.
-    def rb_vm_insn_decode(encoded)
-      Primitive.cexpr! 'INT2NUM(rb_vm_insn_decode(NUM2PTR(encoded)))'
-    end
-
-    # Convert insn BINs to encoded VM pointers. This one is not used by the compiler, but useful for debugging.
-    def rb_vm_insn_encode(bin)
-      Primitive.cexpr! 'PTR2NUM((VALUE)rb_vm_get_insns_address_table()[NUM2INT(bin)])'
-    end
-
-    def insn_may_depend_on_sp_or_pc(insn, opes)
-      _opes_addr = opes.to_i
-      Primitive.cexpr! 'RBOOL(insn_may_depend_on_sp_or_pc(NUM2INT(insn), (VALUE *)NUM2PTR(_opes_addr)))'
-    end
-
-    # Convert Integer VALUE to an actual Ruby object
-    def to_ruby(value)
-      Primitive.cexpr! '(VALUE)NUM2PTR(value)'
-    end
-
-    # Convert RubyVM::InstructionSequence to C.rb_iseq_t. Not used by the compiler, but useful for debugging.
-    def rb_iseqw_to_iseq(iseqw)
-      iseq_addr = Primitive.cexpr! 'PTR2NUM((VALUE)rb_iseqw_to_iseq(iseqw))'
-      rb_iseq_t.new(iseq_addr)
-    end
-
-    # TODO: remove this after migration
-    def fprintf(f, str)
-      Primitive.cstmt! %{
-        fprintf((FILE *)NUM2PTR(f), "%s", RSTRING_PTR(str));
-        return Qnil;
-      }
-    end
-
-    def rb_cFalseClass; Primitive.cexpr! 'PTR2NUM(rb_cFalseClass)' end
-    def rb_cNilClass;   Primitive.cexpr! 'PTR2NUM(rb_cNilClass)'   end
-    def rb_cTrueClass;  Primitive.cexpr! 'PTR2NUM(rb_cTrueClass)'  end
-    def rb_cInteger;    Primitive.cexpr! 'PTR2NUM(rb_cInteger)'    end
-    def rb_cSymbol;     Primitive.cexpr! 'PTR2NUM(rb_cSymbol)'     end
-    def rb_cFloat;      Primitive.cexpr! 'PTR2NUM(rb_cFloat)'      end
-  end
-
   require "mjit/instruction"
   require "mjit/compiler"
 end
diff --git a/tool/mjit/bindgen.rb b/tool/mjit/bindgen.rb
index 32a487d4bb..8fa20fe64c 100755
--- a/tool/mjit/bindgen.rb
+++ b/tool/mjit/bindgen.rb
@@ -100,16 +100,20 @@ end https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L100
 
 # Convert Node objects to a Ruby binding source.
 class BindingGenerator
+  BINDGEN_BEG = '### MJIT bindgen begin ###'
+  BINDGEN_END = '### MJIT bindgen end ###'
   DEFAULTS = { '_Bool' => 'CType::Bool.new' }
   DEFAULTS.default_proc = proc { |_h, k| "CType::Stub.new(:#{k})" }
 
   attr_reader :src
 
+  # @param src_path [String] Source path used for preamble/postamble
   # @param macros [Array<String>] Imported macros
   # @param enums [Hash{ Symbol => Array<String> }] Imported enum values
   # @param types [Array<String>] Imported types
   # @param ruby_fields [Hash{ Symbol => Array<String> }] Struct VALUE fields that are considered Ruby objects
-  def initialize(macros:, enums:, types:, ruby_fields:)
+  def initialize(src_path:, macros:, enums:, types:, ruby_fields:)
+    @preamble, @postamble = split_ambles(src_path)
     @src = String.new
     @macros = macros.sort
     @enums = enums.transform_keys(&:to_s).transform_values(&:sort).sort.to_h
@@ -119,9 +123,7 @@ class BindingGenerator https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L123
   end
 
   def generate(_nodes)
-    println "module RubyVM::MJIT"
-    println "  C = Object.new"
-    println
+    println @preamble
 
     # Define macros
     @macros.each do |macro|
@@ -129,8 +131,7 @@ class BindingGenerator https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L131
       println
     end
 
-    chomp
-    println "end if RubyVM::MJIT.enabled?"
+    print @postamble
   end
 
   # TODO: Remove this
@@ -176,6 +177,20 @@ class BindingGenerator https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L177
 
   private
 
+  # Return code before BINDGEN_BEG and code after BINDGEN_END
+  def split_ambles(src_path)
+    lines = File.read(src_path).lines
+
+    preamble_end = lines.index { |l| l.include?(BINDGEN_BEG) }
+    raise "`#{BINDGEN_BEG}` was not found in '#{src_path}'" if preamble_end.nil?
+
+    postamble_beg = lines.index { |l| l.include?(BINDGEN_END) }
+    raise "`#{BINDGEN_END}` was not found in '#{src_path}'" if postamble_beg.nil?
+    raise "`#{BINDGEN_BEG}` was found after `#{BINDGEN_END}`" if preamble_end >= postamble_beg
+
+    return lines[0..preamble_end].join, lines[postamble_beg..-1].join
+  end
+
   def generate_macro(macro)
     if macro.start_with?('USE_')
       "Primitive.cexpr! %q{ RBOOL(#{macro} != 0) }"
@@ -293,6 +308,7 @@ class BindingGenerator https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L308
 end
 
 src_dir = File.expand_path('../..', __dir__)
+src_path = File.join(src_dir, 'tool/ruby_vm/views/mjit_c.rb.erb')
 build_dir = File.expand_path(build_dir)
 cflags = [
   src_dir,
@@ -303,6 +319,7 @@ cflags = [ https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L319
 
 nodes = HeaderParser.new(File.join(src_dir, 'mjit_compiler.h'), cflags: cflags).parse
 generator = BindingGenerator.new(
+  src_path: src_path,
   macros: %w[
     NOT_COMPILED_STACK_SIZE
     USE_LAZY_LOAD
@@ -366,4 +383,4 @@ generator = BindingGenerator.new( https://github.com/ruby/ruby/blob/trunk/tool/mjit/bindgen.rb#L383
 )
 generator.generate(nodes)
 
-File.write(File.join(src_dir, 'tool/ruby_vm/views/mjit_c.rb.erb'), generator.src)
+File.write(src_path, generator.src)
diff --git a/tool/ruby_vm/views/mjit_c.rb.erb b/tool/ruby_vm/views/mjit_c.rb.erb
index 416f8bfeaf..5def975dcc 100644
--- a/tool/ruby_vm/views/mjit_c.rb.erb
+++ b/tool/ruby_vm/views/mjit_c.rb.erb
@@ -1,6 +1,128 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/mjit_c.rb.erb#L1
+# Part of this file is generated by tool/mjit/bindgen.rb.
+# Run `make mjit-bindgen` to update code between "MJIT bindgen begin" and "MJIT bindgen end".
 module RubyVM::MJIT
   C = Object.new
 
+  class << C
+    def ROBJECT_EMBED_LEN_MAX
+      Primitive.cexpr! 'INT2NUM(RBIMPL_EMBED_LEN_MAX_OF(VALUE))'
+    end
+
+    def cdhash_to_hash(cdhash_addr)
+      Primitive.cdhash_to_hash(cdhash_addr)
+    end
+
+    def builtin_compiler(f, bf, index, stack_size, builtin_inline_p)
+      Primitive.builtin_compile(f, bf.to_i, index, stack_size, builtin_inline_p)
+    end
+
+    def has_cache_for_send(cc, insn)
+      Primitive.has_cache_for_send(cc.to_i, insn)
+    end
+
+    def rb_iseq_check(iseq)
+      _iseq_addr = iseq.to_i
+      iseq_addr = Primitive.cexpr! 'PTR2NUM((VALUE)rb_iseq_check((rb_iseq_t *)NUM2PTR(_iseq_addr)))'
+      rb_iseq_t.new(iseq_addr)
+    end
+
+    def rb_iseq_path(iseq)
+      _iseq_addr = iseq.to_i
+      Primitive.cexpr! 'rb_iseq_path((rb_iseq_t *)NUM2PTR(_iseq_addr))'
+    end
+
+    def vm_ci_argc(ci)
+      _ci_addr = ci.to_i
+      Primitive.cexpr! 'UINT2NUM(vm_ci_argc( (... truncated)

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

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