diff -uprN yarv000a.orig/yarv/insns.def yarv000a/yarv/insns.def
--- yarv000a.orig/yarv/insns.def	2004-01-13 22:08:32.000000000 +0900
+++ yarv000a/yarv/insns.def	2004-01-15 21:30:55.545291200 +0900
@@ -608,8 +608,26 @@ send
     bsobj = newbsobj;
     bs    = newbs;
     
+#ifdef YARV_TCC_GEN_SRC
+    {
+      //vm->pc = pc;
+      vm->sp = sp;
+      vm->lfp = lfp;
+      vm->dfp = dfp;
+      bsobj = bs->cfunc(vm, bsobj);
+      GetBSVal(bsobj, bs);
+      //pc = vm->pc;
+      sp = vm->sp;
+      lfp = vm->lfp;
+      dfp = vm->dfp;
+      /* XXX */
+      val = TOPN(0);
+      POPN(1);
+    }
+#else
 //    END_INSN();
     goto first;
+#endif
     
     
     break;
diff -uprN yarv000a.orig/yarv/tmpl/vm.inc.tmpl yarv000a/yarv/tmpl/vm.inc.tmpl
--- yarv000a.orig/yarv/tmpl/vm.inc.tmpl	2004-01-13 02:31:22.000000000 +0900
+++ yarv000a/yarv/tmpl/vm.inc.tmpl	2004-01-15 21:08:24.793004800 +0900
@@ -46,6 +46,11 @@ int vm_exec(VALUE self, VALUE bsobj){
   dfp= vm->dfp;
 
 first:
+  if (bs->cfunc) {
+    bs->cfunc(vm, bsobj);
+    goto finish;
+  } else {
+
   INSN_DISPATCH();
 
 <%= vm_body %>
@@ -54,6 +59,8 @@ first:
 /************************************/
   END_INSNS_DISPATCH();
 
+  }
+
   /* finish */
 finish:
 
diff -uprN yarv000a.orig/yarv/vm.h yarv000a/yarv/vm.h
--- yarv000a.orig/yarv/vm.h	2004-01-13 02:31:22.000000000 +0900
+++ yarv000a/yarv/vm.h	2004-01-15 21:35:43.789766400 +0900
@@ -13,7 +13,7 @@
 
 #define VMDEBUG 0
 
-#if defined(__GNUC__) && __GNUC__ >= 2
+#if defined(__GNUC__) && __GNUC__ >= 2 && 0
 #define DISPATCH_THREADED_CODE
 /* more speed up option */
 #define DISPATCH_DIRECT_THREADED_CODE
diff -uprN yarv000a.orig/yarv/yarvcore.c yarv000a/yarv/yarvcore.c
--- yarv000a.orig/yarv/yarvcore.c	2004-01-13 09:59:24.000000000 +0900
+++ yarv000a/yarv/yarvcore.c	2004-01-15 21:32:09.591764800 +0900
@@ -130,6 +130,7 @@ static VALUE bs_init(VALUE self, VALUE n
   struct bs_object *bsobj;
   GetBSVal(self, bsobj);
   bsobj->name = name;
+  bsobj->cfunc = NULL;
   bs_compile(self, node);
 
 #ifdef DISPATCH_DIRECT_THREADED_CODE
@@ -151,6 +152,24 @@ static VALUE bs_inspect(VALUE self){
   return rb_str_new2(bs_inspect_char(self));
 }
 
+static VALUE bs_bcseq(VALUE self){
+  struct bs_object *bsobj;
+  VALUE a;
+  int i;
+
+  a = rb_ary_new();
+  GetBSVal(self, bsobj);
+  for (i = 0; i < bsobj->size; i++)
+    rb_ary_push(a, ULONG2NUM(bsobj->bcseq[i]));
+  return a;
+}
+
+static VALUE bs_set_cfunc(VALUE self, VALUE sym){
+  struct bs_object *bsobj;
+  GetBSVal(self, bsobj);
+  bsobj->cfunc = (void*)NUM2ULONG(sym);
+  return sym;
+}
 
 /*********/
 /* Label */
@@ -322,6 +341,8 @@ void Init_yarvcore(){
   rb_define_method(cBS, "initialize", bs_init, 2);
   rb_define_method(cBS, "inspect",    bs_inspect, 0);
   rb_define_method(cBS, "disasm",     bs_disasm, 0);
+  rb_define_method(cBS, "bcseq",      bs_bcseq, 0);
+  rb_define_method(cBS, "set_cfunc",  bs_set_cfunc, 1);
   
   /* declare YARVCore::BytecodeSequence::Label */
   cLabel = rb_define_class_under(cBS, "Label", rb_cObject);
diff -uprN yarv000a.orig/yarv/yarvcore.h yarv000a/yarv/yarvcore.h
--- yarv000a.orig/yarv/yarvcore.h	2004-01-13 09:59:24.000000000 +0900
+++ yarv000a/yarv/yarvcore.h	2004-01-15 21:10:51.003244800 +0900
@@ -43,6 +43,7 @@ struct bs_object{
 #ifdef DISPATCH_DIRECT_THREADED_CODE
   VALUE *bcseq_dt;
 #endif
+  VALUE (*cfunc)(void*, VALUE);
   
   unsigned long size;
   unsigned long dlsize;
diff -uprN yarv000a.orig/yarv/yarvtcc.rb yarv000a/yarv/yarvtcc.rb
--- yarv000a.orig/yarv/yarvtcc.rb	1970-01-01 09:00:00.000000000 +0900
+++ yarv000a/yarv/yarvtcc.rb	2004-01-15 22:01:40.347987200 +0900
@@ -0,0 +1,160 @@
+require 'yarvcore'
+require 'insns2vm'
+require 'rbconfig'
+require 'tcc'
+require 'stringio'
+require 'shellwords'
+
+
+module YARVTCC
+  INSNS = InsnsDef.new
+
+  def self.compile(bs)
+    bcseq = bs.bcseq ###
+    src = bs2c(bcseq)
+    c2sym(src)
+  end
+
+
+  def self.bs2c(ary)
+    vars = INSNS.instance_eval{
+      vars = ''
+      InsnsDef::VARS.to_a.map{|e| [e[1], e[0]]}.sort.each{|type, var|
+	vars << "  #{type} #{var};\n"
+      }
+      vars
+    }
+
+    out = StringIO.new    
+    out.puts <<END
+#include <ruby.h>
+#include <node.h>
+
+#include "vm.h"
+#include "insnhelper.h"
+#include "insns.h"
+#include "yarvcore.h"
+
+#ifndef HAVE_TYPE_ULONG
+typedef unsigned long ulong;
+#endif
+
+#define YARV_TCC_GEN_SRC
+
+VALUE f(struct vm_object* vm, VALUE bsobj){
+  int error_code = 0; /* error code */
+  struct bs_object* bs;
+
+  VALUE *pc;
+  VALUE *sp;
+  VALUE *lfp;
+  VALUE *dfp;
+  VALUE tos = Qundef;
+
+  #{vars}
+
+  GetBSVal(bsobj, bs);
+  pc = vm->pc = GET_SEQ(bs);
+  sp = vm->sp;
+  lfp= vm->lfp;
+  dfp= vm->dfp;
+
+END
+
+    ary = ary.dup
+    pc = 0    
+    while not ary.empty?
+      out.puts "pc_#{pc}:"
+  
+      opes, pops, src = INSNS.instance_eval{
+        insn = @insns[ary.shift]
+        [@insn_opes[insn], @insn_pops[insn], @insn_body[insn]]
+      }
+
+      pc += opes.size + 1
+ 
+      src = src.select{|l| /GET_OPERAND/ !~ l }.join("")
+      src = src.select{|l| /ADD_PC/ !~ l }.join("")
+      src = src.select{|l| /END_INSN/ !~ l }.join("")
+      src.sub!(/INSN_ENTRY\(([^)]+)\)/){ "/* " + $1 + " */\n" }
+  
+      opes.each{|type, var|
+        break if type == '...'
+	v = ary.shift
+        src.gsub!(/JUMP\(#{var}\)/, "goto pc_#{pc+v}")
+        src.gsub!(/\b#{var}\b/, "((#{type})#{v})")
+      }
+  
+      out.puts src
+    end
+
+    out.puts <<END
+  /* finish */
+finish:
+  vm->sp = sp;
+  vm->pc = pc;
+  vm->lfp= lfp;
+  vm->dfp= dfp;
+
+  return bsobj;
+}
+END
+    
+    out.string
+  end # to_c_source
+
+
+
+  def self.c2sym(src)
+    # extracted from mkmf.rb
+    srcdir  = Config::CONFIG["srcdir"]
+    archdir = Config::CONFIG["archdir"]
+    if File.exist? archdir + "/ruby.h"
+      hdrdir = archdir
+    elsif File.exist? srcdir + "/ruby.h"
+      hdrdir = srcdir
+    else
+      $stderr.puts "ERROR: Can't find header files for ruby. Exiting..."
+      exit 1
+    end
+  
+    tcc = TCC.new
+    tcc.set_output_type(TCC::OUTPUT_MEMORY)
+    tcc.add_include_path(hdrdir)
+  
+    Shellwords.shellwords("#{Config::CONFIG['CFLAGS']}").each{
+      |flag|
+  
+      if m = /-I(.*)/.match(flag)
+        tcc.add_include_path(m[1])
+      elsif m = /-D([^=]+)(?:=(.+))/.match(flag)
+        m[2] ? tcc.define_symbol(m[1], m[2]) : tcc.define_symbol(m[1])
+      elsif m = /-U(.+)/.match(flag)
+        tcc.undefine_symbol(m[1])
+      elsif flag == '-g'
+        tcc.enable_debug if tcc.respond_to? :enable_debug
+      elsif m = /-O(.)/.match(flag)
+      elsif m = /-W(.*)/.match(flag)
+        tcc.set_warning(m[1], true)
+      else
+        #puts "unknown flag: #{flag}"
+      end
+    }
+  
+    tcc.compile_string(src)
+    tcc.relocate
+    tcc.get_symbol("f", "IPI")
+  end
+
+end # class YARVTCC
+
+
+module YARVCore
+  class BytecodeSequence
+    @@tcc_orig_init = instance_method(:initialize)
+    def initialize(*args)
+      @@tcc_orig_init.bind(self).call(*args)
+      self.set_cfunc(YARVTCC.compile(self).to_ptr.to_i)
+    end
+  end
+end
