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

ruby-changes:8840

From: nobu <ko1@a...>
Date: Thu, 27 Nov 2008 16:44:45 +0900 (JST)
Subject: [ruby-changes:8840] Ruby:r20376 (mvm): * merged from trunk r20281:20375.

nobu	2008-11-27 16:42:55 +0900 (Thu, 27 Nov 2008)

  New Revision: 20376

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

  Log:
    * merged from trunk r20281:20375.

  Modified files:
    branches/mvm/.merged-trunk-revision
    branches/mvm/ChangeLog
    branches/mvm/array.c
    branches/mvm/configure.in
    branches/mvm/ext/bigdecimal/bigdecimal.c
    branches/mvm/ext/bigdecimal/bigdecimal.h
    branches/mvm/ext/curses/curses.c
    branches/mvm/ext/curses/extconf.rb
    branches/mvm/ext/gdbm/gdbm.c
    branches/mvm/ext/pty/pty.c
    branches/mvm/ext/syck/rubyext.c
    branches/mvm/ext/tk/ChangeLog.tkextlib
    branches/mvm/ext/tk/lib/tkextlib/blt/tabnotebook.rb
    branches/mvm/ext/tk/lib/tkextlib/blt/tabset.rb
    branches/mvm/ext/tk/lib/tkextlib/blt/vector.rb
    branches/mvm/ext/tk/lib/tkextlib/blt.rb
    branches/mvm/ext/tk/lib/tkextlib/version.rb
    branches/mvm/file.c
    branches/mvm/lib/date/format.rb
    branches/mvm/lib/date.rb
    branches/mvm/lib/logger.rb
    branches/mvm/lib/minitest/unit.rb
    branches/mvm/lib/time.rb
    branches/mvm/node.h
    branches/mvm/numeric.c
    branches/mvm/process.c
    branches/mvm/ruby.c
    branches/mvm/sampledriver/main.c
    branches/mvm/signal.c
    branches/mvm/strftime.c
    branches/mvm/test/bigdecimal/test_bigdecimal.rb
    branches/mvm/test/cgi/test_cgi_session.rb
    branches/mvm/test/date/test_date.rb
    branches/mvm/test/date/test_date_attr.rb
    branches/mvm/test/date/test_date_strftime.rb
    branches/mvm/test/ruby/test_method.rb
    branches/mvm/test/ruby/test_time.rb
    branches/mvm/test/yaml/test_yaml.rb
    branches/mvm/thread.c
    branches/mvm/version.h
    branches/mvm/vm.c

Index: mvm/array.c
===================================================================
--- mvm/array.c	(revision 20375)
+++ mvm/array.c	(revision 20376)
@@ -2549,7 +2549,10 @@
     }
 
     len = NUM2LONG(times);
-    if (len == 0) return ary_new(rb_obj_class(ary), 0);
+    if (len == 0) {
+	ary2 = ary_new(rb_obj_class(ary), 0);
+	goto out;
+    }
     if (len < 0) {
 	rb_raise(rb_eArgError, "negative argument");
     }
@@ -2564,6 +2567,7 @@
     for (i=0; i<len; i+=RARRAY_LEN(ary)) {
 	MEMCPY(RARRAY_PTR(ary2)+i, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
     }
+  out:
     OBJ_INFECT(ary2, ary);
 
     return ary2;
Index: mvm/configure.in
===================================================================
--- mvm/configure.in	(revision 20375)
+++ mvm/configure.in	(revision 20376)
@@ -789,7 +789,7 @@
 	      setsid telldir seekdir fchmod cosh sinh tanh log2 round signbit\
 	      setuid setgid daemon select_large_fdset setenv unsetenv\
               mktime timegm gmtime_r clock_gettime gettimeofday\
-              pread sendfile shutdown)
+              pread sendfile shutdown sigaltstack)
 
 AC_CACHE_CHECK(for __builtin_setjmp, ac_cv_func___builtin_setjmp,
 [AC_TRY_LINK([@%:@include <setjmp.h>
@@ -1157,7 +1157,6 @@
 	AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled")
     fi
     AC_CHECK_FUNCS(nanosleep sched_yield pthread_attr_setinheritsched)
-    AC_CHECK_FUNCS(sigaltstack)
     AC_CHECK_FUNCS(pthread_getattr_np pthread_attr_getstack)
     AC_CHECK_FUNCS(pthread_attr_get_np)
     AC_CHECK_FUNCS(pthread_get_stackaddr_np pthread_get_stacksize_np)
Index: mvm/ChangeLog
===================================================================
--- mvm/ChangeLog	(revision 20375)
+++ mvm/ChangeLog	(revision 20376)
@@ -1,3 +1,246 @@
+Thu Nov 27 16:32:53 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* signal.c (register_sigaltstack): stores alt stack for debug
+	  purpose.
+
+Thu Nov 27 16:12:33 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* signal.c (ruby_sigaction_t): added.
+
+Thu Nov 27 15:59:16 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* gc.c (ruby_stack_check): no check if using sigaltstack.
+
+	* signal.c (ALT_STACK_SIZE): default minimum size is insufficient
+	  for method calls.
+
+	* signal.c (sigsegv): handles stack overflow if possible.
+
+	* thread.c (ruby_thread_stack_overflow): helper function to raise
+	  sysstack_error.
+
+	* thread_pthread.c (ruby_stack_overflowed_p): checks for stack
+	  overflow.
+
+Thu Nov 27 10:40:52 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_div2): should return
+	  Integer for #div operation.
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_div2): should raise
+	  ZeroDivisionError if divisor is zero.  [ruby-dev:37207]
+
+Wed Nov 26 23:15:47 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* strftime.c (STRFTIME): use rb_strftime() recursively, instead of
+	  platform's strftime().
+
+Wed Nov 26 22:46:23 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ext/bigdecimal/bigdecimal.c (VpException): bigdecimal zero
+	  division should raise FloatDomainError if mode
+	  VP_EXCEPTION_ZERODIVIDE is set.  [ruby-dev:37204]
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_mode): should handle
+	  VP_EXCEPTION_ZERODIVIDE.
+
+Wed Nov 26 15:16:07 2008  Kazuhiro NISHIYAMA  <zn@m...>
+
+	* ext/gdbm/gdbm.c (rb_gdbm_nextkey): fix memory leak.
+
+Wed Nov 26 03:17:48 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_to_r): raise exception
+	  for nan/inf conversion.  [ruby-dev:37187] fix #793
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_to_i): ditto.
+
+Wed Nov 26 03:00:59 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ext/bigdecimal/bigdecimal.c (VpAlloc): avoid ALLOCA_N() to avoid
+	  segmentation fault caused by (insanely) long decimal values.
+	  [ruby-dev:37189] fix #794
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_dump, BigDecimal_to_i,
+	  BigDecimal_to_f, BigDecimal_to_s, BigDecimal_split,
+	  BigDecimal_inspect): ditto.
+
+	* ext/bigdecimal/bigdecimal.c (VpToString): small performance
+	  improvement.
+
+Wed Nov 26 00:26:30 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* strftime.c (STRFTIME): should add padding for %[xXrR] etc.
+	  [ruby-dev:37185] fix: #792
+
+Tue Nov 25 16:26:12 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* array.c (rb_ary_times): taint (and untrust) status should be
+	  inherited by "ary * 0".  [ruby-dev:37024]
+
+Tue Nov 25 15:54:07 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* strftime.c (rb_strftime): should not swallow incomplete
+	  formatter, e.g. "%E".  [ruby-dev:37170] fix: #787
+
+	* strftime.c (rb_strftime): clear flags before processing unknown
+	  formatter, e.g. "%i".  [ruby-dev:37180]
+
+Tue Nov 25 10:35:29 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* strftime.c (rb_strftime): "%^P" should convert to upper case.
+	  [ruby-dev:37180]
+
+Tue Nov 25 07:51:18 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* strftime.c (FMT): use "%0d" formatter for zero padding, not "%.d".
+	  [ruby-dev:37168]  fix: #768
+
+	* strftime.c (rb_strftime): %s to use zero padding by default.
+	  [ruby-dev:37180]
+
+Tue Nov 25 03:37:42 2008  Hidetoshi NAGAI  <nagai@a...>
+
+	* ext/tk/lib/tkextlib/blt/tabset.rb, 
+	  ext/tk/lib/tkextlib/blt/tabnotebook.rb: 
+	  fix many bugs. Now, those work properly.
+
+Tue Nov 25 03:26:04 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* numeric.c (num_step): treat infinite step specially.
+	  [ruby-dev:37157] fix: #781.
+
+Tue Nov 25 01:23:25 2008  Tadayoshi Funaba  <tadf@d...>
+
+	* lib/date/format.rb (strftime): ignores '_' flag for %[LN].
+
+Tue Nov 25 00:08:22 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* process.c (rb_fork): stops the timer thread during fork.
+	  [ruby-dev:37117]
+
+	* thread.c (rb_thread_start_timer_thread): timer thread needs
+	  system_working to be set.
+
+Mon Nov 24 23:27:28 2008  Shugo Maeda  <shugo@r...>
+
+	* strftime.c (rb_strftime): The # flag should work with %a, %A, %b,
+	  %B, and %h.  [ruby-dev:37162]
+
+	* test/ruby/test_time.rb (test_strftime): ditto.
+
+Mon Nov 24 23:16:32 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* signal.c (register_sigaltstack): should not add external
+	  variable (with some cosmetic changes).  [ruby-dev:37158]
+
+Mon Nov 24 22:57:25 2008  Shugo Maeda  <shugo@r...>
+
+	* strftime.c (rb_strftime): A width specifier for %t and %n should
+	  work.  [ruby-dev:37160]
+
+	* test/ruby/test_time.rb (test_strftime): ditto.
+
+Mon Nov 24 22:07:07 2008  Shugo Maeda  <shugo@r...>
+
+	* strftime.c (rb_strftime): The precision of %0N should be 9.
+	  [ruby-dev:37156]
+
+	* test/ruby/test_time.rb (test_strftime): ditto.
+
+Mon Nov 24 21:38:23 2008  Shugo Maeda  <shugo@r...>
+
+	* strftime.c (rb_strftime): The default precision should be 1, not
+	  0.  [ruby-dev:37155]
+
+	* test/ruby/test_time.rb (test_strftime): ditto.
+
+Mon Nov 24 19:53:47 2008  Tadayoshi Funaba  <tadf@d...>
+
+	* lib/date.rb (inspect): changed again.
+
+Mon Nov 24 18:35:00 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* lib/time.rb: r20251 reverted.  The patched behavior do not round
+	  trip.  [ruby-core:19988]
+
+Sun Nov 23 16:04:05 2008  Yuki Sonoda (Yugui)  <yugui@y...>
+
+	* signal.c (default_handler, Init_signal): compile error if
+	  USE_SIGALTSTACK is not defined.
+
+Sun Nov 23 00:04:14 2008  Yuki Sonoda (Yugui)  <yugui@y...>
+
+	* signal.c (ALT_STACK_SIZE): 4KB is not enough on Mac OS X.
+	  Uses SIGSTKSZ.
+
+Sat Nov 22 21:29:54 2008  Yuki Sonoda (Yugui)  <yugui@y...>
+
+	* test/ruby/test_method.rb (test_default_accessiblity): test case for
+	  [ruby-dev:37124].
+
+Sat Nov 22 18:24:24 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* file.c (rb_file_world_writable_p): should return nil for non
+	  world-writable files.
+
+Sat Nov 22 10:31:25 2008  Hidetoshi NAGAI  <nagai@a...>
+
+	* ext/tk/lib/tkextlib/blt.rb, ext/tk/lib/tkextlib/blt/vector.rb: 
+	  fix NameError bug.
+
+Sat Nov 22 03:41:22 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ext/pty/pty.c (get_device_once): abandon asynchronous exception
+	  that might cause serious problem if a program terminated early.
+	  asynchronous exception is a very bad thing anyway.  use
+	  Process.waitpid(pid) or PTY.check(pid) to poll program
+	  termination. if PTY.check is called with optional second
+	  argument being true, it raises an exception same as one from
+	  previous behavior.  [incompatible] fix: [ruby-core:19583]
+
+Fri Nov 21 22:24:31 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ext/curses/curses.c (curses_escdelay_set): support ESCDELAY.  a
+	  patch from Giancarlo F Bellido <support at coaxialhost.com> in
+	  [ruby-core:19961].
+
+Fri Nov 21 22:17:15 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ruby.c (usage): -W description updated.  [ruby-core:19858]
+
+Fri Nov 21 21:50:54 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* signal.c (register_sigaltstack): use alternative stack for
+	  SIGSEGV to avoid uncaught stack overflow. based on a patch from
+	  Hiro Yoshioka <hyoshiok at miraclelinux.com> in [ruby-dev:37134].
+	  [ruby-dev:36993]
+
+Fri Nov 21 16:06:54 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* vm.c (thread_free): th->vm may be NULL when pthread_create
+	  failed for ENOMEM.  [ruby-dev:37095]
+
+Thu Nov 20 07:33:15 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* lib/logger.rb (Logger): should handle the case that cvs/svn do
+	  not expand $Id keyword.  [ruby-core:19991]
+
+Thu Nov 20 07:27:36 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* lib/minitest/unit.rb (MiniTest::Assertions#capture_io): adjust
+	  indentation to shut up warning.  [ruby-core:19993]
+
+Wed Nov 19 17:48:05 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ext/syck/rubyext.c (rb_syck_mktime): return DateTime for a value
+	  out of range of Time.   [ruby-core:19919]
+
+Wed Nov 19 14:14:38 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* node.h (NOEX_MODFUNC): should be include NOEX_PRIVATE. 
+	  [ruby-dev:37124]
+
 Wed Nov 19 03:01:04 2008  Masatoshi SEKI  <m_seki@m...>
 
 	* test/rinda/test_rinda.rb: fixed fails occasionally [ruby-dev:37119].
Index: mvm/sampledriver/main.c
===================================================================
--- mvm/sampledriver/main.c	(revision 20375)
+++ mvm/sampledriver/main.c	(revision 20376)
@@ -28,17 +28,17 @@
  */
 
 #include <stdio.h>
-#include <ruby/mvm.h>
+#include <ruby/vm.h>
 
 /* simple interpreter */
 static int
-simple_driver_example(int argc, const char *argv[])
+simple_driver_example(int argc, char *argv[])
 {
     rb_vm_t *vm;
     int err;
 
     /* create VM with command line options */
-    vm = ruby_vm_new(argc-1, argv+1);
+    vm = ruby_vm_new(argc, argv);
 
     /* invoke this VM in current thread (synchronous) */
     err = ruby_vm_run(vm);
@@ -121,13 +121,21 @@
     return 0;
 }
 
+static const char *pl[] = {
+    "",
+    "-E", "utf-8",
+    "-e", "p [RUBY_PLATFORM, RUBY_VERSION, Encoding::default_external]",
+    NULL
+};
+
 int
 main(int argc, char *argv[])
 {
-    RUBY_INITSTACK();
+    RUBY_INIT_STACK;
     ruby_sysinit(&argc, &argv); /* process level initialize */
 
     if (1) {
+	simple_driver_example(sizeof(pl)/sizeof(pl[0])-1, (char **)pl);
 	return simple_driver_example(argc, argv);
     }
     else {
Index: mvm/lib/logger.rb
===================================================================
--- mvm/lib/logger.rb	(revision 20375)
+++ mvm/lib/logger.rb	(revision 20376)
@@ -182,7 +182,13 @@
 class Logger
   VERSION = "1.2.6"
   id, name, rev = %w$Id$
-  ProgName = "#{name.chomp(",v")}/#{rev}"
+  if name
+    name = name.chomp(",v")
+  else
+    name = File.basename(__FILE__)
+  end
+  rev ||= "v#{VERSION}"
+  ProgName = "#{name}/#{rev}"
 
   class Error < RuntimeError; end
   class ShiftingError < Error; end
Index: mvm/lib/date/format.rb
===================================================================
--- mvm/lib/date/format.rb	(revision 20375)
+++ mvm/lib/date/format.rb	(revision 20376)
@@ -255,6 +255,7 @@
       when 'j'; emit_n(yday, 3, f)
       when 'k'; emit_a(hour, 2, f)
       when 'L'
+	f[:p] = nil
 	w = f[:w] || 3
 	u = 10**w
 	emit_n((sec_fraction * u).floor, w, f)
@@ -262,6 +263,7 @@
       when 'M', 'OM'; emit_n(min, 2, f)
       when 'm', 'Om'; emit_n(mon, 2, f)
       when 'N'
+	f[:p] = nil
 	w = f[:w] || 9
 	u = 10**w
 	emit_n((sec_fraction * u).floor, w, f)
Index: mvm/lib/date.rb
===================================================================
--- mvm/lib/date.rb	(revision 20375)
+++ mvm/lib/date.rb	(revision 20376)
@@ -1470,7 +1470,9 @@
   def hash() @ajd.hash end
 
   # Return internal object state as a programmer-readable string.
-  def inspect() format('#<%s: %s,%s,%s>', self.class, @ajd, @of, @sg) end
+  def inspect
+    format('#<%s: %s (%s,%s,%s)>', self.class, to_s, @ajd, @of, @sg)
+  end
 
   # Return the date as a human-readable string.
   #
Index: mvm/lib/minitest/unit.rb
===================================================================
--- mvm/lib/minitest/unit.rb	(revision 20375)
+++ mvm/lib/minitest/unit.rb	(revision 20376)
@@ -191,12 +191,12 @@
       assert caught, message(msg) { default }
     end
 
-   def capture_io
-     require 'stringio'
+    def capture_io
+      require 'stringio'
 
-     orig_stdout, orig_stderr         = $stdout, $stderr
-     captured_stdout, captured_stderr = StringIO.new, StringIO.new
-     $stdout, $stderr                 = captured_stdout, captured_stderr
+      orig_stdout, orig_stderr         = $stdout, $stderr
+      captured_stdout, captured_stderr = StringIO.new, StringIO.new
+      $stdout, $stderr                 = captured_stdout, captured_stderr
 
       yield
 
Index: mvm/lib/time.rb
===================================================================
--- mvm/lib/time.rb	(revision 20375)
+++ mvm/lib/time.rb	(revision 20376)
@@ -84,9 +84,27 @@
     end
 
     def zone_utc?(zone)
-      # * -0000 means localtime. [RFC 2822]
-      # * GMT is a localtime abbreviation in Europe/London, etc.
-      if /\A(?:\+00:00|\+0000|\+00|UTC|Z|UT)\z/i =~ zone
+      # * +0000
+      #   In RFC 2822, +0000 indicate a time zone at Universal Time.
+      #   Europe/London is "a time zone at Universal Time" in Winter.
+      #   Europe/Lisbon is "a time zone at Universal Time" in Winter.
+      #   Atlantic/Reykjavik is "a time zone at Universal Time".
+      #   Africa/Dakar is "a time zone at Universal Time".
+      #   So +0000 is a local time such as Europe/London, etc.
+      # * GMT
+      #   GMT is used as a time zone abbreviation in Europe/London,
+      #   Africa/Dakar, etc.
+      #   So it is a local time.
+      #
+      # * -0000, -00:00
+      #   In RFC 2822, -0000 the date-time contains no information about the
+      #   local time zone.
+      #   In RFC 3339, -00:00 is used for the time in UTC is known,
+      #   but the offset to local time is unknown.
+      #   They are not appropriate for specific time zone such as
+      #   Europe/London because time zone neutral, 
+      #   So -00:00 and -0000 are treated as UTC.
+      if /\A(?:-00:00|-0000|-00|UTC|Z|UT)\z/i =~ zone
         true
       else
         false
@@ -409,7 +427,7 @@
   #
   # where zone is [+-]hhmm.
   #
-  # If +self+ is a UTC time, +0000 is used as zone.
+  # If +self+ is a UTC time, -0000 is used as zone.
   #
   def rfc2822
     sprintf('%s, %02d %s %d %02d:%02d:%02d ',
@@ -417,7 +435,7 @@
       day, RFC2822_MONTH_NAME[mon-1], year,
       hour, min, sec) +
     if utc?
-      '+0000'
+      '-0000'
     else
       off = utc_offset
       sign = off < 0 ? '-' : '+'
@@ -730,86 +748,98 @@
 
     def test_zone_0000
       assert_equal(true, Time.parse("2000-01-01T00:00:00Z").utc?)
-      assert_equal(true, Time.parse("2000-01-01T00:00:00+00:00").utc?)
-      assert_equal(false, Time.parse("2000-01-01T00:00:00-00:00").utc?)
+      assert_equal(true, Time.parse("2000-01-01T00:00:00-00:00").utc?)
+      assert_equal(false, Time.parse("2000-01-01T00:00:00+00:00").utc?)
       assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 GMT").utc?)
-      assert_equal(true, Time.parse("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
-      assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+      assert_equal(true, Time.parse("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+      assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
       assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 GMT").utc?)
-      assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
-      assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+      assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+      assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
       assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 UTC").utc?)
     end
 
+    def test_rfc2822_utc_roundtrip_winter
+      t1 = Time.local(2008,12,1)
+      t2 = Time.rfc2822(t1.rfc2822)
+      assert_equal(t1.utc?, t2.utc?, "[ruby-dev:37126]")
+    end
+
+    def test_rfc2822_utc_roundtrip_summer
+      t1 = Time.local(2008,8,1)
+      t2 = Time.rfc2822(t1.rfc2822)
+      assert_equal(t1.utc?, t2.utc?)
+    end
+
     def test_parse_leap_second
       t = Time.utc(1998,12,31,23,59,59)
       assert_equal(t, Time.parse("Thu Dec 31 23:59:59 UTC 1998"))
-      assert_equal(t, Time.parse("Fri Dec 31 23:59:59 +0000 1998"));t.localtime
+      assert_equal(t, Time.parse("Fri Dec 31 23:59:59 -0000 1998"));t.localtime
       assert_equal(t, Time.parse("Fri Jan  1 08:59:59 +0900 1999"))
       assert_equal(t, Time.parse("Fri Jan  1 00:59:59 +0100 1999"))
-      assert_equal(t, Time.parse("Fri Dec 31 23:59:59 -0000 1998"))
+      assert_equal(t, Time.parse("Fri Dec 31 23:59:59 +0000 1998"))
       assert_equal(t, Time.parse("Fri Dec 31 22:59:59 -0100 1998"));t.utc
       t += 1
       assert_equal(t, Time.parse("Thu Dec 31 23:59:60 UTC 1998"))
-      assert_equal(t, Time.parse("Fri Dec 31 23:59:60 +0000 1998"));t.localtime
+      assert_equal(t, Time.parse("Fri Dec 31 23:59:60 -0000 1998"));t.localtime
       assert_equal(t, Time.parse("Fri Jan  1 08:59:60 +0900 1999"))
       assert_equal(t, Time.parse("Fri Jan  1 00:59:60 +0100 1999"))
-      assert_equal(t, Time.parse("Fri Dec 31 23:59:60 -0000 1998"))
+      assert_equal(t, Time.parse("Fri Dec 31 23:59:60 +0000 1998"))
       assert_equal(t, Time.parse("Fri Dec 31 22:59:60 -0100 1998"));t.utc
       t += 1 if t.sec == 60
       assert_equal(t, Time.parse("Thu Jan  1 00:00:00 UTC 1999"))
-      assert_equal(t, Time.parse("Fri Jan  1 00:00:00 +0000 1999"));t.localtime
+      assert_equal(t, Time.parse("Fri Jan  1 00:00:00 -0000 1999"));t.localtime
       assert_equal(t, Time.parse("Fri Jan  1 09:00:00 +0900 1999"))
       assert_equal(t, Time.parse("Fri Jan  1 01:00:00 +0100 1999"))
-      assert_equal(t, Time.parse("Fri Jan  1 00:00:00 -0000 1999"))
+      assert_equal(t, Time.parse("Fri Jan  1 00:00:00 +0000 1999"))
       assert_equal(t, Time.parse("Fri Dec 31 23:00:00 -0100 1998"))
     end
 
     def test_rfc2822_leap_second
       t = Time.utc(1998,12,31,23,59,59)
       assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:59 UTC"))
-      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 +0000"));t.localtime
+      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 -0000"));t.localtime
       assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 08:59:59 +0900"))
       assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:59:59 +0100"))
-      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 -0000"))
+      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 +0000"))
       assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:59 -0100"));t.utc
       t += 1
       assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:60 UTC"))
-      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 +0000"));t.localtime
+      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 -0000"));t.localtime
       assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 08:59:60 +0900"))
       assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:59:60 +0100"))
-      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 -0000"))
+      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 +0000"))
       assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:60 -0100"));t.utc
       t += 1 if t.sec == 60
       assert_equal(t, Time.rfc2822("Thu,  1 Jan 1999 00:00:00 UTC"))
-      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:00:00 +0000"));t.localtime
+      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:00:00 -0000"));t.localtime
       assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 09:00:00 +0900"))
       assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 01:00:00 +0100"))
-      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:00:00 -0000"))
+      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:00:00 +0000"))
       assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:00:00 -0100"))
     end
 
     def test_xmlschema_leap_second
       t = Time.utc(1998,12,31,23,59,59)
       assert_equal(t, Time.xmlschema("1998-12-31T23:59:59Z"))
-      assert_equal(t, Time.xmlschema("1998-12-31T23:59:59+00:00"));t.localtime
+      assert_equal(t, Time.xmlschema("1998-12-31T23:59:59-00:00"));t.localtime
       assert_equal(t, Time.xmlschema("1999-01-01T08:59:59+09:00"))
       assert_equal(t, Time.xmlschema("1999-01-01T00:59:59+01:00"))
-      assert_equal(t, Time.xmlschema("1998-12-31T23:59:59-00:00"))
+      assert_equal(t, Time.xmlschema("1998-12-31T23:59:59+00:00"))
       assert_equal(t, Time.xmlschema("1998-12-31T22:59:59-01:00"));t.utc
       t += 1
       assert_equal(t, Time.xmlschema("1998-12-31T23:59:60Z"))
-      assert_equal(t, Time.xmlschema("1998-12-31T23:59:60+00:00"));t.localtime
+      assert_equal(t, Time.xmlschema("1998-12-31T23:59:60-00:00"));t.localtime
       assert_equal(t, Time.xmlschema("1999-01-01T08:59:60+09:00"))
       assert_equal(t, Time.xmlschema("1999-01-01T00:59:60+01:00"))
-      assert_equal(t, Time.xmlschema("1998-12-31T23:59:60-00:00"))
+      assert_equal(t, Time.xmlschema("1998-12-31T23:59:60+00:00"))
       assert_equal(t, Time.xmlschema("1998-12-31T22:59:60-01:00"));t.utc
       t += 1 if t.sec == 60
       assert_equal(t, Time.xmlschema("1999-01-01T00:00:00Z"))
-      assert_equal(t, Time.xmlschema("1999-01-01T00:00:00+00:00"));t.localtime
+      assert_equal(t, Time.xmlschema("1999-01-01T00:00:00-00:00"));t.localtime
       assert_equal(t, Time.xmlschema("1999-01-01T09:00:00+09:00"))
       assert_equal(t, Time.xmlschema("1999-01-01T01:00:00+01:00"))
-      assert_equal(t, Time.xmlschema("1999-01-01T00:00:00-00:00"))
+      assert_equal(t, Time.xmlschema("1999-01-01T00:00:00+00:00"))
       assert_equal(t, Time.xmlschema("1998-12-31T23:00:00-01:00"))
     end
 
Index: mvm/thread.c
===================================================================
--- mvm/thread.c	(revision 20375)
+++ mvm/thread.c	(revision 20376)
@@ -1268,6 +1268,14 @@
     rb_thread_raise(2, argv, th->vm->main_thread);
 }
 
+void
+ruby_thread_stack_overflow(rb_thread_t *th)
+{
+    th->errinfo = sysstack_error;
+    th->raised_flag = 0;
+    TH_JUMP_TAG(th, TAG_RAISE);
+}
+
 int
 rb_thread_set_raised(rb_thread_t *th)
 {
@@ -2489,6 +2497,7 @@
 void
 rb_thread_start_timer_thread(void)
 {
+    system_working = 1;
     rb_thread_create_timer_thread();
 }
 
Index: mvm/strftime.c
===================================================================
--- mvm/strftime.c	(revision 20375)
+++ mvm/strftime.c	(revision 20376)
@@ -270,22 +270,37 @@
 				goto unknown; \
 		} while (0)
 #define NEEDS(n) do if (s + (n) >= endp - 1) goto err; while (0)
+#define FILL_PADDING(i) do { \
+	if (!(flags & BIT_OF(LEFT)) && precision > i) { \
+		NEEDS(precision); \
+		memset(s, padding ? padding : ' ', precision - i); \
+		s += precision - i; \
+	} \
+	else { \
+		NEEDS(i); \
+	} \
+} while (0);
 #define FMT(def_pad, def_prec, fmt, val) \
 		do { \
 			int l; \
 			if (precision <= 0) precision = (def_prec); \
 			if (flags & BIT_OF(LEFT)) precision = 1; \
 			l = snprintf(s, endp - s, \
-				     ((padding == '0' || (!padding && def_pad == '0')) ? "%.*"fmt : "%*"fmt), \
+				     ((padding == '0' || (!padding && def_pad == '0')) ? "%0*"fmt : "%*"fmt), \
 				     precision, val); \
 			if (l < 0) goto err; \
 			s += l; \
 		} while (0)
-#define STRFTIME(fmt, tm) \
+#define STRFTIME(fmt) \
 		do { \
-			i = strftime(s, endp - s, fmt, tm); \
+			i = rb_strftime(s, endp - s, fmt, timeptr, ts, gmt); \
 			if (!i) return 0; \
-			s += i; \
+			if (precision > i) {\
+				memmove(s + precision - i, s, i);\
+				memset(s, padding ? padding : ' ', precision - i); \
+				s += precision;	\
+	                }\
+			else s += i; \
 		} while (0)
 
 		if (*format != '%') {
@@ -300,14 +315,18 @@
 	again:
 		switch (*++format) {
 		case '\0':
-			*s++ = '%';
-			goto out;
+			format--;
+			goto unknown;
 
 		case '%':
 			*s++ = '%';
 			continue;
 
 		case 'a':	/* abbreviated weekday name */
+			if (flags & BIT_OF(CHCASE)) {
+				flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
+				flags |= BIT_OF(UPPER);
+			}
 			if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
 				i = 1, tp = "?";
 			else
@@ -315,6 +334,10 @@
 			break;
 
 		case 'A':	/* full weekday name */
+			if (flags & BIT_OF(CHCASE)) {
+				flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
+				flags |= BIT_OF(UPPER);
+			}
 			if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
 				i = 1, tp = "?";
 			else
@@ -325,6 +348,10 @@
 		case 'h':	/* abbreviated month name */
 #endif
 		case 'b':	/* abbreviated month name */
+			if (flags & BIT_OF(CHCASE)) {
+				flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
+				flags |= BIT_OF(UPPER);
+			}
 			if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
 				i = 1, tp = "?";
 			else
@@ -332,6 +359,10 @@
 			break;
 
 		case 'B':	/* full month name */
+			if (flags & BIT_OF(CHCASE)) {
+				flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
+				flags |= BIT_OF(UPPER);
+			}
 			if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
 				i = 1, tp = "?";
 			else
@@ -339,7 +370,7 @@
 			break;
 
 		case 'c':	/* appropriate date and time representation */
-			STRFTIME("%a %b %e %H:%M:%S %Y", timeptr);
+			STRFTIME("%a %b %e %H:%M:%S %Y");
 			continue;
 
 		case 'd':	/* day of the month, 01 - 31 */
@@ -378,7 +409,7 @@
 		case 'p':	/* AM or PM based on 12-hour clock */
 		case 'P':	/* am or pm based on 12-hour clock */
 			if ((*format == 'p' && (flags & BIT_OF(CHCASE))) ||
-			    (*format == 'P' && !(flags & BIT_OF(CHCASE)))) {
+			    (*format == 'P' && !(flags & (BIT_OF(CHCASE)|BIT_OF(UPPER))))) {
 				flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE));
 				flags |= BIT_OF(LOWER);
 			}
@@ -391,7 +422,7 @@
 			break;
 
 		case 's':
-			FMT(' ', 1, "d", (int) ts->tv_sec);
+			FMT('0', 1, "d", (int) ts->tv_sec);
 			continue;
 
 		case 'S':	/* second, 00 - 60 */
@@ -405,7 +436,7 @@
 
 		case 'w':	/* weekday, Sunday == 0, 0 - 6 */
 			i = range(0, timeptr->tm_wday, 6);
-			FMT('0', 0, "d", i);
+			FMT('0', 1, "d", i);
 			continue;
 
 		case 'W':	/* week of year, Monday is first day of week */
@@ -413,11 +444,11 @@
 			continue;
 
 		case 'x':	/* appropriate date representation */
-			STRFTIME("%m/%d/%y", timeptr);
+			STRFTIME("%m/%d/%y");
 			continue;
 
 		case 'X':	/* appropriate time representation */
-			STRFTIME("%H:%M:%S", timeptr);
+			STRFTIME("%H:%M:%S");
 			continue;
 
 		case 'y':	/* year without a century, 00 - 99 */
@@ -426,7 +457,7 @@
 			continue;
 
 		case 'Y':	/* year with century */
-			FMT('0', 0, "ld", 1900L + timeptr->tm_year);
+			FMT('0', 1, "ld", 1900L + timeptr->tm_year);
 			continue;
 
 #ifdef MAILHEADER_EXT
@@ -540,17 +571,17 @@
 
 #ifdef SYSV_EXT
 		case 'n':	/* same as \n */
-			NEEDS(1);
+			FILL_PADDING(1);
 			*s++ = '\n';
 			continue;
 
 		case 't':	/* same as \t */
-			NEEDS(1);
+			FILL_PADDING(1);
 			*s++ = '\t';
 			continue;
 
 		case 'D':	/* date as %m/%d/%y */
-			STRFTIME("%m/%d/%y", timeptr);
+			STRFTIME("%m/%d/%y");
 			continue;
 
 		case 'e':	/* day of month, blank padded */
@@ -558,15 +589,15 @@
 			continue;
 
 		case 'r':	/* time as %I:%M:%S %p */
-			STRFTIME("%I:%M:%S %p", timeptr);
+			STRFTIME("%I:%M:%S %p");
 			continue;
 
 		case 'R':	/* time as %H:%M */
-			STRFTIME("%H:%M", timeptr);
+			STRFTIME("%H:%M");
 			continue;
 
 		case 'T':	/* time as %H:%M:%S */
-			STRFTIME("%H:%M:%S", timeptr);
+			STRFTIME("%H:%M:%S");
 			continue;
 #endif
 
@@ -623,7 +654,7 @@
 
 		case 'u':
 		/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
-			FMT('0', 0, "d", timeptr->tm_wday == 0 ? 7 : timeptr->tm_wday);
+			FMT('0', 1, "d", timeptr->tm_wday == 0 ? 7 : timeptr->tm_wday);
 			continue;
 #endif	/* POSIX2_DATE */
 
@@ -648,7 +679,7 @@
 				y = 1900L + timeptr->tm_year;
 
 			if (*format == 'G')
-				FMT('0', 0, "ld", y);
+				FMT('0', 1, "ld", y);
 			else
 				FMT('0', 2, "ld", y % 100);
 			continue;
@@ -673,8 +704,7 @@
 			{
 				long n = ts->tv_nsec;
 
-				if (precision == 0) continue;
-				if (precision < 0) {
+				if (precision <= 0) {
 				    precision = w;
 				}
 				NEEDS(precision);
@@ -737,19 +767,15 @@
 
 		default:
 		unknown:
+			i = format - sp + 1;
 			tp = sp;
-			i = format - sp + 1;
+			precision = -1;
+			flags = 0;
+			padding = 0;
 			break;
 		}
 		if (i) {
-			if (!(flags & BIT_OF(LEFT)) && precision > i) {
-				NEEDS(precision);
-				memset(s, padding ? padding : ' ', precision - i);
-				s += precision - i;
-			}
-			else {
-				NEEDS(i);
-			}
+			FILL_PADDING(i);
 			memcpy(s, tp, i);
 			switch (flags & (BIT_OF(UPPER)|BIT_OF(LOWER))) {
 			case BIT_OF(UPPER):
@@ -768,7 +794,6 @@
 			}
 		}
 	}
-out:
 	if (s >= endp) {
 		goto err;
 	}
Index: mvm/process.c
===================================================================
--- mvm/process.c	(revision 20375)
+++ mvm/process.c	(revision 20376)
@@ -969,6 +969,8 @@
   (rb_enable_interrupt(), rb_thread_stop_timer_thread())
 #define after_exec() \
   (rb_thread_start_timer_thread(), rb_disable_interrupt())
+#define before_fork() before_exec()
+#define after_fork() after_exec()
 
 #include "dln.h"
 
@@ -2275,7 +2277,8 @@
 	}
     }
 #endif
-    for (; (pid = fork()) < 0; prefork()) {
+    for (; before_fork(), (pid = fork()) < 0; prefork()) {
+	after_fork();
 	switch (errno) {
 	  case EAGAIN:
 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
@@ -2301,7 +2304,6 @@
 	}
     }
     if (!pid) {
-	rb_thread_reset_timer_thread();
 	if (chfunc) {
 #ifdef FD_CLOEXEC
 	    close(ep[0]);
@@ -2317,10 +2319,10 @@
 	    _exit(127);
 #endif
 	}
-	rb_thread_start_timer_thread();
     }
+    after_fork();
 #ifdef FD_CLOEXEC
-    else if (chfunc) {
+    if (pid && chfunc) {
 	close(ep[1]);
 	if ((state = read(ep[0], &err, sizeof(err))) < 0) {
 	    err = errno;
Index: mvm/ext/bigdecimal/bigdecimal.c
===================================================================
--- mvm/ext/bigdecimal/bigdecimal.c	(revision 20375)
+++ mvm/ext/bigdecimal/bigdecimal.c	(revision 20376)
@@ -309,17 +309,19 @@
 BigDecimal_dump(int argc, VALUE *argv, VALUE self)
 {
     ENTER(5);
-    char sz[50];
     Real *vp;
     char *psz;
     VALUE dummy;
+    volatile VALUE dump;
+
     rb_scan_args(argc, argv, "01", &dummy);
     GUARD_OBJ(vp,GetVpValue(self,1));
-    sprintf(sz,"%lu:",VpMaxPrec(vp)*VpBaseFig());
-    psz = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E")+strlen(sz));
-    sprintf(psz,"%s",sz);
+    dump = rb_str_new(0,VpNumOfChars(vp,"E")+50);
+    psz = RSTRING_PTR(dump);
+    sprintf(psz,"%lu:",VpMaxPrec(vp)*VpBaseFig());
     VpToString(vp, psz+strlen(psz), 0, 0);
-    return rb_str_new2(psz);
+    rb_str_resize(dump, strlen(psz));
+    return dump;
 }
 
 /*
@@ -423,6 +425,11 @@
                            (fo&(~VP_EXCEPTION_UNDERFLOW))));
         }
         fo = VpGetException();
+        if(f&VP_EXCEPTION_ZERODIVIDE) {
+            VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_ZERODIVIDE):
+                           (fo&(~VP_EXCEPTION_ZERODIVIDE))));
+        }
+        fo = VpGetException();
         return INT2FIX(fo);
     }
     if(VP_ROUND_MODE==f) {
@@ -519,6 +526,18 @@
     return Qtrue;
 }
 
+static void
+BigDecimal_check_num(Real *p)
+{
+    if(VpIsNaN(p)) {
+       VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",1);
+    } else if(VpIsPosInf(p)) {
+       VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",1);
+    } else if(VpIsNegInf(p)) {
+       VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",1);
+    }
+}
+
 /* Returns the value as an integer (Fixnum or Bignum).
  *
  * If the BigNumber is infinity or NaN, returns nil.
@@ -529,23 +548,13 @@
     ENTER(5);
     int e,n,i,nf;
     U_LONG v,b,j;
+    volatile VALUE str;
     char *psz,*pch;
     Real *p;
 
     GUARD_OBJ(p,GetVpValue(self,1));
+    BigDecimal_check_num(p);
 
-    /* Infinity or NaN not converted. */
-    if(VpIsNaN(p)) {
-       VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",0);
-       return Qnil;
-    } else if(VpIsPosInf(p)) {
-       VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",0);
-       return Qnil;
-    } else if(VpIsNegInf(p)) {
-       VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",0);
-       return Qnil;
-    }
-
     e = VpExponent10(p);
     if(e<=0) return INT2FIX(0);
     nf = VpBaseFig();
@@ -553,7 +562,8 @@
         e = VpGetSign(p)*p->frac[0];
         return INT2FIX(e);
     }
-    psz = ALLOCA_N(char,(unsigned int)(e+nf+2));
+    str = rb_str_new(0, e+nf+2);
+    psz = RSTRING_PTR(str);
 
     n = (e+nf-1)/nf;
     pch = psz;
@@ -591,10 +601,12 @@
     double d;
     S_LONG e;
     char *buf;
+    volatile VALUE str;
 
     GUARD_OBJ(p,GetVpValue(self,1));
     if(VpVtoD(&d, &e, p)!=1) return rb_float_new(d);
-    buf = ALLOCA_N(char,(unsigned int)VpNumOfChars(p,"E"));
+    str = rb_str_new(0, VpNumOfChars(p,"E"));
+    buf = RSTRING_PTR(str);
     VpToString(p, buf, 0, 0);
     errno = 0;
     d = strtod(buf, 0);
@@ -619,6 +631,8 @@
     VALUE a, digits, numerator;
 
     p = GetVpValue(self,1);
+    BigDecimal_check_num(p);
+
     sign = VpGetSign(p);
     power = VpExponent10(p);
     a = BigDecimal_split(self);
@@ -1155,7 +1169,10 @@
        Real *mod;
        obj = BigDecimal_DoDivmod(self,b,&div,&mod);
        if(obj!=(VALUE)0) return obj;
-       return ToValue(div);
+       if(VpIsNaN(div) && rb_equal(b, INT2FIX(0))) {
+	   rb_raise(rb_eZeroDivError, "divided by 0");
+       }
+       return BigDecimal_to_i(ToValue(div));
     } else {    /* div in BigDecimal sense */
        U_LONG ix = (U_LONG)GetPositiveInt(n);
        if(ix==0) return BigDecimal_div(self,b);
@@ -1541,6 +1558,7 @@
     int   fmt=0;   /* 0:E format */
     int   fPlus=0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */
     Real  *vp;
+    volatile VALUE str;
     char  *psz;
     char   ch;
     U_LONG nc;
@@ -1577,14 +1595,16 @@
     }
     if(mc>0) nc += (nc + mc - 1) / mc + 1;
 
-    psz = ALLOCA_N(char,(unsigned int)nc);
+    str = rb_str_new(0, nc);
+    psz = RSTRING_PTR(str);
 
     if(fmt) {
         VpToFString(vp, psz, mc, fPlus);
     } else {
         VpToString (vp, psz, mc, fPlus);
     }
-    return rb_str_new2(psz);
+    rb_str_resize(str, strlen(psz));
+    return str;
 }
 
 /* Splits a BigDecimal number into four parts, returned as an array of values.
@@ -1616,24 +1636,29 @@
 {
     ENTER(5);
     Real *vp;
-    VALUE obj,obj1;
+    VALUE obj,str;
     S_LONG e;
     S_LONG s;
     char *psz1;
 
     GUARD_OBJ(vp,GetVpValue(self,1));
-    psz1 = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E"));
+    str = rb_str_new(0, VpNumOfChars(vp,"E"));
+    psz1 = RSTRING_PTR(str);
     VpSzMantissa(vp,psz1);
     s = 1;
     if(psz1[0]=='-') {
-        s = -1; ++psz1;
+	int len = strlen(psz1+1);
+
+	memmove(psz1, psz1+1, len);
+	psz1[len] = '\0';
+        s = -1;
     }
     if(psz1[0]=='N') s=0; /* NaN */
     e = VpExponent10(vp);
-    obj1 = rb_str_new2(psz1);
     obj  = rb_ary_new2(4);
     rb_ary_push(obj, INT2FIX(s));
-    rb_ary_push(obj, obj1);
+    rb_ary_push(obj, str);
+    rb_str_resize(str, strlen(psz1));
     rb_ary_push(obj, INT2FIX(10));
     rb_ary_push(obj, INT2NUM(e));
     return obj;
@@ -1666,20 +1691,22 @@
 {
     ENTER(5);
     Real *vp;
-    VALUE obj;
+    volatile VALUE obj;
     unsigned int nc;
-    char *psz1;
-    char *pszAll;
+    char *psz, *tmp;
 
     GUARD_OBJ(vp,GetVpValue(self,1));
     nc = VpNumOfChars(vp,"E");
     nc +=(nc + 9) / 10;
 
-    psz1   = ALLOCA_N(char,nc);
-    pszAll = ALLOCA_N(char,nc+256);
-    VpToString(vp, psz1, 10, 0);
-    sprintf(pszAll,"#<BigDecimal:%lx,'%s',%lu(%lu)>",self,psz1,VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig());
-    obj = rb_str_new2(pszAll);
+    obj = rb_str_new(0, nc+256);
+    psz = RSTRING_PTR(obj);
+    sprintf(psz,"#<BigDecimal:%lx,'",self);
+    tmp = psz + strlen(psz);
+    VpToString(vp, tmp, 10, 0);
+    tmp += strlen(tmp);
+    sprintf(tmp,"',%lu(%lu)>",VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig());
+    rb_str_resize(obj, strlen(psz));
     return obj;
 }
 
@@ -2251,18 +2278,12 @@
         switch(f)
         {
         /*
-        case VP_EXCEPTION_ZERODIVIDE:
         case VP_EXCEPTION_OVERFLOW:
         */
+        case VP_EXCEPTION_ZERODIVIDE:
         case VP_EXCEPTION_INFINITY:
-             exc = rb_eFloatDomainError;
-             goto raise;
         case VP_EXCEPTION_NaN:
-             exc = rb_eFloatDomainError;
-             goto raise;
         case VP_EXCEPTION_UNDERFLOW:
-             exc = rb_eFloatDomainError;
-             goto raise;
         case VP_EXCEPTION_OP:
              exc = rb_eFloatDomainError;
              goto raise;
@@ -2534,6 +2555,7 @@
     int  sign=1;
     Real *vp = NULL;
     U_LONG mf = VpGetPrecLimit();
+    volatile VALUE buf;
 
     mx = (mx + BASE_FIG - 1) / BASE_FIG + 1;    /* Determine allocation unit. */
     if(szVal) {
@@ -2561,7 +2583,8 @@
 
     /* Skip all '_' after digit: 2006-6-30 */
     ni = 0;
-    psz = ALLOCA_N(char,strlen(szVal)+1);
+    buf = rb_str_new(0,strlen(szVal)+1);
+    psz = RSTRING_PTR(buf);
     i   = 0;
     ipn = 0;
     while((psz[i]=szVal[ipn])!=0) {
@@ -3656,7 +3679,7 @@
                 nc += fprintf(fp, "0.");
                 n = a->Prec;
                 for(i=0;i < n;++i) {
-                 m = BASE1;
+		    m = BASE1;
                     e = a->frac[i];
                     while(m) {
                         nn = e / m;
@@ -3838,7 +3861,7 @@
 /* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */
 {
     U_LONG i, ZeroSup;
-    U_LONG n, m, e, nn;
+    U_LONG n, e;
     char *pszSav = psz;
     S_LONG ex;
 
@@ -3854,18 +3877,12 @@
     *psz++ = '.';
     n = a->Prec;
     for(i=0;i < n;++i) {
-        m = BASE1;
         e = a->frac[i];
-        while(m) {
-            nn = e / m;
-            if((!ZeroSup) || nn) {
-                sprintf(psz, "%lu", nn);    /* The reading zero(s) */
-                psz += strlen(psz);
-                /* as 0.00xx will be ignored. */
-                ZeroSup = 0;    /* Set to print succeeding zeros */
-            }
-            e = e - nn * m;
-            m /= 10;
+	if((!ZeroSup) || e) {
+	    sprintf(psz, "%lu", e);    /* The reading zero(s) */
+	    psz += strlen(psz);
+	    /* as 0.00xx will be ignored. */
+	    ZeroSup = 0;    /* Set to print succeeding zeros */
         }
     }
     ex =(a->exponent) * BASE_FIG;
Index: mvm/ext/bigdecimal/bigdecimal.h
===================================================================
--- mvm/ext/bigdecimal/bigdecimal.h	(revision 20375)
+++ mvm/ext/bigdecimal/bigdecimal.h	(revision 20376)
@@ -45,7 +45,7 @@
 #define VP_EXCEPTION_NaN        ((unsigned short)0x0002)
 #define VP_EXCEPTION_UNDERFLOW  ((unsigned short)0x0004)
 #define VP_EXCEPTION_OVERFLOW   ((unsigned short)0x0001) /* 0x0008) */
-#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0001) /* 0x0010) */
+#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010)
 
 /* Following 2 exceptions cann't controlled by user */
 #define VP_EXCEPTION_OP         ((unsigned short)0x0020)
Index: mvm/ext/curses/curses.c
===================================================================
--- mvm/ext/curses/curses.c	(revision 20375)
+++ mvm/ext/curses/curses.c	(revision 20376)
@@ -573,6 +573,27 @@
 }
 
 static VALUE
+curses_escdelay_set(VALUE obj, VALUE val)
+{
+#if defined(HAVE_ESCDELAY)
+	ESCDELAY=NUM2INT(val);
+	return INT2NUM(ESCDELAY);
+#else
+	rb_notimplement();
+#endif
+}
+
+static VALUE
+curses_escdelay_get(VALUE obj)
+{
+#if defined(HAVE_ESCDELAY)
+	return INT2NUM(ESCDELAY);
+#else
+	rb_notimplement();
+#endif
+}
+
+static VALUE
 curses_resizeterm(VALUE obj, VALUE lin, VALUE col)
 {
 #if defined(HAVE_RESIZETERM)
@@ -1419,6 +1440,8 @@
     rb_define_method(cMouseEvent, "bstate", curs_mouse_bstate, 0);
 #endif /* USE_MOUSE */
 
+    rb_define_module_function(mCurses, "ESCDELAY=", curses_escdelay_set, 1);
+    rb_define_module_function(mCurses, "ESCDELAY", curses_escdelay_get, 0);
     rb_define_module_function(mCurses, "init_screen", curses_init_screen, 0);
     rb_define_module_function(mCurses, "close_screen", curses_close_screen, 0);
     rb_define_module_function(mCurses, "closed?", curses_closed, 0);
Index: mvm/ext/curses/extconf.rb
===================================================================
--- mvm/ext/curses/extconf.rb	(revision 20375)
+++ mvm/ext/curses/extconf.rb	(revision 20376)
@@ -6,6 +6,7 @@
 
 make=false
 headers = []
+
 have_library("mytinfo", "tgetent") if /bow/ =~ RUBY_PLATFORM
 have_library("tinfo", "tgetent") or have_library("termcap", "tgetent")
 if have_header(*curses=%w"ncurses.h") and have_library("ncurses", "initscr")
@@ -27,5 +28,6 @@
   if try_static_assert("sizeof(char*)>sizeof(int)", %w[stdio.h stdlib.h]+curses , flag)
     $defs << flag
   end
+  have_var("ESCDELAY", curses)
   create_makefile("curses")
 end
Index: mvm/ext/pty/pty.c
===================================================================
--- mvm/ext/pty/pty.c	(revision 20375)
+++ mvm/ext/pty/pty.c	(revision 20376)
@@ -127,51 +127,8 @@
 struct pty_info {
     int fd;
     rb_pid_t child_pid;
-    VALUE thread;
 };
 
-static void
-raise_from_wait(const char *state, const struct pty_info *info)
-{
-    char buf[1024];
-    VALUE exc;
-
-    snprintf(buf, sizeof(buf), "pty - %s: %ld", state, (long)info->child_pid);
-    exc = rb_exc_new2(eChildExited, buf);
-    rb_iv_set(exc, "status", rb_last_status_get());
-    rb_funcall(info->thread, rb_intern("raise"), 1, exc);
-}
-
-static VALUE
-pty_syswait(void *arg)
-{
-    const struct pty_info *const info = arg;
-    rb_pid_t cpid;
-    int status;
-
-    for (;;) {
-	cpid = rb_waitpid(info->child_pid, &status, WUNTRACED);
-	if (cpid == -1) return Qnil;
-
-#if defined(WIFSTOPPED)
-#elif defined(IF_STOPPED)
-#define WIFSTOPPED(status) IF_STOPPED(status)
-#else
----->> Either IF_STOPPED or WIFSTOPPED is needed <<----
-#endif /* WIFSTOPPED | IF_STOPPED */
-	if (WIFSTOPPED(status)) { /* suspend */
-	    raise_from_wait("stopped", info);
-	}
-	else if (kill(info->child_pid, 0) == 0) {
-	    raise_from_wait("changed", info);
-	}
-	else {
-	    raise_from_wait("exited", info);
-	    return Qnil;
-	}
-    }
-}
-
 static void getDevice(int*, int*, char [DEVICELEN]);
 
 struct exec_info {
@@ -217,7 +174,6 @@
     }
     getDevice(&master, &slave, SlaveName);
 
-    info->thread = rb_thread_current();
     if ((pid = fork()) < 0) {
 	close(master);
 	close(slave);
@@ -288,15 +244,6 @@
     info->fd = master;
 }
 
-static VALUE
-pty_finalize_syswait(struct pty_info *info)
-{
-    rb_thread_kill(info->thread);
-    rb_funcall(info->thread, rb_intern("value"), 0);
-    rb_detach_process(info->child_pid);
-    return Qnil;
-}
-
 static int
 get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
 {
@@ -396,13 +343,19 @@
     }
 }
 
+static VALUE
+pty_detach_process(struct pty_info *info)
+{
+    rb_detach_process(info->child_pid);
+    return Qnil;
+}
+
 /* ruby function: getpty */
 static VALUE
 pty_getpty(int argc, VALUE *argv, VALUE self)
 {
     VALUE res;
     struct pty_info info;
-    struct pty_info thinfo;
     rb_io_t *wfptr,*rfptr;
     VALUE rport = rb_obj_alloc(rb_cFile);
     VALUE wport = rb_obj_alloc(rb_cFile);
@@ -426,32 +379,55 @@
     rb_ary_store(res,1,(VALUE)wport);
     rb_ary_store(res,2,PIDT2NUM(info.child_pid));
 
-    thinfo.thread = rb_thread_create(pty_syswait, (void*)&info);
-    thinfo.child_pid = info.child_pid;
-    rb_thread_schedule();
-
     if (rb_block_given_p()) {
-	rb_ensure(rb_yield, res, pty_finalize_syswait, (VALUE)&thinfo);
+	rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info);
 	return Qnil;
     }
     return res;
 }
 
-/* ruby function: protect_signal - obsolete */
-static VALUE
-pty_protect(VALUE self)
+static void
+raise_from_check(pid_t pid, int status)
 {
-    rb_warn("PTY::protect_signal is no longer needed");
-    rb_yield(Qnil);
-    return self;
+    const char *state;
+    char buf[1024];
+    VALUE exc;
+
+#if defined(WIFSTOPPED)
+#elif defined(IF_STOPPED)
+#define WIFSTOPPED(status) IF_STOPPED(status)
+#else
+---->> Either IF_STOPPED or WIFSTOPPED is needed <<----
+#endif /* WIFSTOPPED | IF_STOPPED */
+    if (WIFSTOPPED(status)) { /* suspend */
+	state = "stopped";
+    }
+    else if (kill(pid, 0) == 0) {
+	state = "changed";
+    }
+    else {
+	state = "exited";
+    }
+    snprintf(buf, sizeof(buf), "pty - %s: %ld", state, (long)pid);
+    exc = rb_exc_new2(eChildExited, buf);
+    rb_iv_set(exc, "status", rb_last_status_get());
+    rb_exc_raise(exc);
 }
 
-/* ruby function: reset_signal - obsolete */
 static VALUE
-pty_reset_signal(VALUE self)
+pty_check(int argc, VALUE *argv, VALUE self)
 {
-    rb_warn("PTY::reset_signal is no longer needed");
-    return self;
+    VALUE pid, exc;
+    pid_t cpid;
+    int status;
+
+    rb_scan_args(argc, argv, "11", &pid, &exc);
+    cpid = rb_waitpid(NUM2PIDT(pid), &status, WUNTRACED);
+    if (cpid == -1) return Qnil;
+
+    if (!RTEST(exc)) return status;
+    raise_from_check(pid, status);
+    return Qnil;		/* not reached */
 }
 
 static VALUE cPTY;
@@ -462,8 +438,7 @@
     cPTY = rb_define_module("PTY");
     rb_define_module_function(cPTY,"getpty",pty_getpty,-1);
     rb_define_module_function(cPTY,"spawn",pty_getpty,-1);
-    rb_define_module_function(cPTY,"protect_signal",pty_protect,0);
-    rb_define_module_function(cPTY,"reset_signal",pty_reset_signal,0);
+    rb_define_singleton_function(cPTY,"check",pty_check,-1);
 
     eChildExited = rb_define_class_under(cPTY,"ChildExited",rb_eRuntimeError);
     rb_define_method(eChildExited,"status",echild_status,0);
Index: mvm/ext/tk/lib/tkextlib/blt/tabset.rb
===================================================================
--- mvm/ext/tk/lib/tkextlib/blt/tabset.rb	(revision 20375)
+++ mvm/ext/tk/lib/tkextlib/blt/tabset.rb	(revision 20376)
@@ -27,7 +27,7 @@
         tpath = tabset.path
         TabID_TBL.mutex.synchronize{
           if TabID_TBL[tpath]
-            TabID_TBL[tpath][id]? TabID_TBL[tpath]: id
+            TabID_TBL[tpath][id]? TabID_TBL[tpath][id]: id
           else
             id
           end
@@ -48,6 +48,13 @@
         TabID_TBL.mutex.synchronize{
           if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name]
             obj = TabID_TBL[parent.path][name]
+            if pos
+              if pos.to_s == 'end'
+                obj.move_after('end')
+              else
+                obj.move_before(pos)
+              end
+            end
             obj.configure if keys && ! keys.empty?
           else
             (obj = self.allocate).instance_eval{
@@ -69,9 +76,9 @@
             if pos
               idx = tk_call(@tpath, 'index', '-name', @id)
               if pos.to_s == 'end'
-                tk_call(@tpath, idx, 'moveto', 'after', 'end')
+                tk_call(@tpath, 'move', idx, 'after', 'end')
               else
-                tk_call(@tpath, idx, 'moveto', 'before', pos)
+                tk_call(@tpath, 'move', idx, 'before', pos)
               end
             end
             tk_call(@tpath, 'tab', 'configure', @id, keys)
@@ -80,11 +87,11 @@
             tk_call(@tpath, 'insert', pos, @id, keys)
           end
         else
+          pos = 'end' unless pos
           TabsetTab_ID.mutex.synchronize{
             @path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_)
             TabsetTab_ID[1].succ!
           }
-          pos = 'end' unless pos
           tk_call(@tpath, 'insert', pos, @id, keys)
         end
       end
@@ -173,10 +180,10 @@
       end
 
       def perforation_highlight(mode)
-        @t.perforation.highlight(self.index, mode)
+        @t.perforation_highlight(self.index, mode)
       end
       def perforation_invoke()
-        @t.perforation.invoke(self.index)
+        @t.perforation_invoke(self.index)
       end
 
       def see()
@@ -335,19 +342,43 @@
     end
 
     def get_tab(index)
-      Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('get', tagindex(index)))
+      if (idx = tk_send_without_enc('get', tagindex(index))).empty?
+        nil
+      else
+        Tk::BLT::Tabset::Tab.id2obj(self, idx)
+      end
     end
+    def get_tabobj(index)
+      if (idx = tk_send_without_enc('get', tagindex(index))).empty?
+        nil
+      else
+       Tk::BLT::Tabset::Tab.new(self, nil, name, {})
+      end
+    end
 
     def index(str)
       num_or_str(tk_send('index', str))
     end
     def index_name(tab)
-      num_or_str(tk_send('index', '-mame', tagid(tab)))
+      num_or_str(tk_send('index', '-name', tagid(tab)))
     end
 
     def insert(pos, tab, keys={})
+      pos = 'end' if pos.nil?
       Tk::BLT::Tabset::Tab.new(self, tagindex(pos), tagid(tab), keys)
     end
+    def insert_tabs(pos, *tabs)
+      pos = 'end' if pos.nil?
+      if tabs[-1].kind_of?(Hash)
+        keys = tabs.pop
+      else
+        keys = {}
+      end
+      fail ArgumentError, 'no tabs is given' if tabs.empty?
+      tabs.map!{|tab| tagid(tab)}
+      tk_send('insert', tagindex(pos), *(tabs + [keys]))
+      tabs.collect{|tab| Tk::BLT::Tabset::Tab.new(self, nil, tagid(tab))}
+    end
 
     def invoke(index)
       tk_send('invoke', tagindex(index))
@@ -363,16 +394,32 @@
     end
 
     def nearest(x, y)
-      Tk::BLT::Tabset::Tab.id2obj(num_or_str(tk_send_without_enc('nearest', x, y)))
+      Tk::BLT::Tabset::Tab.id2obj(self, num_or_str(tk_send_without_enc('nearest', x, y)))
     end
 
-    def perforation_highlight(index, mode)
-      tk_send('perforation', 'highlight', tagindex(index), mode)
+    def perforation_activate(mode)
+      tk_send('perforation', 'activate', mode)
       self
     end
-    def perforation_invoke(index)
-      tk_send('perforation', 'invoke', tagindex(index))
+    def perforation_highlight(index, *args)
+      if args.empty?
+        # index --> mode
+        tk_send('perforation', 'highlight', index)
+      elsif args.size == 1
+        # args[0] --> mode
+        tk_send('perforation', 'highlight', tagindex(index), args[0])
+      else # Error: call to get Tcl's error message
+        tk_send('perforation', 'highlight', tagindex(index), *args)
+      end
+      self
     end
+    def perforation_invoke(index=nil)
+      if index
+        tk_send('perforation', 'invoke', tagindex(index))
+      else
+        tk_send('perforation', 'invoke')
+      end
+    end
 
     def scan_mark(x, y)
       tk_send_without_enc('scan', 'mark', x, y)
@@ -397,16 +444,39 @@
       self
     end
 
+    def tab_dockall
+      tk_send('tab', 'dockall')
+      self
+    end
+
     def tab_names(pat=None)
       simplelist(tk_send('tab', 'names', pat)).collect{|name|
-        Tk::BLT::Tabset::Tab.id2obj(name)
+        Tk::BLT::Tabset::Tab.id2obj(self, name)
       }
     end
 
-    def tab_tearoff(index, name=None)
-      window(tk_send('tab', 'tearoff', tagindex(index), name))
+    def tab_objs(pat=None)
+      simplelist(tk_send('tab', 'names', pat)).collect{|name|
+        Tk::BLT::Tabset::Tab.new(self, nil, name, {})
+      }
     end
 
+    def tab_ids(pat=None)
+      simplelist(tk_send('tab', 'names', pat))
+    end
+
+    def tab_pageheight
+      number(tk_send('tab', 'pageheight'))
+    end
+
+    def tab_pagewidth
+      number(tk_send('tab', 'pagewidth'))
+    end
+
+    def tab_tearoff(index, parent=None)
+      window(tk_send('tab', 'tearoff', tagindex(index), parent))
+    end
+
     def xscrollcommand(cmd=Proc.new)
       configure_cmd 'scrollcommand', cmd
       self
Index: mvm/ext/tk/lib/tkextlib/blt/vector.rb
===================================================================
--- mvm/ext/tk/lib/tkextlib/blt/vector.rb	(revision 20375)
+++ mvm/ext/tk/lib/tkextlib/blt/vector.rb	(revision 20376)
@@ -49,11 +49,11 @@
         size = size.join(':')
       end
       if size
-        @id = INTERP._invoke('::blt::vector', 'create', 
-                             "#auto(#{size})", *hash_kv(keys))
+        @id = TkCore::INTERP._invoke('::blt::vector', 'create', 
+                                     "#auto(#{size})", *hash_kv(keys))
       else
-        @id = INTERP._invoke('::blt::vector', 'create', 
-                             "#auto", *hash_kv(keys))
+        @id = TkCore::INTERP._invoke('::blt::vector', 'create', 
+                                     "#auto", *hash_kv(keys))
       end
 
       TkVar_ID_TBL.mutex.synchronize{
@@ -68,7 +68,7 @@
       @trace_opts = nil
 
       # teach Tk-ip that @id is global var
-      INTERP._invoke_without_enc('global', @id)
+      TkCore::INTERP._invoke_without_enc('global', @id)
     end
 
     def destroy
@@ -250,7 +250,7 @@
       @trace_opts = nil
 
       # teach Tk-ip that @id is global var
-      INTERP._invoke_without_enc('global', @id)
+      TkCore::INTERP._invoke_without_enc('global', @id)
     end
   end
 end
Index: mvm/ext/tk/lib/tkextlib/blt/tabnotebook.rb
===================================================================
--- mvm/ext/tk/lib/tkextlib/blt/tabnotebook.rb	(revision 20375)
+++ mvm/ext/tk/lib/tkextlib/blt/tabnotebook.rb	(revision 20376)
@@ -13,9 +13,98 @@
     WidgetClassName = 'Tabnotebook'.freeze
     WidgetClassNames[WidgetClassName] = self
 
+    class Tab < Tk::BLT::Tabset::Tab
+      def self.new(parent, pos=nil, name=nil, keys={})
+        if pos.kind_of?(Hash)
+          keys = pos
+          name = nil
+          pos  = nil
+        end
+        if name.kind_of?(Hash)
+          keys = name
+          name = nil
+        end
+        obj = nil
+        TabID_TBL.mutex.synchronize{
+          if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name]
+            obj = TabID_TBL[parent.path][name]
+            if pos
+              if pos.to_s == 'end'
+                obj.move_after('end')
+              else
+                obj.move_before(pos)
+              end
+            end
+            obj.configure if keys && ! keys.empty?
+          else
+            (obj = self.allocate).instance_eval{
+              initialize(parent, pos, name, keys)
+              TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]
+              TabID_TBL[@tpath][@id] = self
+            }
+          end
+        }
+        obj
+      end
+
+      def initialize(parent, pos, name, keys)
+        @t = parent
+        @tpath = parent.path
+        if name
+          @path = @id = name
+          unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?)
+            if pos
+              idx = tk_call(@tpath, 'index', @id)
+              if pos.to_s == 'end'
+                tk_call(@tpath, 'move', idx, 'after', 'end')
+              else
+                tk_call(@tpath, 'move', idx, 'before', pos)
+              end
+            end
+            tk_call(@tpath, 'tab', 'configure', @id, keys)
+          else
+            fail ArgumentError, "can't find tab \"#{@id}\" in #{@t}"
+          end
+        else
+          pos = 'end' unless pos
+          @path = @id = tk_call(@tpath, 'insert', pos, keys)
+        end
+      end
+    end
+
+    #######################################
+
     def get_tab(index)
-      Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('id', tagindex(index)))
+      if (idx = tk_send_without_enc('id', tagindex(index))).empty?
+        nil
+      else
+        Tk::BLT::Tabset::Tab.id2obj(self, idx)
+      end
     end
     alias get_id get_tab
+
+    def get_tabobj(index)
+      if (idx = tk_send_without_enc('id', tagindex(index))).empty?
+        nil
+      else
+        Tk::BLT::Tabnotebook::Tab.new(self, nil, idx)
+      end
+    end
+
+    alias index_name index
+
+    def insert(pos=nil, keys={})
+      if pos.kind_of?(Hash)
+        keys = pos
+        pos = nil
+      end
+      pos = 'end' if pos.nil?
+      Tk::BLT::Tabnotebook::Tab.new(self, nil, 
+                                    tk_send('insert', tagindex(pos), keys))
+
+    end
+    undef :insert_tabs
+
+    undef :tab_pageheight, :tab_pagewidth
   end
 end
Index: mvm/ext/tk/lib/tkextlib/blt.rb
===================================================================
--- mvm/ext/tk/lib/tkextlib/blt.rb	(revision 20375)
+++ mvm/ext/tk/lib/tkextlib/blt.rb	(revision 20376)
@@ -26,14 +26,14 @@
     PATCH_LEVEL = tk_call('set', 'blt_patchLevel')
 
     begin
-      lib = INTERP._invoke('set', 'blt_library')
+      lib = TkCore::INTERP._invoke('set', 'blt_library')
     rescue
       lib = ''
     end
     LIBRARY  = TkVarAccess.new('blt_library', lib)
 
     begin
-      lib = INTERP._invoke('set', 'blt_libPath')
+      lib = TkCore::INTERP._invoke('set', 'blt_libPath')
     rescue
       lib = ''
     end
Index: mvm/ext/tk/lib/tkextlib/version.rb
===================================================================
--- mvm/ext/tk/lib/tkextlib/version.rb	(revision 20375)
+++ mvm/ext/tk/lib/tkextlib/version.rb	(revision 20376)
@@ -2,5 +2,5 @@
 # release date of tkextlib
 #
 module Tk
-  Tkextlib_RELEASE_DATE = '2008-05-23'.freeze
+  Tkextlib_RELEASE_DATE = '2008-11-25'.freeze
 end
Index: mvm/ext/tk/ChangeLog.tkextlib
===================================================================
--- mvm/ext/tk/ChangeLog.tkextlib	(revision 20375)
+++ mvm/ext/tk/ChangeLog.tkextlib	(revision 20376)
@@ -1,3 +1,14 @@
+Tue Nov 25 03:37:42 2008  Hidetoshi NAGAI  <nagai@a...>
+
+	* ext/tk/lib/tkextlib/blt/tabset.rb, 
+	  ext/tk/lib/tkextlib/blt/tabnotebook.rb: 
+	  fix many bugs. Now, those work properly.
+
+Sat Nov 22 10:31:25 2008  Hidetoshi NAGAI  <nagai@a...>
+
+	* ext/tk/lib/tkextlib/blt.rb, ext/tk/lib/tkextlib/blt/vector.rb: 
+	  fix NameError bug.
+
 2008-05-12  Hidetoshi NAGAI  <nagai@a...>
 
 	* ext/tk/lib/tkextlib/tkDND/shape.rb: wrong package name.
Index: mvm/ext/gdbm/gdbm.c
===================================================================
--- mvm/ext/gdbm/gdbm.c	(revision 20375)
+++ mvm/ext/gdbm/gdbm.c	(revision 20376)
@@ -344,6 +344,7 @@
         return Qnil;
 
     str = rb_str_new(key2.dptr, key2.dsize);
+    free(key2.dptr);
     OBJ_TAINT(str);
     return str;
 }
Index: mvm/ext/syck/rubyext.c
===================================================================
--- mvm/ext/syck/rubyext.c	(revision 20375)
+++ mvm/ext/syck/rubyext.c	(revision 20376)
@@ -50,11 +50,11 @@
  * symbols and constants
  */
 static ID s_new, s_utc, s_at, s_to_f, s_to_i, s_read, s_binmode, s_call, s_cmp, s_transfer, s_update, s_dup, s_haskey, s_match, s_keys, s_unpack, s_tr_bang, s_default_set, s_tag_read_class, s_tag_subclasses, s_resolver, s_push, s_emitter, s_level, s_detect_implicit, s_node_import, s_out, s_input, s_intern, s_transform, s_yaml_new, s_yaml_initialize, s_node_export, s_to_yaml, s_write, s_set_resolver, s_each;
-static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set;
+static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set, s_parse;
 static VALUE sym_model, sym_generic, sym_input, sym_bytecode;
 static VALUE sym_scalar, sym_seq, sym_map;
 static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline;
-static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter;
+static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter, cDateTime;
 static VALUE oDefaultResolver, oGenericResolver;
 
 /*
@@ -207,10 +207,17 @@
 /*
  * creating timestamps
  */
+struct mktime_arg {
+    char *str;
+    long len;
+};
+
 SYMID
-rb_syck_mktime(char *str, long len)
+mktime_do(struct mktime_arg *arg)
 {
     VALUE time;
+    char *str = arg->str;
+    long len = arg->len;
     char *ptr = str;
     VALUE year = INT2FIX(0);
     VALUE mon = INT2FIX(0);
@@ -312,6 +319,29 @@
     }
 }
 
+SYMID
+mktime_r(struct mktime_arg *arg)
+{
+    if (!cDateTime) {
+        /*
+         * Load Date module
+         */
+        rb_require("date");
+        cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
+    }
+    return rb_funcall(cDateTime, s_parse, 1, rb_str_new(arg->str, arg->len));
+}
+
+SYMID
+rb_syck_mktime(char *str, long len)
+{
+    struct mktime_arg a;
+
+    a.str = str;
+    a.len = len;
+    return rb_rescue2(mktime_do, (VALUE)&a, mktime_r, (VALUE)&a, rb_eArgError, NULL);
+}
+
 /*
  * handles merging of an array of hashes
  * (see http://www.yaml.org/type/merge/)
@@ -2112,6 +2142,7 @@
     s_yaml_new = rb_intern("yaml_new");
     s_yaml_initialize = rb_intern("yaml_initialize");
     s_each = rb_intern("each");
+    s_parse = rb_intern("parse");
 
     s_tags = rb_intern("@tags");
     s_name = rb_intern("@name");
Index: mvm/.merged-trunk-revision
===================================================================
--- mvm/.merged-trunk-revision	(revision 20375)
+++ mvm/.merged-trunk-revision	(revision 20376)
@@ -1 +1 @@
-20281
+20375
Index: mvm/numeric.c
===================================================================
--- mvm/numeric.c	(revision 20375)
+++ mvm/numeric.c	(revision 20376)
@@ -1495,11 +1495,16 @@
 	double err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
 	long i;
 
-	if (err>0.5) err=0.5;
-	n = floor(n + err) + 1;
-	for (i=0; i<n; i++) {
-	    rb_yield(DBL2NUM(i*unit+beg));
+	if (isinf(unit)) {
+	    if (unit > 0) rb_yield(DBL2NUM(beg));
 	}
+	else {
+	    if (err>0.5) err=0.5;
+	    n = floor(n + err) + 1;
+	    for (i=0; i<n; i++) {
+		rb_yield(DBL2NUM(i*unit+beg));
+	    }
+	}
     }
     else {
 	VALUE i = from;
Index: mvm/vm.c
===================================================================
--- mvm/vm.c	(revision 20375)
+++ mvm/vm.c	(revision 20376)
@@ -1478,7 +1478,7 @@
 	rb_queue_destroy(&th->queue.message);
 	rb_queue_destroy(&th->queue.signal);
 
-	if (th->vm->main_thread == th) {
+	if (th->vm && th->vm->main_thread == th) {
 	    RUBY_GC_INFO("main thread\n");
 	}
 	else {
Index: mvm/version.h
===================================================================
--- mvm/version.h	(revision 20375)
+++ mvm/version.h	(revision 20376)
@@ -1,7 +1,7 @@
 #define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2008-11-19"
+#define RUBY_RELEASE_DATE "2008-11-27"
 #define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20081119
+#define RUBY_RELEASE_CODE 20081127
 #define RUBY_PATCHLEVEL 0
 
 #define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
 #define RUBY_VERSION_TEENY 0
 #define RUBY_RELEASE_YEAR 2008
 #define RUBY_RELEASE_MONTH 11
-#define RUBY_RELEASE_DAY 19
+#define RUBY_RELEASE_DAY 27
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
Index: mvm/ruby.c
===================================================================
--- mvm/ruby.c	(revision 20375)
+++ mvm/ruby.c	(revision 20376)
@@ -146,7 +146,7 @@
 	"-T[level]       turn on tainting checks",
 	"-v              print version number, then turn on verbose mode",
 	"-w              turn warnings on for your script",
-	"-W[level]       set warning level; 0=silence, 1=medium, 2=verbose (default)",
+	"-W[level]       set warning level; 0=silence, 1=medium, 2=verbose (default for level)",
 	"-x[directory]   strip off text before #!ruby line and perhaps cd to directory",
 	"--copyright     print the copyright",
 	"--version       print the version",
Index: mvm/test/bigdecimal/test_bigdecimal.rb
===================================================================
--- mvm/test/bigdecimal/test_bigdecimal.rb	(revision 20375)
+++ mvm/test/bigdecimal/test_bigdecimal.rb	(revision 20376)
@@ -77,6 +77,7 @@
   end
 
   def test_exception_zerodivide
+    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
     _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { 1 / BigDecimal.new("0") }
     _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { -1 / BigDecimal.new("0") }
   end
@@ -275,6 +276,7 @@
 
   def test_finite_infinite_nan
     BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+    BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
 
     x = BigDecimal.new("0")
     assert_equal(true, x.finite?)
@@ -303,9 +305,9 @@
     x = BigDecimal.new("0")
     assert_kind_of(Integer, x.to_i)
     assert_equal(0, x.to_i)
-    assert_nil(( 1 / x).to_i)
-    assert_nil((-1 / x).to_i)
-    assert_nil(( 0 / x).to_i)
+    assert_raise(FloatDomainError){( 1 / x).to_i}
+    assert_raise(FloatDomainError){(-1 / x).to_i}
+    assert_raise(FloatDomainError) {( 0 / x).to_i}
     x = BigDecimal.new("1")
     assert_equal(1, x.to_i)
     x = BigDecimal.new((2**100).to_s)
@@ -315,6 +317,7 @@
   def test_to_f
     BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
     BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+    BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
 
     x = BigDecimal.new("0")
     assert_instance_of(Float, x.to_f)
@@ -616,6 +619,7 @@
   def test_sign
     BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
     BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+    BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
 
     assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("0").sign)
     assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-0").sign)
Index: mvm/test/ruby/test_method.rb
===================================================================
--- mvm/test/ruby/test_method.rb	(revision 20375)
+++ mvm/test/ruby/test_method.rb	(revision 20376)
@@ -27,6 +27,15 @@
   class Derived < Base
     def foo() :derived end
   end
+  class T
+    def initialize; end
+    def normal_method; end
+  end
+  module M
+    def func; end
+    module_function :func
+    def meth; end
+  end
 
   def test_arity
     assert_equal(0, method(:m0).arity)
@@ -221,4 +230,11 @@
     assert_raise(ArgumentError) { o.method(:foo=).call(1, 2, 3) }
     assert_raise(ArgumentError) { o.method(:foo).call(1) }
   end
+
+  def test_default_accessibility
+    assert T.public_instance_methods.include?(:normal_method), 'normal methods are public by default'
+    assert !T.public_instance_methods.include?(:initialize), '#initialize is private'
+    assert !M.public_instance_methods.include?(:func), 'module methods are private by default'
+    assert M.public_instance_methods.include?(:meth), 'normal methods are public by default'
+  end
 end
Index: mvm/test/ruby/test_time.rb
===================================================================
--- mvm/test/ruby/test_time.rb	(revision 20375)
+++ mvm/test/ruby/test_time.rb	(revision 20376)
@@ -396,7 +396,7 @@
     assert_equal("123456", t.strftime("%6N"))
     assert_equal("123456789", t.strftime("%9N"))
     assert_equal("1234567890", t.strftime("%10N"))
-    assert_equal("", t.strftime("%0N"))
+    assert_equal("123456789", t.strftime("%0N"))
     assert_equal("000", t.strftime("%3S"))
     assert_equal("946684800", t.strftime("%s"))
     assert_equal("946684800", t.utc.strftime("%s"))
@@ -444,5 +444,29 @@
     assert_equal(" 2", t.strftime("%l"))
     assert_equal("02", t.strftime("%0l"))
     assert_equal(" 2", t.strftime("%_l"))
+
+    # [ruby-dev:37155]
+    t = Time.mktime(1970, 1, 18)
+    assert_equal("0", t.strftime("%w"))
+    assert_equal("7", t.strftime("%u"))
+
+    # [ruby-dev:37160]
+    assert_equal("\t", T2000.strftime("%t"))
+    assert_equal("\t", T2000.strftime("%0t"))
+    assert_equal("\t", T2000.strftime("%1t"))
+    assert_equal("  \t", T2000.strftime("%3t"))
+    assert_equal("00\t", T2000.strftime("%03t"))
+    assert_equal("\n", T2000.strftime("%n"))
+    assert_equal("\n", T2000.strftime("%0n"))
+    assert_equal("\n", T2000.strftime("%1n"))
+    assert_equal("  \n", T2000.strftime("%3n"))
+    assert_equal("00\n", T2000.strftime("%03n"))
+
+    # [ruby-dev:37162]
+    assert_equal("SAT", T2000.strftime("%#a"))
+    assert_equal("SATURDAY", T2000.strftime("%#A"))
+    assert_equal("JAN", T2000.strftime("%#b"))
+    assert_equal("JANUARY", T2000.strftime("%#B"))
+    assert_equal("JAN", T2000.strftime("%#h"))
   end
 end
Index: mvm/test/cgi/test_cgi_session.rb
===================================================================
--- mvm/test/cgi/test_cgi_session.rb	(revision 20375)
+++ mvm/test/cgi/test_cgi_session.rb	(revision 20376)
@@ -3,19 +3,18 @@
 require 'cgi/session'
 require 'cgi/session/pstore'
 require 'stringio'
+require 'tmpdir'
 
 class CGISessionTest < Test::Unit::TestCase
-
-
   def setup
-    FileUtils.rm(Dir::glob(File.dirname(__FILE__)+"/session_dir/*"))
+    @session_dir = Dir.mktmpdir('__test_dir__')+'/session_dir/'
+    FileUtils.mkdir_p @session_dir
   end
 
-
   def teardown
     @environ.each do |key, val| ENV.delete(key) end
     $stdout = STDOUT
-#    FileUtils.rm(Dir::glob(File.dirname(__FILE__)+"/session_dir/*"))
+    FileUtils.rm_rf(@session_dir)
   end
 
   def test_cgi_session_filestore
@@ -31,7 +30,7 @@
     value2.force_encoding("SJIS") if RUBY_VERSION>="1.9"
     ENV.update(@environ)
     cgi = CGI.new
-    session = CGI::Session.new(cgi,"tmpdir"=>File.dirname(__FILE__)+"/session_dir")
+    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
     session["key1"]=value1
     session["key2"]=value2
     assert_equal(value1,session["key1"])
@@ -49,7 +48,7 @@
     }
     ENV.update(@environ)
     cgi = CGI.new
-    session = CGI::Session.new(cgi,"tmpdir"=>File.dirname(__FILE__)+"/session_dir")
+    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
     $stdout = StringIO.new
     assert_equal(value1,session["key1"])
     assert_equal(value2,session["key2"])
@@ -69,7 +68,7 @@
     value2.force_encoding("SJIS") if RUBY_VERSION>="1.9"
     ENV.update(@environ)
     cgi = CGI.new
-    session = CGI::Session.new(cgi,"tmpdir"=>File.dirname(__FILE__)+"/session_dir","database_manager"=>CGI::Session::PStore)
+    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
     session["key1"]=value1
     session["key2"]=value2
     assert_equal(value1,session["key1"])
@@ -87,7 +86,7 @@
     }
     ENV.update(@environ)
     cgi = CGI.new
-    session = CGI::Session.new(cgi,"tmpdir"=>File.dirname(__FILE__)+"/session_dir","database_manager"=>CGI::Session::PStore)
+    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
     $stdout = StringIO.new
     assert_equal(value1,session["key1"])
     assert_equal(value2,session["key2"])
Index: mvm/test/date/test_date_attr.rb
===================================================================
--- mvm/test/date/test_date_attr.rb	(revision 20375)
+++ mvm/test/date/test_date_attr.rb	(revision 20376)
@@ -9,10 +9,10 @@
 
     [date, datetime].each_with_index do |d, i|
       if i == 0
-	assert_match(/\#<Date\d?: 4877807\/2,0,2299161>/,
+	assert_match(/\#<Date\d?: 1965-05-23 \(4877807\/2,0,2299161\)>/,
 		     d.inspect)
       else
-	assert_match(/\#<DateTime\d?: 210721343519\/86400,0,2299161>/,
+	assert_match(/\#<DateTime\d?: 1965-05-23T22:31:59\+00:00 \(210721343519\/86400,0,2299161\)>/,
 		     d.inspect)
       end
 
Index: mvm/test/date/test_date_strftime.rb
===================================================================
--- mvm/test/date/test_date_strftime.rb	(revision 20375)
+++ mvm/test/date/test_date_strftime.rb	(revision 20376)
@@ -299,6 +299,24 @@
     assert_equal('-2000', d.strftime('%05Y'))
   end
 
+  def test_strftime__gnuext_LN # coreutils
+    d = DateTime.parse('2008-11-25T00:11:22.0123456789')
+    assert_equal('012', d.strftime('%L'))
+    assert_equal('012', d.strftime('%0L'))
+    assert_equal('0', d.strftime('%1L'))
+    assert_equal('01', d.strftime('%2L'))
+    assert_equal('01234567890', d.strftime('%11L'))
+    assert_equal('01234567890', d.strftime('%011L'))
+    assert_equal('01234567890', d.strftime('%_11L'))
+    assert_equal('012345678', d.strftime('%N'))
+    assert_equal('012345678', d.strftime('%0N'))
+    assert_equal('0', d.strftime('%1N'))
+    assert_equal('01', d.strftime('%2N'))
+    assert_equal('01234567890', d.strftime('%11N'))
+    assert_equal('01234567890', d.strftime('%011N'))
+    assert_equal('01234567890', d.strftime('%_11N'))
+  end
+
   def test_strftime__gnuext_z # coreutils
     d = DateTime.parse('2006-08-08T23:15:33+09:08:07')
     assert_equal('+0908', d.strftime('%z'))
Index: mvm/test/date/test_date.rb
===================================================================
--- mvm/test/date/test_date.rb	(revision 20375)
+++ mvm/test/date/test_date.rb	(revision 20376)
@@ -41,9 +41,9 @@
     assert_instance_of(DateSub, DateSub.today)
     assert_instance_of(DateTimeSub, DateTimeSub.now)
 
-    assert_equal('#<DateSub: -1/2,0,2299161>', d.inspect)
+    assert_equal('#<DateSub: -4712-01-01 (-1/2,0,2299161)>', d.inspect)
     assert_equal('-4712-01-01', d.to_s)
-    assert_equal('#<DateTimeSub: -1/2,0,2299161>', dt.inspect)
+    assert_equal('#<DateTimeSub: -4712-01-01T00:00:00+00:00 (-1/2,0,2299161)>', dt.inspect)
     assert_equal('-4712-01-01T00:00:00+00:00', dt.to_s)
 
     d2 = d + 1
Index: mvm/test/yaml/test_yaml.rb
===================================================================
--- mvm/test/yaml/test_yaml.rb	(revision 20375)
+++ mvm/test/yaml/test_yaml.rb	(revision 20376)
@@ -1306,6 +1306,10 @@
       raise "id collision in ordered map" if omap.to_yaml =~ /id\d+/
     end
 
+    def test_date_out_of_range
+      assert_nothing_raised{YAML::load('1900-01-01T00:00:00+00:00')}
+    end
+
     def test_normal_exit
       YAML.load("2000-01-01 00:00:00.#{"0"*1000} +00:00\n")
       # '[ruby-core:13735]'
Index: mvm/signal.c
===================================================================
--- mvm/signal.c	(revision 20375)
+++ mvm/signal.c	(revision 20376)
@@ -418,7 +418,40 @@
 #endif
 
 #ifdef POSIX_SIGNAL
-static int
+#if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
+#define USE_SIGALTSTACK
+#endif
+
+#ifdef USE_SIGALTSTACK
+#ifdef SIGSTKSZ
+#define ALT_STACK_SIZE (SIGSTKSZ*2)
+#else
+#define ALT_STACK_SIZE (4*1024)
+#endif
+/* alternate stack for SIGSEGV */
+static void
+register_sigaltstack(void)
+{
+    static void *altstack = 0;
+    stack_t newSS, oldSS;
+
+    if (altstack) return;
+
+    newSS.ss_sp = altstack = malloc(ALT_STACK_SIZE);
+    if (newSS.ss_sp == NULL)
+	/* should handle error */
+	rb_bug("register_sigaltstack. malloc error\n");
+    newSS.ss_size = ALT_STACK_SIZE;
+    newSS.ss_flags = 0;
+
+    if (sigaltstack(&newSS, &oldSS) < 0) 
+	rb_bug("register_sigaltstack. error\n");
+}
+#else
+#define register_sigaltstack() ((void)0)
+#endif
+
+static void
 ruby_sigaction(int signum, ruby_sigaction_t *handler, int altstack, struct sigaction *old)
 {
     struct sigaction sigact;
@@ -431,10 +464,6 @@
 #ifdef SA_SIGINFO
     sigact.sa_sigaction = handler;
     sigact.sa_flags = SA_SIGINFO;
-#ifdef HAVE_SIGALTSTACK
-    if (altstack)
-	sigact.sa_flags |= SA_ONSTACK;
-#endif
 #else
     sigact.sa_handler = (sighandler_t)handler;
     sigact.sa_flags = 0;
@@ -444,7 +473,12 @@
     if (signum == SIGCHLD && (sighandler_t)handler == SIG_IGN)
 	sigact.sa_flags |= SA_NOCLDWAIT;
 #endif
-    return sigaction(signum, &sigact, old);
+#ifdef SA_ONSTACK
+    if (altstack)
+	sigact.sa_flags |= SA_ONSTACK;
+#endif
+    if (sigaction(signum, &sigact, old) < 0)
+        rb_bug("sigaction error.\n");
 }
 
 static sighandler_t
@@ -464,16 +498,7 @@
 void
 ruby_install_altstack(rb_thread_t *th)
 {
-#ifdef HAVE_SIGALTSTACK
-    stack_t sigstk;
-    static void *segv_stack;
-
-    if (!segv_stack) segv_stack = malloc(SIGSTKSZ * 2);
-    sigstk.ss_sp = segv_stack;
-    sigstk.ss_size = SIGSTKSZ;
-    sigstk.ss_flags = 0;
-    sigaltstack(&sigstk, 0);
-#endif
+    register_sigaltstack();
 }
 
 #else /* !POSIX_SIGNAL */
@@ -572,13 +597,12 @@
 static RETSIGTYPE
 sigsegv(int sig SIGINFO_ARG)
 {
-#ifdef HAVE_SIGALTSTACK
+#ifdef USE_SIGALTSTACK
     int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
+    NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th));
     rb_thread_t *th = GET_THREAD();
     if (ruby_stack_overflowed_p(th, info->si_addr)) {
-	th->errinfo = sysstack_error;
-	rb_thread_raised_clear(th);
-	TH_JUMP_TAG(th, TAG_RAISE);
+	ruby_thread_stack_overflow(th);
     }
 #endif
     if (segv_received) {
@@ -715,6 +739,7 @@
 #ifdef SIGSEGV
       case SIGSEGV:
         func = (sighandler_t)sigsegv;
+        register_sigaltstack();
         break;
 #endif
 #ifdef SIGPIPE
@@ -1109,8 +1134,8 @@
 #endif
     }
 #ifdef SIGSEGV
+    register_sigaltstack();
     ruby_sigaction(SIGSEGV, sigsegv, Qtrue, NULL);
-    ruby_install_altstack(GET_THREAD());
 #endif
 #ifdef SIGPIPE
     install_sighandler(SIGPIPE, sigpipe);
Index: mvm/file.c
===================================================================
--- mvm/file.c	(revision 20375)
+++ mvm/file.c	(revision 20376)
@@ -1298,7 +1298,7 @@
 #ifdef S_IWOTH
     struct stat st;
 
-    if (rb_stat(fname, &st) < 0) return Qfalse;
+    if (rb_stat(fname, &st) < 0) return Qnil;
     if ((st.st_mode & (S_IWOTH)) == S_IWOTH) {
 	return UINT2NUM(st.st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
     }
Index: mvm/node.h
===================================================================
--- mvm/node.h	(revision 20375)
+++ mvm/node.h	(revision 20376)
@@ -468,7 +468,7 @@
 
 #define NOEX_UNDEF     NOEX_NOSUPER
 
-#define NOEX_MODFUNC   0x10
+#define NOEX_MODFUNC   0x12
 #define NOEX_SUPER     0x20
 #define NOEX_VCALL     0x40
 

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

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