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

ruby-changes:6373

From: nobu <ko1@a...>
Date: Sat, 5 Jul 2008 21:25:43 +0900 (JST)
Subject: [ruby-changes:6373] Ruby:r17889 (mvm): * merged from trunk r17835:17888.

nobu	2008-07-05 21:25:07 +0900 (Sat, 05 Jul 2008)

  New Revision: 17889

  Added directories:
    branches/mvm/ext/coverage/
  Added files:
    branches/mvm/test/test_singleton.rb
  Modified files:
    branches/mvm/.merged-trunk-revision
    branches/mvm/ChangeLog
    branches/mvm/configure.in
    branches/mvm/encoding.c
    branches/mvm/eval.c
    branches/mvm/ext/win32ole/win32ole.c
    branches/mvm/gc.c
    branches/mvm/include/ruby/encoding.h
    branches/mvm/include/ruby/oniguruma.h
    branches/mvm/insns.def
    branches/mvm/iseq.c
    branches/mvm/lib/coverage.rb
    branches/mvm/lib/net/ftp.rb
    branches/mvm/lib/net/smtp.rb
    branches/mvm/lib/test/unit/autorunner.rb
    branches/mvm/lib/test/unit/collector/dir.rb
    branches/mvm/lib/test/unit/collector/objectspace.rb
    branches/mvm/lib/test/unit/testcase.rb
    branches/mvm/numeric.c
    branches/mvm/parse.y
    branches/mvm/re.c
    branches/mvm/test/ruby/test_m17n.rb
    branches/mvm/test/win32ole/test_win32ole.rb
    branches/mvm/test/win32ole/test_win32ole_variant.rb
    branches/mvm/test/win32ole/test_word.rb
    branches/mvm/thread.c
    branches/mvm/version.h
    branches/mvm/vm.c
    branches/mvm/vm_core.h

  Log:
    * merged from trunk r17835:17888.  Added: branches/mvm/ext/coverage/


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

Index: mvm/encoding.c
===================================================================
--- mvm/encoding.c	(revision 17888)
+++ mvm/encoding.c	(revision 17889)
@@ -19,10 +19,12 @@
 
 static ID id_encoding, id_base_encoding;
 VALUE rb_cEncoding;
+static VALUE rb_encoding_list;
 
 struct rb_encoding_entry {
     const char *name;
     rb_encoding *enc;
+    rb_encoding *base;
 };
 
 static struct {
@@ -49,36 +51,60 @@
 static VALUE
 enc_new(rb_encoding *encoding)
 {
-    VALUE enc = Data_Wrap_Struct(rb_cEncoding, enc_mark, 0, encoding);
-    encoding->auxiliary_data = (void *)enc;
-    return enc;
+    return Data_Wrap_Struct(rb_cEncoding, enc_mark, 0, encoding);
 }
 
 VALUE
 rb_enc_from_encoding(rb_encoding *encoding)
 {
+    VALUE list, enc;
+    int idx;
+
     if (!encoding) return Qnil;
-    if (enc_initialized_p(encoding))
-	return ENC_FROM_ENCODING(encoding);
-    return enc_new(encoding);
+    idx = ENC_TO_ENCINDEX(encoding);
+    if (!(list = rb_encoding_list)) {
+	rb_bug("rb_enc_from_encoding(%d\"%s\"): no rb_encoding_list",
+	       idx, rb_enc_name(encoding));
+    }
+    enc = rb_ary_entry(list, idx);
+    if (NIL_P(enc)) {
+	rb_bug("rb_enc_from_encoding(%d\"%s\"): not created yet",
+	       idx, rb_enc_name(encoding));
+    }
+    return enc;
 }
 
+static int enc_autoload(rb_encoding *);
+
 static int
-enc_check_encoding(VALUE obj)
+check_encoding(rb_encoding *enc)
 {
-    int index;
-    rb_encoding *enc;
+    int index = rb_enc_to_index(enc);
+    if (rb_enc_from_index(index) != enc)
+	return -1;
+    if (enc_autoload_p(enc)) {
+	index = enc_autoload(enc);
+    }
+    return index;
+}
 
+static int
+enc_check_encoding(VALUE obj)
+{
     if (SPECIAL_CONST_P(obj) || BUILTIN_TYPE(obj) != T_DATA ||
 	RDATA(obj)->dmark != enc_mark) {
 	return -1;
     }
-    enc = (rb_encoding*)RDATA(obj)->data;
-    index = rb_enc_to_index(enc);
-    if (rb_enc_from_index(index) != enc)
-	return -1;
-    if (enc_autoload_p(enc)) {
-	index = rb_enc_find_index(enc->name);
+    return check_encoding(RDATA(obj)->data);
+}
+
+static int
+must_encoding(VALUE enc)
+{
+    int index = enc_check_encoding(enc);
+    if (index < 0) {
+	rb_raise(rb_eTypeError, "wrong argument type %s (expected Encoding)",
+		 rb_obj_classname(enc));
     }
     return index;
 }
@@ -116,13 +142,6 @@
 void
 rb_gc_mark_encodings(void)
 {
-    int i;
-    for (i = 0; i < enc_table.count; ++i) {
-	rb_encoding *enc = enc_table.list[i].enc;
-	if (enc && enc_initialized_p(enc)) {
-	    rb_gc_mark(ENC_FROM_ENCODING(enc));
-	}
-    }
 }
 
 static int
@@ -145,7 +164,7 @@
 enc_register_at(int index, const char *name, rb_encoding *encoding)
 {
     struct rb_encoding_entry *ent = &enc_table.list[index];
-    void *obj = ENC_UNINITIALIZED;
+    VALUE list;
 
     if (!ent->name) {
 	ent->name = name = strdup(name);
@@ -156,9 +175,6 @@
     if (!ent->enc) {
 	ent->enc = xmalloc(sizeof(rb_encoding));
     }
-    else {
-	obj = ent->enc->auxiliary_data;
-    }
     if (encoding) {
 	*ent->enc = *encoding;
     }
@@ -169,16 +185,11 @@
     encoding->name = name;
     encoding->ruby_encoding_index = index;
     st_insert(enc_table.names, (st_data_t)name, (st_data_t)index);
-    if (obj != ENC_UNINITIALIZED) {
-	encoding->auxiliary_data = obj;
-    }
-    else if (rb_cEncoding) {
+    list = rb_encoding_list;
+    if (list && NIL_P(rb_ary_entry(list, index))) {
 	/* initialize encoding data */
-	enc_new(encoding);
+	rb_ary_store(list, index, enc_new(encoding));
     }
-    else {
-	encoding->auxiliary_data = ENC_UNINITIALIZED;
-    }
     return index;
 }
 
@@ -205,9 +216,7 @@
 	if (STRCASECMP(name, rb_enc_name(oldenc))) {
 	    index = enc_register(name, encoding);
 	}
-	else if (!enc_autoload_p(oldenc) ||
-		 (enc_initialized_p(oldenc) &&
-		  !ENC_DUMMY_P(ENC_FROM_ENCODING(oldenc)))) {
+	else if (enc_autoload_p(oldenc) || !ENC_DUMMY_P(oldenc)) {
 	    enc_register_at(index, name, encoding);
 	}
 	else {
@@ -239,12 +248,12 @@
     }
 }
 
-static VALUE
+static rb_encoding*
 set_base_encoding(int index, rb_encoding *base)
 {
-    VALUE enc = rb_enc_from_encoding(enc_table.list[index].enc);
+    rb_encoding *enc = enc_table.list[index].enc;
 
-    rb_ivar_set(enc, id_base_encoding, rb_enc_from_encoding(base));
+    enc_table.list[index].base = base;
     if (rb_enc_dummy_p(base)) ENC_SET_DUMMY(enc);
     return enc;
 }
@@ -293,7 +302,7 @@
 rb_define_dummy_encoding(const char *name)
 {
     int index = rb_enc_replicate(name, rb_ascii8bit_encoding());
-    VALUE enc = rb_enc_from_encoding(enc_table.list[index].enc);
+    rb_encoding *enc = enc_table.list[index].enc;
 
     ENC_SET_DUMMY(enc);
     return index;
@@ -304,7 +313,7 @@
 {
     int index = enc_replicate(rb_enc_registered(name), name,
 			      rb_ascii8bit_encoding());
-    VALUE enc = rb_enc_from_encoding(enc_table.list[index].enc);
+    rb_encoding *enc = enc_table.list[index].enc;
 
     ENC_SET_DUMMY(enc);
     return index;
@@ -326,7 +335,7 @@
 static VALUE
 enc_dummy_p(VALUE enc)
 {
-    return ENC_DUMMY_P(enc) ? Qtrue : Qfalse;
+    return ENC_DUMMY_P(enc_table.list[must_encoding(enc)].enc) ? Qtrue : Qfalse;
 }
 
 static int
@@ -448,33 +457,44 @@
     return idx;
 }
 
+static int
+enc_autoload(rb_encoding *enc)
+{
+    int i;
+    rb_encoding *base = enc_table.list[ENC_TO_ENCINDEX(enc)].base;
+
+    if (base) {
+	i = 0;
+	do {
+	    if (i >= enc_table.count) return -1;
+	} while (enc_table.list[i].enc != base && (++i, 1));
+	if (enc_autoload_p(base)) {
+	    if (enc_autoload(base) < 0) return -1;
+	}
+	i = ENC_TO_ENCINDEX(enc);
+	enc_register_at(i, rb_enc_name(enc), base);
+    }
+    else {
+	i = load_encoding(rb_enc_name(enc));
+    }
+    return i;
+}
+
 int
 rb_enc_find_index(const char *name)
 {
-    int i = rb_enc_registered(name), b;
+    int i = rb_enc_registered(name);
     rb_encoding *enc;
-    VALUE base;
 
     if (i < 0) {
 	i = load_encoding(name);
     }
     else if (enc_autoload_p(enc = rb_enc_from_index(i))) {
-	if (enc_initialized_p(enc) &&
-	    (base = enc_base_encoding(ENC_FROM_ENCODING(enc)), !NIL_P(base))) {
-	    if ((b = enc_check_encoding(base)) < 0) {
-		goto failed;
-	    }
-	    enc_register_at(i, rb_enc_name(enc), rb_enc_from_index(b));
+	if (enc_autoload(enc) < 0) {
+	    rb_warn("failed to load encoding (%s); use ASCII-8BIT instead",
+		    name);
+	    return 0;
 	}
-	else {
-	    i = load_encoding(rb_enc_name(enc));
-	    if (i < 0) {
-	      failed:
-		rb_warn("failed to load encoding (%s); use ASCII-8BIT instead",
-			name);
-		return 0;
-	    }
-	}
     }
     return i;
 }
@@ -503,33 +523,6 @@
     }
 }
 
-#if 0
-static void
-enc_check_capable(VALUE x)
-{
-    if (!enc_capable(x)) {
-	const char *etype;
-
-	if (NIL_P(x)) {
-	    etype = "nil";
-	}
-	else if (FIXNUM_P(x)) {
-	    etype = "Fixnum";
-	}
-	else if (SYMBOL_P(x)) {
-	    etype = "Symbol";
-	}
-	else if (rb_special_const_p(x)) {
-	    etype = RSTRING_PTR(rb_obj_as_string(x));
-	}
-	else {
-	    etype = rb_obj_classname(x);
-	}
-	rb_raise(rb_eTypeError, "wrong argument type %s (not encode capable)", etype);
-    }
-}
-#endif
-
 ID
 rb_id_encoding(void)
 {
@@ -777,7 +770,7 @@
 {
     VALUE str = rb_sprintf("#<%s:%s%s>", rb_obj_classname(self),
 		      rb_enc_name((rb_encoding*)DATA_PTR(self)),
-		      (ENC_DUMMY_P(self) ? " (dummy)" : ""));
+		      (enc_dummy_p(self) ? " (dummy)" : ""));
     ENCODING_CODERANGE_SET(str, rb_usascii_encindex(), ENC_CODERANGE_7BIT);
     return str;
 }
@@ -799,7 +792,9 @@
 static VALUE
 enc_base_encoding(VALUE self)
 {
-    return rb_attr_get(self, id_base_encoding);
+    rb_encoding *base = enc_table.list[must_encoding(self)].base;
+    if (!base) return Qnil;
+    return ENC_FROM_ENCODING(base);
 }
 
 /*
@@ -823,14 +818,8 @@
 static VALUE
 enc_list(VALUE klass)
 {
-    VALUE ary = rb_ary_new2(enc_table.count);
-    int i;
-    for (i = 0; i < enc_table.count; ++i) {
-	rb_encoding *enc = enc_table.list[i].enc;
-	if (enc) {
-	    rb_ary_push(ary, rb_enc_from_encoding(enc));
-	}
-    }
+    VALUE ary = rb_ary_new2(0);
+    rb_ary_replace(ary, rb_encoding_list);
     return ary;
 }
 
@@ -1183,6 +1172,8 @@
 Init_Encoding(void)
 {
 #undef rb_intern
+    VALUE list;
+    int i;
 
     id_base_encoding = rb_intern("#base_encoding");
 
@@ -1204,6 +1195,14 @@
 
     rb_define_singleton_method(rb_cEncoding, "default_external", get_default_external, 0);
     rb_define_singleton_method(rb_cEncoding, "locale_charmap", rb_locale_charmap, 0);
+
+    rb_gc_register_address(&rb_encoding_list);
+    list = rb_ary_new2(enc_table.count);
+    RBASIC(list)->klass = 0;
+    rb_encoding_list = list;
+    for (i = 0; i < enc_table.count; ++i) {
+	rb_ary_push(list, enc_new(enc_table.list[i].enc));
+    }
 }
 
 /* locale insensitive functions */
Index: mvm/include/ruby/encoding.h
===================================================================
--- mvm/include/ruby/encoding.h	(revision 17888)
+++ mvm/include/ruby/encoding.h	(revision 17889)
@@ -70,7 +70,7 @@
 
 int rb_enc_replicate(const char *, rb_encoding *);
 int rb_define_dummy_encoding(const char *);
-#define rb_enc_to_index(enc) ((enc) ? ((enc)->ruby_encoding_index) : 0)
+#define rb_enc_to_index(enc) ((enc) ? ENC_TO_ENCINDEX(enc) : 0)
 int rb_enc_get_index(VALUE obj);
 void rb_enc_set_index(VALUE obj, int encindex);
 int rb_enc_find_index(const char *name);
@@ -176,20 +176,21 @@
 long rb_memsearch(const void*,long,const void*,long,rb_encoding*);
 
 RUBY_EXTERN VALUE rb_cEncoding;
+#define enc_initialized_p(enc) ((enc)->ruby_encoding_index != ENC_UNINITIALIZED)
+#define ENC_DUMMY_FLAG (1<<24)
+#define ENC_INDEX_MASK (~(~0U<<24))
 
-#define ENC_UNINITIALIZED (&rb_cEncoding)
-#define enc_initialized_p(enc) ((enc)->auxiliary_data != &rb_cEncoding)
-#define ENC_FROM_ENCODING(enc) ((VALUE)(enc)->auxiliary_data)
+#define ENC_TO_ENCINDEX(enc)   ((enc)->ruby_encoding_index & ENC_INDEX_MASK)
+#define ENC_FROM_ENCINDEX(idx) (RARRAY_PTR(rb_encoding_list)[idx])
+#define ENC_FROM_ENCODING(enc) ENC_FROM_ENCINDEX(ENC_TO_ENCINDEX(enc))
 
-#define ENC_DUMMY_FLAG FL_USER2
-#define ENC_DUMMY_P(enc) (RBASIC(enc)->flags & ENC_DUMMY_FLAG)
-#define ENC_SET_DUMMY(enc) (RBASIC(enc)->flags |= ENC_DUMMY_FLAG)
+#define ENC_DUMMY_P(enc) ((enc)->ruby_encoding_index & ENC_DUMMY_FLAG)
+#define ENC_SET_DUMMY(enc) ((enc)->ruby_encoding_index |= ENC_DUMMY_FLAG)
 
 static inline int
 rb_enc_dummy_p(rb_encoding *enc)
 {
-    if (!enc_initialized_p(enc)) return Qfalse;
-    return ENC_DUMMY_P(ENC_FROM_ENCODING(enc));
+    return ENC_DUMMY_P(enc) != 0;
 }
 
 VALUE rb_str_transcode(VALUE str, VALUE to);
Index: mvm/include/ruby/oniguruma.h
===================================================================
--- mvm/include/ruby/oniguruma.h	(revision 17888)
+++ mvm/include/ruby/oniguruma.h	(revision 17889)
@@ -166,7 +166,6 @@
   int    (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], struct OnigEncodingTypeST* enc);
   OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p, struct OnigEncodingTypeST* enc);
   int    (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end, struct OnigEncodingTypeST* enc);
-  void *auxiliary_data;
   int ruby_encoding_index;
 } OnigEncodingType;
 
Index: mvm/configure.in
===================================================================
--- mvm/configure.in	(revision 17888)
+++ mvm/configure.in	(revision 17889)
@@ -700,6 +700,27 @@
   ;;
 esac
 AC_FUNC_MEMCMP
+
+# http://sources.redhat.com/ml/libc-hacker/2005-08/msg00008.html
+# Debian GNU/Linux Etch's libc6.1 2.3.6.ds1-13etch5 has this problem.
+# Debian GNU/Linux Lenny's libc6.1 2.7-10 has no problem.
+AC_CACHE_CHECK(for broken erfc of glibc-2.3.6 on IA64, rb_broken_glibc_ia64_erfc,
+  [AC_TRY_RUN([
+#include <math.h>
+int
+main()
+{
+   erfc(10000.0);
+   return 0;
+}
+],
+	rb_broken_glibc_ia64_erfc=no,
+	rb_broken_glibc_ia64_erfc=yes,
+	rb_broken_glibc_ia64_erfc=no)])
+case $rb_broken_glibc_ia64_erfc in
+  yes) ac_cv_func_erf=no;;
+esac
+
 AC_REPLACE_FUNCS(dup2 memmove strerror strftime\
 		 strchr strstr crypt flock vsnprintf\
 		 isnan finite isinf hypot acosh erf tgamma lgamma_r cbrt \
Index: mvm/re.c
===================================================================
--- mvm/re.c	(revision 17888)
+++ mvm/re.c	(revision 17889)
@@ -2085,7 +2085,8 @@
 
 static int
 unescape_nonascii(const char *p, const char *end, rb_encoding *enc,
-        VALUE buf, rb_encoding **encp, onig_errmsg_buffer err)
+        VALUE buf, rb_encoding **encp, int *has_property,
+        onig_errmsg_buffer err)
 {
     char c;
     char smallbuf[2];
@@ -2163,6 +2164,12 @@
                     break;
                 }
 
+              case 'p': /* \p{Hiragana} */
+                if (!*encp) {
+                    *has_property = 1;
+                }
+                goto escape_asis;
+
               default: /* \n, \\, \d, \9, etc. */
 escape_asis:
                 smallbuf[0] = '\\';
@@ -2186,6 +2193,7 @@
         rb_encoding **fixed_enc, onig_errmsg_buffer err)
 {
     VALUE buf;
+    int has_property = 0;
 
     buf = rb_str_buf_new(0);
 
@@ -2196,9 +2204,13 @@
         rb_enc_associate(buf, enc);
     }
 
-    if (unescape_nonascii(p, end, enc, buf, fixed_enc, err) != 0)
+    if (unescape_nonascii(p, end, enc, buf, fixed_enc, &has_property, err) != 0)
         return Qnil;
 
+    if (has_property && !*fixed_enc) {
+        *fixed_enc = enc;
+    }
+
     if (*fixed_enc) {
         rb_enc_associate(buf, *fixed_enc);
     }
Index: mvm/insns.def
===================================================================
--- mvm/insns.def	(revision 17888)
+++ mvm/insns.def	(revision 17889)
@@ -853,23 +853,7 @@
 {
     rb_event_flag_t flag = nf;
 
-    if (flag == RUBY_EVENT_COVERAGE) {
-	VALUE coverage = GET_ISEQ()->coverage;
-	if (coverage) {
-	    long line = vm_get_sourceline(GET_CFP()) - 1;
-	    long count;
-	    if (RARRAY_PTR(coverage)[line] == Qnil) {
-		rb_bug("bug");
-	    }
-	    count = FIX2LONG(RARRAY_PTR(coverage)[line]) + 1;
-	    if (POSFIXABLE(count)) {
-		RARRAY_PTR(coverage)[line] = LONG2FIX(count);
-	    }
-	}
-    }
-    else {
-	EXEC_EVENT_HOOK(th, flag, GET_SELF(), 0, 0 /* TODO: id, klass */);
-    }
+    EXEC_EVENT_HOOK(th, flag, GET_SELF(), 0, 0 /* TODO: id, klass */);
 }
 
 /**********************************************************/
Index: mvm/ChangeLog
===================================================================
--- mvm/ChangeLog	(revision 17888)
+++ mvm/ChangeLog	(revision 17889)
@@ -1,3 +1,157 @@
+Sat Jul  5 20:53:18 2008  Masaki Suketa  <masaki.suketa@n...>
+
+	* test/win32ole/test_word.rb: check word installed.
+
+Sat Jul  5 16:12:54 2008  Narihiro Nakamura  <authorNari@g...>
+
+	* gc.c: revert. before lazy sweep.
+
+Sat Jul  5 09:55:44 2008  Masaki Suketa  <masaki.suketa@n...>
+
+	* ext/win32ole/win32ole.c: add WIN32OLE#ole_respond_to?
+
+	* test/win32ole/test_win32ole.rb: ditto.
+
+Sat Jul  5 08:48:05 2008  Tanaka Akira  <akr@f...>
+
+	* re.c (unescape_nonascii): add has_property argument not to
+	  raise error by /\p{Hiragana}\u{3042}/ in EUC-JP script.
+	  (rb_reg_preprocess): use has_property argument to make regexp
+	  encoding fixed.
+
+Sat Jul  5 08:29:47 2008  Tanaka Akira  <akr@f...>
+
+	* re.c (unescape_nonascii): make regexp fixed_encoding if \p is used.
+	  fixed [ruby-core:17279].
+
+Fri Jul  4 23:12:53 2008  Masaki Suketa  <masaki.suketa@n...>
+
+	* ext/win32ole/win32ole.c (d2time): fix the bug of VT_DATE 
+	  to String conversion when negative value.
+	  
+	* test/win32ole/test_win32ole_variant.rb: ditto.
+
+Fri Jul  4 22:15:29 2008  Tanaka Akira  <akr@f...>
+
+	* lib/test/unit/testcase.rb: collect decendants of
+	  Test::Unit::TestCase using inherited.
+
+	* lib/test/unit/autorunner.rb: don't use ObjectSpace.each_object.
+
+	* lib/test/unit/collector/dir.rb: ditto.
+
+	* lib/test/unit/collector/objectspace.rb: ditto.
+
+	[ruby-core:17126]
+
+Fri Jul  4 20:43:53 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* include/ruby/oniguruma.h (OnigEncoding): removed auxiliary_data.
+
+	* include/ruby/encoding.h (ENC_DUMMY_P): moved dummy encoding flag to
+	  rb_encoding from Encoding instance.
+
+	* encoding.c (rb_encoding_list): list of Encoding instances.
+
+	* encoding.c (struct rb_encoding_entry): moved base encoding from
+	  instance variable.
+
+Fri Jul  4 17:51:07 2008  NAKAMURA Usaku  <usa@r...>
+
+	* numeric.c (check_uint, rb_num2uint, rb_fix2uint): proper check.
+
+Fri Jul  4 14:17:22 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/net/ftp.rb (Net::FTP#sendport): use divmod.  [ruby-core:17557]
+
+Fri Jul  4 11:08:37 2008  Narihiro Nakamura  <authorNari@g...>
+
+	* gc.c (garbage_collect_force): sweep is completely ended.
+
+	* gc.c (os_obj_of): invoke garbage_collect_force() when freelist none.
+
+Fri Jul  4 05:01:26 2008  NAKAMURA Usaku  <usa@r...>
+
+	* numeric.c (rb_num2uint, rb_fix2uint): typo.
+
+Fri Jul  4 02:21:06 2008  NAKAMURA Usaku  <usa@r...>
+
+	* numeric.c (check_uint, rb_num2uint, rb_fix2uint): also needs checking
+	  negative value. see [ruby-dev:33683]
+
+Thu Jul  3 23:26:36 2008  Yusuke Endoh  <mame@t...>
+
+	* include/ruby/intern.h: remove prototypes about coverage.
+
+	* iseq.c (prepare_iseq_build): add prototype.
+
+	* parse.y (coverage): ditto.
+
+	* thread.c (clear_coverage): ditto.
+
+	* thread.c (update_coverage): use rb_sourceline.
+
+	* thread.c (rb_get_coverages): rename and move to vm.c.
+
+	* vm.c (rb_vm_get_coverages): ditto.
+
+	* ext/coverage/coverage.c: add rdoc.
+
+Thu Jul  3 21:51:21 2008  Yusuke Endoh  <mame@t...>
+
+	* ext/coverage/coverage.c, ext/coverage/extconf.rb: eliminate
+	  COVERAGE__ and introduce coverage.so instead.  How to measure
+	  coverage: (1) require "coverage.so", (2) require or load Ruby source
+	  file, and (3) Coverage.result will return the same hash as COVERAGE__.
+	  [ruby-dev:35324]
+
+	* thread.c (rb_enable_coverages): start coverage measurement by using
+	  rb_add_event_hook.
+
+	* thread.c (rb_get_coverages): returns current results of coverage
+	  measurement.
+
+	* include/ruby/intern.h: add prototype for above two functions.
+
+	* vm_core.h, vm.c: add field of coverages to rb_vm_t.
+
+	* insns.def (trace): remove special handling for COVERAGE__.
+
+	* iseq.c (prepare_iseq_build): switch COVERAGE__ to
+	  rb_get_coverages().
+
+	* parse.y (coverage): ditto.
+
+	* thread.c (clear_coverage): ditto.
+
+	* lib/coverage.rb: use coverage.so instead of COVERAGE__.
+
+Thu Jul  3 21:20:45 2008  Yusuke Endoh  <mame@t...>
+
+	* thread.c (thread_initialize): NUM2INT returns long.
+
+Thu Jul  3 21:06:16 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* eval.c (Init_eval): typo fixed in r17833.
+
+Thu Jul  3 19:44:44 2008  Masaki Suketa  <masaki.suketa@n...>
+
+	* ext/win32ole/win32ole.c (Init_win32ole): remove duplicate line.
+
+Thu Jul  3 16:08:36 2008  Tanaka Akira  <akr@f...>
+
+	* configure.in (erfc): erfc of glibc comes with Debian GNU/Linux Etch
+	  on IA64 is broken.  erfc(10000.0) aborts.
+	  use missing/erf.c instead.
+	  http://sources.redhat.com/ml/libc-hacker/2005-08/msg00008.html
+
+Thu Jul  3 12:49:39 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* lib/net/smtp.rb (Net::SMTP::start): use 'localhost' instead of
+	  'localhost.localdomain'.  [ruby-dev:35333]
+
+	* lib/net/smtp.rb (Net::SMTP::SMTP.start): ditto.
+
 Thu Jul  3 07:06:02 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* Makefile.in (SET_LC_MESSAGES): LC_MESSAGES must be C.
@@ -45,11 +199,15 @@
 	* include/ruby/intern.h: ditto.
 
 Wed Jul  2 09:49:10 2008  Narihiro Nakamura  <authorNari@g...>
-	
-	* gc.c (gc_lazy_sweep) : use lazy sweep algorithm for response performance gain.
-	 (garbage_collect_force) : mark and lazysweep invoke, after erasing all mark.
-	 (GC_NOT_LAZY_SWEEP) : not lazy sweep flag. for debug.
 
+	* gc.c (gc_lazy_sweep) : use lazy sweep algorithm for response
+	  performance gain.
+
+	* gc.c (garbage_collect_force) : mark and lazysweep invoke, after
+	  erasing all mark.
+
+	* gc.c (GC_NOT_LAZY_SWEEP) : not lazy sweep flag. for debug.
+
 Wed Jul  2 03:42:44 2008  Yusuke Endoh  <mame@t...>
 
 	* test/ruby/test_settracefunc.rb: fix expected traces for
Index: mvm/vm_core.h
===================================================================
--- mvm/vm_core.h	(revision 17888)
+++ mvm/vm_core.h	(revision 17889)
@@ -342,6 +342,7 @@
     int src_encoding_index;
 
     VALUE verbose, debug, progname;
+    VALUE coverages;
 
 #ifdef RUBY_DEBUG_ENV
     int enable_coredump;
Index: mvm/iseq.c
===================================================================
--- mvm/iseq.c	(revision 17888)
+++ mvm/iseq.c	(revision 17889)
@@ -194,12 +194,11 @@
 
     iseq->coverage = Qfalse;
     if (!GET_THREAD()->parse_in_eval) {
-	if (rb_const_defined_at(rb_cObject, rb_intern("COVERAGE__"))) {
-	    VALUE hash = rb_const_get_at(rb_cObject, rb_intern("COVERAGE__"));
-	    if (TYPE(hash) == T_HASH) {
-		iseq->coverage = rb_hash_aref(hash, filename);
-		if (NIL_P(iseq->coverage)) iseq->coverage = Qfalse;
-	    }
+	extern VALUE rb_vm_get_coverages(void);
+	VALUE coverages = rb_vm_get_coverages();
+	if (RTEST(coverages)) {
+	    iseq->coverage = rb_hash_aref(coverages, filename);
+	    if (NIL_P(iseq->coverage)) iseq->coverage = Qfalse;
 	}
     }
 
Index: mvm/lib/coverage.rb
===================================================================
--- mvm/lib/coverage.rb	(revision 17888)
+++ mvm/lib/coverage.rb	(revision 17889)
@@ -1,4 +1,5 @@
-COVERAGE__ ||= {}
+require "coverage.so"
+
 ext = ENV["COVERUBY_EXT"] || ".cov"
 accum = ENV["COVERUBY_ACCUM"]
 accum = !accum || accum == "" || !(%w(f n 0).include?(accum[0]))
@@ -6,7 +7,7 @@
 
 at_exit do
   Dir.chdir(pwd) do
-    COVERAGE__.each do |sfile, covs|
+    Coverage.result.each do |sfile, covs|
       cfile = sfile + ext
 
       writable = proc do |f|
Index: mvm/lib/test/unit/autorunner.rb
===================================================================
--- mvm/lib/test/unit/autorunner.rb	(revision 17888)
+++ mvm/lib/test/unit/autorunner.rb	(revision 17889)
@@ -14,10 +14,7 @@
       
       def self.standalone?
         return false unless("-e" == $0)
-        ObjectSpace.each_object(Class) do |klass|
-          return false if(klass < TestCase)
-        end
-        true
+        TestCase::DECENDANT_CLASSES.empty?
       end
 
       RUNNERS = {
Index: mvm/lib/test/unit/collector/dir.rb
===================================================================
--- mvm/lib/test/unit/collector/dir.rb	(revision 17888)
+++ mvm/lib/test/unit/collector/dir.rb	(revision 17889)
@@ -10,7 +10,7 @@
         attr_reader :pattern, :exclude
         attr_accessor :base
 
-        def initialize(dir=::Dir, file=::File, object_space=::ObjectSpace, req=nil)
+        def initialize(dir=::Dir, file=::File, object_space=nil, req=nil)
           super()
           @dir = dir
           @file = file
@@ -43,8 +43,14 @@
 
         def find_test_cases(ignore=[])
           cases = []
-          @object_space.each_object(Class) do |c|
-            cases << c if(c < TestCase && !ignore.include?(c))
+          if @object_space
+            @object_space.each_object(Class) do |c|
+              cases << c if(c < TestCase && !ignore.include?(c))
+            end
+          else
+            TestCase::DECENDANT_CLASSES.each do |c|
+              cases << c if !ignore.include?(c)
+            end
           end
           ignore.concat(cases)
           cases
Index: mvm/lib/test/unit/collector/objectspace.rb
===================================================================
--- mvm/lib/test/unit/collector/objectspace.rb	(revision 17888)
+++ mvm/lib/test/unit/collector/objectspace.rb	(revision 17889)
@@ -10,9 +10,9 @@
       class ObjectSpace
         include Test::Unit::Collector
         
-        NAME = 'collected from the ObjectSpace'
+        NAME = 'collected from the subclasses of TestSuite'
         
-        def initialize(source=::ObjectSpace)
+        def initialize(source=nil)
           super()
           @source = source
         end
@@ -20,8 +20,14 @@
         def collect(name=NAME)
           suite = TestSuite.new(name)
           sub_suites = []
-          @source.each_object(Class) do |klass|
-            if(Test::Unit::TestCase > klass)
+          if @source
+            @source.each_object(Class) do |klass|
+              if(Test::Unit::TestCase > klass)
+                add_suite(sub_suites, klass.suite)
+              end
+            end
+          else
+            TestCase::DECENDANT_CLASSES.each do |klass|
               add_suite(sub_suites, klass.suite)
             end
           end
Index: mvm/lib/test/unit/testcase.rb
===================================================================
--- mvm/lib/test/unit/testcase.rb	(revision 17888)
+++ mvm/lib/test/unit/testcase.rb	(revision 17889)
@@ -34,6 +34,11 @@
       PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt,
                                 SystemExit]
 
+      DECENDANT_CLASSES = []
+      def self.inherited(decendant)
+        DECENDANT_CLASSES << decendant
+      end
+
       # Creates a new instance of the fixture for running the
       # test represented by test_method_name.
       def initialize(test_method_name)
Index: mvm/lib/net/smtp.rb
===================================================================
--- mvm/lib/net/smtp.rb	(revision 17888)
+++ mvm/lib/net/smtp.rb	(revision 17889)
@@ -437,7 +437,7 @@
     # +port+ is the port to connect to; it defaults to port 25.
     #
     # +helo+ is the _HELO_ _domain_ provided by the client to the
-    # server (see overview comments); it defaults to 'localhost.localdomain'. 
+    # server (see overview comments); it defaults to 'localhost'. 
     #
     # The remaining arguments are used for SMTP authentication, if required
     # or desired.  +user+ is the account name; +secret+ is your password
@@ -457,7 +457,7 @@
     # * IOError
     # * TimeoutError
     #
-    def SMTP.start(address, port = nil, helo = 'localhost.localdomain',
+    def SMTP.start(address, port = nil, helo = 'localhost',
                    user = nil, secret = nil, authtype = nil,
                    &block)   # :yield: smtp
       new(address, port).start(helo, user, secret, authtype, &block)
@@ -518,7 +518,7 @@
     # * IOError
     # * TimeoutError
     #
-    def start(helo = 'localhost.localdomain',
+    def start(helo = 'localhost',
               user = nil, secret = nil, authtype = nil)   # :yield: smtp
       if block_given?
         begin
Index: mvm/lib/net/ftp.rb
===================================================================
--- mvm/lib/net/ftp.rb	(revision 17888)
+++ mvm/lib/net/ftp.rb	(revision 17889)
@@ -296,12 +296,9 @@
     def sendport(host, port)
       af = (@sock.peeraddr)[0]
       if af == "AF_INET"
-	hbytes = host.split(".")
-	pbytes = [port / 256, port % 256]
-	bytes = hbytes + pbytes
-	cmd = "PORT " + bytes.join(",")
+	cmd = "PORT " + (host.split(".") + port.divmod(256)).join(",")
       elsif af == "AF_INET6"
-	cmd = "EPRT |2|" + host + "|" + sprintf("%d", port) + "|"
+	cmd = sprintf("EPRT |2|%s|%d|", host, port)
       else
 	raise FTPProtoError, host
       end
Index: mvm/thread.c
===================================================================
--- mvm/thread.c	(revision 17888)
+++ mvm/thread.c	(revision 17889)
@@ -498,7 +498,7 @@
 	    rb_raise(rb_eThreadError, "already initialized thread - %s",
 		     file);
 	}
-        rb_raise(rb_eThreadError, "already initialized thread - %s:%d",
+        rb_raise(rb_eThreadError, "already initialized thread - %s:%ld",
                  file, NUM2INT(line));
     }
     return thread_create_core(thread, args, 0);
@@ -2127,11 +2127,10 @@
 static void
 clear_coverage(void)
 {
-    if (rb_const_defined_at(rb_cObject, rb_intern("COVERAGE__"))) {
-	VALUE hash = rb_const_get_at(rb_cObject, rb_intern("COVERAGE__"));
-	if (TYPE(hash) == T_HASH) {
-	    st_foreach(RHASH_TBL(hash), clear_coverage_i, 0);
-	}
+    extern VALUE rb_vm_get_coverages(void);
+    VALUE coverages = rb_vm_get_coverages();
+    if (RTEST(coverages)) {
+	st_foreach(RHASH_TBL(coverages), clear_coverage_i, 0);
     }
 }
 
@@ -3596,3 +3595,34 @@
 {
     return ruby_vm_specific_ptr(GET_VM(), key);
 }
+
+static void
+update_coverage(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass)
+{
+    VALUE coverage = GET_THREAD()->cfp->iseq->coverage;
+    if (coverage) {
+	long line = rb_sourceline() - 1;
+	long count;
+	if (RARRAY_PTR(coverage)[line] == Qnil) {
+	    rb_bug("bug");
+	}
+	count = FIX2LONG(RARRAY_PTR(coverage)[line]) + 1;
+	if (POSFIXABLE(count)) {
+	    RARRAY_PTR(coverage)[line] = LONG2FIX(count);
+	}
+    }
+}
+
+void
+rb_enable_coverages(void)
+{
+    VALUE rb_mCoverage;
+
+    if (!RTEST(GET_VM()->coverages)) {
+	extern VALUE rb_vm_get_coverages(void);
+	GET_VM()->coverages = rb_hash_new();
+	rb_add_event_hook(update_coverage, RUBY_EVENT_COVERAGE, Qnil);
+	rb_mCoverage = rb_define_module("Coverage");
+	rb_define_module_function(rb_mCoverage, "result", rb_vm_get_coverages, 0);
+    }
+}
Index: mvm/eval.c
===================================================================
--- mvm/eval.c	(revision 17888)
+++ mvm/eval.c	(revision 17889)
@@ -1223,7 +1223,7 @@
 
     rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
 
-    exception_error = rb_exc_new2(rb_eFatal,
+    exception_error = rb_exc_new3(rb_eFatal,
 				  rb_obj_freeze(rb_str_new2("exception reentered")));
     rb_ivar_set(exception_error, idThrowState, INT2FIX(TAG_FATAL));
     OBJ_TAINT(exception_error);
Index: mvm/gc.c
===================================================================
--- mvm/gc.c	(revision 17888)
+++ mvm/gc.c	(revision 17889)
@@ -129,17 +129,10 @@
 #pragma pack(pop)
 #endif
 
-enum slot_color {
-    WHITE = 0x00,  /* garbage */
-    BLACK = 0x01,  /* used */
-    GRAY  = 0x02,  /* not sweep */
-};
-
 struct heaps_slot {
     void *membase;
     RVALUE *slot;
     int limit;
-    enum slot_color color;
 };
 
 #define HEAP_MIN_SLOTS 10000
@@ -169,11 +162,6 @@
 	RVALUE *freelist;
 	RVALUE *range[2];
 	RVALUE *freed;
-	size_t live;
-	size_t dead;
-	size_t do_heap_free;
-	size_t sweep_index;
-	size_t sweep_increment;
     } heap;
     struct {
 	int dont_gc;
@@ -212,11 +200,6 @@
 #define himem			objspace->heap.range[1]
 #define heaps_inc		objspace->heap.increment
 #define heaps_freed		objspace->heap.freed
-#define live			objspace->heap.live
-#define dead			objspace->heap.dead
-#define do_heap_free		objspace->heap.do_heap_free
-#define heaps_sweep_index	objspace->heap.sweep_index
-#define heaps_sweep_inc 	objspace->heap.sweep_increment
 #define dont_gc 		objspace->flags.dont_gc
 #define during_gc		objspace->flags.during_gc
 #define finalizer_table 	objspace->final.table
@@ -266,7 +249,6 @@
 
 static void run_final(rb_objspace_t *objspace, VALUE obj);
 static int garbage_collect(rb_objspace_t *objspace);
-static int garbage_collect_force(rb_objspace_t *objspace);
 
 void
 rb_global_variable(VALUE *var)
@@ -343,11 +325,11 @@
 
     if ((ruby_gc_stress && !ruby_disable_gc_stress) ||
 	(malloc_increase+size) > malloc_limit) {
-	garbage_collect_force(objspace);
+	garbage_collect(objspace);
     }
     RUBY_CRITICAL(mem = malloc(size));
     if (!mem) {
-	if (garbage_collect_force(objspace)) {
+	if (garbage_collect(objspace)) {
 	    RUBY_CRITICAL(mem = malloc(size));
 	}
 	if (!mem) {
@@ -383,9 +365,10 @@
     objspace->malloc_params.allocated_size -= size;
     ptr = (size_t *)ptr - 1;
 #endif
+
     RUBY_CRITICAL(mem = realloc(ptr, size));
     if (!mem) {
-	if (garbage_collect_force(objspace)) {
+	if (garbage_collect(objspace)) {
 	    RUBY_CRITICAL(mem = realloc(ptr, size));
 	}
 	if (!mem) {
@@ -576,8 +559,6 @@
     heaps_length = next_heaps_length;
 }
 
-#define RANY(o) ((RVALUE*)(o))
-
 static void
 assign_heap_slot(rb_objspace_t *objspace)
 {
@@ -621,7 +602,6 @@
     heaps[hi].membase = membase;
     heaps[hi].slot = p;
     heaps[hi].limit = objs;
-    heaps[hi].color = BLACK;
     pend = p + objs;
     if (lomem == 0 || lomem > p) lomem = p;
     if (himem < pend) himem = pend;
@@ -633,9 +613,6 @@
 	freelist = p;
 	p++;
     }
-    if (hi < heaps_sweep_index) {
-	heaps_sweep_index++;
-    }
 }
 
 static void
@@ -678,13 +655,15 @@
     return Qfalse;
 }
 
+#define RANY(o) ((RVALUE*)(o))
+
 static VALUE
 rb_newobj_from_heap(rb_objspace_t *objspace)
 {
     VALUE obj;
 	
     if ((ruby_gc_stress && !ruby_disable_gc_stress) || !freelist) {
-   	if (!garbage_collect(objspace)) {
+    	if (!heaps_increment(objspace) && !garbage_collect(objspace)) {
 	    rb_memerror();
 	}
     }
@@ -1065,7 +1044,6 @@
     if (obj->as.basic.flags == 0) return;       /* free cell */
     if (obj->as.basic.flags & FL_MARK) return;  /* already marked */
     obj->as.basic.flags |= FL_MARK;
-    live++;
 
     if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
 	if (!mark_stack_overflow) {
@@ -1101,7 +1079,6 @@
     if (obj->as.basic.flags == 0) return;       /* free cell */
     if (obj->as.basic.flags & FL_MARK) return;  /* already marked */
     obj->as.basic.flags |= FL_MARK;
-    live++;
 
   marking:
     if (FL_TEST(obj, FL_EXIVAR)) {
@@ -1361,133 +1338,139 @@
 	if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
             VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
 	    p->as.free.flags = 0;
+	    p->as.free.next = freelist;
+	    freelist = p;
 	}
 	p = tmp;
     }
 }
 
-void rb_gc_abort_threads(void);
-
-static int
-slot_sweep(rb_objspace_t *objspace, struct heaps_slot *target)
+static void
+free_unused_heaps(rb_objspace_t *objspace)
 {
-    RVALUE *p, *pend, *free;
-    RVALUE *final;
-    int freed = 0;
+    size_t i, j;
+    RVALUE *last = 0;
 
-    if (target->color == BLACK || target->color == WHITE) {
-	return Qfalse;
-    }
-
-    final = deferred_final_list;
-    free = freelist;
-    p = target->slot; pend = p + target->limit;
-    while (p < pend) {
-	if (!(p->as.basic.flags & FL_MARK)) {
-	    if (p->as.basic.flags) {
-		obj_free(objspace, (VALUE)p);
+    for (i = j = 1; j < heaps_used; i++) {
+	if (heaps[i].limit == 0) {
+	    if (!last) {
+		last = heaps[i].membase;
 	    }
-	    if (need_call_final && FL_TEST(p, FL_FINALIZE)) {
-		p->as.free.flags = FL_MARK; /* remain marked */
-		p->as.free.next = deferred_final_list;
-		deferred_final_list = p;
-	    }
 	    else {
-		VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
-		p->as.free.flags = 0;
-		p->as.free.next = freelist;
-		freelist = p;
+		free(heaps[i].membase);
 	    }
-	    freed++;
+	    heaps_used--;
 	}
-	else if (RBASIC(p)->flags == FL_MARK) {
-	    /* objects to be finalized */
-	    /* do nothing remain marked */
-	}
 	else {
-	    p->as.basic.flags &= ~FL_MARK;
+	    if (i != j) {
+		heaps[j] = heaps[i];
+	    }
+	    j++;
 	}
-	p++;
     }
-    dead += freed;
-    if (freed == target->limit && dead > do_heap_free) {
-	RVALUE *pp;
-
-	target->limit = 0;
-	target->color = WHITE;
-	for (pp = deferred_final_list; pp != final; pp = pp->as.free.next) {
-	    pp->as.free.flags |= FL_SINGLETON; /* freeing page mark */
+    if (last) {
+	if (last < heaps_freed) {
+	    free(heaps_freed);
+	    heaps_freed = last;
 	}
-	freelist = free;	/* cancel this page from freelist */
+	else {
+	    free(last);
+	}
     }
-    else {
-	target->color = BLACK;
-    }
-    return Qtrue;
 }
 
 static void
-heap_sweep_increment(rb_objspace_t *objspace)
+gc_sweep(rb_objspace_t *objspace)
 {
-    int i = 0;
+    RVALUE *p, *pend, *final_list;
+    size_t freed = 0;
+    size_t i;
+    size_t live = 0, free_min = 0, do_heap_free = 0;
 
-    while (i < heaps_sweep_inc && heaps_sweep_index < heaps_used) {
-	if (slot_sweep(objspace, &heaps[heaps_sweep_index])) {
-	    i++;
-	}
-	heaps_sweep_index++;
+    do_heap_free = (heaps_used * HEAP_OBJ_LIMIT) * 0.65;
+    free_min = (heaps_used * HEAP_OBJ_LIMIT)  * 0.2;
+    if (free_min < FREE_MIN) {
+	do_heap_free = heaps_used * HEAP_OBJ_LIMIT;
+        free_min = FREE_MIN;
     }
-}
 
-static void
-heap_sweep(rb_objspace_t *objspace)
-{
-    while (!freelist && heaps_sweep_index < heaps_used) {
-	slot_sweep(objspace, &heaps[heaps_sweep_index]);
-	heaps_sweep_index++;
-    }
-}
+    freelist = 0;
+    final_list = deferred_final_list;
+    deferred_final_list = 0;
+    for (i = 0; i < heaps_used; i++) {
+	int n = 0;
+	RVALUE *free = freelist;
+	RVALUE *final = final_list;
 
-#define GC_NOT_LAZY_SWEEP 0
+	p = heaps[i].slot; pend = p + heaps[i].limit;
+	while (p < pend) {
+	    if (!(p->as.basic.flags & FL_MARK)) {
+		if (p->as.basic.flags) {
+		    obj_free(objspace, (VALUE)p);
+		}
+		if (need_call_final && FL_TEST(p, FL_FINALIZE)) {
+		    p->as.free.flags = FL_MARK; /* remain marked */
+		    p->as.free.next = final_list;
+		    final_list = p;
+		}
+		else {
+                    VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
+		    p->as.free.flags = 0;
+		    p->as.free.next = freelist;
+		    freelist = p;
+		}
+		n++;
+	    }
+	    else if (RBASIC(p)->flags == FL_MARK) {
+		/* objects to be finalized */
+		/* do nothing remain marked */
+	    }
+	    else {
+		RBASIC(p)->flags &= ~FL_MARK;
+		live++;
+	    }
+	    p++;
+	}
+	if (n == heaps[i].limit && freed > do_heap_free) {
+	    RVALUE *pp;
 
-#ifdef GC_NOT_LAZY_SWEEP
-static void
-heap_all_sweep(rb_objspace_t *objspace)
-{
-    while (heaps_sweep_index < heaps_used) {
-	slot_sweep(objspace, &heaps[heaps_sweep_index]);
-	heaps_sweep_index++;
+	    heaps[i].limit = 0;
+	    for (pp = final_list; pp != final; pp = pp->as.free.next) {
+		p->as.free.flags |= FL_SINGLETON; /* freeing page mark */
+	    }
+	    freelist = free;	/* cancel this page from freelist */
+	}
+	else {
+	    freed += n;
+	}
     }
-}
-#endif
-
-static int
-gc_lazy_sweep(rb_objspace_t *objspace, rb_thread_t *th)
-{
-
-    if (heaps_increment(objspace)) {
-	heap_sweep_increment(objspace);
+    if (malloc_increase > malloc_limit) {
+	malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed);
+	if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT;
     }
-    else {
-	heap_sweep(objspace);
+    malloc_increase = 0;
+    if (freed < free_min) {
+    	set_heaps_increment(objspace);
+	heaps_increment(objspace);
     }
+    during_gc = 0;
 
-#ifdef GC_NOT_LAZY_SWEEP
-    if (GC_NOT_LAZY_SWEEP) heap_all_sweep(objspace);
-#endif
-
-    if (!freelist) {
-	return Qfalse;
+    /* clear finalization list */
+    if (final_list) {
+	deferred_final_list = final_list;
+	return;
     }
-
-    return Qtrue;
+    free_unused_heaps(objspace);
 }
 
 void
 rb_gc_force_recycle(VALUE p)
 {
+    rb_objspace_t *objspace = &rb_objspace;
     VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
     RANY(p)->as.free.flags = 0;
+    RANY(p)->as.free.next = freelist;
+    freelist = RANY(p);
 }
 
 static void
@@ -1688,87 +1671,30 @@
 
 void rb_gc_mark_encodings(void);
 
-static void
-gc_mark_all_clear(rb_objspace_t *objspace)
+static int
+garbage_collect(rb_objspace_t *objspace)
 {
-    RVALUE *last = 0;
-    size_t i, j;
-    
-    for (i = j = 0; j < heaps_used; i++) {
-	if (heaps[i].color == WHITE && !deferred_final_list) {
-	    if (!last) {
-		last = heaps[i].membase;
-	    }
-	    else {
-		free(heaps[i].membase);
-	    }
-	    heaps_used--;
-	}
-	else {
-	    if (heaps[i].color == GRAY) {
-		RVALUE *p, *pend;
-		p = heaps[i].slot; pend = p + heaps[i].limit;
-		while (p < pend) {
-		    if (!(RBASIC(p)->flags & FL_MARK)) {
-			if (p->as.basic.flags && !FL_TEST(p, FL_FINALIZE)) {
-			    obj_free(objspace, (VALUE)p);
-			    VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
-			    p->as.free.flags = 0;
-			}
-		    }
-		    else if (RBASIC(p)->flags != FL_MARK) {
-			p->as.basic.flags &= ~FL_MARK;
-		    }
-		    p++;
-		}
-	    }
-	    else {
-		heaps[i].color = GRAY;
-	    }
-	    if (i != j) {
-		heaps[j] = heaps[i];
-	    }
-	    j++;
-	}
-    }
-    if (last) {
-	if (last < heaps_freed) {
-	    free(heaps_freed);
-	    heaps_freed = last;
-	}
-	else {
-	    free(last);
-	}
-    }
-}
+    struct gc_list *list;
+    rb_thread_t *th = GET_THREAD();
 
-static void
-set_lazy_sweep_params(rb_objspace_t *objspace)
-{
-    size_t free_min = 0;
+    if (GC_NOTIFY) printf("start garbage_collect()\n");
 
-    dead = 0;
-    heaps_sweep_index = 0;
-    heaps_sweep_inc = (heaps_used / 10) + 1;
-    do_heap_free = (heaps_used * HEAP_OBJ_LIMIT) * 0.65;
-    free_min = (heaps_used * HEAP_OBJ_LIMIT)  * 0.2;
-    if (free_min < FREE_MIN) free_min = FREE_MIN;
-    if (free_min > (heaps_used * HEAP_OBJ_LIMIT - live)) {
-	set_heaps_increment(objspace);
-	heaps_sweep_inc = (heaps_used + heaps_sweep_inc) / heaps_sweep_inc + 1;
+    if (!heaps) {
+	return Qfalse;
     }
-}
 
-static void
-gc_marks(rb_objspace_t *objspace, rb_thread_t *th)
-{
-    struct gc_list *list;
+    if (dont_gc || during_gc) {
+	if (!freelist) {
+            if (!heaps_increment(objspace)) {
+                set_heaps_increment(objspace);
+                heaps_increment(objspace);
+            }
+	}
+	return Qtrue;
+    }
+    during_gc++;
+    objspace->count++;
 
-    live = 0;
-    freelist = 0;
-
-    gc_mark_all_clear(objspace);
-
     SET_STACK_END;
 
     init_mark_stack(objspace);
@@ -1785,7 +1711,6 @@
     rb_gc_mark_symbols();
     rb_gc_mark_encodings();
 
-
     /* mark protected global variables */
     for (list = global_List; list; list = list->next) {
 	rb_gc_mark_maybe(*list->varptr);
@@ -1811,51 +1736,9 @@
 	}
     }
 
-    set_lazy_sweep_params(objspace);
-}
+    gc_sweep(objspace);
 
-static int
-garbage_collect_force(rb_objspace_t *objspace)
-{
-    if (malloc_increase > malloc_limit) {
-	malloc_limit += (malloc_increase - malloc_limit) * (double)live / (heaps_used * HEAP_OBJ_LIMIT);
-	if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT;
-    }
-    malloc_increase = 0;
-    gc_marks(objspace, GET_THREAD());
-    return garbage_collect(objspace);
-}
-
-static int
-garbage_collect(rb_objspace_t *objspace)
-{
-    rb_thread_t *th = GET_THREAD();
-
-    if (GC_NOTIFY) printf("start garbage_collect()\n");
-
-    if (!heaps) {
-	return Qfalse;
-    }
-
-    if (dont_gc || during_gc) {
-	if (!freelist) {
-            if (!heaps_increment(objspace)) {
-                set_heaps_increment(objspace);
-                heaps_increment(objspace);
-            }
-	}
-	return Qtrue;
-    }
-    during_gc++;
-    objspace->count++;
-
-    while (!gc_lazy_sweep(objspace, th)) {
-        gc_marks(objspace, th);
-    }
-
     if (GC_NOTIFY) printf("end garbage_collect()\n");
-    during_gc = 0;
-
     return Qtrue;
 }
 
@@ -2155,6 +2038,7 @@
     if (p) {
 	finalize_list(objspace, p);
     }
+    free_unused_heaps(objspace);
 }
 
 void
@@ -2226,8 +2110,8 @@
 rb_gc(void)
 {
     rb_objspace_t *objspace = &rb_objspace;
-    gc_finalize_deferred(objspace);
     garbage_collect(objspace);
+    gc_finalize_deferred(objspace);
 }
 
 /*
Index: mvm/parse.y
===================================================================
--- mvm/parse.y	(revision 17888)
+++ mvm/parse.y	(revision 17889)
@@ -4672,17 +4672,16 @@
 static VALUE
 coverage(const char *f, int n)
 {
-    if (rb_const_defined_at(rb_cObject, rb_intern("COVERAGE__"))) {
-	VALUE hash = rb_const_get_at(rb_cObject, rb_intern("COVERAGE__"));
-	if (TYPE(hash) == T_HASH) {
-	    VALUE fname = rb_str_new2(f);
-	    VALUE lines = rb_ary_new2(n);
-	    int i;
-	    for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
-	    RARRAY(lines)->len = n;
-	    rb_hash_aset(hash, fname, lines);
-	    return lines;
-	}
+    extern VALUE rb_vm_get_coverages(void);
+    VALUE coverages = rb_vm_get_coverages();
+    if (RTEST(coverages)) {
+	VALUE fname = rb_str_new2(f);
+	VALUE lines = rb_ary_new2(n);
+	int i;
+	for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
+	RARRAY(lines)->len = n;
+	rb_hash_aset(coverages, fname, lines);
+	return lines;
     }
     return 0;
 }
Index: mvm/ext/coverage/extconf.rb
===================================================================
--- mvm/ext/coverage/extconf.rb	(revision 0)
+++ mvm/ext/coverage/extconf.rb	(revision 17889)
@@ -0,0 +1,2 @@
+require 'mkmf'
+create_makefile('coverage')

Property changes on: mvm/ext/coverage/extconf.rb
___________________________________________________________________
Name: svn:eol-style
   + LF

Index: mvm/ext/coverage/coverage.c
===================================================================
--- mvm/ext/coverage/coverage.c	(revision 0)
+++ mvm/ext/coverage/coverage.c	(revision 17889)
@@ -0,0 +1,47 @@
+/************************************************
+
+  coverage.c -
+
+  $Author: $
+
+  Copyright (c) 2008 Yusuke Endoh
+
+************************************************/
+
+#include "ruby.h"
+
+extern void rb_enable_coverages(void);
+
+/* Coverage provides coverage measurement feature for Ruby.
+ *
+ * = Usage
+ *
+ * (1) require "coverage.so"
+ * (2) require or load Ruby source file
+ * (3) Coverage.result will return a hash that contains filename as key and
+ *     coverage array as value.
+ *
+ * = Example
+ *
+ *   [foo.rb]
+ *   s = 0
+ *   10.times do |x|
+ *     s += x
+ *   end
+ *
+ *   if s == 45
+ *     p :ok
+ *   else
+ *     p :ng
+ *   end
+ *   [EOF]
+ *
+ *   require "coverage.so"
+ *   require "foo.rb"
+ *   p COVERAGE__  #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]}
+ */
+void
+Init_coverage(void)
+{
+    rb_enable_coverages();
+}

Property changes on: mvm/ext/coverage/coverage.c
___________________________________________________________________
Name: svn:eol-style
   + LF


Property changes on: mvm/ext/coverage
___________________________________________________________________
Name: svn:ignore
   + extconf.h
Makefile


Index: mvm/ext/win32ole/win32ole.c
===================================================================
--- mvm/ext/win32ole/win32ole.c	(revision 17888)
+++ mvm/ext/win32ole/win32ole.c	(revision 17889)
@@ -24,6 +24,7 @@
 #include <olectl.h>
 #include <ole2.h>
 #include <stdlib.h>
+#include <math.h>
 #ifdef HAVE_STDARG_PROTOTYPES
 #include <stdarg.h>
 #define va_init_list(a,b) va_start(a,b)
@@ -117,7 +118,7 @@
 
 #define WC2VSTR(x) ole_wc2vstr((x), TRUE)
 
-#define WIN32OLE_VERSION "1.1.8"
+#define WIN32OLE_VERSION "1.2.0"
 
 typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
     (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@@ -367,6 +368,7 @@
 static VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo);
 static VALUE fole_typelib(VALUE self);
 static VALUE fole_query_interface(VALUE self, VALUE str_iid);
+static VALUE fole_respond_to(VALUE self, VALUE method);
 static HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
 static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
 static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
@@ -763,7 +765,7 @@
     double d_hh, d_mm, d_ss;
     int    i_hh, i_mm, i_ss;
 
-    double d = v * 86400.0;
+    double d = fabs(v * 86400.0);
 
     d_hh = d / 3600.0;
     i_hh = (int)d_hh;
@@ -4373,6 +4375,32 @@
     return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
 }
 
+/*
+ *  call-seq:
+ *     WIN32OLE#ole_respond_to?(method) -> true or false
+ * 
+ *  Returns true when OLE object has OLE method, otherwise returns false.
+ *
+ *      ie = WIN32OLE.new('InternetExplorer.Application')
+ *      ie.ole_respond_to?("gohome") => true
+ */
+static VALUE
+fole_respond_to(VALUE self, VALUE method)
+{
+    struct oledata *pole;
+    BSTR wcmdname;
+    DISPID DispID;
+    HRESULT hr;
+    rb_secure(4);
+    Check_SafeStr(method);
+    OLEData_Get_Struct(self, pole);
+    wcmdname = ole_vstr2wc(method);
+    hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
+	    &wcmdname, 1, cWIN32OLE_lcid, &DispID);
+    SysFreeString(wcmdname);
+    return SUCCEEDED(hr) ? Qtrue : Qfalse;
+}
+
 static HRESULT
 ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
 {
@@ -8281,7 +8309,6 @@
     message_filter.MessagePending = mf_MessagePending;
  
     com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
-    com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
     rb_register_mark_object(com_hash);
 
     cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
@@ -8331,6 +8358,7 @@
     rb_define_alias(cWIN32OLE, "ole_obj_help", "ole_type");
     rb_define_method(cWIN32OLE, "ole_typelib", fole_typelib, 0);
     rb_define_method(cWIN32OLE, "ole_query_interface", fole_query_interface, 1);
+    rb_define_method(cWIN32OLE, "ole_respond_to?", fole_respond_to, 1);
 
     rb_define_const(cWIN32OLE, "VERSION", rb_str_new2(WIN32OLE_VERSION));
     rb_define_const(cWIN32OLE, "ARGV", rb_ary_new());
Index: mvm/.merged-trunk-revision
===================================================================
--- mvm/.merged-trunk-revision	(revision 17888)
+++ mvm/.merged-trunk-revision	(revision 17889)
@@ -1 +1 @@
-17835
+17888
Index: mvm/numeric.c
===================================================================
--- mvm/numeric.c	(revision 17888)
+++ mvm/numeric.c	(revision 17889)
@@ -1615,9 +1615,10 @@
 {
     unsigned long num = rb_num2ulong(val);
 
-    if (RTEST(rb_funcall(INT2FIX(0), '<', 1, val))) {
+    if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0))))
+	check_int(num);
+    else
 	check_uint(num);
-    }
     return num;
 }
 
@@ -1630,9 +1631,10 @@
 	return rb_num2uint(val);
     }
     num = FIX2ULONG(val);
-    if (FIX2LONG(val) > 0) {
+    if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0))))
+	check_int(num);
+    else
 	check_uint(num);
-    }
     return num;
 }
 #else
Index: mvm/vm.c
===================================================================
--- mvm/vm.c	(revision 17888)
+++ mvm/vm.c	(revision 17889)
@@ -1395,6 +1395,7 @@
 	RUBY_MARK_UNLESS_NULL(vm->load_path);
 	RUBY_MARK_UNLESS_NULL(vm->loaded_features);
 	RUBY_MARK_UNLESS_NULL(vm->top_self);
+	RUBY_MARK_UNLESS_NULL(vm->coverages);
 	rb_gc_mark_locations(vm->special_exceptions, vm->special_exceptions + ruby_special_error_count - 1);
 
 	if (vm->loading_table) {
@@ -1915,3 +1916,9 @@
 {
     return ruby_vm_debug_ptr(GET_VM());
 }
+
+VALUE
+rb_vm_get_coverages(void)
+{
+    return GET_VM()->coverages;
+}
Index: mvm/version.h
===================================================================
--- mvm/version.h	(revision 17888)
+++ mvm/version.h	(revision 17889)
@@ -1,7 +1,7 @@
 #define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2008-07-03"
+#define RUBY_RELEASE_DATE "2008-07-05"
 #define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20080703
+#define RUBY_RELEASE_CODE 20080705
 #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 7
-#define RUBY_RELEASE_DAY 3
+#define RUBY_RELEASE_DAY 5
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
Index: mvm/test/ruby/test_m17n.rb
===================================================================
--- mvm/test/ruby/test_m17n.rb	(revision 17888)
+++ mvm/test/ruby/test_m17n.rb	(revision 17889)
@@ -493,6 +493,33 @@
     assert_match(/[[:space:]]/, "\u{00a0}")
   end
 
+  def test_regexp_property
+    s = '\p{Hiragana}'.force_encoding("euc-jp")
+    assert_equal(Encoding::EUC_JP, s.encoding)
+    r = nil
+    assert_nothing_raised {
+      r = Regexp.new(s)
+    }
+    assert(r.fixed_encoding?)
+    assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+    r = eval('/\p{Hiragana}/'.force_encoding("euc-jp"))
+    assert(r.fixed_encoding?)
+    assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+    r = /\p{Hiragana}/e
+    assert(r.fixed_encoding?)
+    assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+    r = eval('/\u{3042}\p{Hiragana}/'.force_encoding("euc-jp"))
+    assert(r.fixed_encoding?)
+    assert_equal(Encoding::UTF_8, r.encoding)
+
+    r = eval('/\p{Hiragana}\u{3042}/'.force_encoding("euc-jp"))
+    assert(r.fixed_encoding?)
+    assert_equal(Encoding::UTF_8, r.encoding)
+  end
+
   def test_regexp_embed_preprocess
     r1 = /\xa4\xa2/e
     r2 = /#{r1}/
Index: mvm/test/win32ole/test_win32ole.rb
===================================================================
--- mvm/test/win32ole/test_win32ole.rb	(revision 17888)
+++ mvm/test/win32ole/test_win32ole.rb	(revision 17889)
@@ -246,6 +246,16 @@
       assert_instance_of(WIN32OLE, shell2)
     end
 
+    def test_ole_respond_to
+      fso = WIN32OLE.new('Scripting.FileSystemObject')
+      assert(fso.ole_respond_to?('getFolder'))
+      assert(fso.ole_respond_to?('GETFOLDER'))
+      assert(!fso.ole_respond_to?('XXXXX'))
+      assert_raise(TypeError) {
+        assert_raise(fso.ole_respond_to?(1))
+      }
+    end
+
     def test_s_const_load
       assert(!defined?(CONST1::SsfWINDOWS))
       shell=WIN32OLE.new('Shell.Application')
Index: mvm/test/win32ole/test_win32ole_variant.rb
===================================================================
--- mvm/test/win32ole/test_win32ole_variant.rb	(revision 17888)
+++ mvm/test/win32ole/test_win32ole_variant.rb	(revision 17889)
@@ -540,6 +540,44 @@
       }
     end
 
+    def test_conversion_vt_date
+      obj = WIN32OLE_VARIANT.new(-657434, WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("0100/01/01 00:00:00", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("1500/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("1500/12/29 23:59:59", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("1500/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("1500/12/30 00:00:00", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("1500/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("1500/12/30 00:00:01", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("1899/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("1899/12/29 23:59:59", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("1899/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("1899/12/30 00:00:00", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("1899/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("1899/12/30 00:00:01", obj.value)
+
+      obj = WIN32OLE_VARIANT.new(0, WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("1899/12/30 00:00:00", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("2008/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("2008/12/29 23:59:59", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("2008/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("2008/12/30 00:00:00", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("2008/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("2008/12/30 00:00:01", obj.value)
+
+      obj = WIN32OLE_VARIANT.new("9999/12/31 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+      assert_equal("9999/12/31 23:59:59", obj.value)
+    end
+
     def test_create_nil_dispatch
       var = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
       assert_nil(var.value)
Index: mvm/test/win32ole/test_word.rb
===================================================================
--- mvm/test/win32ole/test_word.rb	(revision 17888)
+++ mvm/test/win32ole/test_word.rb	(revision 17889)
@@ -7,39 +7,66 @@
 end
 require "test/unit"
 
-if defined?(WIN32OLE)
-  class TestWIN32OLE_WITH_WORD < Test::Unit::TestCase
-    
-    def setup
-      begin
-        @obj = WIN32OLE.new('Word.Application')
-      rescue WIN32OLERuntimeError
-        @obj = nil
+def word_installed?
+  installed = false
+  w = nil
+  if defined?(WIN32OLE)
+    begin
+      w = WIN32OLE.new('Word.Application')
+      installed = true
+    rescue
+    ensure
+      if w
+        w.quit
+        w = nil
       end
     end
+  end
+  return installed
+end
 
-    def test_ole_methods
-      if @obj
-        @obj.visible = true
-        @obj.wordbasic.disableAutoMacros(true)
-        assert(true)
+if defined?(WIN32OLE)
+  w = nil
+  dotest = word_installed?
+  if !dotest
+    STDERR.puts("\n#{__FILE__} skipped(Microsoft Word not found.)")
+  end
+  if dotest
+    class TestWIN32OLE_WITH_WORD < Test::Unit::TestCase
+      def setup
+        begin
+          @obj = WIN32OLE.new('Word.Application')
+        rescue WIN32OLERuntimeError
+          @obj = nil
+          if !$skipped 
+              $skipped = true
+          end
+        end
       end
-    end
 
-    def test_s_connect
-      if @obj
-        obj2 = WIN32OLE.connect("Word.Application")
-        assert_instance_of(WIN32OLE, obj2)
-        obj2.visible = true
+      def test_ole_methods
+        if @obj
+          @obj.visible = true
+          @obj.wordbasic.disableAutoMacros(true)
+          assert(true)
+        else
+        end
       end
-    end
 
-    def teardown
-      if @obj
-        @obj.quit
-        @obj = nil
+      def test_s_connect
+        if @obj
+          obj2 = WIN32OLE.connect("Word.Application")
+          assert_instance_of(WIN32OLE, obj2)
+          obj2.visible = true
+        end
       end
+
+      def teardown
+        if @obj
+          @obj.quit
+          @obj = nil
+        end
+      end
     end
-
   end
 end
Index: mvm/test/test_singleton.rb
===================================================================
--- mvm/test/test_singleton.rb	(revision 0)
+++ mvm/test/test_singleton.rb	(revision 17889)
@@ -0,0 +1,15 @@
+require 'test/unit'
+require 'singleton'
+
+class TestSingleton < Test::Unit::TestCase
+  class C
+    include Singleton
+  end
+
+  def test_marshal
+    o1 = C.instance
+    m = Marshal.dump(o1)
+    o2 = Marshal.load(m)
+    assert_same(o1, o2)
+  end
+end

Property changes on: mvm/test/test_singleton.rb
___________________________________________________________________
Name: svn:eol-style
   + LF


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

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