summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtool/insns2vm.rb4
-rw-r--r--tool/ruby_vm/helpers/dumper.rb120
-rw-r--r--tool/ruby_vm/helpers/scanner.rb21
-rw-r--r--tool/ruby_vm/loaders/insns_def.rb8
-rw-r--r--tool/ruby_vm/loaders/opt_insn_unif_def.rb6
-rw-r--r--tool/ruby_vm/loaders/opt_operand_def.rb13
-rw-r--r--tool/ruby_vm/loaders/vm_opts_h.rb4
-rw-r--r--tool/ruby_vm/models/attribute.rb10
-rw-r--r--tool/ruby_vm/models/bare_instructions.rb19
-rw-r--r--tool/ruby_vm/models/c_expr.rb8
-rw-r--r--tool/ruby_vm/models/instructions_unifications.rb10
-rw-r--r--tool/ruby_vm/models/operands_unifications.rb10
-rw-r--r--tool/ruby_vm/models/trace_instructions.rb4
13 files changed, 123 insertions, 114 deletions
diff --git a/tool/insns2vm.rb b/tool/insns2vm.rb
index e6fe64d189..8117b789fb 100755
--- a/tool/insns2vm.rb
+++ b/tool/insns2vm.rb
@@ -8,6 +8,8 @@ require_relative 'ruby_vm/scripts/insns2vm'
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
diff --git a/tool/ruby_vm/helpers/dumper.rb b/tool/ruby_vm/helpers/dumper.rb
index 8f14d90d1f..3ba7310f56 100644
--- a/tool/ruby_vm/helpers/dumper.rb
+++ b/tool/ruby_vm/helpers/dumper.rb
@@ -16,67 +16,69 @@ require_relative 'c_escape'
class RubyVM::Dumper
include RubyVM::CEscape
+ 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
- # 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 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 = {}
diff --git a/tool/ruby_vm/helpers/scanner.rb b/tool/ruby_vm/helpers/scanner.rb
index 3dce6ffdfe..5ae1363480 100644
--- a/tool/ruby_vm/helpers/scanner.rb
+++ b/tool/ruby_vm/helpers/scanner.rb
@@ -11,8 +11,10 @@
# 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
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
diff --git a/tool/ruby_vm/loaders/insns_def.rb b/tool/ruby_vm/loaders/insns_def.rb
index 58748c3ca6..987e29640a 100644
--- a/tool/ruby_vm/loaders/insns_def.rb
+++ b/tool/ruby_vm/loaders/insns_def.rb
@@ -41,7 +41,7 @@ grammar = %r'
'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
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
}
end
- l3 = scanner.scan!(/#{grammar}\g<block>/o)
+ l3 = scanner.scan!(/\G#{grammar}\g<block>/o)
json << {
name: name,
location: [path, l1],
diff --git a/tool/ruby_vm/loaders/opt_insn_unif_def.rb b/tool/ruby_vm/loaders/opt_insn_unif_def.rb
index a5af409e71..0f5de69930 100644
--- a/tool/ruby_vm/loaders/opt_insn_unif_def.rb
+++ b/tool/ruby_vm/loaders/opt_insn_unif_def.rb
@@ -16,10 +16,10 @@ json = []
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
diff --git a/tool/ruby_vm/loaders/opt_operand_def.rb b/tool/ruby_vm/loaders/opt_operand_def.rb
index 5c94b4bced..3022f9915d 100644
--- a/tool/ruby_vm/loaders/opt_operand_def.rb
+++ b/tool/ruby_vm/loaders/opt_operand_def.rb
@@ -29,18 +29,17 @@ grammar = %r/
/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 << {
diff --git a/tool/ruby_vm/loaders/vm_opts_h.rb b/tool/ruby_vm/loaders/vm_opts_h.rb
index f898fb36a4..d28db4eaa2 100644
--- a/tool/ruby_vm/loaders/vm_opts_h.rb
+++ b/tool/ruby_vm/loaders/vm_opts_h.rb
@@ -18,14 +18,14 @@ grammar = %r/
(?<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
diff --git a/tool/ruby_vm/models/attribute.rb b/tool/ruby_vm/models/attribute.rb
index 0b6d6e09b2..f6d95bd67c 100644
--- a/tool/ruby_vm/models/attribute.rb
+++ b/tool/ruby_vm/models/attribute.rb
@@ -16,11 +16,11 @@ class RubyVM::Attribute
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
diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb
index c3a96b8f08..a9cb4db953 100644
--- a/tool/ruby_vm/models/bare_instructions.rb
+++ b/tool/ruby_vm/models/bare_instructions.rb
@@ -18,16 +18,16 @@ require_relative 'attribute'
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
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|
diff --git a/tool/ruby_vm/models/c_expr.rb b/tool/ruby_vm/models/c_expr.rb
index b19dd8bb48..923651a26b 100644
--- a/tool/ruby_vm/models/c_expr.rb
+++ b/tool/ruby_vm/models/c_expr.rb
@@ -17,10 +17,10 @@ class RubyVM::CExpr
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.
diff --git a/tool/ruby_vm/models/instructions_unifications.rb b/tool/ruby_vm/models/instructions_unifications.rb
index 346cebd709..aa8cef1bd5 100644
--- a/tool/ruby_vm/models/instructions_unifications.rb
+++ b/tool/ruby_vm/models/instructions_unifications.rb
@@ -19,10 +19,10 @@ class RubyVM::InstructionsUnifications
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
end
@instances = RubyVM::OptInsnUnifDef.map do |h|
- new(**h)
+ new h
end
def self.to_a
diff --git a/tool/ruby_vm/models/operands_unifications.rb b/tool/ruby_vm/models/operands_unifications.rb
index c0ae0ece45..2a34ea0f62 100644
--- a/tool/ruby_vm/models/operands_unifications.rb
+++ b/tool/ruby_vm/models/operands_unifications.rb
@@ -19,13 +19,13 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions
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 < RubyVM::BareInstructions
end
@instances = RubyVM::OptOperandDef.map do |h|
- new(**h)
+ new h
end
def self.to_a
diff --git a/tool/ruby_vm/models/trace_instructions.rb b/tool/ruby_vm/models/trace_instructions.rb
index a99a933ac7..fc904a11b5 100644
--- a/tool/ruby_vm/models/trace_instructions.rb
+++ b/tool/ruby_vm/models/trace_instructions.rb
@@ -18,7 +18,7 @@ class RubyVM::TraceInstructions
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
private
- @instances = RubyVM::Instructions.map {|i| new orig: i }
+ @instances = RubyVM::Instructions.map {|i| new i }
def self.to_a
@instances