diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-01-10 01:53:24 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-01-10 01:53:24 +0000 |
commit | 5ad95486e63675b2bb3ad665bb2b84eb260c6f29 (patch) | |
tree | 9ed7d02028ba1edd4a74e090fb4c7155b55aafd6 /tool | |
parent | 7c7d47d2369881f8ea22da34077459771276786a (diff) |
merge revisions 61753:61750 61747:61740 61737:61728
Revert all the VM generator rewrites; requested by naruse
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61755 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'tool')
39 files changed, 1259 insertions, 1817 deletions
diff --git a/tool/insns2vm.rb b/tool/insns2vm.rb index e6fe64d189..ecbbb52643 100755 --- a/tool/insns2vm.rb +++ b/tool/insns2vm.rb @@ -3,11 +3,16 @@ # This is used by Makefile.in to generate .inc files. # See Makefile.in for details. -require_relative 'ruby_vm/scripts/insns2vm' +require 'optparse' + +Version = %w$Revision: 11626 $[1..-1] + +require "#{File.join(File.dirname(__FILE__), 'instruction')}" if $0 == __FILE__ - router(ARGV).each do |(path, generator)| - str = generator.generate path - path.write str, mode: 'wb:utf-8' - end + opts = ARGV.options + maker = RubyVM::SourceCodeGenerator.def_options(opts) + files = opts.parse! + generator = maker.call + generator.generate(files) end diff --git a/tool/instruction.rb b/tool/instruction.rb new file mode 100755 index 0000000000..447fed5948 --- /dev/null +++ b/tool/instruction.rb @@ -0,0 +1,1249 @@ +#!./miniruby +# -*- coding: us-ascii -*- +# +# This library is used by insns2vm.rb as part of autogenerating +# instruction files with .inc extensions like insns.inc and vm.inc. + +require 'erb' +$:.unshift(File.dirname(__FILE__)) +require 'vpath' + +class RubyVM + class Instruction + def initialize name, opes, pops, rets, comm, body, tvars, sp_inc, + orig = self, defopes = [], type = nil, + nsc = [], psc = [[], []] + + @name = name + @opes = opes # [[type, name], ...] + @pops = pops # [[type, name], ...] + @rets = rets # [[type, name], ...] + @comm = comm # {:c => category, :e => en desc, :j => ja desc} + @body = body # '...' + + @orig = orig + @defopes = defopes + @type = type + @tvars = tvars + + @nextsc = nsc + @pushsc = psc + @sc = [] + @unifs = [] + @optimized = [] + @is_sc = false + @sp_inc = sp_inc + @trace = trace + end + + def add_sc sci + @sc << sci + sci.set_sc + end + + attr_reader :name, :opes, :pops, :rets + attr_reader :body, :comm + attr_reader :nextsc, :pushsc + attr_reader :orig, :defopes, :type + attr_reader :sc + attr_reader :unifs, :optimized + attr_reader :is_sc + attr_reader :tvars + attr_reader :sp_inc + attr_accessor :trace + + def set_sc + @is_sc = true + end + + def add_unif insns + @unifs << insns + end + + def add_optimized insn + @optimized << insn + end + + def sp_increase_c_expr + if(pops.any?{|t, v| v == '...'} || + rets.any?{|t, v| v == '...'}) + # user definition + raise "no sp increase definition" if @sp_inc.nil? + ret = "int inc = 0;\n" + + @opes.each_with_index{|(t, v), i| + if (t == 'rb_num_t' && ((re = /\b#{v}\b/n) =~ @sp_inc)) || + (@defopes.any?{|t, val| re =~ val}) + ret << " int #{v} = FIX2INT(opes[#{i}]);\n" + elsif (t == 'CALL_INFO' && ((re = /\b#{v}\b/n) =~ @sp_inc)) + ret << " CALL_INFO #{v} = (CALL_INFO)(opes[#{i}]);\n" + end + } + + @defopes.each_with_index{|((t, var), val), i| + if t == 'rb_num_t' && val != '*' && /\b#{var}\b/ =~ @sp_inc + ret << " #{t} #{var} = #{val};\n" + end + } + + ret << " #{@sp_inc};\n" + ret << " return depth + inc;" + ret + else + "return depth + #{rets.size - pops.size};" + end + end + + def inspect + "#<Instruction:#{@name}>" + end + end + + class InstructionsLoader + def initialize opts = {} + @insns = [] + @insn_map = {} + + @vpath = opts[:VPATH] || File + @use_const = opts[:use_const] + @verbose = opts[:verbose] + @destdir = opts[:destdir] + + (@vm_opts = load_vm_opts).each {|k, v| + @vm_opts[k] = opts[k] if opts.key?(k) + } + + load_insns_def opts[:"insns.def"] || 'insns.def' + + load_opt_operand_def opts[:"opope.def"] || 'defs/opt_operand.def' + load_insn_unification_def opts[:"unif.def"] || 'defs/opt_insn_unif.def' + make_stackcaching_insns if vm_opt?('STACK_CACHING') + make_trace_insns + end + + attr_reader :vpath + attr_reader :destdir + + %w[use_const verbose].each do |attr| + attr_reader attr + alias_method "#{attr}?", attr + remove_method attr + end + + def [](s) + @insn_map[s.to_s] + end + + def each + @insns.each{|insn| + yield insn + } + end + + def size + @insns.size + end + + ### + private + + def vm_opt? name + @vm_opts[name] + end + + def load_vm_opts file = nil + file ||= 'vm_opts.h' + opts = {} + vpath.open(file) do |f| + f.grep(/^\#define\s+OPT_([A-Z_]+)\s+(\d+)/) do + opts[$1] = !$2.to_i.zero? + end + end + opts + end + + SKIP_COMMENT_PATTERN = Regexp.compile(Regexp.escape('/** ##skip')) + + include Enumerable + + def add_insn insn + @insns << insn + @insn_map[insn.name] = insn + end + + def make_insn name, opes, pops, rets, comm, body, sp_inc + add_insn Instruction.new(name, opes, pops, rets, comm, body, [], sp_inc) + end + + # str -> [[type, var], ...] + def parse_vars line + raise unless /\((.*?)\)/ =~ line + vars = $1.split(',') + vars.map!{|v| + if /\s*(\S+)\s+(\S+)\s*/ =~ v + type = $1 + var = $2 + elsif /\s*\.\.\.\s*/ =~ v + type = var = '...' + else + raise + end + [type, var] + } + vars + end + + def parse_comment comm + c = 'others' + j = '' + e = '' + comm.each_line{|line| + case line + when /@c (.+)/ + c = $1 + when /@e (.+)/ + e = $1 + when /@e\s*$/ + e = '' + when /@j (.+)$/ + j = $1 + when /@j\s*$/ + j = '' + end + } + { :c => c, + :e => e, + :j => j, + } + end + + def load_insns_def file + body = insn = opes = pops = rets = nil + comment = '' + + vpath.open(file) {|f| + f.instance_variable_set(:@line_no, 0) + class << f + def line_no + @line_no + end + def gets + @line_no += 1 + super + end + end + + while line = f.gets + line.chomp! + case line + + when SKIP_COMMENT_PATTERN + while line = f.gets.chomp + if /\s+\*\/$/ =~ line + break + end + end + + # collect instruction comment + when /^\/\*\*$/ + while line = f.gets + if /\s+\*\/\s*$/ =~ line + break + else + comment << line + end + end + + # start instruction body + when /^DEFINE_INSN$/ + insn = f.gets.chomp + opes = parse_vars(f.gets.chomp) + pops = parse_vars(f.gets.chomp).reverse + rets_str = f.gets.chomp + rets = parse_vars(rets_str).reverse + comment = parse_comment(comment) + insn_in = true + body = '' + + sp_inc = rets_str[%r"//\s*(.+)", 1] + + raise unless /^\{$/ =~ f.gets.chomp + line_no = f.line_no + + # end instruction body + when /^\}/ + if insn_in + body.instance_variable_set(:@line_no, line_no) + body.instance_variable_set(:@file, f.path) + insn = make_insn(insn, opes, pops, rets, comment, body, sp_inc) + insn_in = false + comment = '' + end + + else + if insn_in + body << line + "\n" + end + end + end + } + end + + ## opt op + def load_opt_operand_def file + vpath.foreach(file) {|line| + line = line.gsub(/\#.*/, '').strip + next if line.length == 0 + break if /__END__/ =~ line + /(\S+)\s+(.+)/ =~ line + insn = $1 + opts = $2 + add_opt_operand insn, opts.split(/,/).map{|e| e.strip} + } if file + end + + def label_escape label + label.gsub(/\(/, '_O_'). + gsub(/\)/, '_C_'). + gsub(/\*/, '_WC_') + end + + def add_opt_operand insn_name, opts + insn = @insn_map[insn_name] + opes = insn.opes + + if opes.size != opts.size + raise "operand size mismatch for #{insn.name} (opes: #{opes.size}, opts: #{opts.size})" + end + + ninsn = insn.name + '_OP_' + opts.map{|e| label_escape(e)}.join('_') + nopes = [] + defv = [] + + opts.each_with_index{|e, i| + if e == '*' + nopes << opes[i] + end + defv << [opes[i], e] + } + + make_insn_operand_optimized(insn, ninsn, nopes, defv) + end + + def make_insn_operand_optimized orig_insn, name, opes, defopes + comm = orig_insn.comm.dup + comm[:c] = 'optimize' + add_insn insn = Instruction.new( + name, opes, orig_insn.pops, orig_insn.rets, comm, + orig_insn.body, orig_insn.tvars, orig_insn.sp_inc, + orig_insn, defopes) + orig_insn.add_optimized insn + end + + ## insn unif + def load_insn_unification_def file + vpath.foreach(file) {|line| + line = line.gsub(/\#.*/, '').strip + next if line.length == 0 + break if /__END__/ =~ line + make_unified_insns line.split.map{|e| + raise "unknown insn: #{e}" unless @insn_map[e] + @insn_map[e] + } + } if file + end + + def all_combination sets + ret = sets.shift.map{|e| [e]} + + sets.each{|set| + prev = ret + ret = [] + prev.each{|ary| + set.each{|e| + eary = ary.dup + eary << e + ret << eary + } + } + } + ret + end + + def make_unified_insns insns + if vm_opt?('UNIFY_ALL_COMBINATION') + insn_sets = insns.map{|insn| + [insn] + insn.optimized + } + + all_combination(insn_sets).each{|insns_set| + make_unified_insn_each insns_set + } + else + make_unified_insn_each insns + end + end + + def mk_private_val vals, i, redef + vals.dup.map{|v| + # v[0] : type + # v[1] : var name + + v = v.dup + if v[0] != '...' + redef[v[1]] = v[0] + v[1] = "#{v[1]}_#{i}" + end + v + } + end + + def mk_private_val2 vals, i, redef + vals.dup.map{|v| + # v[0][0] : type + # v[0][1] : var name + # v[1] : default val + + pv = v.dup + v = pv[0] = pv[0].dup + if v[0] != '...' + redef[v[1]] = v[0] + v[1] = "#{v[1]}_#{i}" + end + pv + } + end + + def make_unified_insn_each insns + names = [] + opes = [] + pops = [] + rets = [] + comm = { + :c => 'optimize', + :e => 'unified insn', + :j => 'unified insn', + } + body = '' + passed = [] + tvars = [] + defopes = [] + sp_inc = '' + + insns.each_with_index{|insn, i| + names << insn.name + redef_vars = {} + + e_opes = mk_private_val(insn.opes, i, redef_vars) + e_pops = mk_private_val(insn.pops, i, redef_vars) + e_rets = mk_private_val(insn.rets, i, redef_vars) + # ToDo: fix it + e_defs = mk_private_val2(insn.defopes, i, redef_vars) + + passed_vars = [] + while pvar = e_pops.pop + rvar = rets.pop + if rvar + raise "unsupported unif insn: #{insns.inspect}" if rvar[0] == '...' + passed_vars << [pvar, rvar] + tvars << rvar + else + e_pops.push pvar + break + end + end + + opes.concat e_opes + pops.concat e_pops + rets.concat e_rets + defopes.concat e_defs + sp_inc << "#{insn.sp_inc}" + + body << "{ /* unif: #{i} */\n" + + passed_vars.map{|rpvars| + pv = rpvars[0] + rv = rpvars[1] + "#define #{pv[1]} #{rv[1]}" + }.join("\n") + + "\n" + + redef_vars.map{|v, type| + "#{type} #{v} = #{v}_#{i};" + }.join("\n") + "\n" + if line = insn.body.instance_variable_get(:@line_no) + file = insn.body.instance_variable_get(:@file) + body << "#line #{line+1} \"#{file}\"\n" + body << insn.body + body << "\n#line __CURRENT_LINE__ \"__CURRENT_FILE__\"\n" + else + body << insn.body + end + body << redef_vars.keys.map{|v| + "#{v}_#{i} = #{v};" + }.join("\n") + + "\n" + + passed_vars.map{|rpvars| + "#undef #{rpvars[0][1]}" + }.join("\n") + + "\n}\n" + } + + tvars_ary = [] + tvars.each{|tvar| + unless opes.any?{|var| + var[1] == tvar[1] + } || defopes.any?{|pvar| + pvar[0][1] == tvar[1] + } + tvars_ary << tvar + end + } + add_insn insn = Instruction.new("UNIFIED_" + names.join('_'), + opes, pops, rets.reverse, comm, body, + tvars_ary, sp_inc) + insn.defopes.replace defopes + insns[0].add_unif [insn, insns] + end + + ## sc + SPECIAL_INSN_FOR_SC_AFTER = { + /\Asend/ => [:a], + /\Aend/ => [:a], + /\Ayield/ => [:a], + /\Aclassdef/ => [:a], + /\Amoduledef/ => [:a], + } + FROM_SC = [[], [:a], [:b], [:a, :b], [:b, :a]] + + def make_stackcaching_insns + pops = rets = nil + + @insns.dup.each{|insn| + opops = insn.pops + orets = insn.rets + oopes = insn.opes + ocomm = insn.comm + oname = insn.name + + after = SPECIAL_INSN_FOR_SC_AFTER.find {|k, v| k =~ oname} + + insns = [] + FROM_SC.each{|from| + name, pops, rets, pushs1, pushs2, nextsc = + *calc_stack(insn, from, after, opops, orets) + + make_insn_sc(insn, name, oopes, pops, rets, [pushs1, pushs2], nextsc) + } + } + end + + def make_trace_insns + @insns.dup.each{|insn| + body = <<-EOS + vm_trace(ec, GET_CFP(), GET_PC()); + DISPATCH_ORIGINAL_INSN(#{insn.name}); + EOS + + trace_insn = Instruction.new(name = "trace_#{insn.name}", + insn.opes, insn.pops, insn.rets, insn.comm, + body, insn.tvars, insn.sp_inc) + trace_insn.trace = true + add_insn trace_insn + } + end + + def make_insn_sc orig_insn, name, opes, pops, rets, pushs, nextsc + comm = orig_insn.comm.dup + comm[:c] = 'optimize(sc)' + + scinsn = Instruction.new( + name, opes, pops, rets, comm, + orig_insn.body, orig_insn.tvars, orig_insn.sp_inc, + orig_insn, orig_insn.defopes, :sc, nextsc, pushs) + + add_insn scinsn + orig_insn.add_sc scinsn + end + + def self.complement_name st + "#{st[0] ? st[0] : 'x'}#{st[1] ? st[1] : 'x'}" + end + + def add_stack_value st + len = st.length + if len == 0 + st[0] = :a + [nil, :a] + elsif len == 1 + if st[0] == :a + st[1] = :b + else + st[1] = :a + end + [nil, st[1]] + else + st[0], st[1] = st[1], st[0] + [st[1], st[1]] + end + end + + def calc_stack insn, ofrom, oafter, opops, orets + from = ofrom.dup + pops = opops.dup + rets = orets.dup + rest_scr = ofrom.dup + + pushs_before = [] + pushs= [] + + pops.each_with_index{|e, i| + if e[0] == '...' + pushs_before = from + from = [] + end + r = from.pop + break unless r + pops[i] = pops[i].dup << r + } + + if oafter + from = oafter + from.each_with_index{|r, i| + rets[i] = rets[i].dup << r if rets[i] + } + else + rets = rets.reverse + rets.each_with_index{|e, i| + break if e[0] == '...' + pushed, r = add_stack_value from + rets[i] = rets[i].dup << r + if pushed + if rest_scr.pop + pushs << pushed + end + + if i - 2 >= 0 + rets[i-2].pop + end + end + } + end + + if false #|| insn.name =~ /test3/ + p ofrom + p pops + p rets + p pushs_before + p pushs + p from + exit + end + + ret = ["#{insn.name}_SC_#{InstructionsLoader.complement_name(ofrom)}_#{complement_name(from)}", + pops, rets, pushs_before, pushs, from] + end + end + + class SourceCodeGenerator + def initialize insns + @insns = insns + end + + attr_reader :insns + + def generate + raise "should not reach here" + end + + def vpath + @insns.vpath + end + + def verbose? + @insns.verbose? + end + + def use_const? + @insns.use_const? + end + + def template(name) + ERB.new(vpath.read("template/#{name}"), nil, '%-') + end + + def build_string + @lines = [] + yield + @lines.join("\n") + end + + EMPTY_STRING = ''.freeze + + def commit str = EMPTY_STRING + @lines << str + end + + def comment str + @lines << str if verbose? + end + + def output_path(fn) + d = @insns.destdir + fn = File.join(d, fn) if d + fn + end + end + + ################################################################### + # vm.inc + class VmBodyGenerator < SourceCodeGenerator + # vm.inc + def generate + template('vm.inc.tmpl').result(binding) + end + + def generate_from_insnname insnname + make_insn_def @insns[insnname.to_s] + end + + ####### + private + + def make_header_prepare_stack insn + comment " /* prepare stack status */" + + push_ba = insn.pushsc + raise "unsupport" if push_ba[0].size > 0 && push_ba[1].size > 0 + + n = 0 + push_ba.each {|pushs| n += pushs.length} + commit " CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, #{n});" if n > 0 + push_ba.each{|pushs| + pushs.each{|r| + commit " PUSH(SCREG(#{r}));" + } + } + end + + def make_header_operands insn + comment " /* declare and get from iseq */" + + vars = insn.opes + n = 0 + ops = [] + + vars.each_with_index{|(type, var), i| + if type == '...' + break + end + + # skip make operands when body has no reference to this operand + # TODO: really needed? + re = /\b#{var}\b/n + if re =~ insn.body or re =~ insn.sp_inc or insn.rets.any?{|t, v| re =~ v} or re =~ 'ic' or re =~ 'ci' or re =~ 'cc' + ops << " #{type} #{var} = (#{type})GET_OPERAND(#{i+1});" + end + + n += 1 + } + @opn = n + + # reverse or not? + # ops.join + commit ops.reverse + end + + def make_header_default_operands insn + vars = insn.defopes + + vars.each{|e| + next if e[1] == '*' + if use_const? + commit " const #{e[0][0]} #{e[0][1]} = #{e[1]};" + else + commit " #define #{e[0][1]} #{e[1]}" + end + } + end + + def make_footer_default_operands insn + comment " /* declare and initialize default opes */" + if use_const? + commit + else + vars = insn.defopes + + vars.each{|e| + next if e[1] == '*' + commit "#undef #{e[0][1]}" + } + end + end + + def make_header_stack_pops insn + comment " /* declare and pop from stack */" + + n = 0 + pops = [] + vars = insn.pops + vars.each_with_index{|iter, i| + type, var, r = *iter + if type == '...' + break + end + if r + pops << " #{type} #{var} = SCREG(#{r});" + else + pops << " #{type} #{var} = TOPN(#{n});" + n += 1 + end + } + @popn = n + + # reverse or not? + commit pops.reverse + end + + def make_header_temporary_vars insn + comment " /* declare temporary vars */" + + insn.tvars.each{|var| + commit " #{var[0]} #{var[1]};" + } + end + + def make_header_stack_val insn + comment "/* declare stack push val */" + + vars = insn.opes + insn.pops + insn.defopes.map{|e| e[0]} + + insn.rets.each{|var| + if vars.all?{|e| e[1] != var[1]} && var[1] != '...' + commit " #{var[0]} #{var[1]};" + end + } + end + + def make_header_analysis insn + commit " COLLECT_USAGE_INSN(BIN(#{insn.name}));" + insn.opes.each_with_index{|op, i| + commit " COLLECT_USAGE_OPERAND(BIN(#{insn.name}), #{i}, #{op[1]});" + } + end + + def make_header_pc insn + commit " ADD_PC(1+#{@opn});" + commit " PREFETCH(GET_PC());" + end + + def make_header_popn insn + comment " /* management */" + commit " POPN(#{@popn});" if @popn > 0 + end + + def make_header_debug insn + comment " /* for debug */" + commit " DEBUG_ENTER_INSN(\"#{insn.name}\");" + end + + def make_header_defines insn + commit " #define CURRENT_INSN_#{insn.name} 1" + commit " #define INSN_IS_SC() #{insn.sc ? 0 : 1}" + commit " #define INSN_LABEL(lab) LABEL_#{insn.name}_##lab" + commit " #define LABEL_IS_SC(lab) LABEL_##lab##_###{insn.sc.size == 0 ? 't' : 'f'}" + end + + def each_footer_stack_val insn + insn.rets.reverse_each{|v| + break if v[1] == '...' + yield v + } + end + + def make_footer_stack_val insn + comment " /* push stack val */" + + n = 0 + each_footer_stack_val(insn){|v| + n += 1 unless v[2] + } + commit " CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, #{n});" if n > 0 + each_footer_stack_val(insn){|v| + if v[2] + commit " SCREG(#{v[2]}) = #{v[1]};" + else + commit " PUSH(#{v[1]});" + end + } + end + + def make_footer_undefs insn + commit "#undef CURRENT_INSN_#{insn.name}" + commit "#undef INSN_IS_SC" + commit "#undef INSN_LABEL" + commit "#undef LABEL_IS_SC" + end + + def make_header insn + label = insn.trace ? '' : "START_OF_ORIGINAL_INSN(#{insn.name});" + commit "INSN_ENTRY(#{insn.name}){#{label}" + make_header_prepare_stack insn + commit "{" + unless insn.trace + make_header_stack_val insn + make_header_default_operands insn + make_header_operands insn + make_header_stack_pops insn + make_header_temporary_vars insn + # + make_header_debug insn + make_header_pc insn + make_header_popn insn + make_header_defines insn + make_header_analysis insn + end + commit "{" + end + + def make_footer insn + unless insn.trace + make_footer_stack_val insn + make_footer_default_operands insn + make_footer_undefs insn + end + commit " END_INSN(#{insn.name});}}}" + end + + def make_insn_def insn + build_string do + make_header insn + if line = insn.body.instance_variable_get(:@line_no) + file = insn.body.instance_variable_get(:@file) + commit "#line #{line+1} \"#{file}\"" + commit insn.body + commit '#line __CURRENT_LINE__ "__CURRENT_FILE__"' + else + commit insn.body + end + make_footer(insn) + end + end + end + + ################################################################### + # vmtc.inc + class VmTCIncGenerator < SourceCodeGenerator + def generate + template('vmtc.inc.tmpl').result(binding) + end + end + + ################################################################### + # insns_info.inc + class InsnsInfoIncGenerator < SourceCodeGenerator + def generate + template('insns_info.inc.tmpl').result(binding) + end + + ### + private + + def op2typesig op + case op + when /^OFFSET/ + "TS_OFFSET" + when /^rb_num_t/ + "TS_NUM" + when /^lindex_t/ + "TS_LINDEX" + when /^VALUE/ + "TS_VALUE" + when /^ID/ + "TS_ID" + when /GENTRY/ + "TS_GENTRY" + when /^IC/ + "TS_IC" + when /^CALL_INFO/ + "TS_CALLINFO" + when /^CALL_CACHE/ + "TS_CALLCACHE" + when /^\.\.\./ + "TS_VARIABLE" + when /^CDHASH/ + "TS_CDHASH" + when /^ISEQ/ + "TS_ISEQ" + when /rb_insn_func_t/ + "TS_FUNCPTR" + else + raise "unknown op type: #{op}" + end + end + + TYPE_CHARS = { + 'TS_OFFSET' => 'O', + 'TS_NUM' => 'N', + 'TS_LINDEX' => 'L', + 'TS_VALUE' => 'V', + 'TS_ID' => 'I', + 'TS_GENTRY' => 'G', + 'TS_IC' => 'K', + 'TS_CALLINFO' => 'C', + 'TS_CALLCACHE' => 'E', + 'TS_CDHASH' => 'H', + 'TS_ISEQ' => 'S', + 'TS_VARIABLE' => '.', + 'TS_FUNCPTR' => 'F', + } + + def max_length(array) + max = 0 + array.each do |i| + if (n = i.length) > max + max = n + end + end + max + end + end + + ################################################################### + # insns.inc + class InsnsIncGenerator < SourceCodeGenerator + def generate + template('insns.inc.tmpl').result(binding) + end + end + + ################################################################### + # minsns.inc + class MInsnsIncGenerator < SourceCodeGenerator + def generate + template('minsns.inc.tmpl').result(binding) + end + end + + ################################################################### + # optinsn.inc + class OptInsnIncGenerator < SourceCodeGenerator + def generate + optinsn_inc + end + + ### + private + + def val_as_type op + type = op[0][0] + val = op[1] + + case type + when /^long/, /^rb_num_t/, /^lindex_t/ + "INT2FIX(#{val})" + when /^VALUE/ + val + when /^ID/ + "INT2FIX(#{val})" + when /^ISEQ/, /^rb_insn_func_t/ + val + when /GENTRY/ + raise + when /^\.\.\./ + raise + else + raise "type: #{type}" + end + end + + # optinsn.inc + def optinsn_inc + opt_insns_map = Hash.new{[]} + + @insns.each{|insn| + next if insn.defopes.size == 0 + next if insn.type == :sc + next if /^UNIFIED/ =~ insn.name.to_s + + originsn = insn.orig + opt_insns_map[originsn] <<= insn + } + + opt_insns_map.each_value do |optinsns| + sorted = optinsns.sort_by {|opti| + opti.defopes.find_all{|e| e[1] == '*'}.size + } + optinsns.replace(sorted) + end + + template('optinsn.inc.tmpl').result(binding) + end + end + + ################################################################### + # optunifs.inc + class OptUnifsIncGenerator < SourceCodeGenerator + def generate + template('optunifs.inc.tmpl').result(binding) + end + end + + ################################################################### + # opt_sc.inc + class OptSCIncGenerator < SourceCodeGenerator + def generate + sc_insn_info = [] + @insns.each{|insn| + insns = insn.sc + if insns.size > 0 + insns = ['SC_ERROR'] + insns.map{|e| " BIN(#{e.name})"} + else + insns = Array.new(6){'SC_ERROR'} + end + sc_insn_info << " {\n#{insns.join(",\n")}}" + } + sc_insn_info = sc_insn_info.join(",\n") + + sc_insn_next = @insns.map{|insn| + " SCS_#{InstructionsLoader.complement_name(insn.nextsc).upcase}" + + (verbose? ? " /* #{insn.name} */" : '') + }.join(",\n") + template('opt_sc.inc.tmpl').result(binding) + end + end + + ################################################################### + # yasmdata.rb + class YASMDataRbGenerator < SourceCodeGenerator + def generate + insn_id2no = '' + @insns.each_with_index{|insn, i| + insn_id2no << " :#{insn.name} => #{i},\n" + } + template('yasmdata.rb').result(binding) + end + end + + ################################################################### + # yarvarch.* + class YARVDocGenerator < SourceCodeGenerator + def generate + + end + + def desc lang + d = '' + i = 0 + cat = nil + @insns.each{|insn| + seq = insn.opes.map{|t,v| v}.join(' ') + before = insn.pops.reverse.map{|t,v| v}.join(' ') + after = insn.rets.reverse.map{|t,v| v}.join(' ') + + if cat != insn.comm[:c] + d << "** #{insn.comm[:c]}\n\n" + cat = insn.comm[:c] + end + + d << "*** #{insn.name}\n" + d << "\n" + d << insn.comm[lang] << "\n\n" + d << ":instruction sequence: 0x%02x " % i << seq << "\n" + d << ":stack: #{before} => #{after}\n\n" + i+=1 + } + d + end + + def desc_ja + d = desc :j + template('yarvarch.ja').result(binding) + end + + def desc_en + d = desc :e + template('yarvarch.en').result(binding) + end + end + + class SourceCodeGenerator + Files = { # codes + 'vm.inc' => VmBodyGenerator, + 'vmtc.inc' => VmTCIncGenerator, + 'insns.inc' => InsnsIncGenerator, + 'insns_info.inc' => InsnsInfoIncGenerator, + # 'minsns.inc' => MInsnsIncGenerator, + 'optinsn.inc' => OptInsnIncGenerator, + 'optunifs.inc' => OptUnifsIncGenerator, + 'opt_sc.inc' => OptSCIncGenerator, + 'yasmdata.rb' => YASMDataRbGenerator, + } + + def generate args = [] + args = Files.keys if args.empty? + args.each{|fn| + s = Files[fn].new(@insns).generate + open(output_path(fn), 'w') {|f| f.puts(s)} + } + end + + def self.def_options(opt) + opts = { + :"insns.def" => 'insns.def', + :"opope.def" => 'defs/opt_operand.def', + :"unif.def" => 'defs/opt_insn_unif.def', + } + + opt.on("-Dname", /\AOPT_(\w+)\z/, "enable VM option") {|s, v| + opts[v] = true + } + opt.on("--enable=name[,name...]", Array, + "enable VM options (without OPT_ prefix)") {|*a| + a.each {|v| opts[v] = true} + } + opt.on("-Uname", /\AOPT_(\w+)\z/, "disable VM option") {|s, v| + opts[v] = false + } + opt.on("--disable=name[,name...]", Array, + "disable VM options (without OPT_ prefix)") {|*a| + a.each {|v| opts[v] = false} + } + opt.on("-i", "--insnsdef=FILE", "--instructions-def", + "instructions definition file") {|n| + opts[:insns_def] = n + } + opt.on("-o", "--opt-operanddef=FILE", "--opt-operand-def", + "vm option: operand definition file") {|n| + opts[:opope_def] = n + } + opt.on("-u", "--opt-insnunifdef=FILE", "--opt-insn-unif-def", + "vm option: instruction unification file") {|n| + opts[:unif_def] = n + } + opt.on("-C", "--[no-]use-const", + "use consts for default operands instead of macros") {|v| + opts[:use_const] = v + } + opt.on("-d", "--destdir", "--output-directory=DIR", + "make output file underneath DIR") {|v| + opts[:destdir] = v + } + opt.on("-V", "--[no-]verbose") {|v| + opts[:verbose] = v + } + + vpath = VPath.new + vpath.def_options(opt) + + proc { + opts[:VPATH] = vpath + build opts + } + end + + def self.build opts, vpath = ['./'] + opts[:VPATH] ||= VPath.new(*vpath) + self.new InstructionsLoader.new(opts) + end + end +end + diff --git a/tool/ruby_vm/controllers/application_controller.rb b/tool/ruby_vm/controllers/application_controller.rb deleted file mode 100644 index bb86873d25..0000000000 --- a/tool/ruby_vm/controllers/application_controller.rb +++ /dev/null @@ -1,24 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/dumper' -require_relative '../models/instructions' -require_relative '../models/typemap' -require_relative '../loaders/vm_opts_h' - -class ApplicationController - def generate i - path = Pathname.new i - dumper = RubyVM::Dumper.new i - return [path, dumper] - end -end diff --git a/tool/ruby_vm/helpers/c_escape.rb b/tool/ruby_vm/helpers/c_escape.rb deleted file mode 100644 index 088df1562e..0000000000 --- a/tool/ruby_vm/helpers/c_escape.rb +++ /dev/null @@ -1,120 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require 'securerandom' - -module RubyVM::CEscape - module_function - - # generate comment, with escaps. - def commentify str - return "/* #{str.strip.b.gsub '*/', '*\\/'} */" - end - - # Mimic gensym of CL. - def gensym prefix = 'gensym_' - return as_tr_cpp "#{prefix}#{SecureRandom.uuid}" - end - - # Mimic AS_TR_CPP() of autoconf. - def as_tr_cpp name - q = name.b - q.gsub! %r/[^a-zA-Z0-9_]/m, '_' - q.gsub! %r/_+/, '_' - return q - end - - # Section 6.10.4 of ISO/IEC 9899:1999 specifies that the file name used for - # #line directive shall be a "character string literal". So this is needed. - # - # I'm not sure how many chars are allowed here, though. The standard - # specifies 4095 chars at most, after string concatenation (section 5.2.4.1). - # But it is easy to have a path that is longer than that. - # - # Here we ignore the standard. Just create single string literal of any - # needed length. - def rstring2cstr str - # I believe this is the fastest implementation done in pure-ruby. - # Constants cached, gsub skips block evaluation, string literal optimized. - buf = str.b - buf.gsub! %r/./n, RString2CStr - return %'"#{buf}"' - end - - RString2CStr = { - "\x00"=> "\\0", "\x01"=> "\\x1", "\x02"=> "\\x2", "\x03"=> "\\x3", - "\x04"=> "\\x4", "\x05"=> "\\x5", "\x06"=> "\\x6", "\a"=> "\\a", - "\b"=> "\\b", "\t"=> "\\t", "\n"=> "\\n", "\v"=> "\\v", - "\f"=> "\\f", "\r"=> "\\r", "\x0E"=> "\\xe", "\x0F"=> "\\xf", - "\x10"=>"\\x10", "\x11"=>"\\x11", "\x12"=>"\\x12", "\x13"=>"\\x13", - "\x14"=>"\\x14", "\x15"=>"\\x15", "\x16"=>"\\x16", "\x17"=>"\\x17", - "\x18"=>"\\x18", "\x19"=>"\\x19", "\x1A"=>"\\x1a", "\e"=>"\\x1b", - "\x1C"=>"\\x1c", "\x1D"=>"\\x1d", "\x1E"=>"\\x1e", "\x1F"=>"\\x1f", - " "=> " ", "!"=> "!", "\""=> "\\\"", "#"=> "#", - "$"=> "$", "%"=> "%", "&"=> "&", "'"=> "\\'", - "("=> "(", ")"=> ")", "*"=> "*", "+"=> "+", - ","=> ",", "-"=> "-", "."=> ".", "/"=> "/", - "0"=> "0", "1"=> "1", "2"=> "2", "3"=> "3", - "4"=> "4", "5"=> "5", "6"=> "6", "7"=> "7", - "8"=> "8", "9"=> "9", ":"=> ":", ";"=> ";", - "<"=> "<", "="=> "=", ">"=> ">", "?"=> "?", - "@"=> "@", "A"=> "A", "B"=> "B", "C"=> "C", - "D"=> "D", "E"=> "E", "F"=> "F", "G"=> "G", - "H"=> "H", "I"=> "I", "J"=> "J", "K"=> "K", - "L"=> "L", "M"=> "M", "N"=> "N", "O"=> "O", - "P"=> "P", "Q"=> "Q", "R"=> "R", "S"=> "S", - "T"=> "T", "U"=> "U", "V"=> "V", "W"=> "W", - "X"=> "X", "Y"=> "Y", "Z"=> "Z", "["=> "[", - "\\"=> "\\\\", "]"=> "]", "^"=> "^", "_"=> "_", - "`"=> "`", "a"=> "a", "b"=> "b", "c"=> "c", - "d"=> "d", "e"=> "e", "f"=> "f", "g"=> "g", - "h"=> "h", "i"=> "i", "j"=> "j", "k"=> "k", - "l"=> "l", "m"=> "m", "n"=> "n", "o"=> "o", - "p"=> "p", "q"=> "q", "r"=> "r", "s"=> "s", - "t"=> "t", "u"=> "u", "v"=> "v", "w"=> "w", - "x"=> "x", "y"=> "y", "z"=> "z", "{"=> "{", - "|"=> "|", "}"=> "}", "~"=> "~", "\x7F"=>"\\x7f", - "\x80"=>"\\x80", "\x81"=>"\\x81", "\x82"=>"\\x82", "\x83"=>"\\x83", - "\x84"=>"\\x84", "\x85"=>"\\x85", "\x86"=>"\\x86", "\x87"=>"\\x87", - "\x88"=>"\\x88", "\x89"=>"\\x89", "\x8A"=>"\\x8a", "\x8B"=>"\\x8b", - "\x8C"=>"\\x8c", "\x8D"=>"\\x8d", "\x8E"=>"\\x8e", "\x8F"=>"\\x8f", - "\x90"=>"\\x90", "\x91"=>"\\x91", "\x92"=>"\\x92", "\x93"=>"\\x93", - "\x94"=>"\\x94", "\x95"=>"\\x95", "\x96"=>"\\x96", "\x97"=>"\\x97", - "\x98"=>"\\x98", "\x99"=>"\\x99", "\x9A"=>"\\x9a", "\x9B"=>"\\x9b", - "\x9C"=>"\\x9c", "\x9D"=>"\\x9d", "\x9E"=>"\\x9e", "\x9F"=>"\\x9f", - "\xA0"=>"\\xa0", "\xA1"=>"\\xa1", "\xA2"=>"\\xa2", "\xA3"=>"\\xa3", - "\xA4"=>"\\xa4", "\xA5"=>"\\xa5", "\xA6"=>"\\xa6", "\xA7"=>"\\xa7", - "\xA8"=>"\\xa8", "\xA9"=>"\\xa9", "\xAA"=>"\\xaa", "\xAB"=>"\\xab", - "\xAC"=>"\\xac", "\xAD"=>"\\xad", "\xAE"=>"\\xae", "\xAF"=>"\\xaf", - "\xB0"=>"\\xb0", "\xB1"=>"\\xb1", "\xB2"=>"\\xb2", "\xB3"=>"\\xb3", - "\xB4"=>"\\xb4", "\xB5"=>"\\xb5", "\xB6"=>"\\xb6", "\xB7"=>"\\xb7", - "\xB8"=>"\\xb8", "\xB9"=>"\\xb9", "\xBA"=>"\\xba", "\xBB"=>"\\xbb", - "\xBC"=>"\\xbc", "\xBD"=>"\\xbd", "\xBE"=>"\\xbe", "\xBF"=>"\\xbf", - "\xC0"=>"\\xc0", "\xC1"=>"\\xc1", "\xC2"=>"\\xc2", "\xC3"=>"\\xc3", - "\xC4"=>"\\xc4", "\xC5"=>"\\xc5", "\xC6"=>"\\xc6", "\xC7"=>"\\xc7", - "\xC8"=>"\\xc8", "\xC9"=>"\\xc9", "\xCA"=>"\\xca", "\xCB"=>"\\xcb", - "\xCC"=>"\\xcc", "\xCD"=>"\\xcd", "\xCE"=>"\\xce", "\xCF"=>"\\xcf", - "\xD0"=>"\\xd0", "\xD1"=>"\\xd1", "\xD2"=>"\\xd2", "\xD3"=>"\\xd3", - "\xD4"=>"\\xd4", "\xD5"=>"\\xd5", "\xD6"=>"\\xd6", "\xD7"=>"\\xd7", - "\xD8"=>"\\xd8", "\xD9"=>"\\xd9", "\xDA"=>"\\xda", "\xDB"=>"\\xdb", - "\xDC"=>"\\xdc", "\xDD"=>"\\xdd", "\xDE"=>"\\xde", "\xDF"=>"\\xdf", - "\xE0"=>"\\xe0", "\xE1"=>"\\xe1", "\xE2"=>"\\xe2", "\xE3"=>"\\xe3", - "\xE4"=>"\\xe4", "\xE5"=>"\\xe5", "\xE6"=>"\\xe6", "\xE7"=>"\\xe7", - "\xE8"=>"\\xe8", "\xE9"=>"\\xe9", "\xEA"=>"\\xea", "\xEB"=>"\\xeb", - "\xEC"=>"\\xec", "\xED"=>"\\xed", "\xEE"=>"\\xee", "\xEF"=>"\\xef", - "\xF0"=>"\\xf0", "\xF1"=>"\\xf1", "\xF2"=>"\\xf2", "\xF3"=>"\\xf3", - "\xF4"=>"\\xf4", "\xF5"=>"\\xf5", "\xF6"=>"\\xf6", "\xF7"=>"\\xf7", - "\xF8"=>"\\xf8", "\xF9"=>"\\xf9", "\xFA"=>"\\xfa", "\xFB"=>"\\xfb", - "\xFC"=>"\\xfc", "\xFD"=>"\\xfd", "\xFE"=>"\\xfe", "\xFF"=>"\\xff", - }.freeze - private_constant :RString2CStr -end diff --git a/tool/ruby_vm/helpers/dumper.rb b/tool/ruby_vm/helpers/dumper.rb deleted file mode 100644 index 8f14d90d1f..0000000000 --- a/tool/ruby_vm/helpers/dumper.rb +++ /dev/null @@ -1,108 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require 'pathname' -require 'erb' -require_relative 'c_escape' - -class RubyVM::Dumper - include RubyVM::CEscape - - # 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 - end - } - - def initialize path - @erb = {} - @empty = new_binding - dst = Pathname.new Dir.getwd - dst += path - @file = cstr dst.realdirpath.to_path - end - - def render partial, locals: {} - return do_render "_#{partial}.erb", locals - end - - def generate template - str = do_render "#{template}.erb", {} - return replace_pragma str - end - - private - - # view helpers - - alias cstr rstring2cstr - alias comm commentify - - def render_c_expr expr - render 'c_expr', locals: { expr: expr, } - end -end diff --git a/tool/ruby_vm/helpers/scanner.rb b/tool/ruby_vm/helpers/scanner.rb deleted file mode 100644 index 3dce6ffdfe..0000000000 --- a/tool/ruby_vm/helpers/scanner.rb +++ /dev/null @@ -1,49 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require 'pathname' -require 'strscan' - -class RubyVM::Scanner - attr_reader :__FILE__ - attr_reader :__LINE__ - - def initialize path - src = Pathname.new __dir__ - src += path - @__LINE__ = 1 - @__FILE__ = src.realpath.to_path - str = src.read mode: 'rt:utf-8:utf-8' - @scanner = StringScanner.new str - end - - def eos? - @scanner.eos? - end - - def scan re - ret = @__LINE__ - match = @scanner.scan re - return unless match - @__LINE__ += match.count "\n" - return ret - end - - def scan! re - scan re or raise sprintf "parse error at %s:%d near:\n %s...", \ - @__FILE__, @__LINE__, @scanner.peek(32) - end - - def [] key - return @scanner[key] - end -end diff --git a/tool/ruby_vm/loaders/insns_def.rb b/tool/ruby_vm/loaders/insns_def.rb deleted file mode 100644 index 58748c3ca6..0000000000 --- a/tool/ruby_vm/loaders/insns_def.rb +++ /dev/null @@ -1,92 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/scanner' - -json = [] -scanner = RubyVM::Scanner.new '../../../insns.def' -path = scanner.__FILE__ -grammar = %r' - (?<comment> /[*] [^*]* [*]+ (?: [^*/] [^*]* [*]+ )* / ){0} - (?<keyword> typedef | extern | static | auto | register | - struct | union | enum ){0} - (?<C> (?: \g<block> | [^{}]+ )* ){0} - (?<block> \{ \g<ws>* ^ \g<C> $ \g<ws>* \} ){0} - (?<ws> \g<comment> | \s ){0} - (?<ident> [_a-zA-Z] [0-9_a-zA-Z]* ){0} - (?<type> (?: \g<keyword> \g<ws>+ )* \g<ident> ){0} - (?<arg> \g<type> \g<ws>+ \g<ident> | \.\.\. ){0} - (?<argv> (?# empty ) | - void | - \g<arg> (?: \g<ws>* , \g<ws>* \g<arg> \g<ws>* )* ){0} - (?<pragma> \g<ws>* // \s* attr \g<ws>+ - (?<pragma:type> \g<type> ) \g<ws>+ - (?<pragma:name> \g<ident> ) \g<ws>* - = \g<ws>* - (?<pragma:expr> .+?; ) \g<ws>* ){0} - (?<insn> DEFINE_INSN \g<ws>+ - (?<insn:name> \g<ident> ) \g<ws>* - [(] \g<ws>* (?<insn:opes> \g<argv> ) \g<ws>* [)] \g<ws>* - [(] \g<ws>* (?<insn:pops> \g<argv> ) \g<ws>* [)] \g<ws>* - [(] \g<ws>* (?<insn:rets> \g<argv> ) \g<ws>* [)] \g<ws>* ){0} -'x - -until scanner.eos? do - next if scanner.scan(/#{grammar}\g<ws>+/o) - split = -> (v) { - case v when /\Avoid\z/ then - [] - else - v.split(/, */) - end - } - - l1 = scanner.scan!(/#{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 - attrs << { - location: [path, l2], - name: scanner["pragma:name"], - type: scanner["pragma:type"], - expr: scanner["pragma:expr"], - } - end - - l3 = scanner.scan!(/#{grammar}\g<block>/o) - json << { - name: name, - location: [path, l1], - signature: { - name: name, - ope: ope, - pop: pop, - ret: ret, - }, - attributes: attrs, - expr: { - location: [path, l3], - expr: scanner["block"], - }, - } -end - -RubyVM::InsnsDef = json - -if __FILE__ == $0 then - require 'json' - JSON.dump RubyVM::InsnsDef, STDOUT -end diff --git a/tool/ruby_vm/loaders/opt_insn_unif_def.rb b/tool/ruby_vm/loaders/opt_insn_unif_def.rb deleted file mode 100644 index a5af409e71..0000000000 --- a/tool/ruby_vm/loaders/opt_insn_unif_def.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/scanner' - -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) - - pos = scanner.scan!(/(?<series> (?: [\ \t]* \w+ )+ ) \n /mx) - json << { - location: [path, pos], - signature: scanner["series"].strip.split - } -end - -RubyVM::OptInsnUnifDef = json - -if __FILE__ == $0 then - require 'json' - JSON.dump RubyVM::OptInsnUnifDef, STDOUT -end diff --git a/tool/ruby_vm/loaders/opt_operand_def.rb b/tool/ruby_vm/loaders/opt_operand_def.rb deleted file mode 100644 index 5c94b4bced..0000000000 --- a/tool/ruby_vm/loaders/opt_operand_def.rb +++ /dev/null @@ -1,57 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/scanner' - -json = [] -scanner = RubyVM::Scanner.new '../../../defs/opt_operand.def' -path = scanner.__FILE__ -grammar = %r/ - (?<comment> \# .+? \n ){0} - (?<ws> \g<comment> | \s ){0} - (?<insn> \w+ ){0} - (?<paren> \( (?: \g<paren> | [^()]+)* \) ){0} - (?<expr> (?: \g<paren> | [^(),\ \n] )+ ){0} - (?<remain> \g<expr> ){0} - (?<arg> \g<expr> ){0} - (?<extra> , \g<ws>* \g<remain> ){0} - (?<args> \g<arg> \g<extra>* ){0} - (?<decl> \g<insn> \g<ws>+ \g<args> \n ){0} -/mx - -until scanner.eos? do - break if scanner.scan(/ ^ __END__ $ /x) - next if scanner.scan(/#{grammar} \g<ws>+ /ox) - - line = scanner.scan!(/#{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"] - break unless args - end - json << { - location: [path, line], - signature: [insn, ary] - } -end - -RubyVM::OptOperandDef = json - -if __FILE__ == $0 then - require 'json' - JSON.dump RubyVM::OptOperandDef, STDOUT -end diff --git a/tool/ruby_vm/loaders/vm_opts_h.rb b/tool/ruby_vm/loaders/vm_opts_h.rb deleted file mode 100644 index f898fb36a4..0000000000 --- a/tool/ruby_vm/loaders/vm_opts_h.rb +++ /dev/null @@ -1,37 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/scanner' - -json = {} -scanner = RubyVM::Scanner.new '../../../vm_opts.h' -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 ) -/mx - -until scanner.eos? do - if scanner.scan grammar then - json[scanner['key']] = ! scanner['value'].to_i.zero? # not nonzero? - else - scanner.scan(/.*\n/) - end -end - -RubyVM::VmOptsH = json - -if __FILE__ == $0 then - require 'json' - JSON.dump RubyVM::VmOptsH, STDOUT -end diff --git a/tool/ruby_vm/models/attribute.rb b/tool/ruby_vm/models/attribute.rb deleted file mode 100644 index 0b6d6e09b2..0000000000 --- a/tool/ruby_vm/models/attribute.rb +++ /dev/null @@ -1,44 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative 'c_expr' - -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 - end - - def name - as_tr_cpp "attr #{@key} @ #{@insn.name}" - end - - def pretty_name - "attr #{type} #{key} @ #{insn.pretty_name}" - end - - def declaration - argv = @insn.opes.map {|o| o[:decl] }.join(', ') - sprintf '%s %s(%s)', @type, name, argv - end - - def definition - argv = @insn.opes.map {|o| "MAYBE_UNUSED(#{o[:decl]})" }.join(",\n ") - argv = "\n #{argv}\n" if @insn.opes.size > 1 - sprintf "%s\n%s(%s)", @type, name, argv - end -end diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb deleted file mode 100644 index c3a96b8f08..0000000000 --- a/tool/ruby_vm/models/bare_instructions.rb +++ /dev/null @@ -1,162 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../loaders/insns_def' -require_relative 'c_expr' -require_relative 'typemap' -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 - @opes = typesplit @sig[:ope] - @pops = typesplit @sig[:pop].reject {|i| i == '...' } - @rets = typesplit @sig[:ret].reject {|i| i == '...' } - @attrs = attributes.map {|i| - RubyVM::Attribute.new insn: self, **i - }.each_with_object({}) {|a, h| - h[a.key] = a - } - @attrs_orig = @attrs.dup - end - - def pretty_name - n = @sig[:name] - o = @sig[:ope].map{|i| i[/\S+$/] }.join ', ' - p = @sig[:pop].map{|i| i[/\S+$/] }.join ', ' - r = @sig[:ret].map{|i| i[/\S+$/] }.join ', ' - return sprintf "%s(%s)(%s)(%s)", n, o, p, r - end - - def bin - return "BIN(#{name})" - end - - def call_attribute name - return sprintf 'CALL_ATTRIBUTE(%s)', [ - name, @name, @opes.map {|i| i[:name] } - ].flatten.compact.join(', ') - end - - def sp_inc - return @attrs.fetch "sp_inc" do |k| - return generate_attribute k, 'rb_snum_t', rets.size - pops.size - end - end - - def has_attribute? k - @attrs_orig.has_key? k - end - - def attributes - # need to generate predefined attribute defaults - sp_inc - # other_attribute - # ... - return @attrs.values - end - - def width - return 1 + opes.size - end - - def declarations - return @variables \ - . values \ - . group_by {|h| h[:type] } \ - . map {|t, v| [t, v.map {|i| i[:name] }.sort ] } \ - . map {|t, v| sprintf("%s %s", t, v.join(', ')) } \ - . sort - end - - def preamble - # preamble makes sense for operand unifications - return [] - end - - def sc? - # sc stands for stack caching. - return false - end - - def cast_to_VALUE var, expr = var[:name] - RubyVM::Typemap.typecast_to_VALUE var[:type], expr - end - - def cast_from_VALUE var, expr = var[:name] - RubyVM::Typemap.typecast_from_VALUE var[:type], expr - end - - def operands_info - opes.map {|o| - c, _ = RubyVM::Typemap.fetch o[:type] - next c - }.join - end - - def pushs_frame? - opes.any? {|o| /CALL_INFO/ =~ o[:type] } - end - - def inspect - sprintf "#<%s@%s:%d>", @name, @loc[0], @loc[1] - end - - private - - def generate_attribute k, t, v - attr = RubyVM::Attribute.new \ - insn: self, \ - name: k, \ - type: t, \ - location: [], \ - expr: v.to_s + ';' - return @attrs[k] = attr - end - - def typesplit a - @variables ||= {} - a.map do |decl| - md = %r' - (?<comment> /[*] [^*]* [*]+ (?: [^*/] [^*]* [*]+ )* / ){0} - (?<ws> \g<comment> | \s ){0} - (?<ident> [_a-zA-Z] [0-9_a-zA-Z]* ){0} - (?<type> (?: \g<ident> \g<ws>+ )* \g<ident> ){0} - (?<var> \g<ident> ){0} - \G \g<ws>* \g<type> \g<ws>+ \g<var> - 'x.match(decl) - @variables[md['var']] ||= { - decl: decl, - type: md['type'], - name: md['var'], - } - end - end - - @instances = RubyVM::InsnsDef.map {|h| new template: h, **h } - - def self.fetch name - @instances.find do |insn| - insn.name == name - end or raise IndexError, "instruction not found: #{name}" - end - - def self.to_a - @instances - end -end diff --git a/tool/ruby_vm/models/c_expr.rb b/tool/ruby_vm/models/c_expr.rb deleted file mode 100644 index b19dd8bb48..0000000000 --- a/tool/ruby_vm/models/c_expr.rb +++ /dev/null @@ -1,41 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/c_escape.rb' - -class RubyVM::CExpr - include RubyVM::CEscape - - attr_reader :__FILE__, :__LINE__, :expr - - def initialize location:, expr: - @__FILE__ = location[0] - @__LINE__ = location[1] - @expr = expr - end - - # blank, in sense of C program. - RE = %r'\A{\g<s>*}\z|\A(?<s>\s|/[*][^*]*[*]+([^*/][^*]*[*]+)*/)*\z' - if RUBY_VERSION > '2.4' then - def blank? - RE.match? @expr - end - else - def blank? - RE =~ @expr - end - end - - def inspect - sprintf "#<%s:%d %s>", @__FILE__, @__LINE__, @expr - end -end diff --git a/tool/ruby_vm/models/instructions.rb b/tool/ruby_vm/models/instructions.rb deleted file mode 100644 index 5a04190a19..0000000000 --- a/tool/ruby_vm/models/instructions.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative 'bare_instructions' -require_relative 'operands_unifications' -require_relative 'instructions_unifications' - -RubyVM::Instructions = RubyVM::BareInstructions.to_a + \ - RubyVM::OperandsUnifications.to_a + \ - RubyVM::InstructionsUnifications.to_a - -require_relative 'trace_instructions' -RubyVM::Instructions.freeze diff --git a/tool/ruby_vm/models/instructions_unifications.rb b/tool/ruby_vm/models/instructions_unifications.rb deleted file mode 100644 index 346cebd709..0000000000 --- a/tool/ruby_vm/models/instructions_unifications.rb +++ /dev/null @@ -1,43 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/c_escape' -require_relative '../loaders/opt_insn_unif_def' -require_relative 'bare_instructions' - -class RubyVM::InstructionsUnifications - include RubyVM::CEscape - - attr_reader :name - - def initialize location:, signature: - @location = location - @name = namegen signature - @series = signature.map do |i| - RubyVM::BareInstructions.fetch i # Misshit is fatal - end - end - - private - - def namegen signature - as_tr_cpp ['UNIFIED', *signature].join('_') - end - - @instances = RubyVM::OptInsnUnifDef.map do |h| - new(**h) - end - - def self.to_a - @instances - end -end diff --git a/tool/ruby_vm/models/operands_unifications.rb b/tool/ruby_vm/models/operands_unifications.rb deleted file mode 100644 index c0ae0ece45..0000000000 --- a/tool/ruby_vm/models/operands_unifications.rb +++ /dev/null @@ -1,137 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/c_escape' -require_relative '../loaders/opt_operand_def' -require_relative 'bare_instructions' - -class RubyVM::OperandsUnifications < RubyVM::BareInstructions - include RubyVM::CEscape - - attr_reader :preamble, :original, :spec - - def initialize location:, signature: - name = signature[0] - @original = RubyVM::BareInstructions.fetch name - template = @original.template - parts = compose location, signature, template[:signature] - json = template.dup - json[:location] = location - json[:signature] = parts[:signature] - json[:name] = parts[:name] - @preamble = parts[:preamble] - @spec = parts[:spec] - super template: template, **json - parts[:vars].each do |v| - @variables[v[:name]] ||= v - end - end - - def operand_shift_of var - before = @original.opes.find_index var - after = @opes.find_index var - raise "no #{var} for #{@name}" unless before and after - return before - after - end - - def condition ptr - # :FIXME: I'm not sure if this method should be in model? - exprs = @spec.each_with_index.map do |(var, val), i| - case val when '*' then - next nil - else - type = @original.opes[i][:type] - expr = RubyVM::Typemap.typecast_to_VALUE type, val - next "#{ptr}[#{i}] == #{expr}" - end - end - exprs.compact! - if exprs.size == 1 then - return exprs[0] - else - exprs.map! {|i| "(#{i})" } - return exprs.join ' && ' - end - end - - private - - def namegen signature - insn, argv = *signature - wcary = argv.map do |i| - case i when '*' then - 'WC' - else - i - end - end - as_tr_cpp [insn, *wcary].join(', ') - end - - def compose location, spec, template - name = namegen spec - *, argv = *spec - opes = @original.opes - if opes.size != argv.size - raise sprintf("operand size mismatch for %s (%s's: %d, given: %d)", - name, template[:name], opes.size, argv.size) - else - src = [] - mod = [] - spec = [] - vars = [] - argv.each_index do |i| - j = argv[i] - k = opes[i] - spec[i] = [k, j] - case j when '*' then - # operand is from iseq - mod << k[:decl] - else - # operand is inside C - vars << k - src << { - location: location, - expr: " #{k[:name]} = #{j};" - } - end - end - src.map! {|i| RubyVM::CExpr.new i } - return { - name: name, - signature: { - name: name, - ope: mod, - pop: template[:pop], - ret: template[:ret], - }, - preamble: src, - vars: vars, - spec: spec - } - end - end - - @instances = RubyVM::OptOperandDef.map do |h| - new(**h) - end - - def self.to_a - @instances - end - - def self.each_group - to_a.group_by(&:original).each_pair do |k, v| - yield k, v - end - end -end diff --git a/tool/ruby_vm/models/trace_instructions.rb b/tool/ruby_vm/models/trace_instructions.rb deleted file mode 100644 index a99a933ac7..0000000000 --- a/tool/ruby_vm/models/trace_instructions.rb +++ /dev/null @@ -1,71 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/c_escape' -require_relative 'bare_instructions' - -class RubyVM::TraceInstructions - include RubyVM::CEscape - - attr_reader :name - - def initialize orig: - @orig = orig - @name = as_tr_cpp "trace @ #{@orig.name}" - end - - def pretty_name - return sprintf "%s(...)(...)(...)", @name - end - - def jump_destination - return @orig.name - end - - def bin - return sprintf "BIN(%s)", @name - end - - def width - return @orig.width - end - - def operands_info - return @orig.operands_info - end - - def rets - return ['...'] - end - - def pops - return ['...'] - end - - def attributes - return [] - end - - def has_attribute? *; - return false - end - - private - - @instances = RubyVM::Instructions.map {|i| new orig: i } - - def self.to_a - @instances - end - - RubyVM::Instructions.push(*to_a) -end diff --git a/tool/ruby_vm/models/typemap.rb b/tool/ruby_vm/models/typemap.rb deleted file mode 100644 index d818ce9878..0000000000 --- a/tool/ruby_vm/models/typemap.rb +++ /dev/null @@ -1,61 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -RubyVM::Typemap = { - "..." => %w[. TS_VARIABLE], - "CALL_CACHE" => %w[E TS_CALLCACHE], - "CALL_INFO" => %w[C TS_CALLINFO], - "CDHASH" => %w[H TS_CDHASH], - "GENTRY" => %w[G TS_GENTRY], - "IC" => %w[K TS_IC], - "ID" => %w[I TS_ID], - "ISEQ" => %w[S TS_ISEQ], - "OFFSET" => %w[O TS_OFFSET], - "VALUE" => %w[V TS_VALUE], - "lindex_t" => %w[L TS_LINDEX], - "rb_insn_func_t" => %w[F TS_FUNCPTR], - "rb_num_t" => %w[N TS_NUM], -} - -# :FIXME: should this method be here? -class << RubyVM::Typemap - def typecast_from_VALUE type, val - # see also iseq_set_sequence() - case type - when '...' - raise "cast not possible: #{val}" - when 'VALUE' then - return val - when 'rb_num_t', 'lindex_t' then - return "NUM2LONG(#{val})" - when 'ID' then - return "SYM2ID(#{val})" - else - return "(#{type})(#{val})" - end - end - - def typecast_to_VALUE type, val - case type - when 'VALUE' then - return val - when 'ISEQ', 'rb_insn_func_t' then - return "(VALUE)(#{val})" - when 'rb_num_t', 'lindex_t' - "LONG2NUM(#{val})" - when 'ID' then - return "ID2SYM(#{val})" - else - raise ":FIXME: TBW for #{type}" - end - end -end diff --git a/tool/ruby_vm/scripts/converter.rb b/tool/ruby_vm/scripts/converter.rb deleted file mode 100644 index 4e7c28d67b..0000000000 --- a/tool/ruby_vm/scripts/converter.rb +++ /dev/null @@ -1,29 +0,0 @@ -# This script was needed only once when I converted the old insns.def. -# Consider historical. -# -# ruby converter.rb insns.def | sponge insns.def - -BEGIN { $str = ARGF.read } -END { puts $str } - -# deal with spaces -$str.gsub! %r/\r\n|\r|\n|\z/, "\n" -$str.gsub! %r/([^\t\n]*)\t/ do - x = $1 - y = 8 - x.length % 8 - next x + ' ' * y -end -$str.gsub! %r/\s+$/, "\n" - -# deal with comments -$str.gsub! %r/@c.*?@e/m, '' -$str.gsub! %r/@j.*?\*\//m, '*/' -$str.gsub! %r/\n(\s*\n)+/, "\n\n" -$str.gsub! %r/\/\*\*?\s*\n\s*/, "/* " -$str.gsub! %r/\n\s+\*\//, " */" -$str.gsub! %r/^(?!.*\/\*.+\*\/$)(.+?)\s*\*\//, "\\1\n */" - -# deal with sp_inc -$str.gsub! %r/ \/\/ inc -= (.*)/, ' // inc += -\\1' -$str.gsub! %r/\s+\/\/ inc \+= (.*)/, "\n// attr rb_snum_t sp_inc = \\1;" -$str.gsub! %r/;;$/, ";" diff --git a/tool/ruby_vm/scripts/insns2vm.rb b/tool/ruby_vm/scripts/insns2vm.rb deleted file mode 100644 index 1083e42b8e..0000000000 --- a/tool/ruby_vm/scripts/insns2vm.rb +++ /dev/null @@ -1,88 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require 'optparse' -require_relative '../controllers/application_controller.rb' - -def router argv - targets = generate_parser.parse argv - return targets.map do |i| - next ApplicationController.new.generate i - end -end - -def generate_parser - OptionParser.new do |this| - this.on "-I", "--srcdir=DIR", <<'end' - Historically this option has been passed to the script. This is - supposedly because at the beginning the script was placed outside - of the ruby source tree. Decades passed since the merge of - YARV, now I can safely assume this feature is obsolescent. Just - ignore the passed value here. -end - - this.on "-L", "--vpath=SPEC", <<'end' - Likewise, this option is no longer supported. -end - - this.on "--path-separator=SEP", /\A(?:\W\z|\.(\W).+)/, <<'end' - Old script says this option is a "separator for vpath". I am - confident we no longer need this option. -end - - this.on "-Dname", "--enable=name[,name...]", Array, <<'end' - This option used to override VM option that is defined in - vm_opts.h. Now it is officially unsupported because vm_opts.h to - remain mismatched with this option must break things. Just edit - vm_opts.h directly. -end - - this.on "-Uname", "--disable=name[,name...]", Array, <<'end' - This option used to override VM option that is defined in - vm_opts.h. Now it is officially unsupported because vm_opts.h to - remain mismatched with this option must break things. Just edit - vm_opts.h directly. -end - - this.on "-i", "--insnsdef=FILE", "--instructions-def", <<'end' - This option used to specify alternative path to insns.def. For - the same reason to ignore -I, we no longer support this. -end - - this.on "-o", "--opt-operanddef=FILE", "--opt-operand-def", <<'end' - This option used to specify alternative path to opt_operand.def. - For the same reason to ignore -I, we no longer support this. -end - - this.on "-u", "--opt-insnunifdef=FILE", "--opt-insn-unif-def", <<'end' - This option used to specify alternative path to - opt_insn_unif.def. For the same reason to ignore -I, we no - longer support this. -end - - this.on "-C", "--[no-]use-const", <<'end' - We use const whenever possible now so this option is ignored. - The author believes that C compilers can constant-fold. -end - - this.on "-d", "--destdir", "--output-directory=DIR", <<'begin' do |dir| - THIS IS THE ONLY OPTION THAT WORKS today. Change destination - directory from the current working directory to the given path. -begin - Dir.chdir dir - end - - this.on "-V", "--[no-]verbose", <<'end' - Please let us ignore this and be modest. -end - end -end diff --git a/tool/ruby_vm/tests/.gitkeep b/tool/ruby_vm/tests/.gitkeep deleted file mode 100644 index 8b13789179..0000000000 --- a/tool/ruby_vm/tests/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tool/ruby_vm/views/_attributes.erb b/tool/ruby_vm/views/_attributes.erb deleted file mode 100644 index 258bf02906..0000000000 --- a/tool/ruby_vm/views/_attributes.erb +++ /dev/null @@ -1,34 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# -typedef long OFFSET; -typedef unsigned long lindex_t; -typedef VALUE GENTRY; -typedef rb_iseq_t *ISEQ; - -#define CALL_ATTRIBUTE(name, insn, ...) attr_ ## name ## _ ## insn(__VA_ARGS__) - -% attrs = RubyVM::Instructions.map(&:attributes).flatten -% -% attrs.each do |a| -PUREFUNC(MAYBE_UNUSED(static <%= a.declaration %>)); -% end -% -% attrs.each do |a| - -/* <%= a.pretty_name %> */ -<%= a.definition %> -{ -% str = render_c_expr a.expr -% case str when /\A#/ then - return -<%= str -%> -% else - return <%= str -%> -% end -} -% end diff --git a/tool/ruby_vm/views/_c_expr.erb b/tool/ruby_vm/views/_c_expr.erb deleted file mode 100644 index cebe4d7a5d..0000000000 --- a/tool/ruby_vm/views/_c_expr.erb +++ /dev/null @@ -1,17 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -% if expr.blank? -% # empty -% elsif ! expr.__LINE__ -<%= expr.expr %> -% else -#line <%= expr.__LINE__ %> <%=cstr expr.__FILE__ %> -<%= expr.expr %> -#pragma RubyVM reset source -% end diff --git a/tool/ruby_vm/views/_copyright.erb b/tool/ruby_vm/views/_copyright.erb deleted file mode 100644 index a449b0b735..0000000000 --- a/tool/ruby_vm/views/_copyright.erb +++ /dev/null @@ -1,31 +0,0 @@ -%# -*- mode: c; style: ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%; -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -%; -%# Below is the licensing term for the generated output, not this erb file. -/* This is an auto-generated file and is a part of the programming language - * Ruby. The person who created a program to generate this file (``I'' - * hereafter) would like to refrain from defining licensing of this generated - * source code. - * - * This file consist of many small parts of codes copyrighted by each authors, - * not only the ``I'' person. Those original authors agree with some - * open-source license. I believe that the license we agree is the condition - * mentioned in the file COPYING. It states "4. You may modify and include - * the part of the software into any other software ...". But the problem is, - * the license never makes it clear if such modified parts still remain in the - * same license, or not. The fact that we agree with the source code's - * licensing terms do not automatically define that of generated ones. This is - * the reason why this file is under unclear situation. All that I know is - * that above provision guarantees this file to exist. - * - * Please let me hesitate to declare something about this nuanced contract. I - * am not in the position to take over other authors' license to merge into my - * one. Changing them to (say) GPLv3 is not doable by myself. Perhaps someday - * it might turn out to be okay to say this file is under a license. I wish the - * situation would become more clear in the future. */ diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb deleted file mode 100644 index cebca8b8d0..0000000000 --- a/tool/ruby_vm/views/_insn_entry.erb +++ /dev/null @@ -1,50 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; - -/* insn <%= insn.pretty_name %> */ -#define NAME_OF_CURRENT_INSN <%= insn.name %> -INSN_ENTRY(<%= insn.name %>) -{ -% unless insn.declarations.empty? - <%= insn.declarations.join(";\n ") %>; - -% end - START_OF_ORIGINAL_INSN(<%= insn.name %>); -% insn.preamble.each do |konst| -<%= render_c_expr konst -%> -% end -% -% insn.opes.each_with_index do |ope, i| - <%= ope[:name] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>); -% end -% -% insn.pops.reverse_each.with_index.reverse_each do |pop, i| - <%= pop[:name] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>; -% end - DEBUG_ENTER_INSN(<%=cstr insn.name %>); - ADD_PC(<%= insn.width %>); - PREFETCH(GET_PC()); -% unless insn.pops.empty? - POPN(<%= insn.pops.size %>); -% end - COLLECT_USAGE_INSN(<%= insn.bin %>); -% insn.opes.each_with_index do |ope, i| - COLLECT_USAGE_OPERAND(<%= insn.bin %>, <%= i %>, <%= ope[:name] %>); -% end -<%= render_c_expr insn.expr -%> -% unless insn.rets.empty? - CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, <%= insn.rets.size %>); -% insn.rets.each_with_index do |ret, i| - PUSH(<%= insn.cast_to_VALUE ret %>); -% end -% end -% - END_INSN(<%= insn.name %>); -} -#undef NAME_OF_CURRENT_INSN diff --git a/tool/ruby_vm/views/_insn_len_info.erb b/tool/ruby_vm/views/_insn_len_info.erb deleted file mode 100644 index abbdb2e92c..0000000000 --- a/tool/ruby_vm/views/_insn_len_info.erb +++ /dev/null @@ -1,23 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -CONSTFUNC(MAYBE_UNUSED(static int insn_len(VALUE insn))); -extern const char rb_vm_insn_len_info[]; - -#ifdef RUBY_VM_INSNS_INFO -const char rb_vm_insn_len_info[] = { -% RubyVM::Instructions.each_slice 25 do |a| - <%= a.map(&:width).join(', ') -%>, -% end -}; -#endif - -int -insn_len(VALUE i) -{ - return rb_vm_insn_len_info[i]; -} diff --git a/tool/ruby_vm/views/_insn_name_info.erb b/tool/ruby_vm/views/_insn_name_info.erb deleted file mode 100644 index 79a48cd9cb..0000000000 --- a/tool/ruby_vm/views/_insn_name_info.erb +++ /dev/null @@ -1,47 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% -% a = RubyVM::Instructions.map {|i| i.name } -% b = (0...a.size) -% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) } -% c.pop -% -CONSTFUNC(MAYBE_UNUSED(static const char *insn_name(VALUE insn))); -extern const char *rb_vm_insn_name_info; -extern const unsigned short rb_vm_insn_name_offset[]; - -#ifdef RUBY_VM_INSNS_INFO -const unsigned short rb_vm_insn_name_offset[] = { -% c.each_slice 12 do |d| - <%= d.map {|i| sprintf("%4d", i) }.join(', ') %>, -% end -}; -ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_name_offset); - -PACKED_STRUCT(struct rb_vm_insn_name_info_tag { -% b.each_slice 3 do |d| - <%= d.map {|i| - sprintf("const char L%03d[%2d]", i, a[i].length + 1) - }.join('; ') %>; -% end -}); - -static const struct rb_vm_insn_name_info_tag rb_vm_insn_name_base = { -% a.each_slice 2 do |d| - <%= d.map {|i| sprintf("%-30s", cstr(i)) }.join(', ') %>, -% end -}; - -const char *rb_vm_insn_name_info = (const char *)&rb_vm_insn_name_base; -#endif - -const char * -insn_name(VALUE i) -{ - return &rb_vm_insn_name_info[rb_vm_insn_name_offset[i]]; -} diff --git a/tool/ruby_vm/views/_insn_operand_info.erb b/tool/ruby_vm/views/_insn_operand_info.erb deleted file mode 100644 index f6b6565d59..0000000000 --- a/tool/ruby_vm/views/_insn_operand_info.erb +++ /dev/null @@ -1,59 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% -% a = RubyVM::Instructions.map {|i| i.operands_info } -% b = (0...a.size) -% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) } -% c.pop -% -CONSTFUNC(MAYBE_UNUSED(static const char *insn_op_types(VALUE insn))); -CONSTFUNC(MAYBE_UNUSED(static int insn_op_type(VALUE insn, long pos))); -extern const char *rb_vm_insn_op_info; -extern const unsigned short rb_vm_insn_op_offset[]; - -#ifdef RUBY_VM_INSNS_INFO -const unsigned short rb_vm_insn_op_offset[] = { -% c.each_slice 14 do |d| - <%= d.map {|i| sprintf("%3d", i) }.join(', ') %>, -% end -}; -ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_op_offset); - -PACKED_STRUCT(struct rb_vm_insn_op_info_tag { -% b.each_slice 3 do |d| - <%= d.map {|i| - sprintf("const char L%03d[%2d]", i, a[i].length + 1) - }.join('; ') %>; -% end -}); - -static const struct rb_vm_insn_op_info_tag rb_vm_insn_op_base = { -% a.each_slice 8 do |d| - <%= d.map {|i| sprintf("%-6s", cstr(i)) }.join(', ') %>, -% end -}; - -const char *rb_vm_insn_op_info = (const char *)&rb_vm_insn_op_base; -#endif - -const char * -insn_op_types(VALUE i) -{ - return &rb_vm_insn_op_info[rb_vm_insn_op_offset[i]]; -} - -int -insn_op_type(VALUE i, long j) -{ - if (j >= insn_len(i)) { - return 0; - } - else { - return insn_op_types(i)[j]; - } -} diff --git a/tool/ruby_vm/views/_insn_stack_increase.erb b/tool/ruby_vm/views/_insn_stack_increase.erb deleted file mode 100644 index bfe0a3dc6b..0000000000 --- a/tool/ruby_vm/views/_insn_stack_increase.erb +++ /dev/null @@ -1,53 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%# -PUREFUNC(MAYBE_UNUSED(static int insn_stack_increase(int depth, int insn, const VALUE *opes))); -PUREFUNC(static rb_snum_t insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes)); - -rb_snum_t -insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes) -{ - static const signed char t[] = { -% RubyVM::Instructions.each_slice 8 do |a| - <%= a.map { |i| - if i.has_attribute?('sp_inc') - '-127' - else - sprintf("%4d", i.rets.size - i.pops.size) - end - }.join(', ') -%>, -% end - }; - signed char c = t[insn]; - - ASSERT_VM_INSTRUCTION_SIZE(t); - if (c != -127) { - return c; - } - else switch(insn) { - default: - UNREACHABLE; -% RubyVM::Instructions.each do |i| -% next unless i.has_attribute?('sp_inc') - case <%= i.bin %>: - return CALL_ATTRIBUTE(sp_inc, <%= i.name %><%= - i.opes.map.with_index do |v, j| - k = i.cast_from_VALUE v, "opes[#{j}]" - next ", #{k}" - end.join - %>); -% end - } -} - -int -insn_stack_increase(int depth, int insn, const VALUE *opes) -{ - enum ruby_vminsn_type itype = (enum ruby_vminsn_type)insn; - return depth + (int)insn_stack_increase_dispatch(itype, opes); -} diff --git a/tool/ruby_vm/views/_insn_type_chars.erb b/tool/ruby_vm/views/_insn_type_chars.erb deleted file mode 100644 index b3eff5624f..0000000000 --- a/tool/ruby_vm/views/_insn_type_chars.erb +++ /dev/null @@ -1,12 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% -% map = RubyVM::Typemap.each_pair.map {|k, (c, t)| sprintf "%s = '%s'", t, c } -enum ruby_insn_type_chars { - <%= map.join(",\n ") %> -}; diff --git a/tool/ruby_vm/views/_notice.erb b/tool/ruby_vm/views/_notice.erb deleted file mode 100644 index 8c6cdaf533..0000000000 --- a/tool/ruby_vm/views/_notice.erb +++ /dev/null @@ -1,22 +0,0 @@ -%# -*- mode: c; style: ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%; -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -%; -/*******************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/** - This file <%= this_file %>. - - ---- - This file is auto generated by insns2vm.rb - DO NOT TOUCH! - - If you want to fix something, you must edit <%= cstr edit %> - or tool/insns2vm.rb - */ diff --git a/tool/ruby_vm/views/_trace_instruction.erb b/tool/ruby_vm/views/_trace_instruction.erb deleted file mode 100644 index 30933a6f5a..0000000000 --- a/tool/ruby_vm/views/_trace_instruction.erb +++ /dev/null @@ -1,16 +0,0 @@ -%# -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; - -/* insn <%= insn.pretty_name %> */ -INSN_ENTRY(<%= insn.name %>) -{ - vm_trace(ec, GET_CFP(), GET_PC()); - DISPATCH_ORIGINAL_INSN(<%= insn.jump_destination %>); - END_INSN(<%= insn.name %>); -} diff --git a/tool/ruby_vm/views/insns.inc.erb b/tool/ruby_vm/views/insns.inc.erb deleted file mode 100644 index 78dddd69d1..0000000000 --- a/tool/ruby_vm/views/insns.inc.erb +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'contains YARV instruction list', - edit: __FILE__, -} -%> - -/* BIN : Basic Instruction Name */ -#define BIN(n) YARVINSN_##n - -enum ruby_vminsn_type { -% RubyVM::Instructions.each do |i| - <%= i.bin %>, -% end - VM_INSTRUCTION_SIZE -}; - -#define ASSERT_VM_INSTRUCTION_SIZE(array) \ - STATIC_ASSERT(numberof_##array, numberof(array) == VM_INSTRUCTION_SIZE) diff --git a/tool/ruby_vm/views/insns_info.inc.erb b/tool/ruby_vm/views/insns_info.inc.erb deleted file mode 100644 index e08a15e5ef..0000000000 --- a/tool/ruby_vm/views/insns_info.inc.erb +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'contains instruction information for yarv instruction sequence.', - edit: __FILE__, -} %> -<%= render 'insn_type_chars' %> -<%= render 'insn_name_info' %> -<%= render 'insn_len_info' %> -<%= render 'insn_operand_info' %> -<%= render 'attributes' %> -<%= render 'insn_stack_increase' %> diff --git a/tool/ruby_vm/views/opt_sc.inc.erb b/tool/ruby_vm/views/opt_sc.inc.erb deleted file mode 100644 index fdc9ee3d08..0000000000 --- a/tool/ruby_vm/views/opt_sc.inc.erb +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% raise ':FIXME:TBW' if RubyVM::VmOptsH['STACK_CACHING'] -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'is for threaded code', - edit: __FILE__, -} -%> - -#define SC_STATE_SIZE 6 - -#define SCS_XX 1 -#define SCS_AX 2 -#define SCS_BX 3 -#define SCS_AB 4 -#define SCS_BA 5 - -#define SC_ERROR 0xffffffff - -static const VALUE sc_insn_info[][SC_STATE_SIZE] = { -#define NO_SC { SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR } -% RubyVM::Instructions.each_slice 8 do |a| - <%= a.map{|i| 'NO_SC' }.join(', ') %>, -% end -#undef NO_SC -}; - -static const VALUE sc_insn_next[] = { -% RubyVM::Instructions.each_slice 8 do |a| - <%= a.map{|i| 'SCS_XX' }.join(', ') %>, -% end -}; - -ASSERT_VM_INSTRUCTION_SIZE(sc_insn_next); diff --git a/tool/ruby_vm/views/optinsn.inc.erb b/tool/ruby_vm/views/optinsn.inc.erb deleted file mode 100644 index 1cb09d4809..0000000000 --- a/tool/ruby_vm/views/optinsn.inc.erb +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' -%> -<%= render 'notice', locals: { - this_file: 'is for threaded code', - edit: __FILE__, -} -%> - -static INSN * -insn_operands_unification(INSN *iobj) -{ -#ifdef OPT_OPERANDS_UNIFICATION - VALUE *op = iobj->operands; - - switch (iobj->insn_id) { - default: - /* do nothing */; - break; - -% RubyVM::OperandsUnifications.each_group do |orig, unifs| - case <%= orig.bin %>: -% unifs.each do |insn| - - /* <%= insn.pretty_name %> */ - if ( <%= insn.condition('op') %> ) { -% insn.opes.each_with_index do |o, x| -% n = insn.operand_shift_of(o) -% if n != 0 then - op[<%= x %>] = op[<%= x + n %>]; -% end -% end - iobj->insn_id = <%= insn.bin %>; - iobj->operand_size = <%= insn.opes.size %>; - break; - } -% end - - break; -% end - } -#endif - return iobj; -} - -int -rb_insn_unified_local_var_level(VALUE insn) -{ -#ifdef OPT_OPERANDS_UNIFICATION - /* optimize rule */ - switch (insn) { - default: - return -1; /* do nothing */; -% RubyVM::OperandsUnifications.each_group do |orig, unifs| -% unifs.each do|insn| - case <%= insn.bin %>: -% insn.spec.map{|(var,val)|val}.reject{|i| i == '*' }.each do |val| - return <%= val %>; -% break -% end -% end -% end - } -#endif - return -1; -} diff --git a/tool/ruby_vm/views/optunifs.inc.erb b/tool/ruby_vm/views/optunifs.inc.erb deleted file mode 100644 index 29d8ca2855..0000000000 --- a/tool/ruby_vm/views/optunifs.inc.erb +++ /dev/null @@ -1,21 +0,0 @@ -/* -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% raise ':FIXME:TBW' if RubyVM::VmOptsH['INSTRUCTIONS_UNIFICATION'] -% n = RubyVM::Instructions.size -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'is for threaded code', - edit: __FILE__, -} -%> - -/* Let .bss section automatically initialize this variable */ -/* cf. Section 6.7.8 of ISO/IEC 9899:1999 */ -static const int *const *const unified_insns_data[<%= n %>]; - -ASSERT_VM_INSTRUCTION_SIZE(unified_insns_data); diff --git a/tool/ruby_vm/views/vm.inc.erb b/tool/ruby_vm/views/vm.inc.erb deleted file mode 100644 index 24181fab95..0000000000 --- a/tool/ruby_vm/views/vm.inc.erb +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'is VM main loop', - edit: __FILE__, -} -%> - -#include "vm_insnhelper.h" -% RubyVM::BareInstructions.to_a.each do |insn| -<%= render 'insn_entry', locals: { insn: insn } -%> -% end -% -% RubyVM::OperandsUnifications.to_a.each do |insn| -<%= render 'insn_entry', locals: { insn: insn } -%> -% end -% -% RubyVM::InstructionsUnifications.to_a.each do |insn| -<%= render 'insn_entry', locals: { insn: insn } -%> -% end -% -% RubyVM::TraceInstructions.to_a.each do |insn| -<%= render 'trace_instruction', locals: { insn: insn } -%> -% end diff --git a/tool/ruby_vm/views/vmtc.inc.erb b/tool/ruby_vm/views/vmtc.inc.erb deleted file mode 100644 index 16886a1ea6..0000000000 --- a/tool/ruby_vm/views/vmtc.inc.erb +++ /dev/null @@ -1,21 +0,0 @@ -/* -*- mode:c; style:ruby; coding: utf-8; indent-tabs-mode: nil -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' -%> -<%= render 'notice', locals: { - this_file: 'is for threaded code', - edit: __FILE__, -} -%> - -static const void *const insns_address_table[] = { -% RubyVM::Instructions.each do |i| - LABEL_PTR(<%= i.name %>), -% end -}; - -ASSERT_VM_INSTRUCTION_SIZE(insns_address_table); |