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/