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

ruby-changes:7991

From: ko1 <ko1@a...>
Date: Wed, 24 Sep 2008 14:50:46 +0900 (JST)
Subject: [ruby-changes:7991] Ruby:r19515 (ricsin): * ricsin/ricsin.rb: moved from tool/ricsin.rb.

ko1	2008-09-24 14:50:28 +0900 (Wed, 24 Sep 2008)

  New Revision: 19515

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=19515

  Log:
    * ricsin/ricsin.rb: moved from tool/ricsin.rb.
    * ricsin/ricsin.rb: fix to skip string and comment
      while preprocessing C source.

  Added files:
    branches/ricsin/ricsin/ChangeLog
    branches/ricsin/ricsin/ricsin.rb
  Removed files:
    branches/ricsin/ricsin/Makefile
    branches/ricsin/tool/ricsin.rb
  Modified files:
    branches/ricsin/ricsin/t.rcb

Index: ricsin/ricsin/Makefile
===================================================================
--- ricsin/ricsin/Makefile	(revision 19514)
+++ ricsin/ricsin/Makefile	(revision 19515)
@@ -1,173 +0,0 @@
-
-SHELL = /bin/sh
-
-#### Start of system configuration section. ####
-
-srcdir = .
-topdir = /tmp/ricsin/include/ruby-1.9.0
-hdrdir = /tmp/ricsin/include/ruby-1.9.0
-arch_hdrdir = /tmp/ricsin/include/ruby-1.9.0/$(arch)
-VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
-prefix = $(DESTDIR)/tmp/ricsin
-exec_prefix = $(prefix)
-bindir = $(exec_prefix)/bin
-sbindir = $(exec_prefix)/sbin
-libexecdir = $(exec_prefix)/libexec
-datarootdir = $(prefix)/share
-datadir = $(datarootdir)
-sysconfdir = $(prefix)/etc
-sharedstatedir = $(prefix)/com
-localstatedir = $(prefix)/var
-includedir = $(prefix)/include
-oldincludedir = $(DESTDIR)/usr/include
-docdir = $(datarootdir)/doc/$(PACKAGE)
-infodir = $(datarootdir)/info
-htmldir = $(docdir)
-dvidir = $(docdir)
-pdfdir = $(docdir)
-psdir = $(docdir)
-libdir = $(exec_prefix)/lib
-localedir = $(datarootdir)/locale
-mandir = $(datarootdir)/man
-sitedir = $(libdir)/ruby/site_ruby
-vendordir = $(libdir)/ruby/vendor_ruby
-rubyhdrdir = $(includedir)/ruby-$(ruby_version)
-sitehdrdir = $(rubyhdrdir)/site_ruby
-vendorhdrdir = $(rubyhdrdir)/vendor_ruby
-rubylibdir = $(libdir)/ruby/$(ruby_version)
-archdir = $(rubylibdir)/$(arch)
-sitelibdir = $(sitedir)/$(ruby_version)
-sitearchdir = $(sitelibdir)/$(sitearch)
-vendorlibdir = $(vendordir)/$(ruby_version)
-vendorarchdir = $(vendorlibdir)/$(sitearch)
-
-CC = gcc
-CXX = g++
-LIBRUBY = $(LIBRUBY_A)
-LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
-LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir) 
-LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
-OUTFLAG = -o 
-COUTFLAG = -o 
-
-RUBY_EXTCONF_H = 
-cflags   = $(optflags) $(debugflags) $(warnflags)
-optflags = -O2
-debugflags = -g
-warnflags = -Wall -Wno-parentheses
-CFLAGS   =  -fPIC  $(cflags) 
-INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
-DEFS     = -D_FILE_OFFSET_BITS=64
-CPPFLAGS =   $(DEFS) $(cppflags)
-CXXFLAGS = $(CFLAGS)  $(cxxflags)
-ldflags  = -L.  -rdynamic -Wl,-export-dynamic
-dldflags = 
-archflag = 
-DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
-LDSHARED = $(CC) -shared
-LDSHAREDXX = $(CXX) -shared
-AR = ar
-EXEEXT = 
-
-RUBY_INSTALL_NAME = ruby
-RUBY_SO_NAME = ruby
-arch = i686-linux
-sitearch = i686-linux
-ruby_version = 1.9.0
-ruby = /tmp/ricsin/bin/ruby
-RUBY = $(ruby)
-RM = rm -f
-RM_RF = $(RUBY) -run -e rm -- -rf
-MAKEDIRS = mkdir -p
-INSTALL = /usr/bin/install -c
-INSTALL_PROG = $(INSTALL) -m 0755
-INSTALL_DATA = $(INSTALL) -m 644
-COPY = cp
-
-#### End of system configuration section. ####
-
-preload = 
-
-libpath = . $(libdir)
-LIBPATH =  -L. -L$(libdir) -Wl,-R$(libdir)
-DEFFILE = 
-
-CLEANFILES = mkmf.log
-DISTCLEANFILES = 
-
-extout = 
-extout_prefix = 
-target_prefix = 
-LOCAL_LIBS = 
-LIBS =   -lpthread -lrt -ldl -lcrypt -lm   -lc
-SRCS = benchmark.c
-OBJS = benchmark.o
-TARGET = ricsin_benchmark
-DLLIB = $(TARGET).so
-EXTSTATIC = 
-STATIC_LIB = 
-
-BINDIR        = $(bindir)
-RUBYCOMMONDIR = $(sitedir)$(target_prefix)
-RUBYLIBDIR    = $(sitelibdir)$(target_prefix)
-RUBYARCHDIR   = $(sitearchdir)$(target_prefix)
-HDRDIR        = $(rubyhdrdir)/ruby$(target_prefix)
-ARCHHDRDIR    = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
-
-TARGET_SO     = $(DLLIB)
-CLEANLIBS     = $(TARGET).so 
-CLEANOBJS     = *.o  *.bak
-
-all:		$(DLLIB)
-static:		$(STATIC_LIB)
-
-clean:
-		@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
-
-distclean:	clean
-		@-$(RM_RF) conftest.dSYM
-		@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
-		@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
-
-realclean:	distclean
-install: install-so install-rb
-
-install-so: $(RUBYARCHDIR)
-install-so: $(RUBYARCHDIR)/$(DLLIB)
-$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
-	$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
-install-rb: pre-install-rb install-rb-default
-install-rb-default: pre-install-rb-default
-pre-install-rb: Makefile
-pre-install-rb-default: Makefile
-$(RUBYARCHDIR):
-	$(MAKEDIRS) $@
-
-site-install: site-install-so site-install-rb
-site-install-so: install-so
-site-install-rb: install-rb
-
-.SUFFIXES: .c .m .cc .cxx .cpp .C .o
-
-.cc.o:
-	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
-
-.cxx.o:
-	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
-
-.cpp.o:
-	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
-
-.C.o:
-	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
-
-.c.o:
-	$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
-
-$(DLLIB): $(OBJS)
-	@-$(RM) $(@)
-	$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
-
-
-
-$(OBJS): ruby.h defines.h
Index: ricsin/ricsin/ChangeLog
===================================================================
--- ricsin/ricsin/ChangeLog	(revision 0)
+++ ricsin/ricsin/ChangeLog	(revision 19515)
@@ -0,0 +1,6 @@
+Wed Sep 24 14:47:29 2008  Koichi Sasada  <ko1@a...>
+
+	* ricsin/ricsin.rb: moved from tool/ricsin.rb.
+
+	* ricsin/ricsin.rb: fix to skip string and comment
+	  while preprocessing C source.
Index: ricsin/ricsin/t.rcb
===================================================================
--- ricsin/ricsin/t.rcb	(revision 19514)
+++ ricsin/ricsin/t.rcb	(revision 19515)
@@ -1,3 +1,10 @@
+
+$foo = 42
+p __C__('return $foo; /* $foo */')
+
+
+__END__
+
 p __C__('return INT2FIX(42);')
 
 __END__
Index: ricsin/ricsin/ricsin.rb
===================================================================
--- ricsin/ricsin/ricsin.rb	(revision 0)
+++ ricsin/ricsin/ricsin.rb	(revision 19515)
@@ -0,0 +1,428 @@
+require 'optparse'
+require 'pp'
+
+class Ricsin
+  VERSION = '0.0.1'
+  VERSION_STRING = "ricsin #{VERSION}"
+
+  def self.generate file, option
+    ricsin = self.new(file, option)
+    ricsin.generate
+    ricsin.run if option[:run]
+  end
+
+  def initialize file, option
+    @basename = File.basename(file, '.rcb')
+    @output_dir = option[:output_dir]
+    @src_rcb = file
+    @out_rb = File.join(@output_dir, "#{@basename}.rb")
+    @out_c  = File.join(@output_dir, "#{@basename}.c")
+    @out_so = nil
+    @so_basename = "ricsin_#{@basename}"
+    @src = nil
+    @option = option
+    @ids = {}
+  end
+
+  def run
+    raise unless @out_so
+    require @out_so
+  end
+
+  def generate
+    @src = preprocess(@src_rcb)
+    File.open(@out_rb, 'w'){|f|
+      f.write @src
+    } if @option[:output_rb]
+
+    generate_csrc
+    generate_dll
+  end
+
+  def preprocess file
+    # #C cexpr => __Cx__ %q{ cexpr }, 0
+    # #C:10 cexpr => __Cx__ %q{ cexpr }, 10
+
+    # kill __END__ lines
+    src = File.read(file).sub(/^__END__.+/m, '')
+
+    src = src.gsub(/^(\s*\#C\s+(.+)(?:\n|\z))+/){|lines|
+      csrc = lines.strip.split(/[\n]+/).map{|line|
+        if /^\s*\#C\s+(.+)\s*$/ =~ line
+          $1.chomp.dump
+        else
+          raise line.dump
+        end
+      }.join("\\\n")
+      "__Cx__(#{csrc}, 0)\n"
+    }
+    # .gsub(/^\s*=begin C\s*$(.+)^\s*=end\s*$/m){
+    #  #/^\s*=begin C$.+^\s*=end$/m
+    #  "__C__ <<'EOS__'\n#{$1.strip}\nEOS__"
+    #}
+
+    src
+  end
+
+  def generate_dll
+    require 'rbconfig'
+    ruby = File.join(
+      RbConfig::CONFIG["bindir"],
+      RbConfig::CONFIG["ruby_install_name"])
+
+    Dir.chdir(@output_dir){
+      if FileTest.exist? 'extconf.rb'
+        system("#{ruby} extconf.rb")
+      else
+        cmd = "#{ruby} -r mkmf -e "\
+              "'$objs=[#{(File.basename(@src_rcb, '.rcb')+'.o').dump}]; " \
+              "create_makefile(#{@so_basename.dump})'"
+        system(cmd)
+      end or raise "extconf"
+      system("make") or raise "make"
+      @out_so = File.expand_path("#{@so_basename}.#{RbConfig::CONFIG['DLEXT']}")
+    }
+  end
+
+  Str = /("[^\\"]*(?:\\.[^\\"]*)*")/m
+  Com = /(\/\*.*?\*\/)/m
+  Oth = /([\w\W]+?(?=[\"\/]|\z))/m
+  CProg = /\G(?:#{Str}|#{Com}|#{Oth})/m
+
+  def preprocess_c src
+    ret = ''
+    src.scan(CProg){|str, comm, body|
+      ret << str if str
+      ret << comm if comm
+      ret << body.gsub(/\$(\w+)\b/){
+        # @ids[$~.to_s] = $1
+        "RGV(#{$1})"
+      }.gsub(/\@(\w+)\b/){
+        @ids[$~.to_s] = $1
+        "RIV(#{$1})"
+      } if body
+    }
+    ret
+  end
+
+  def csrc_function name, params, src, pre_csrc, fastcall = true
+    # self
+    if /\bself\b/ =~ src
+      self_decl = "const VALUE self = RICSIN_RUBY_SELF();"
+    else
+      self_decl = ''
+    end
+
+<<EOS
+static VALUE
+#{fastcall ? "FUNC_FASTCALL(#{name})" : name}(#{params})
+{
+  #{self_decl}
+  #{pre_csrc}
+{
+#{src}
+}
+  return Qnil;
+}
+EOS
+   end
+
+   def csrc_init_function
+<<EOS
+/* #line #{__LINE__} "#{__FILE__}" */
+
+static const rb_insn_func_t ricsin_functions[] = {
+  #{@funcs.join(",\n  ")}
+};
+
+static const char ruby_source[] = {
+#{src = ''
+  @src.each_byte.each_slice(10){|e|
+    src << '  ' + e.map{|e| '0x%02x, ' % e}.join << "\n"
+  }; src
+}
+};
+
+VALUE rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE line, VALUE opt);
+
+void
+Init_#{@so_basename}(void)
+{
+  VALUE src = rb_str_new(ruby_source, sizeof(ruby_source));
+  VALUE file = rb_str_new2("#{File.basename(@src_rcb)}");
+  VALUE line = INT2FIX(1);
+  VALUE opt = rb_hash_new();
+  VALUE iseq;
+
+  #{
+    $ricsin_init_source.map{|e|
+      "{#{e}}"
+    }.join("\n")
+  }
+
+  #{
+    @ids.map{|(k, v)|
+      "__ricsin_id_#{v} = rb_intern(\"#{k}\");"
+    }.join("\n")
+  }
+
+  rb_hash_aset(opt, ID2SYM(rb_intern("ricsin_mode")), INT2FIX(2) /* exec mode */);
+  rb_hash_aset(opt, ID2SYM(rb_intern("ricsin_funcptrs")), (VALUE)ricsin_functions | 0x01);
+
+  iseq = rb_iseq_compile_with_option(src, file, line, opt);
+
+  if (0) {
+    VALUE disasm_str = ruby_iseq_disasm(iseq);
+    rb_io_puts(1, &disasm_str, rb_stdout);
+  }
+
+  rb_iseq_eval(iseq);
+}
+EOS
+  end
+
+  def generate_func f, lvtbl, dvtbl, funcname, csrc,
+                    pre_csrc, blockcall = false
+    f.puts
+    f.puts
+    undefs = []
+
+    # write header
+
+    lvtbl.each{|(v, i)|
+      if true
+        f.puts "#define #{v} RICSIN_RUBY_VAR__#{v}"
+        undefs << v
+      end
+      f.puts "#define RICSIN_RUBY_VAR__#{v} RICSIN_RUBY_LVAR_ACCESS(#{i})"
+      undefs << "RICSIN_RUBY_VAR__#{v}"
+    }
+
+    dvtbl.each_with_index{|(v, lev, i)|
+      if true
+        f.puts "#define #{v} RICSIN_RUBY_VAR__#{v}"
+        undefs << v
+      end
+      f.puts "#define RICSIN_RUBY_VAR__#{v} RICSIN_RUBY_DVAR_ACCESS(#{lev}, #{i})"
+      undefs << "RICSIN_RUBY_VAR__#{v}"
+    }
+
+    # write body
+    if blockcall
+      params = 'VALUE arg, VALUE tval, int argc, VALUE *argv, VALUE blockarg, rb_control_frame_t *__cfp__'
+      f.puts csrc_function(funcname, params, csrc, pre_csrc, false)
+    else
+      params = "rb_control_frame_t *__cfp__"
+      f.puts csrc_function(funcname, params, csrc, pre_csrc)
+    end
+
+    # write hooter
+    undefs.each{|e|
+      f.puts "#undef #{e}"
+    }
+  end
+
+  def generate_csrc
+    $ricsin_decl_source = []
+    $ricsin_init_source = []
+    $ricsin_sources = []
+
+    iseq = RubyVM::InstructionSequence.compile(@src, @src_rcb, 1, {
+      :ricsin_mode => 1 # compile mode
+    })
+
+    # puts iseq.disasm
+    index = 0
+    @cx_info = {} # "[xid, iseqid] => [info...]"
+    @funcs = []
+    func_info = []
+
+    $ricsin_sources.each{|srcinfo|
+      @undefs = []
+      lvtbl, dvtbl, line, csrc, xid, iseqid, npc = *srcinfo
+
+      csrc.replace preprocess_c(csrc)
+
+      if npc
+        if @cx_info[[xid, iseqid]]
+          fn, ary = *@cx_info[[xid, iseqid]]
+          ary << [line, csrc, npc]
+        else
+          fn = "ricsin_func_#{index+=1}"
+          func_info << ary = [fn, srcinfo, [line, csrc, npc]]
+          @cx_info[[xid, iseqid]] = [fn, ary]
+        end
+      else
+        fn = "ricsin_func_#{index+=1}"
+        func_info << [fn, srcinfo]
+      end
+
+      @funcs << fn
+    }
+
+    open(@out_c, 'w'){|f|
+      # header
+      f.puts "/* auto generated C source code by Ricsin */"
+      # f.puts "#include \"../ricsin/ricsin.h\""
+      f.puts DATA.read
+      f.puts
+      f.puts $ricsin_decl_source.join("\n")
+      f.puts
+      f.puts @ids.map{|(k, v)|
+        "static ID __ricsin_id_#{v};"
+      }.join("\n")
+      f.puts
+
+      func_info.each{|(fn, srcinfo, *rest)|
+        lvtbl, dvtbl, line, csrc, xid, iseqid, npc = *srcinfo
+        if npc && rest.size > 1
+          npcs = []
+          csrc = rest.map{|(line, src, npc)|
+            npcs << npc
+            "/* #line #{line} \"#{@src_rcb}\" */\n" \
+            "RICSIN__label_#{npc}:; #{src}; " \
+            "RICSIN_RUBY_SET_PC(#{npc}); return Qnil;"
+          }.join("\n")
+
+          pre = "switch (RICSIN_RUBY_GET_PC()) {\n" + npcs.map{|n|
+            "case #{n}: goto RICSIN__label_#{n};"
+          }.join("\n") + "}\n"
+          generate_func(f, lvtbl, dvtbl, fn, csrc, pre)
+        else
+          csrc = "/* #line #{line} \"#{@src_rcb}\" */\n#{csrc}"
+
+          if xid == :ifunc
+            # arg, ifunc->nd_tval, argc, argv, blockarg
+            generate_func(f, lvtbl, dvtbl, fn, csrc, '', true)
+          else
+            generate_func(f, lvtbl, dvtbl, fn, csrc, '')
+          end
+        end
+      }
+
+      f.puts csrc_init_function
+    }
+  end
+end
+
+#####################################################################
+
+option = {
+  :output_dir => '.',
+  :suffix => '',
+  :run => false,
+  :output_rb => true,
+}
+
+opt = OptionParser.new{|o|
+  o.on("-C", "--directory [DIR]", 'output directory'){|dir|
+    option[:output_dir] = dir
+  }
+  o.on("-s", "--suffix [SUFFIX]", 'specify output suffix'){|s|
+    option[:suffix] = s
+  }
+  o.on("-r", "--run", 'run generated dll'){|r|
+    option[:run] = true
+  }
+  o.on("--save-ruby-file", 'generate preoprocessed ruby source code'){|g|
+    option[:output_rb] = true
+  }
+
+  o.on("-v", "--version", 'show version'){
+    puts Ricsin::VERSION_STRING
+    exit
+  }
+
+  o.on("-h", "--help", 'show this message'){
+    puts Ricsin::VERSION_STRING
+    puts
+    puts o
+    exit
+  }
+}
+
+opt.parse!(ARGV)
+
+if $0 == __FILE__
+  file = ARGV.shift
+  if /rcb$/ !~ file
+    raise "Input file of ricsin should have 'rcb' extension: #{file}"
+  else
+    option[:output_dir] = File.dirname(file)
+    Ricsin.generate file, option
+  end
+end
+
+__END__
+/* ricsin.h */
+
+#ifndef RICSIN_H
+#define RICSIN_H 1
+#include <ruby.h>
+
+typedef struct rb_iseq_struct {
+    VALUE ricsin_type;          /* instruction sequence type */
+    VALUE ricsin_name;	         /* String: iseq name */
+    VALUE ricsin_filename;      /* file information where this sequence from */
+    VALUE *ricsin_iseq;         /* iseq (insn number and openrads) */
+    VALUE *ricsin_iseq_encoded; /* encoded iseq */
+    VALUE dmy[0x10];
+} rb_iseq_t;
+
+typedef struct {
+    VALUE *ricsin_pc;			/* cfp[0] */
+    VALUE *ricsin_sp;			/* cfp[1] */
+    VALUE *ricsin_bp;			/* cfp[2] */
+    rb_iseq_t *ricsin_iseq;		/* cfp[3] */
+    VALUE ricsin_flag;			/* cfp[4] */
+    VALUE ricsin_self;			/* cfp[5] / block[0] */
+    VALUE *ricsin_lfp;			/* cfp[6] / block[1] */
+    VALUE *ricsin_dfp;			/* cfp[7] / block[2] */
+    rb_iseq_t *ricsin_block_iseq;	/* cfp[8] / block[3] */
+    VALUE ricsin_proc;			/* cfp[9] / block[4] */
+    ID ricsin_method_id;               /* cfp[10] saved in special case */
+    VALUE ricsin_method_class;         /* cfp[11] saved in special case */
+} rb_control_frame_t;
+
+typedef VALUE
+  (FUNC_FASTCALL(*rb_insn_func_t))(rb_control_frame_t *);
+
+#define RICSIN_RUBY_SELF()    (__cfp__->ricsin_self)
+
+#define RICSIN_RUBY_LVAR_ACCESS(idx) (*(__cfp__->ricsin_lfp - idx))
+#define RICSIN_RUBY_DVAR_ACCESS(lev, idx) (*ricsin_dvar_ptr(__cfp__, lev, idx))
+#define RICSIN_RUBY_GET_PC() (__cfp__->ricsin_pc - __cfp__->ricsin_iseq->ricsin_iseq_encoded)
+#define RICSIN_RUBY_SET_PC(n) do { \
+    __cfp__->ricsin_pc = __cfp__->ricsin_iseq->ricsin_iseq_encoded + (n); \
+} while (0)
+
+#define RV(name) RICSIN_RUBY_VAR__##name
+#define RIV(name) rb_ivar_get(RICSIN_RUBY_SELF(), __ricsin_id_##name)
+#define RGV(name) rb_gv_get(#name)
+#define RCV(name) rb_vm_ev_cvar_get(CLASS_OF(RUBY_SELF()), rb_intern("@@" #name)
+#define RConst(name) rb_vm_ev_const(__cfp__, rb_intern(#name))
+#define RIV_SET(name, val) rv_ivar_set(RICSIN_RUBY_SELF(), __ricsin_id_##name, val)
+#define RGV_SET(name, val) rb_gv_set(#name, val)
+#define RCV_SET(name, val) rb_vm_ev_cvar_set(__cfp__, rb_intern("@@" #name))
+
+inline static VALUE*
+ricsin_dvar_ptr(rb_control_frame_t *cfp, int lev, int idx)
+{
+    int i;
+    VALUE *dfp2 = cfp->ricsin_dfp;
+
+#define RICSIN_GET_PREV_DFP(dfp) ((VALUE *)((dfp)[0] & ~0x03))
+
+    for (i = 0; i < lev; i++) {
+	dfp2 = RICSIN_GET_PREV_DFP(dfp2);
+    }
+
+    return dfp2 - idx;
+}
+
+VALUE ruby_iseq_disasm(VALUE self);
+VALUE rb_iseq_eval(VALUE iseqval);
+VALUE rb_vm_ev_const(rb_control_frame_t *cfp, ID id);
+
+#endif /* RICSIN_H */
+

Property changes on: ricsin/ricsin/ricsin.rb
___________________________________________________________________
Name: svn:eol-style
   + LF

Index: ricsin/tool/ricsin.rb
===================================================================
--- ricsin/tool/ricsin.rb	(revision 19514)
+++ ricsin/tool/ricsin.rb	(revision 19515)
@@ -1,417 +0,0 @@
-require 'optparse'
-require 'pp'
-
-class Ricsin
-  VERSION = '0.0.1'
-  VERSION_STRING = "ricsin #{VERSION}"
-
-  def self.generate file, option
-    ricsin = self.new(file, option)
-    ricsin.generate
-    ricsin.run if option[:run]
-  end
-
-  def initialize file, option
-    @basename = File.basename(file, '.rcb')
-    @output_dir = option[:output_dir]
-    @src_rcb = file
-    @out_rb = File.join(@output_dir, "#{@basename}.rb")
-    @out_c  = File.join(@output_dir, "#{@basename}.c")
-    @out_so = nil
-    @so_basename = "ricsin_#{@basename}"
-    @src = nil
-    @option = option
-    @ids = {}
-  end
-
-  def run
-    raise unless @out_so
-    require @out_so
-  end
-
-  def generate
-    @src = preprocess(@src_rcb)
-    File.open(@out_rb, 'w'){|f|
-      f.write @src
-    } if @option[:output_rb]
-
-    generate_csrc
-    generate_dll
-  end
-
-  def preprocess file
-    # #C cexpr => __Cx__ %q{ cexpr }, 0
-    # #C:10 cexpr => __Cx__ %q{ cexpr }, 10
-
-    # kill __END__ lines
-    src = File.read(file).sub(/^__END__.+/m, '')
-
-    src = src.gsub(/^(\s*\#C\s+(.+)(?:\n|\z))+/){|lines|
-      csrc = lines.strip.split(/[\n]+/).map{|line|
-        if /^\s*\#C\s+(.+)\s*$/ =~ line
-          $1.chomp.dump
-        else
-          raise line.dump
-        end
-      }.join("\\\n")
-      "__Cx__(#{csrc}, 0)\n"
-    }
-    # .gsub(/^\s*=begin C\s*$(.+)^\s*=end\s*$/m){
-    #  #/^\s*=begin C$.+^\s*=end$/m
-    #  "__C__ <<'EOS__'\n#{$1.strip}\nEOS__"
-    #}
-
-    src
-  end
-
-  def generate_dll
-    require 'rbconfig'
-    ruby = File.join(
-      RbConfig::CONFIG["bindir"],
-      RbConfig::CONFIG["ruby_install_name"])
-
-    Dir.chdir(@output_dir){
-      if FileTest.exist? 'extconf.rb'
-        system("#{ruby} extconf.rb")
-      else
-        cmd = "#{ruby} -r mkmf -e "\
-              "'$objs=[#{(File.basename(@src_rcb, '.rcb')+'.o').dump}]; " \
-              "create_makefile(#{@so_basename.dump})'"
-        system(cmd)
-      end or raise "extconf"
-      system("make") or raise "make"
-      @out_so = File.expand_path("#{@so_basename}.#{RbConfig::CONFIG['DLEXT']}")
-    }
-  end
-
-  def preprocess_c src
-    src.gsub(/\$(\w+)\b/){
-      # @ids[$~.to_s] = $1
-      "RGV(#{$1})"
-    }.gsub(/\@(\w+)\b/){
-      @ids[$~.to_s] = $1
-      "RIV(#{$1})"
-    }
-  end
-
-  def csrc_function name, params, src, pre_csrc, fastcall = true
-    # self
-    if /\bself\b/ =~ src
-      self_decl = "const VALUE self = RICSIN_RUBY_SELF();"
-    else
-      self_decl = ''
-    end
-
-<<EOS
-static VALUE
-#{fastcall ? "FUNC_FASTCALL(#{name})" : name}(#{params})
-{
-  #{self_decl}
-  #{pre_csrc}
-{
-#{src}
-}
-  return Qnil;
-}
-EOS
-   end
-
-   def csrc_init_function
-<<EOS
-/* #line #{__LINE__} "#{__FILE__}" */
-
-static const rb_insn_func_t ricsin_functions[] = {
-  #{@funcs.join(",\n  ")}
-};
-
-static const char ruby_source[] = {
-#{src = ''
-  @src.each_byte.each_slice(10){|e|
-    src << '  ' + e.map{|e| '0x%02x, ' % e}.join << "\n"
-  }; src
-}
-};
-
-VALUE rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE line, VALUE opt);
-
-void
-Init_#{@so_basename}(void)
-{
-  VALUE src = rb_str_new(ruby_source, sizeof(ruby_source));
-  VALUE file = rb_str_new2("#{File.basename(@src_rcb)}");
-  VALUE line = INT2FIX(1);
-  VALUE opt = rb_hash_new();
-  VALUE iseq;
-
-  #{
-    $ricsin_init_source.map{|e|
-      "{#{e}}"
-    }.join("\n")
-  }
-
-  #{
-    @ids.map{|(k, v)|
-      "__ricsin_id_#{v} = rb_intern(\"#{k}\");"
-    }.join("\n")
-  }
-
-  rb_hash_aset(opt, ID2SYM(rb_intern("ricsin_mode")), INT2FIX(2) /* exec mode */);
-  rb_hash_aset(opt, ID2SYM(rb_intern("ricsin_funcptrs")), (VALUE)ricsin_functions | 0x01);
-
-  iseq = rb_iseq_compile_with_option(src, file, line, opt);
-
-  if (0) {
-    VALUE disasm_str = ruby_iseq_disasm(iseq);
-    rb_io_puts(1, &disasm_str, rb_stdout);
-  }
-
-  rb_iseq_eval(iseq);
-}
-EOS
-  end
-
-  def generate_func f, lvtbl, dvtbl, funcname, csrc,
-                    pre_csrc, blockcall = false
-    f.puts
-    f.puts
-    undefs = []
-
-    # write header
-
-    lvtbl.each{|(v, i)|
-      if true
-        f.puts "#define #{v} RICSIN_RUBY_VAR__#{v}"
-        undefs << v
-      end
-      f.puts "#define RICSIN_RUBY_VAR__#{v} RICSIN_RUBY_LVAR_ACCESS(#{i})"
-      undefs << "RICSIN_RUBY_VAR__#{v}"
-    }
-
-    dvtbl.each_with_index{|(v, lev, i)|
-      if true
-        f.puts "#define #{v} RICSIN_RUBY_VAR__#{v}"
-        undefs << v
-      end
-      f.puts "#define RICSIN_RUBY_VAR__#{v} RICSIN_RUBY_DVAR_ACCESS(#{lev}, #{i})"
-      undefs << "RICSIN_RUBY_VAR__#{v}"
-    }
-
-    # write body
-    if blockcall
-      params = 'VALUE arg, VALUE tval, int argc, VALUE *argv, VALUE blockarg, rb_control_frame_t *__cfp__'
-      f.puts csrc_function(funcname, params, csrc, pre_csrc, false)
-    else
-      params = "rb_control_frame_t *__cfp__"
-      f.puts csrc_function(funcname, params, csrc, pre_csrc)
-    end
-
-    # write hooter
-    undefs.each{|e|
-      f.puts "#undef #{e}"
-    }
-  end
-
-  def generate_csrc
-    $ricsin_decl_source = []
-    $ricsin_init_source = []
-    $ricsin_sources = []
-
-    iseq = RubyVM::InstructionSequence.compile(@src, @src_rcb, 1, {
-      :ricsin_mode => 1 # compile mode
-    })
-
-    # puts iseq.disasm
-    index = 0
-    @cx_info = {} # "[xid, iseqid] => [info...]"
-    @funcs = []
-    func_info = []
-
-    $ricsin_sources.each{|srcinfo|
-      @undefs = []
-      lvtbl, dvtbl, line, csrc, xid, iseqid, npc = *srcinfo
-
-      csrc.replace preprocess_c(csrc)
-
-      if npc
-        if @cx_info[[xid, iseqid]]
-          fn, ary = *@cx_info[[xid, iseqid]]
-          ary << [line, csrc, npc]
-        else
-          fn = "ricsin_func_#{index+=1}"
-          func_info << ary = [fn, srcinfo, [line, csrc, npc]]
-          @cx_info[[xid, iseqid]] = [fn, ary]
-        end
-      else
-        fn = "ricsin_func_#{index+=1}"
-        func_info << [fn, srcinfo]
-      end
-
-      @funcs << fn
-    }
-
-    open(@out_c, 'w'){|f|
-      # header
-      f.puts "/* auto generated C source code by Ricsin */"
-      # f.puts "#include \"../ricsin/ricsin.h\""
-      f.puts DATA.read
-      f.puts
-      f.puts $ricsin_decl_source.join("\n")
-      f.puts
-      f.puts @ids.map{|(k, v)|
-        "static ID __ricsin_id_#{v};"
-      }.join("\n")
-      f.puts
-
-      func_info.each{|(fn, srcinfo, *rest)|
-        lvtbl, dvtbl, line, csrc, xid, iseqid, npc = *srcinfo
-        if npc && rest.size > 1
-          npcs = []
-          csrc = rest.map{|(line, src, npc)|
-            npcs << npc
-            "/* #line #{line} \"#{@src_rcb}\" */\n" \
-            "RICSIN__label_#{npc}:; #{src}; " \
-            "RICSIN_RUBY_SET_PC(#{npc}); return Qnil;"
-          }.join("\n")
-
-          pre = "switch (RICSIN_RUBY_GET_PC()) {\n" + npcs.map{|n|
-            "case #{n}: goto RICSIN__label_#{n};"
-          }.join("\n") + "}\n"
-          generate_func(f, lvtbl, dvtbl, fn, csrc, pre)
-        else
-          csrc = "/* #line #{line} \"#{@src_rcb}\" */\n#{csrc}"
-
-          if xid == :ifunc
-            # arg, ifunc->nd_tval, argc, argv, blockarg
-            generate_func(f, lvtbl, dvtbl, fn, csrc, '', true)
-          else
-            generate_func(f, lvtbl, dvtbl, fn, csrc, '')
-          end
-        end
-      }
-
-      f.puts csrc_init_function
-    }
-  end
-end
-
-#####################################################################
-
-option = {
-  :output_dir => '.',
-  :suffix => '',
-  :run => false,
-  :output_rb => true,
-}
-
-opt = OptionParser.new{|o|
-  o.on("-C", "--directory [DIR]", 'output directory'){|dir|
-    option[:output_dir] = dir
-  }
-  o.on("-s", "--suffix [SUFFIX]", 'specify output suffix'){|s|
-    option[:suffix] = s
-  }
-  o.on("-r", "--run", 'run generated dll'){|r|
-    option[:run] = true
-  }
-  o.on("--save-ruby-file", 'generate preoprocessed ruby source code'){|g|
-    option[:output_rb] = true
-  }
-
-  o.on("-v", "--version", 'show version'){
-    puts Ricsin::VERSION_STRING
-    exit
-  }
-
-  o.on("-h", "--help", 'show this message'){
-    puts Ricsin::VERSION_STRING
-    puts
-    puts o
-    exit
-  }
-}
-
-opt.parse!(ARGV)
-
-if $0 == __FILE__
-  file = ARGV.shift
-  if /rcb$/ !~ file
-    raise "Input file of ricsin should have 'rcb' extension: #{file}"
-  else
-    option[:output_dir] = File.dirname(file)
-    Ricsin.generate file, option
-  end
-end
-
-__END__
-/* ricsin.h */
-
-#ifndef RICSIN_H
-#define RICSIN_H 1
-#include <ruby.h>
-
-typedef struct rb_iseq_struct {
-    VALUE ricsin_type;          /* instruction sequence type */
-    VALUE ricsin_name;	         /* String: iseq name */
-    VALUE ricsin_filename;      /* file information where this sequence from */
-    VALUE *ricsin_iseq;         /* iseq (insn number and openrads) */
-    VALUE *ricsin_iseq_encoded; /* encoded iseq */
-    VALUE dmy[0x10];
-} rb_iseq_t;
-
-typedef struct {
-    VALUE *ricsin_pc;			/* cfp[0] */
-    VALUE *ricsin_sp;			/* cfp[1] */
-    VALUE *ricsin_bp;			/* cfp[2] */
-    rb_iseq_t *ricsin_iseq;		/* cfp[3] */
-    VALUE ricsin_flag;			/* cfp[4] */
-    VALUE ricsin_self;			/* cfp[5] / block[0] */
-    VALUE *ricsin_lfp;			/* cfp[6] / block[1] */
-    VALUE *ricsin_dfp;			/* cfp[7] / block[2] */
-    rb_iseq_t *ricsin_block_iseq;	/* cfp[8] / block[3] */
-    VALUE ricsin_proc;			/* cfp[9] / block[4] */
-    ID ricsin_method_id;               /* cfp[10] saved in special case */
-    VALUE ricsin_method_class;         /* cfp[11] saved in special case */
-} rb_control_frame_t;
-
-typedef VALUE
-  (FUNC_FASTCALL(*rb_insn_func_t))(rb_control_frame_t *);
-
-#define RICSIN_RUBY_SELF()    (__cfp__->ricsin_self)
-
-#define RICSIN_RUBY_LVAR_ACCESS(idx) (*(__cfp__->ricsin_lfp - idx))
-#define RICSIN_RUBY_DVAR_ACCESS(lev, idx) (*ricsin_dvar_ptr(__cfp__, lev, idx))
-#define RICSIN_RUBY_GET_PC() (__cfp__->ricsin_pc - __cfp__->ricsin_iseq->ricsin_iseq_encoded)
-#define RICSIN_RUBY_SET_PC(n) do { \
-    __cfp__->ricsin_pc = __cfp__->ricsin_iseq->ricsin_iseq_encoded + (n); \
-} while (0)
-
-#define RV(name) RICSIN_RUBY_VAR__##name
-#define RIV(name) rb_ivar_get(RICSIN_RUBY_SELF(), __ricsin_id_##name)
-#define RGV(name) rb_gv_get(#name)
-#define RCV(name) rb_vm_ev_cvar_get(CLASS_OF(RUBY_SELF()), rb_intern("@@" #name)
-#define RConst(name) rb_vm_ev_const(__cfp__, rb_intern(#name))
-#define RIV_SET(name, val) rv_ivar_set(RICSIN_RUBY_SELF(), __ricsin_id_##name, val)
-#define RGV_SET(name, val) rb_gv_set(#name, val)
-#define RCV_SET(name, val) rb_vm_ev_cvar_set(__cfp__, rb_intern("@@" #name))
-
-inline static VALUE*
-ricsin_dvar_ptr(rb_control_frame_t *cfp, int lev, int idx)
-{
-    int i;
-    VALUE *dfp2 = cfp->ricsin_dfp;
-
-#define RICSIN_GET_PREV_DFP(dfp) ((VALUE *)((dfp)[0] & ~0x03))
-
-    for (i = 0; i < lev; i++) {
-	dfp2 = RICSIN_GET_PREV_DFP(dfp2);
-    }
-
-    return dfp2 - idx;
-}
-
-VALUE ruby_iseq_disasm(VALUE self);
-VALUE rb_iseq_eval(VALUE iseqval);
-VALUE rb_vm_ev_const(rb_control_frame_t *cfp, ID id);
-
-#endif /* RICSIN_H */
-

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

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