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

ruby-changes:49669

From: shyouhei <ko1@a...>
Date: Fri, 12 Jan 2018 17:46:01 +0900 (JST)
Subject: [ruby-changes:49669] shyouhei:r61786 (trunk): tool/ruby_vm support for pre-2.1 BASERUBY

shyouhei	2018-01-12 17:38:11 +0900 (Fri, 12 Jan 2018)

  New Revision: 61786

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61786

  Log:
    tool/ruby_vm support for pre-2.1 BASERUBY
    
    as requested by devs, support for BASERUBY prior to 2.1

  Modified files:
    trunk/tool/insns2vm.rb
    trunk/tool/ruby_vm/helpers/dumper.rb
    trunk/tool/ruby_vm/helpers/scanner.rb
    trunk/tool/ruby_vm/loaders/insns_def.rb
    trunk/tool/ruby_vm/loaders/opt_insn_unif_def.rb
    trunk/tool/ruby_vm/loaders/opt_operand_def.rb
    trunk/tool/ruby_vm/loaders/vm_opts_h.rb
    trunk/tool/ruby_vm/models/attribute.rb
    trunk/tool/ruby_vm/models/bare_instructions.rb
    trunk/tool/ruby_vm/models/c_expr.rb
    trunk/tool/ruby_vm/models/instructions_unifications.rb
    trunk/tool/ruby_vm/models/operands_unifications.rb
    trunk/tool/ruby_vm/models/trace_instructions.rb
Index: tool/ruby_vm/helpers/scanner.rb
===================================================================
--- tool/ruby_vm/helpers/scanner.rb	(revision 61785)
+++ tool/ruby_vm/helpers/scanner.rb	(revision 61786)
@@ -11,8 +11,10 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/helpers/scanner.rb#L11
 # details.
 
 require 'pathname'
-require 'strscan'
 
+# Poor man's StringScanner.
+# Sadly  https://bugs.ruby-lang.org/issues/8343 is  not backported  to 2.0.  We
+# have to do it by hand.
 class RubyVM::Scanner
   attr_reader :__FILE__
   attr_reader :__LINE__
@@ -22,28 +24,29 @@ class RubyVM::Scanner https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/helpers/scanner.rb#L24
     src      += path
     @__LINE__ = 1
     @__FILE__ = src.realpath.to_path
-    str       = src.read mode: 'rt:utf-8:utf-8'
-    @scanner  = StringScanner.new str
+    @str      = src.read mode: 'rt:utf-8:utf-8'
+    @pos      = 0
   end
 
   def eos?
-    @scanner.eos?
+    return @pos >= @str.length
   end
 
   def scan re
     ret   = @__LINE__
-    match = @scanner.scan re
-    return unless match
-    @__LINE__ += match.count "\n"
+    @last_match = @str.match re, @pos
+    return unless @last_match
+    @__LINE__ += @last_match.to_s.count "\n"
+    @pos = @last_match.end 0
     return ret
   end
 
   def scan! re
     scan re or raise sprintf "parse error at %s:%d near:\n %s...", \
-        @__FILE__, @__LINE__, @scanner.peek(32)
+        @__FILE__, @__LINE__, @str[pos, 32]
   end
 
   def [] key
-    return @scanner[key]
+    return @last_match[key]
   end
 end
Index: tool/ruby_vm/helpers/dumper.rb
===================================================================
--- tool/ruby_vm/helpers/dumper.rb	(revision 61785)
+++ tool/ruby_vm/helpers/dumper.rb	(revision 61786)
@@ -16,67 +16,69 @@ require_relative 'c_escape' https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/helpers/dumper.rb#L16
 
 class RubyVM::Dumper
   include RubyVM::CEscape
+  private
 
-  # I learned this handy "super-private" maneuver from @a_matsuda
-  # cf: https://github.com/rails/rails/pull/27363/files
-  using Module.new {
-    refine RubyVM::Dumper do
-      private
-
-      def new_binding
-        # This `eval 'binding'` does not return the current binding
-        # but creates one on top of it.
-        return eval 'binding'
-      end
-
-      def new_erb spec
-        path  = Pathname.new __dir__
-        path += '../views'
-        path += spec
-        src   = path.read mode: 'rt:utf-8:utf-8'
-      rescue Errno::ENOENT
-        raise "don't know how to generate #{path}"
-      else
-        erb = ERB.new src, nil, '%-'
-        erb.filename = path.realpath.to_path
-        return erb
-      end
-
-      def finderb spec
-        return @erb.fetch spec do |k|
-          erb = new_erb k
-          @erb[k] = erb
-        end
-      end
-
-      def replace_pragma_line str, lineno
-        if str == "#pragma RubyVM reset source\n" then
-          return "#line #{lineno + 2} #{@file}\n"
-        else
-          return str
-        end
-      end
-
-      public
-
-      def do_render source, locals
-        erb = finderb source
-        bnd = @empty.dup
-        locals.each_pair do |k, v|
-          bnd.local_variable_set k, v
-        end
-        return erb.result bnd
-      end
-
-      def replace_pragma str
-        return str                                 \
-          . each_line                              \
-          . with_index                             \
-          . map {|i, j| replace_pragma_line i, j } \
-          . join
-      end
+  def new_binding
+    # This `eval 'binding'` does not return the current binding
+    # but creates one on top of it.
+    return eval 'binding'
+  end
+
+  def new_erb spec
+    path  = Pathname.new __dir__
+    path += '../views'
+    path += spec
+    src   = path.read mode: 'rt:utf-8:utf-8'
+  rescue Errno::ENOENT
+    raise "don't know how to generate #{path}"
+  else
+    erb = ERB.new src, nil, '%-'
+    erb.filename = path.realpath.to_path
+    return erb
+  end
+
+  def finderb spec
+    return @erb.fetch spec do |k|
+      erb = new_erb k
+      @erb[k] = erb
     end
-  }
+  end
+
+  def replace_pragma_line str, lineno
+    if str == "#pragma RubyVM reset source\n" then
+      return "#line #{lineno + 2} #{@file}\n"
+    else
+      return str
+    end
+  end
+
+  def local_variable_set bnd, var, val
+    eval '__locals__ ||= {}', bnd
+    locals = eval '__locals__', bnd
+    locals[var] = val
+    eval "#{var} = __locals__[:#{var}]", bnd
+    test = eval "#{var}", bnd
+    raise unless test == val
+  end
+
+  public
+
+  def do_render source, locals
+    erb = finderb source
+    bnd = @empty.dup
+    locals.each_pair do |k, v|
+      local_variable_set bnd, k, v
+    end
+    return erb.result bnd
+  end
+
+  def replace_pragma str
+    return str                                 \
+      . each_line                              \
+      . with_index                             \
+      . map {|i, j| replace_pragma_line i, j } \
+      . join
+  end
 
   def initialize path
     @erb   = {}
Index: tool/ruby_vm/models/bare_instructions.rb
===================================================================
--- tool/ruby_vm/models/bare_instructions.rb	(revision 61785)
+++ tool/ruby_vm/models/bare_instructions.rb	(revision 61786)
@@ -18,16 +18,16 @@ require_relative 'attribute' https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/bare_instructions.rb#L18
 class RubyVM::BareInstructions
   attr_reader :template, :name, :opes, :pops, :rets, :decls, :expr
 
-  def initialize template:, name:, location:, signature:, attributes:, expr:
-    @template = template
-    @name     = name
-    @loc      = location
-    @sig      = signature
-    @expr     = RubyVM::CExpr.new expr
+  def initialize opts = {}
+    @template = opts[:template]
+    @name     = opts[:name]
+    @loc      = opts[:location]
+    @sig      = opts[:signature]
+    @expr     = RubyVM::CExpr.new opts[:expr]
     @opes     = typesplit @sig[:ope]
     @pops     = typesplit @sig[:pop].reject {|i| i == '...' }
     @rets     = typesplit @sig[:ret].reject {|i| i == '...' }
-    @attrs    = attributes.map {|i|
+    @attrs    = opts[:attributes].map {|i|
       RubyVM::Attribute.new insn: self, **i
     }.each_with_object({}) {|a, h|
       h[a.key] = a
@@ -148,7 +148,10 @@ class RubyVM::BareInstructions https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/bare_instructions.rb#L148
     end
   end
 
-  @instances = RubyVM::InsnsDef.map {|h| new template: h, **h }
+  @instances = RubyVM::InsnsDef.map {|h|
+    hh = h.merge(:template => h)
+    new hh
+  }
 
   def self.fetch name
     @instances.find do |insn|
Index: tool/ruby_vm/models/instructions_unifications.rb
===================================================================
--- tool/ruby_vm/models/instructions_unifications.rb	(revision 61785)
+++ tool/ruby_vm/models/instructions_unifications.rb	(revision 61786)
@@ -19,10 +19,10 @@ class RubyVM::InstructionsUnifications https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/instructions_unifications.rb#L19
 
   attr_reader :name
 
-  def initialize location:, signature:
-    @location = location
-    @name     = namegen signature
-    @series   = signature.map do |i|
+  def initialize opts = {}
+    @location = opts[:location]
+    @name     = namegen opts[:signature]
+    @series   = opts[:signature].map do |i|
       RubyVM::BareInstructions.fetch i # Misshit is fatal
     end
   end
@@ -34,7 +34,7 @@ class RubyVM::InstructionsUnifications https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/instructions_unifications.rb#L34
   end
 
   @instances = RubyVM::OptInsnUnifDef.map do |h|
-    new(**h)
+    new h
   end
 
   def self.to_a
Index: tool/ruby_vm/models/c_expr.rb
===================================================================
--- tool/ruby_vm/models/c_expr.rb	(revision 61785)
+++ tool/ruby_vm/models/c_expr.rb	(revision 61786)
@@ -17,10 +17,10 @@ class RubyVM::CExpr https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/c_expr.rb#L17
 
   attr_reader :__FILE__, :__LINE__, :expr
 
-  def initialize location:, expr:
-    @__FILE__  = location[0]
-    @__LINE__  = location[1]
-    @expr      = expr
+  def initialize opts = {}
+    @__FILE__  = opts[:location][0]
+    @__LINE__  = opts[:location][1]
+    @expr      = opts[:expr]
   end
 
   # blank, in sense of C program.
Index: tool/ruby_vm/models/trace_instructions.rb
===================================================================
--- tool/ruby_vm/models/trace_instructions.rb	(revision 61785)
+++ tool/ruby_vm/models/trace_instructions.rb	(revision 61786)
@@ -18,7 +18,7 @@ class RubyVM::TraceInstructions https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/trace_instructions.rb#L18
 
   attr_reader :name
 
-  def initialize orig:
+  def initialize orig
     @orig = orig
     @name = as_tr_cpp "trace @ #{@orig.name}"
   end
@@ -61,7 +61,7 @@ class RubyVM::TraceInstructions https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/trace_instructions.rb#L61
 
   private
 
-  @instances = RubyVM::Instructions.map {|i| new orig: i }
+  @instances = RubyVM::Instructions.map {|i| new i }
 
   def self.to_a
     @instances
Index: tool/ruby_vm/models/attribute.rb
===================================================================
--- tool/ruby_vm/models/attribute.rb	(revision 61785)
+++ tool/ruby_vm/models/attribute.rb	(revision 61786)
@@ -16,11 +16,11 @@ class RubyVM::Attribute https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/attribute.rb#L16
   include RubyVM::CEscape
   attr_reader :insn, :key, :type, :expr
 
-  def initialize insn:, name:, type:, location:, expr:
-    @insn = insn
-    @key = name
-    @expr = RubyVM::CExpr.new location: location, expr: expr
-    @type = type
+  def initialize opts = {}
+    @insn = opts[:insn]
+    @key = opts[:name]
+    @expr = RubyVM::CExpr.new location: opts[:location], expr: opts[:expr]
+    @type = opts[:type]
   end
 
   def name
Index: tool/ruby_vm/models/operands_unifications.rb
===================================================================
--- tool/ruby_vm/models/operands_unifications.rb	(revision 61785)
+++ tool/ruby_vm/models/operands_unifications.rb	(revision 61786)
@@ -19,13 +19,13 @@ class RubyVM::OperandsUnifications < Rub https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/operands_unifications.rb#L19
 
   attr_reader :preamble, :original, :spec
 
-  def initialize location:, signature:
-    name             = signature[0]
+  def initialize opts = {}
+    name             = opts[:signature][0]
     @original        = RubyVM::BareInstructions.fetch name
     template         = @original.template
-    parts            = compose location, signature, template[:signature]
+    parts            = compose opts[:location], opts[:signature], template[:signature]
     json             = template.dup
-    json[:location]  = location
+    json[:location]  = opts[:location]
     json[:signature] = parts[:signature]
     json[:name]      = parts[:name]
     @preamble        = parts[:preamble]
@@ -122,7 +122,7 @@ class RubyVM::OperandsUnifications < Rub https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/operands_unifications.rb#L122
   end
 
   @instances = RubyVM::OptOperandDef.map do |h|
-    new(**h)
+    new h
   end
 
   def self.to_a
Index: tool/ruby_vm/loaders/vm_opts_h.rb
===================================================================
--- tool/ruby_vm/loaders/vm_opts_h.rb	(revision 61785)
+++ tool/ruby_vm/loaders/vm_opts_h.rb	(revision 61786)
@@ -18,14 +18,14 @@ grammar = %r/ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/loaders/vm_opts_h.rb#L18
     (?<ws>      \u0020 ){0}
     (?<key>     \w+    ){0}
     (?<value>   0|1    ){0}
-    (?<define>  \#define \g<ws>+ OPT_\g<key> \g<ws>+ \g<value> \g<ws>*\n )
+    (?<define>  \G \#define \g<ws>+ OPT_\g<key> \g<ws>+ \g<value> \g<ws>*\n )
 /mx
 
 until scanner.eos? do
   if scanner.scan grammar then
     json[scanner['key']] = ! scanner['value'].to_i.zero? # not nonzero?
   else
-    scanner.scan(/.*\n/)
+    scanner.scan(/\G.*\n/)
   end
 end
 
Index: tool/ruby_vm/loaders/insns_def.rb
===================================================================
--- tool/ruby_vm/loaders/insns_def.rb	(revision 61785)
+++ tool/ruby_vm/loaders/insns_def.rb	(revision 61786)
@@ -41,7 +41,7 @@ grammar = %r' https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/loaders/insns_def.rb#L41
 'x
 
 until scanner.eos? do
-  next if scanner.scan(/#{grammar}\g<ws>+/o)
+  next if scanner.scan(/\G#{grammar}\g<ws>+/o)
   split = -> (v) {
     case v when /\Avoid\z/ then
       []
@@ -50,14 +50,14 @@ until scanner.eos? do https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/loaders/insns_def.rb#L50
     end
   }
 
-  l1   = scanner.scan!(/#{grammar}\g<insn>/o)
+  l1   = scanner.scan!(/\G#{grammar}\g<insn>/o)
   name = scanner["insn:name"]
   ope  = split.(scanner["insn:opes"])
   pop  = split.(scanner["insn:pops"])
   ret  = split.(scanner["insn:rets"])
 
   attrs = []
-  while l2 = scanner.scan(/#{grammar}\g<pragma>/o) do
+  while l2 = scanner.scan(/\G#{grammar}\g<pragma>/o) do
     attrs << {
       location: [path, l2],
       name: scanner["pragma:name"],
@@ -66,7 +66,7 @@ until scanner.eos? do https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/loaders/insns_def.rb#L66
     }
   end
 
-  l3 = scanner.scan!(/#{grammar}\g<block>/o)
+  l3 = scanner.scan!(/\G#{grammar}\g<block>/o)
   json << {
     name: name,
     location: [path, l1],
Index: tool/ruby_vm/loaders/opt_insn_unif_def.rb
===================================================================
--- tool/ruby_vm/loaders/opt_insn_unif_def.rb	(revision 61785)
+++ tool/ruby_vm/loaders/opt_insn_unif_def.rb	(revision 61786)
@@ -16,10 +16,10 @@ json    = [] https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/loaders/opt_insn_unif_def.rb#L16
 scanner = RubyVM::Scanner.new '../../../defs/opt_insn_unif.def'
 path    = scanner.__FILE__
 until scanner.eos? do
-  next  if scanner.scan(/ ^ (?: \#.* )? \n /x)
-  break if scanner.scan(/ ^ __END__ $ /x)
+  next  if scanner.scan(/\G ^ (?: \#.* )? \n /x)
+  break if scanner.scan(/\G ^ __END__ $ /x)
 
-  pos = scanner.scan!(/(?<series>  (?: [\ \t]* \w+ )+ ) \n /mx)
+  pos = scanner.scan!(/\G (?<series>  (?: [\ \t]* \w+ )+ ) \n /mx)
   json << {
     location: [path, pos],
     signature: scanner["series"].strip.split
Index: tool/ruby_vm/loaders/opt_operand_def.rb
===================================================================
--- tool/ruby_vm/loaders/opt_operand_def.rb	(revision 61785)
+++ tool/ruby_vm/loaders/opt_operand_def.rb	(revision 61786)
@@ -29,18 +29,17 @@ grammar = %r/ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/loaders/opt_operand_def.rb#L29
 /mx
 
 until scanner.eos? do
-  break if scanner.scan(/ ^ __END__ $ /x)
-  next  if scanner.scan(/#{grammar} \g<ws>+ /ox)
+  break if scanner.scan(/\G ^ __END__ $ /x)
+  next  if scanner.scan(/\G#{grammar} \g<ws>+ /ox)
 
-  line = scanner.scan!(/#{grammar} \g<decl> /mox)
+  line = scanner.scan!(/\G#{grammar} \g<decl> /mox)
   insn = scanner["insn"]
   args = scanner["args"]
   ary  = []
   until args.strip.empty? do
-    tmp = StringScanner.new args
-    tmp.scan(/#{grammar} \g<args> /mox)
-    ary << tmp["arg"]
-    args = tmp["remain"]
+    md = /\G#{grammar} \g<args> /mox.match(args)
+    ary << md["arg"]
+    args = md["remain"]
     break unless args
   end
   json << {
Index: tool/insns2vm.rb
===================================================================
--- tool/insns2vm.rb	(revision 61785)
+++ tool/insns2vm.rb	(revision 61786)
@@ -8,6 +8,8 @@ require_relative 'ruby_vm/scripts/insns2 https://github.com/ruby/ruby/blob/trunk/tool/insns2vm.rb#L8
 if $0 == __FILE__
   router(ARGV).each do |(path, generator)|
     str = generator.generate path
-    path.write str, mode: 'wb:utf-8'
+    path.open 'wb:utf-8' do |fp|
+      fp.write str
+    end
   end
 end

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

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