diff options
Diffstat (limited to 'trunk/tool')
-rw-r--r-- | trunk/tool/asm_parse.rb | 51 | ||||
-rwxr-xr-x | trunk/tool/build-transcode | 16 | ||||
-rw-r--r-- | trunk/tool/compile_prelude.rb | 96 | ||||
-rw-r--r-- | trunk/tool/eval.rb | 161 | ||||
-rwxr-xr-x | trunk/tool/ifchange | 17 | ||||
-rwxr-xr-x | trunk/tool/insns2vm.rb | 15 | ||||
-rw-r--r-- | trunk/tool/instruction.rb | 1385 | ||||
-rwxr-xr-x | trunk/tool/make-snapshot | 183 | ||||
-rwxr-xr-x | trunk/tool/node_name.rb | 4 | ||||
-rw-r--r-- | trunk/tool/parse.rb | 13 | ||||
-rw-r--r-- | trunk/tool/transcode-tblgen.rb | 637 | ||||
-rw-r--r-- | trunk/tool/vtlh.rb | 15 | ||||
-rwxr-xr-x | trunk/tool/ytab.sed | 30 |
13 files changed, 0 insertions, 2623 deletions
diff --git a/trunk/tool/asm_parse.rb b/trunk/tool/asm_parse.rb deleted file mode 100644 index f3d7f73c99..0000000000 --- a/trunk/tool/asm_parse.rb +++ /dev/null @@ -1,51 +0,0 @@ -stat = {} - -while line = ARGF.gets - if /\[start\] (\w+)/ =~ line - name = $1 - puts '--------------------------------------------------------------' - puts line - size = 0 - len = 0 - - while line = ARGF.gets - if /\[start\] (\w+)/ =~ line - puts "\t; # length: #{len}, size: #{size}" - puts "\t; # !!" - stat[name] = [len, size] - # - name = $1 - puts '--------------------------------------------------------------' - puts line - size = 0 - len = 0 - next - end - - unless /(\ALM)|(\ALB)|(\A\.)|(\A\/)/ =~ line - puts line - if /\[length = (\d+)\]/ =~ line - len += $1.to_i - size += 1 - end - end - - - if /__NEXT_INSN__/ !~ line && /\[end \] (\w+)/ =~ line - ename = $1 - if name != ename - puts "!! start with #{name}, but end with #{ename}" - end - stat[ename] = [len, size] - puts "\t; # length: #{len}, size: #{size}" - break - end - end - end -end - -stat.sort_by{|a, b| -b[0] * 1000 - a[0]}.each{|a, b| - puts "#{a}\t#{b.join("\t")}" -} -puts "total length :\t#{stat.inject(0){|r, e| r+e[1][0]}}" -puts "total size :\t#{stat.inject(0){|r, e| r+e[1][1]}}" diff --git a/trunk/tool/build-transcode b/trunk/tool/build-transcode deleted file mode 100755 index fa71155530..0000000000 --- a/trunk/tool/build-transcode +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -[ "$1" -a -d "$1" ] && { cd "$1" || exit $?; } && shift -[ "$#" = 0 ] && set enc/trans/*.trans -for src; do - case "$src" in - *.trans) - c="`dirname $src`/`basename $src .trans`.c" - ${BASERUBY-ruby} tool/transcode-tblgen.rb -vo "$c" "$src" - ;; - *) - echo "$0: don't know how to deal with $src" - continue - ;; - esac -done diff --git a/trunk/tool/compile_prelude.rb b/trunk/tool/compile_prelude.rb deleted file mode 100644 index 70197aebf3..0000000000 --- a/trunk/tool/compile_prelude.rb +++ /dev/null @@ -1,96 +0,0 @@ -# This file is interpreted by $(BASERUBY) and miniruby. -# $(BASERUBY) is used for miniprelude.c. -# miniruby is used for prelude.c. -# Since $(BASERUBY) may be older than Ruby 1.9, -# Ruby 1.9 feature should not be used. - -$:.unshift(File.expand_path("../..", __FILE__)) - -preludes = ARGV.dup -outfile = preludes.pop -init_name = outfile[/\w+(?=_prelude.c\b)/] || 'prelude' - -C_ESC = { - "\\" => "\\\\", - '"' => '\"', - "\n" => '\n', -} - -0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch } -0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch } -C_ESC_PAT = Regexp.union(*C_ESC.keys) - -def c_esc(str) - '"' + str.gsub(C_ESC_PAT) { C_ESC[$&] } + '"' -end - -mkconf = nil -setup_ruby_prefix = nil -teardown_ruby_prefix = nil -lines_list = preludes.map {|filename| - lines = [] - need_ruby_prefix = false - File.readlines(filename).each {|line| - line.gsub!(/RbConfig::CONFIG\["(\w+)"\]/) { - key = $1 - unless mkconf - require 'rbconfig' - mkconf = RbConfig::MAKEFILE_CONFIG.merge('prefix'=>'#{TMP_RUBY_PREFIX}') - setup_ruby_prefix = "TMP_RUBY_PREFIX = $:.reverse.find{|e|e!=\".\"}.sub(%r{(.*)/lib/.*}m, \"\\\\1\")\n" - teardown_ruby_prefix = 'Object.class_eval { remove_const "TMP_RUBY_PREFIX" }' - end - if RbConfig::MAKEFILE_CONFIG.has_key? key - val = RbConfig.expand("$(#{key})", mkconf) - need_ruby_prefix = true if /\A\#\{TMP_RUBY_PREFIX\}/ =~ val - c_esc(val) - else - "nil" - end - } - lines << c_esc(line) - } - setup_lines = [] - if need_ruby_prefix - setup_lines << c_esc(setup_ruby_prefix) - lines << c_esc(teardown_ruby_prefix) - end - [setup_lines, lines] -} - -require 'erb' - -tmp = ERB.new(<<'EOS', nil, '%').result(binding) -#include "ruby/ruby.h" -#include "vm_core.h" - -% preludes.zip(lines_list).each_with_index {|(prelude, (setup_lines, lines)), i| -static const char prelude_name<%=i%>[] = <%=c_esc(File.basename(prelude))%>; -static const char prelude_code<%=i%>[] = -% (setup_lines+lines).each {|line| -<%=line%> -% } -; -% } - -void -Init_<%=init_name%>(void) -{ -% lines_list.each_with_index {|(setup_lines, lines), i| - rb_iseq_eval(rb_iseq_compile( - rb_str_new(prelude_code<%=i%>, sizeof(prelude_code<%=i%>) - 1), - rb_str_new(prelude_name<%=i%>, sizeof(prelude_name<%=i%>) - 1), - INT2FIX(<%=1-setup_lines.length%>))); - -% } -#if 0 -% preludes.length.times {|i| - puts(prelude_code<%=i%>); -% } -#endif -} -EOS - -open(outfile, 'w'){|f| - f << tmp -} - diff --git a/trunk/tool/eval.rb b/trunk/tool/eval.rb deleted file mode 100644 index 906ba9c23c..0000000000 --- a/trunk/tool/eval.rb +++ /dev/null @@ -1,161 +0,0 @@ - -require 'rbconfig' -require 'fileutils' -require 'pp' - -Ruby = ENV['RUBY'] || - File.join(Config::CONFIG["bindir"], - Config::CONFIG["ruby_install_name"] + Config::CONFIG["EXEEXT"]) -# - -OPTIONS = %w{ - opt-direct-threaded-code - opt-basic-operations - opt-operands-unification - opt-instructions-unification - opt-inline-method-cache - opt-stack-caching -}.map{|opt| - '--disable-' + opt -} - -opts = OPTIONS.dup -Configs = OPTIONS.map{|opt| - o = opts.dup - opts.delete(opt) - o -} + [[]] - -pp Configs if $DEBUG - - -def exec_cmd(cmd) - puts cmd - unless system(cmd) - p cmd - raise "error" - end -end - -def dirname idx - "ev-#{idx}" -end - -def build - Configs.each_with_index{|config, idx| - dir = dirname(idx) - FileUtils.rm_rf(dir) if FileTest.exist?(dir) - Dir.mkdir(dir) - FileUtils.cd(dir){ - exec_cmd("#{Ruby} ../extconf.rb " + config.join(" ")) - exec_cmd("make clean test-all") - } - } -end - -def check - Configs.each_with_index{|c, idx| - puts "= #{idx}" - system("#{Ruby} -r ev-#{idx}/yarvcore -e 'puts YARVCore::OPTS'") - } -end - -def bench_each idx - puts "= #{idx}" - 5.times{|count| - print count - FileUtils.cd(dirname(idx)){ - exec_cmd("make benchmark OPT=-y ITEMS=#{ENV['ITEMS']} > ../b#{idx}-#{count}") - } - } - puts -end - -def bench - # return bench_each(6) - Configs.each_with_index{|c, idx| - bench_each idx - } -end - -def parse_result data - flag = false - stat = [] - data.each{|line| - if flag - if /(\w+)\t([\d\.]+)/ =~ line - stat << [$1, $2.to_f] - else - raise "not a data" - end - - end - if /benchmark summary/ =~ line - flag = true - end - } - stat -end - -def calc_each data - data.sort! - data.pop # remove max - data.shift # remove min - - data.inject(0.0){|res, e| - res += e - } / data.size -end - -def calc_stat stats - stat = [] - stats[0].each_with_index{|e, idx| - bm = e[0] - vals = stats.map{|st| - st[idx][1] - } - [bm, calc_each(vals)] - } -end - -def stat - total = [] - Configs.each_with_index{|c, idx| - stats = [] - 5.times{|count| - file = "b#{idx}-#{count}" - # p file - open(file){|f| - stats << parse_result(f.read) - } - } - # merge stats - total << calc_stat(stats) - total - } - # pp total - total[0].each_with_index{|e, idx| - bm = e[0] - # print "#{bm}\t" - total.each{|st| - print st[idx][1], "\t" - } - puts - } -end - -ARGV.each{|cmd| - case cmd - when 'build' - build - when 'check' - check - when 'bench' - bench - when 'stat' - stat - else - raise - end -} - diff --git a/trunk/tool/ifchange b/trunk/tool/ifchange deleted file mode 100755 index 544513ad15..0000000000 --- a/trunk/tool/ifchange +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# usage: ifchange target temporary - -target="$1" -temp="$2" -if [ "$temp" = - ]; then - temp="tmpdata$$.tmp~" - cat > "$temp" || exit $? - trap 'rm -f "$temp"' 0 -fi -if cmp "$target" "$temp" >/dev/null 2>&1; then - echo "$target unchanged" - rm -f "$temp" -else - echo "$target updated" - mv -f "$temp" "$target" -fi diff --git a/trunk/tool/insns2vm.rb b/trunk/tool/insns2vm.rb deleted file mode 100755 index 47aba50c1e..0000000000 --- a/trunk/tool/insns2vm.rb +++ /dev/null @@ -1,15 +0,0 @@ -#!ruby -Kn - -require 'optparse' - -Version = %w$Revision: 11626 $[1..-1] - -require "#{File.join(File.dirname(__FILE__), 'instruction')}" - -if $0 == __FILE__ - opts = ARGV.options - maker = RubyVM::SourceCodeGenerator.def_options(opts) - files = opts.parse! - generator = maker.call - generator.generate(files) -end diff --git a/trunk/tool/instruction.rb b/trunk/tool/instruction.rb deleted file mode 100644 index 5e5eb0b78a..0000000000 --- a/trunk/tool/instruction.rb +++ /dev/null @@ -1,1385 +0,0 @@ -# -# -# - -require 'erb' - -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 - 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 - - 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 definision - 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 << " #{t} #{v} = FIX2INT(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"] || 'opt_operand.def' - load_insn_unification_def opts[:"unif.def"] || 'opt_insn_unif.def' - make_stackcaching_insns if vm_opt?('STACK_CACHING') - 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 mismatcvh 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_optimiized(insn, ninsn, nopes, defv) - end - - def make_insn_operand_optimiized 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| - "#define #{v} #{v}_#{i}" - }.join("\n") + "\n" + - insn.body + - passed_vars.map{|rpvars| - "#undef #{rpvars[0][1]}" - }.join("\n") + - "\n" + - redef_vars.keys.map{|v| - "#undef #{v}" - }.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 - - after = nil - SPECIAL_INSN_FOR_SC_AFTER.any?{|k, v| - if k =~ insn.name - after = v - break - end - } - - 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_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 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 - vm_body = '' - @insns.each{|insn| - vm_body << "\n" - vm_body << make_insn_def(insn) - } - src = vpath.read('template/vm.inc.tmpl') - ERB.new(src).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 - - 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 - - re = /\b#{var}\b/n - if re =~ insn.body or re =~ insn.sp_inc or insn.rets.any?{|t, v| re =~ v} - 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 " USAGE_ANALYSIS_INSN(BIN(#{insn.name}));" - insn.opes.each_with_index{|op, i| - commit " USAGE_ANALYSIS_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_hader_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 make_footer_stack_val insn - comment " /* push stack val */" - - insn.rets.reverse_each{|v| - if v[1] == '...' - break - end - 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 - commit "INSN_ENTRY(#{insn.name}){" - make_header_prepare_stack insn - commit "{" - 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_hader_debug insn - make_header_pc insn - make_header_popn insn - make_header_defines insn - make_header_analysis insn - commit "{" - end - - def make_footer insn - make_footer_stack_val insn - make_footer_default_operands insn - make_footer_undefs insn - 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 - insn.body - end - make_footer(insn) - end - end - end - - ################################################################### - # vmtc.inc - class VmTCIncGenerator < SourceCodeGenerator - def generate - - insns_table = build_string do - @insns.each{|insn| - commit " LABEL_PTR(#{insn.name})," - } - end - - insn_end_table = build_string do - @insns.each{|insn| - commit " ELABEL_PTR(#{insn.name}),\n" - } - end - - ERB.new(vpath.read('template/vmtc.inc.tmpl')).result(binding) - end - end - - ################################################################### - # insns_info.inc - class InsnsInfoIncGenerator < SourceCodeGenerator - def generate - insns_info_inc - end - - ### - private - - def op2typesig op - case op - when /^OFFSET/ - "TS_OFFSET" - when /^rb_num_t/ - "TS_NUM" - when /^lindex_t/ - "TS_LINDEX" - when /^dindex_t/ - "TS_DINDEX" - when /^VALUE/ - "TS_VALUE" - when /^ID/ - "TS_ID" - when /GENTRY/ - "TS_GENTRY" - when /^IC/ - "TS_IC" - 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_DINDEX' => 'D', - 'TS_VALUE' => 'V', - 'TS_ID' => 'I', - 'TS_GENTRY' => 'G', - 'TS_IC' => 'C', - 'TS_CDHASH' => 'H', - 'TS_ISEQ' => 'S', - 'TS_VARIABLE' => '.', - 'TS_FUNCPTR' => 'F', - } - - # insns_info.inc - def insns_info_inc - # insn_type_chars - insn_type_chars = TYPE_CHARS.map{|t, c| - "#define #{t} '#{c}'" - }.join("\n") - - # insn_names - insn_names = '' - @insns.each{|insn| - insn_names << " \"#{insn.name}\",\n" - } - - # operands info - operands_info = '' - operands_num_info = '' - @insns.each{|insn| - opes = insn.opes - operands_info << ' ' - ot = opes.map{|type, var| - TYPE_CHARS.fetch(op2typesig(type)) - } - operands_info << "\"#{ot.join}\"" << ", \n" - - num = opes.size + 1 - operands_num_info << " #{num},\n" - } - - # stack num - stack_num_info = '' - @insns.each{|insn| - num = insn.rets.size - stack_num_info << " #{num},\n" - } - - # stack increase - stack_increase = '' - @insns.each{|insn| - stack_increase << <<-EOS - case BIN(#{insn.name}):{ - #{insn.sp_increase_c_expr} - } - EOS - } - ERB.new(vpath.read('template/insns_info.inc.tmpl')).result(binding) - end - end - - ################################################################### - # insns.inc - class InsnsIncGenerator < SourceCodeGenerator - def generate - i=0 - insns = build_string do - @insns.each{|insn| - commit " %-30s = %d,\n" % ["BIN(#{insn.name})", i] - i+=1 - } - end - - ERB.new(vpath.read('template/insns.inc.tmpl')).result(binding) - end - end - - ################################################################### - # minsns.inc - class MInsnsIncGenerator < SourceCodeGenerator - def generate - i=0 - defs = build_string do - @insns.each{|insn| - commit " rb_define_const(mYarvInsns, %-30s, INT2FIX(%d));\n" % - ["\"I#{insn.name}\"", i] - i+=1 - } - end - ERB.new(vpath.read('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/, /^dindex_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 - rule = '' - opt_insns_map = Hash.new{|h, k| h[k] = []} - - @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 - } - - rule = build_string do - opt_insns_map.each{|originsn, optinsns| - commit "case BIN(#{originsn.name}):" - - optinsns.sort_by{|opti| - opti.defopes.find_all{|e| e[1] == '*'}.size - }.each{|opti| - commit " if(" - i = 0 - commit " " + opti.defopes.map{|opinfo| - i += 1 - next if opinfo[1] == '*' - "insnobj->operands[#{i-1}] == #{val_as_type(opinfo)}" - }.compact.join('&& ') - commit " ){" - idx = 0 - n = 0 - opti.defopes.each{|opinfo| - if opinfo[1] == '*' - if idx != n - commit " insnobj->operands[#{idx}] = insnobj->operands[#{n}];" - end - idx += 1 - else - # skip - end - n += 1 - } - commit " insnobj->insn_id = BIN(#{opti.name});" - commit " insnobj->operand_size = #{idx};" - commit " break;\n }\n" - } - commit " break;"; - } - end - - ERB.new(vpath.read('template/optinsn.inc.tmpl')).result(binding) - end - end - - ################################################################### - # optunifs.inc - class OptUnifsIncGenerator < SourceCodeGenerator - def generate - unif_insns_each = '' - unif_insns = '' - unif_insns_data = [] - - insns = @insns.find_all{|insn| !insn.is_sc} - insns.each{|insn| - size = insn.unifs.size - if size > 0 - insn.unifs.sort_by{|unif| -unif[1].size}.each_with_index{|unif, i| - - uni_insn, uni_insns = *unif - uni_insns = uni_insns[1..-1] - unif_insns_each << "static const int UNIFIED_#{insn.name}_#{i}[] = {" + - " BIN(#{uni_insn.name}), #{uni_insns.size + 2}, \n " + - uni_insns.map{|e| "BIN(#{e.name})"}.join(", ") + "};\n" - } - else - - end - if size > 0 - unif_insns << "static const int *const UNIFIED_#{insn.name}[] = {(int *)#{size+1}, \n" - unif_insns << (0...size).map{|e| " UNIFIED_#{insn.name}_#{e}"}.join(",\n") + "};\n" - unif_insns_data << " UNIFIED_#{insn.name}" - else - unif_insns_data << " 0" - end - } - unif_insns_data = "static const int *const *const unified_insns_data[] = {\n" + - unif_insns_data.join(",\n") + "};\n" - ERB.new(vpath.read('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") - ERB.new(vpath.read('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" - } - ERB.new(vpath.read('template/yasmdata.rb.tmpl')).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 #{seq}\n" % i - d << ":stack: #{before} => #{after}\n\n" - i+=1 - } - d - end - - def desc_ja - d = desc :j - ERB.new(vpath.read('template/yarvarch.ja')).result(binding) - end - - def desc_en - d = desc :e - ERB.new(vpath.read('template/yarvarch.en')).result(binding) - end - end - - module VPATH - def search(meth, base, *rest) - begin - meth.call(base, *rest) - rescue Errno::ENOENT => error - each do |dir| - return meth.call(File.join(dir, base), *rest) rescue nil - end - raise error - end - end - - def process(*args, &block) - search(File.method(__callee__), *args, &block) - end - - alias stat process - alias lstat process - - def open(*args) - f = search(File.method(:open), *args) - if block_given? - begin - yield f - ensure - f.close unless f.closed? - end - else - f - end - end - - def read(*args) - open(*args) {|f| f.read} - end - - def foreach(file, *args, &block) - open(file) {|f| f.each(*args, &block)} - end - - def self.def_options(opt) - vpath = [] - path_sep = ':' - - opt.on("-I", "--srcdir=DIR", "add a directory to search path") {|dir| - vpath |= [dir] - } - opt.on("-L", "--vpath=PATH LIST", "add directories to search path") {|dirs| - vpath |= dirs.split(path_sep) - } - opt.on("--path-separator=SEP", /\A\W\z/, "separator for vpath") {|sep| - path_sep = sep - } - - proc { - vpath.extend(self) unless vpath.empty? - } - 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" => 'opt_operand.def', - :"unif.def" => '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.def_options(opt) - - proc { - opts[:VPATH] = vpath.call - build opts - } - end - - def self.build opts, vpath = ['./'] - opts[:VPATH] = vpath.extend(VPATH) unless opts[:VPATH] - self.new InstructionsLoader.new(opts) - end - end -end - diff --git a/trunk/tool/make-snapshot b/trunk/tool/make-snapshot deleted file mode 100755 index 65f5bd024d..0000000000 --- a/trunk/tool/make-snapshot +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/ruby -s -require 'uri' -require 'digest/md5' -require 'digest/sha2' -require 'fileutils' -require 'tmpdir' -STDOUT.sync = true - -ENV["LC_ALL"] = ENV["LANG"] = "C" -SVNURL = URI.parse("http://svn.ruby-lang.org/repos/ruby/") -RUBY_VERSION_PATTERN = /^\#define\s+RUBY_VERSION\s+"([\d.]+)"/ - -ENV["VPATH"] ||= "include/ruby" -YACC = ENV["YACC"] ||= "bison" -ENV["BASERUBY"] ||= "ruby" -ENV["RUBY"] ||= "ruby" -ENV["MV"] ||= "mv" -ENV["MINIRUBY"] ||= "ruby" - -$patch_file &&= File.expand_path($patch_file) -path = ENV["PATH"].split(File::PATH_SEPARATOR) -%w[YACC BASERUBY RUBY MV MINIRUBY].each do |var| - cmd = ENV[var] - unless path.any? {|dir| - file = File.join(dir, cmd) - File.file?(file) and File.executable?(file) - } - abort "#{File.basename $0}: #{var} command not found - #{cmd}" - end -end - -unless destdir = ARGV.shift - abort "usage: #{File.basename $0} new-directory-to-save [version ...]" -end -revisions = ARGV.empty? ? ["trunk"] : ARGV -unless tmp = $exported - FileUtils.mkpath(destdir) - destdir = File.expand_path(destdir) - tmp = Dir.mktmpdir("ruby-snapshot") - FileUtils.mkpath(tmp) - at_exit { - Dir.chdir "/" - FileUtils.rm_rf(tmp) - } unless $keep_temp -end -Dir.chdir tmp - -def package(rev, destdir) - patchlevel = false - case rev - when /\Atrunk\z/, /\Abranches\//, /\Atags\// - url = SVNURL + rev - when /\Astable\z/ - url = SVNURL + "branches/" - url = url + `svn ls #{url}`[/.*^(ruby_\d+_\d+)\//m, 1] - when /\A\(.*\..*\..*\)-/ - patchlevel = true - url = SVNURL + "tags/v#{rev.sub(/-p?/, '_').tr('.', '_')}" - when /\./ - url = SVNURL + "branches/ruby_#{rev.tr('.', '_')}" - else - warn "#{$0}: unknown version - #{rev}" - return - end - revision = `svn info #{url} 2>&1`[/Last Changed Rev: (\d+)/, 1] - version = nil - unless revision - url = SVNURL + "trunk" - version = `svn cat #{url + "version.h"}`[RUBY_VERSION_PATTERN, 1] - unless rev == version - warn "#{$0}: #{rev} not found" - return - end - revision = `svn info #{url}`[/Last Changed Rev: (\d+)/, 1] - end - unless $exported - puts "Exporting #{rev}@#{revision}" - IO.popen("svn export #{url} ruby") do |pipe| - pipe.each {|line| /^A/ =~ line or print line} - end - unless $?.success? - warn("Export failed") - return - end - end - - if !File.directory?(v = "ruby") - v = Dir.glob("ruby-*").select(&File.method(:directory?)) - v.size == 1 or abort "not exported" - v = v[0] - end - open("#{v}/revision.h", "wb") {|f| f.puts "#define RUBY_REVISION #{revision}"} - version ||= (versionhdr = IO.read("#{v}/version.h"))[RUBY_VERSION_PATTERN, 1] - version or return - if patchlevel - versionhdr ||= IO.read("#{v}/version.h") - patchlevel = versionhdr[/^\#define\s+RUBY_PATCHLEVEL\s+(\d+)/, 1] - tag = (patchlevel ? "p#{patchlevel}" : "r#{revision}") - else - tag = "r#{revision}" - end - v = "ruby-#{version}-#{tag}" - File.directory?(v) or File.rename "ruby", v - system("patch -d #{v} -p0 -i #{$patch_file}") if $patch_file - def (clean = []).add(n) push(n); n end - Dir.chdir(v) do - File.open(clean.add("cross.rb"), "w") {|f| f.puts "CROSS_COMPILING=true"} - unless File.exist?("configure") - print "creating configure..." - unless system("autoconf") - puts " failed" - return - end - puts " done" - end - clean.add("autom4te.cache") - print "creating prerequisites..." - if File.file?("common.mk") && /^prereq/ =~ commonmk = IO.read("common.mk") - puts - extout = clean.add('tmp') - File.open(clean.add("config.status"), "w") {|f| - f.puts "s,@configure_args@,|#_!!_#|,g" - f.puts "s,@EXTOUT@,|#_!!_#|#{extout},g" - f.puts "s,@bindir@,|#_!!_#|,g" - f.puts "s,@ruby_install_name@,|#_!!_#|,g" - f.puts "s,@ARCH_FLAG@,|#_!!_#|,g" - f.puts "s,@CFLAGS@,|#_!!_#|,g" - f.puts "s,@CPPFLAGS@,|#_!!_#|,g" - f.puts "s,@LDFLAGS@,|#_!!_#|,g" - f.puts "s,@DLDFLAGS@,|#_!!_#|,g" - f.puts "s,@LIBEXT@,|#_!!_#|a,g" - f.puts "s,@OBJEXT@,|#_!!_#|o,g" - f.puts "s,@LIBRUBY@,|#_!!_#|liburyb.a,g" - f.puts "s,@LIBRUBY_A@,|#_!!_#|liburyb.a,g" - } - FileUtils.mkpath(hdrdir = "#{extout}/include/ruby") - File.open("#{hdrdir}/config.h", "w") {} - miniruby = ENV['MINIRUBY'] + " -rcross" - IO.popen("make -f - prereq srcdir=. IFCHANGE=tool/ifchange 'MINIRUBY=#{miniruby}'", "w") do |f| - f.puts(IO.read("Makefile.in")[/^lex\.c.*?^$/m]) - f.puts(commonmk.gsub(/\{[^{}]*\}/, "")) - end - clean.push("rbconfig.rb", ".rbconfig.time") - print "prerequisites" - else - system("#{YACC} -o parse.c parse.y") - end - FileUtils.rm_rf(clean) - unless $?.success? - puts " failed" - return - end - puts " done" - end - - return [["bzip tarball", ".tar.bz2", %w"tar cjf"], - ["gzip tarball", ".tar.gz", %w"tar czf"], - ["zip archive", ".zip", %w"zip -qr"] - ].collect do |mesg, ext, cmd| - file = "#{destdir}/#{v}#{ext}" - print "creating #{mesg}... #{file}" - if system(*(cmd + [file, v])) - puts " done" - file - else - puts " failed" - nil - end - end.compact -ensure - FileUtils.rm_rf(v) if v and !$exported and !$keep_temp -end - -revisions.collect {|rev| package(rev, destdir)}.flatten.each do |name| - name or next - str = open(name, "rb") {|f| f.read} - md5 = Digest::MD5.hexdigest str - sha = Digest::SHA256.hexdigest str - puts "MD5(#{name})= #{md5}" - puts "SHA256(#{name})= #{sha}" - puts "SIZE(name)= #{str.size}" - puts -end diff --git a/trunk/tool/node_name.rb b/trunk/tool/node_name.rb deleted file mode 100755 index 5d39e9f5cc..0000000000 --- a/trunk/tool/node_name.rb +++ /dev/null @@ -1,4 +0,0 @@ -#! ./miniruby -n -if ~/enum node_type \{/..~/^\};/ - ~/(NODE_.+),/ and puts(" case #{$1}:\n\treturn \"#{$1}\";") -end diff --git a/trunk/tool/parse.rb b/trunk/tool/parse.rb deleted file mode 100644 index 6243d7aa8e..0000000000 --- a/trunk/tool/parse.rb +++ /dev/null @@ -1,13 +0,0 @@ -$file = ARGV[0] -$str = ARGF.read.sub(/^__END__.*\z/m, '') -puts '# ' + '-' * 70 -puts "# target program: " -puts '# ' + '-' * 70 -puts $str -puts '# ' + '-' * 70 - -$parsed = RubyVM::InstructionSequence.compile_file($file) -puts "# disasm result: " -puts '# ' + '-' * 70 -puts $parsed.disasm -puts '# ' + '-' * 70 diff --git a/trunk/tool/transcode-tblgen.rb b/trunk/tool/transcode-tblgen.rb deleted file mode 100644 index f79fc551ec..0000000000 --- a/trunk/tool/transcode-tblgen.rb +++ /dev/null @@ -1,637 +0,0 @@ -require 'optparse' -require 'erb' -require 'fileutils' - -C_ESC = { - "\\" => "\\\\", - '"' => '\"', - "\n" => '\n', -} - -0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch } -0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch } -C_ESC_PAT = Regexp.union(*C_ESC.keys) - -def c_esc(str) - '"' + str.gsub(C_ESC_PAT) { C_ESC[$&] } + '"' -end - -class StrSet - def self.parse(pattern) - if /\A\s*(([0-9a-f][0-9a-f]|\{([0-9a-f][0-9a-f]|[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f])(,([0-9a-f][0-9a-f]|[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]))*\})+(\s+|\z))*\z/i !~ pattern - raise ArgumentError, "invalid pattern: #{pattern.inspect}" - end - result = [] - pattern.scan(/\S+/) {|seq| - seq_result = [] - while !seq.empty? - if /\A([0-9a-f][0-9a-f])/i =~ seq - byte = $1.to_i(16) - seq_result << [byte..byte] - seq = $' - elsif /\A\{([^\}]+)\}/ =~ seq - set = $1 - seq = $' - set_result = [] - set.scan(/[^,]+/) {|range| - if /\A([0-9a-f][0-9a-f])-([0-9a-f][0-9a-f])\z/ =~ range - b = $1.to_i(16) - e = $2.to_i(16) - set_result << (b..e) - elsif /\A([0-9a-f][0-9a-f])\z/ =~ range - byte = $1.to_i(16) - set_result << (byte..byte) - else - raise "invalid range: #{range.inspect}" - end - } - seq_result << set_result - else - raise "invalid sequence: #{seq.inspect}" - end - end - result << seq_result - } - self.new(result) - end - - def initialize(pat) - @pat = pat - end - - def hash - @pat.hash - end - - def eql?(other) - self.class == other.class && - @pat == other.instance_eval { @pat } - end - - alias == eql? - - def to_s - if @pat.empty? - "(empset)" - else - @pat.map {|seq| - if seq.empty? - "(empstr)" - else - seq.map {|byteset| - if byteset.length == 1 && byteset[0].begin == byteset[0].end - "%02x" % byteset[0].begin - else - "{" + - byteset.map {|range| - if range.begin == range.end - "%02x" % range.begin - else - "%02x-%02x" % [range.begin, range.end] - end - }.join(',') + - "}" - end - }.join('') - end - }.join(' ') - end - end - - def inspect - "\#<#{self.class}: #{self.to_s}>" - end - - def min_length - if @pat.empty? - nil - else - @pat.map {|seq| seq.length }.min - end - end - - def max_length - if @pat.empty? - nil - else - @pat.map {|seq| seq.length }.max - end - end - - def emptyable? - @pat.any? {|seq| - seq.empty? - } - end - - def first_bytes - result = {} - @pat.each {|seq| - next if seq.empty? - seq.first.each {|range| - range.each {|byte| - result[byte] = true - } - } - } - result.keys.sort - end - - def each_firstbyte - h = {} - @pat.each {|seq| - next if seq.empty? - seq.first.each {|range| - range.each {|byte| - (h[byte] ||= []) << seq[1..-1] - } - } - } - h.keys.sort.each {|byte| - yield byte, StrSet.new(h[byte]) - } - end -end - -class ActionMap - def self.parse(hash) - h = {} - hash.each {|pat, action| - h[StrSet.parse(pat)] = action - } - self.new(h) - end - - def initialize(h) - @map = h - end - - def hash - hash = 0 - @map.each {|k,v| - hash ^= k.hash ^ v.hash - } - hash - end - - def eql?(other) - self.class == other.class && - @map == other.instance_eval { @map } - end - - alias == eql? - - def inspect - "\#<#{self.class}:" + - @map.map {|k, v| " [" + k.to_s + "]=>" + v.inspect }.join('') + - ">" - end - - def max_input_length - @map.keys.map {|k| k.max_length }.max - end - - def empty_action - @map.each {|ss, action| - return action if ss.emptyable? - } - nil - end - - def each_firstbyte(valid_encoding=nil) - h = {} - @map.each {|ss, action| - if ss.emptyable? - raise "emptyable pattern" - else - ss.each_firstbyte {|byte, rest| - h[byte] ||= {} - if h[byte][rest] - raise "ambiguous" - end - h[byte][rest] = action - } - end - } - if valid_encoding - valid_encoding.each_firstbyte {|byte, rest| - if h[byte] - am = ActionMap.new(h[byte]) - yield byte, am, rest - else - am = ActionMap.new(rest => :undef) - yield byte, am, nil - end - } - else - h.keys.sort.each {|byte| - am = ActionMap.new(h[byte]) - yield byte, am, nil - } - end - end - - OffsetsMemo = {} - InfosMemo = {} - - def format_offsets(min, max, offsets) - offsets = offsets[min..max] - code = "{ %d, %d,\n" % [min, max] - 0.step(offsets.length-1,16) {|i| - code << " " - code << offsets[i,8].map {|off| "%3d," % off.to_s }.join('') - if i+8 < offsets.length - code << " " - code << offsets[i+8,8].map {|off| "%3d," % off.to_s }.join('') - end - code << "\n" - } - code << '}' - code - end - - def generate_info(info) - case info - when :nomap - "NOMAP" - when :undef - "UNDEF" - when :invalid - "INVALID" - when :func_ii - "FUNii" - when :func_si - "FUNsi" - when :func_io - "FUNio" - when :func_so - "FUNso" - when /\A([0-9a-f][0-9a-f])\z/i - "o1(0x#$1)" - when /\A([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])\z/i - "o2(0x#$1,0x#$2)" - when /\A([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])\z/i - "o3(0x#$1,0x#$2,0x#$3)" - when /\A([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])\z/i - "o4(0x#$1,0x#$2,0x#$3,0x#$4)" - when /\A&/ # pointer to BYTE_LOOKUP structure - info.to_s - else - raise "unexpected action: #{info.inspect}" - end - end - - def format_infos(infos) - infos = infos.map {|info| generate_info(info) } - maxlen = infos.map {|info| info.length }.max - columns = maxlen <= 16 ? 4 : 2 - code = "{\n" - 0.step(infos.length-1, columns) {|i| - code << " " - is = infos[i,columns] - is.each {|info| - code << sprintf(" %#{maxlen}s,", info) - } - code << "\n" - } - code << "}" - code - end - - def generate_lookup_node(name, table) - offsets = [] - infos = [] - infomap = {} - min = max = nil - table.each_with_index {|action, byte| - action ||= :invalid - if action != :invalid - min = byte if !min - max = byte - end - unless o = infomap[action] - infomap[action] = o = infos.length - infos[o] = action - end - offsets[byte] = o - } - if !min - min = max = 0 - end - - offsets_key = [min, max, offsets[min..max]] - if n = OffsetsMemo[offsets_key] - offsets_name = n - offsets_code = '' - else - offsets_name = "#{name}_offsets" - offsets_code = <<"End" -static const unsigned char -#{offsets_name}[#{2+max-min+1}] = #{format_offsets(min,max,offsets)}; -End - OffsetsMemo[offsets_key] = offsets_name - end - - if n = InfosMemo[infos] - infos_name = n - infos_code = '' - else - infos_name = "#{name}_infos" - infos_code = <<"End" -static const struct byte_lookup* const -#{infos_name}[#{infos.length}] = #{format_infos(infos)}; -End - InfosMemo[infos] = infos_name - end - - r = offsets_code + infos_code + <<"End" -static const BYTE_LOOKUP -#{name} = { - #{offsets_name}, - #{infos_name} -}; - -End - r - end - - PreMemo = {} - PostMemo = {} - NextName = "a" - - def generate_node(code, name_hint=nil, valid_encoding=nil) - if n = PreMemo[[self,valid_encoding]] - return n - end - - table = Array.new(0x100, :invalid) - each_firstbyte(valid_encoding) {|byte, rest, rest_valid_encoding| - if a = rest.empty_action - table[byte] = a - else - name_hint2 = nil - name_hint2 = "#{name_hint}_#{'%02X' % byte}" if name_hint - table[byte] = "&" + rest.generate_node(code, name_hint2, rest_valid_encoding) - end - } - - if n = PostMemo[table] - return n - end - - if !name_hint - name_hint = "fun_" + NextName.dup - NextName.succ! - end - - PreMemo[[self,valid_encoding]] = PostMemo[table] = name_hint - - code << generate_lookup_node(name_hint, table) - name_hint - end -end - -def encode_utf8(map) - r = [] - map.each {|k, v| - # integer means UTF-8 encoded sequence. - k = [k].pack("U").unpack("H*")[0].upcase if Integer === k - v = [v].pack("U").unpack("H*")[0].upcase if Integer === v - r << [k,v] - } - r -end - -def transcode_compile_tree(name, from, map) - map = encode_utf8(map) - h = {} - map.each {|k, v| - h[k] = v - } - am = ActionMap.parse(h) - - max_input = am.max_input_length - - if ValidEncoding[from] - valid_encoding = StrSet.parse(ValidEncoding[from]) - else - valid_encoding = nil - end - - code = '' - defined_name = am.generate_node(code, name, valid_encoding) - return defined_name, code, max_input -end - -TRANSCODERS = [] - -def transcode_tblgen(from, to, map) - STDERR.puts "converter from #{from} to #{to}" if VERBOSE_MODE - id_from = from.tr('^0-9A-Za-z', '_') - id_to = to.tr('^0-9A-Za-z', '_') - if from == "UTF-8" - tree_name = "to_#{id_to}" - elsif to == "UTF-8" - tree_name = "from_#{id_from}" - else - tree_name = "from_#{id_from}_to_#{id_to}" - end - map = encode_utf8(map) - real_tree_name, tree_code, max_input = transcode_compile_tree(tree_name, from, map) - transcoder_name = "rb_#{tree_name}" - TRANSCODERS << transcoder_name - input_unit_length = UnitLength[from] - max_output = map.map {|k,v| String === v ? v.length/2 : 1 }.max - transcoder_code = <<"End" -static const rb_transcoder -#{transcoder_name} = { - #{c_esc from}, #{c_esc to}, &#{real_tree_name}, - #{input_unit_length}, /* input_unit_length */ - #{max_input}, /* max_input */ - #{max_output}, /* max_output */ - stateless_converter, /* stateful_type */ - NULL, NULL, NULL, NULL, - NULL, NULL, NULL -}; -End - tree_code + "\n" + transcoder_code -end - -def transcode_generate_node(am, name_hint=nil) - STDERR.puts "converter for #{name_hint}" if VERBOSE_MODE - code = '' - am.generate_node(code, name_hint) - code -end - -def transcode_register_code - code = '' - TRANSCODERS.each {|transcoder_name| - code << " rb_register_transcoder(&#{transcoder_name});\n" - } - code -end - -UnitLength = { - 'UTF-16BE' => 2, - 'UTF-16LE' => 2, - 'UTF-32BE' => 4, - 'UTF-32LE' => 4, -} -UnitLength.default = 1 - -ValidEncoding = { - '1byte' => '{00-ff}', - '2byte' => '{00-ff}{00-ff}', - '4byte' => '{00-ff}{00-ff}{00-ff}{00-ff}', - 'US-ASCII' => '{00-7f}', - 'UTF-8' => '{00-7f} - {c2-df}{80-bf} - e0{a0-bf}{80-bf} - {e1-ec}{80-bf}{80-bf} - ed{80-9f}{80-bf} - {ee-ef}{80-bf}{80-bf} - f0{90-bf}{80-bf}{80-bf} - {f1-f3}{80-bf}{80-bf}{80-bf} - f4{80-8f}{80-bf}{80-bf}', - 'UTF-16BE' => '{00-d7,e0-ff}{00-ff} - {d8-db}{00-ff}{dc-df}{00-ff}', - 'UTF-16LE' => '{00-ff}{00-d7,e0-ff} - {00-ff}{d8-db}{00-ff}{dc-df}', - 'UTF-32BE' => '0000{00-d7,e0-ff}{00-ff} - 00{01-10}{00-ff}{00-ff}', - 'UTF-32LE' => '{00-ff}{00-d7,e0-ff}0000 - {00-ff}{00-ff}{01-10}00', - 'EUC-JP' => '{00-7f} - {a1-fe}{a1-fe} - 8e{a1-fe} - 8f{a1-fe}{a1-fe}', - 'CP51932' => '{00-7f} - {a1-fe}{a1-fe} - 8e{a1-fe}', - 'Shift_JIS' => '{00-7f} - {81-9f,e0-fc}{40-7e,80-fc} - {a1-df}', - 'EUC-KR' => '{00-7f} - {a1-fe}{a1-fe}', - 'CP949' => '{00-7f} - {81-fe}{41-5a,61-7a,81-fe}', - 'Big5' => '{00-7f} - {81-fe}{40-7e,a1-fe}', - 'EUC-TW' => '{00-7f} - {a1-fe}{a1-fe} - 8e{a1-b0}{a1-fe}{a1-fe}', - 'GBK' => '{00-80} - {81-fe}{40-7e,80-fe}', - 'GB18030' => '{00-7f} - {81-fe}{40-7e,80-fe} - {81-fe}{30-39}{81-fe}{30-39}', -} - -{ - 'ASCII-8BIT' => '1byte', - 'ISO-8859-1' => '1byte', - 'ISO-8859-2' => '1byte', - 'ISO-8859-3' => '1byte', - 'ISO-8859-4' => '1byte', - 'ISO-8859-5' => '1byte', - 'ISO-8859-6' => '1byte', - 'ISO-8859-7' => '1byte', - 'ISO-8859-8' => '1byte', - 'ISO-8859-9' => '1byte', - 'ISO-8859-10' => '1byte', - 'ISO-8859-11' => '1byte', - 'ISO-8859-13' => '1byte', - 'ISO-8859-14' => '1byte', - 'ISO-8859-15' => '1byte', - 'Windows-31J' => 'Shift_JIS', -}.each {|k, v| - ValidEncoding[k] = ValidEncoding.fetch(v) -} - -def make_signature(filename, src) - "src=#{filename.dump}, len=#{src.length}, checksum=#{src.sum}" -end - -output_filename = nil -verbose_mode = false -force_mode = false - -op = OptionParser.new -op.def_option("--help", "show help message") { puts op; exit 0 } -op.def_option("--verbose", "verbose mode") { verbose_mode = true } -op.def_option("--force", "force table generation") { force_mode = true } -op.def_option("--output=FILE", "specify output file") {|arg| output_filename = arg } -op.parse! - -VERBOSE_MODE = verbose_mode - -arg = ARGV.shift -dir = File.dirname(arg) -$:.unshift dir unless $:.include? dir -src = File.read(arg) -src.force_encoding("ascii-8bit") if src.respond_to? :force_encoding -this_script = File.read(__FILE__) -this_script.force_encoding("ascii-8bit") if this_script.respond_to? :force_encoding - -base_signature = "/* autogenerated. */\n" -base_signature << "/* #{make_signature(File.basename(__FILE__), this_script)} */\n" -base_signature << "/* #{make_signature(File.basename(arg), src)} */\n" - -if !force_mode && output_filename && File.readable?(output_filename) - old_signature = File.open(output_filename) {|f| f.gets("").chomp } - chk_signature = base_signature.dup - old_signature.each_line {|line| - if %r{/\* src="([0-9a-z_.-]+)",} =~ line - name = $1 - next if name == File.basename(arg) || name == File.basename(__FILE__) - path = File.join(dir, name) - if File.readable? path - chk_signature << "/* #{make_signature(name, File.read(path))} */\n" - end - end - } - if old_signature == chk_signature - now = Time.now - File.utime(now, now, output_filename) - STDERR.puts "already up-to-date: #{output_filename}" if VERBOSE_MODE - exit - end -end - -if VERBOSE_MODE - if output_filename - STDERR.puts "generating #{output_filename} ..." - end -end - -libs1 = $".dup -erb_result = ERB.new(src, nil, '%').result(binding) -libs2 = $".dup - -libs = libs2 - libs1 -lib_sigs = '' -libs.each {|lib| - lib = File.basename(lib) - path = File.join(dir, lib) - if File.readable? path - lib_sigs << "/* #{make_signature(lib, File.read(path))} */\n" - end -} - -result = '' -result << base_signature -result << lib_sigs -result << "\n" -result << erb_result -result << "\n" - -if output_filename - new_filename = output_filename + ".new" - FileUtils.mkdir_p(File.dirname(output_filename)) - File.open(new_filename, "wb") {|f| f << result } - File.rename(new_filename, output_filename) - STDERR.puts "done." if VERBOSE_MODE -else - print result -end diff --git a/trunk/tool/vtlh.rb b/trunk/tool/vtlh.rb deleted file mode 100644 index fcd3630821..0000000000 --- a/trunk/tool/vtlh.rb +++ /dev/null @@ -1,15 +0,0 @@ -# ARGF = open('ha') -cd = `pwd`.chomp + '/' -ARGF.each{|line| - if /^0x([a-z0-9]+),/ =~ line - stat = line.split(',') - addr = stat[0].hex + 0x00400000 - retired = stat[2].to_i - ticks = stat[3].to_i - - src = `addr2line -e miniruby.exe #{addr.to_s(16)}`.chomp - src.sub!(cd, '') - puts '%-40s 0x%08x %8d %8d' % [src, addr, retired, ticks] - end -} - diff --git a/trunk/tool/ytab.sed b/trunk/tool/ytab.sed deleted file mode 100755 index 17a57fe494..0000000000 --- a/trunk/tool/ytab.sed +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sed -f -/^int yydebug;/{ -i\ -#ifndef yydebug -a\ -#endif -} -/^yydestruct.*yymsg/,/#endif/{ - /^yydestruct/{ - /parser/!{ - h - s/^/ruby_parser_&/ - s/)$/, parser)/ - /\*/s/parser)$/struct parser_params *&/ - } - } - /^#endif/{ - x - /^./{ - i\ - struct parser_params *parser; - a\ -#define yydestruct(m, t, v) ruby_parser_yydestruct(m, t, v, parser) - } - x - } -} -s/^\([ ]*\)\(yyerror[ ]*([ ]*parser,\)/\1parser_\2/ -s!^ *extern char \*getenv();!/* & */! -s/^\(#.*\)".*\.tab\.c"/\1"parse.c"/ |