summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--compar.c4
-rw-r--r--enum.c2
-rw-r--r--eval.c6
-rw-r--r--ext/digest/digest.c92
-rw-r--r--ext/digest/digest.h10
-rw-r--r--ext/etc/etc.c4
-rw-r--r--ext/iconv/iconv.c2
-rw-r--r--ext/win32ole/win32ole.c4
-rw-r--r--gc.c12
-rw-r--r--io.c2
-rw-r--r--main.c4
-rw-r--r--ruby.c2
-rw-r--r--signal.c4
-rw-r--r--variable.c4
15 files changed, 73 insertions, 88 deletions
diff --git a/ChangeLog b/ChangeLog
index b050081f5f0..155c9d7a435 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Mon Dec 12 00:33:56 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/digest/digest.c (rb_digest_base_s_digest): add volatile to
+ protect temporary context object. [ruby-dev:27979]
+
+ * ext/iconv/iconv.c (Init_iconv): rb_gc_register_address() should
+ be called before actual variable initialization.
+ [ruby-dev:27986]
+
Sun Dec 11 22:07:58 2005 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* test/rinda/test_rinda.rb (test_remote_array_and_hash): pseudo remote
diff --git a/compar.c b/compar.c
index 234a86027dc..80c4c70ca68 100644
--- a/compar.c
+++ b/compar.c
@@ -53,7 +53,7 @@ cmp_eq(VALUE *a)
{
VALUE c = rb_funcall(a[0], cmp, 1, a[1]);
- if (NIL_P(c)) return Qnil;
+ if (NIL_P(c)) return Qfalse;
if (rb_cmpint(c, a[0], a[1]) == 0) return Qtrue;
return Qfalse;
}
@@ -61,7 +61,7 @@ cmp_eq(VALUE *a)
static VALUE
cmp_failed(void)
{
- return Qnil;
+ return Qfalse;
}
/*
diff --git a/enum.c b/enum.c
index 2229f49da5d..578ea6b4b96 100644
--- a/enum.c
+++ b/enum.c
@@ -449,7 +449,7 @@ sort_by_cmp(const void *ap, const void *bp, void *data)
* values in <i>enum</i> through the given block.
*
* %w{ apple pear fig }.sort_by {|word| word.length}
- #=> ["fig", "pear", "apple"]
+ #=> ["fig", "pear", "apple"]
*
* The current implementation of <code>sort_by</code> generates an
* array of tuples containing the original collection element and the
diff --git a/eval.c b/eval.c
index b1069195451..7be4861cebc 100644
--- a/eval.c
+++ b/eval.c
@@ -7760,14 +7760,14 @@ rb_f_autoload_p(VALUE obj, VALUE sym)
void
Init_load(void)
{
- rb_load_path = rb_ary_new();
rb_define_readonly_variable("$:", &rb_load_path);
rb_define_readonly_variable("$-I", &rb_load_path);
rb_define_readonly_variable("$LOAD_PATH", &rb_load_path);
+ rb_load_path = rb_ary_new();
- rb_features = rb_ary_new();
rb_define_readonly_variable("$\"", &rb_features);
rb_define_readonly_variable("$LOADED_FEATURES", &rb_features);
+ rb_features = rb_ary_new();
rb_define_global_function("load", rb_f_load, -1);
rb_define_global_function("require", rb_f_require, 1);
@@ -7777,8 +7777,8 @@ Init_load(void)
rb_define_global_function("autoload?", rb_f_autoload_p, 1);
rb_global_variable(&ruby_wrapper);
- ruby_dln_librefs = rb_ary_new();
rb_global_variable(&ruby_dln_librefs);
+ ruby_dln_librefs = rb_ary_new();
}
static void
diff --git a/ext/digest/digest.c b/ext/digest/digest.c
index 70f986327af..a63d353ddfe 100644
--- a/ext/digest/digest.c
+++ b/ext/digest/digest.c
@@ -41,8 +41,7 @@ static ID id_metadata;
*/
static algo_t *
-get_digest_base_metadata(klass)
- VALUE klass;
+get_digest_base_metadata(VALUE klass)
{
VALUE obj;
algo_t *algo;
@@ -58,10 +57,8 @@ get_digest_base_metadata(klass)
return algo;
}
-static VALUE rb_digest_base_alloc _((VALUE));
static VALUE
-rb_digest_base_alloc(klass)
- VALUE klass;
+rb_digest_base_alloc(VALUE klass)
{
algo_t *algo;
VALUE obj;
@@ -83,15 +80,12 @@ rb_digest_base_alloc(klass)
}
static VALUE
-rb_digest_base_s_digest(klass, str)
- VALUE klass;
- VALUE str;
+rb_digest_base_s_digest(VALUE klass, VALUE str)
{
algo_t *algo;
void *pctx;
- size_t len;
unsigned char *digest;
- VALUE obj = rb_digest_base_alloc(klass);
+ volatile VALUE obj = rb_digest_base_alloc(klass);
algo = get_digest_base_metadata(klass);
Data_Get_Struct(obj, void, pctx);
@@ -99,28 +93,19 @@ rb_digest_base_s_digest(klass, str)
StringValue(str);
algo->update_func(pctx, RSTRING(str)->ptr, RSTRING(str)->len);
- len = algo->digest_len;
-
- digest = xmalloc(len);
- algo->final_func(digest, pctx);
-
- obj = rb_str_new(digest, len);
-
- free(digest);
+ str = rb_str_new(0, algo->digest_len);
+ algo->final_func(RSTRING(str)->ptr, pctx);
- return obj;
+ return str;
}
static VALUE
-rb_digest_base_s_hexdigest(klass, str)
- VALUE klass;
- VALUE str;
+rb_digest_base_s_hexdigest(VALUE klass, VALUE str)
{
algo_t *algo;
void *pctx;
- size_t len;
unsigned char *hexdigest;
- VALUE obj = rb_digest_base_alloc(klass);
+ volatile VALUE obj = rb_digest_base_alloc(klass);
algo = get_digest_base_metadata(klass);
Data_Get_Struct(obj, void, pctx);
@@ -128,21 +113,14 @@ rb_digest_base_s_hexdigest(klass, str)
StringValue(str);
algo->update_func(pctx, RSTRING(str)->ptr, RSTRING(str)->len);
- len = algo->digest_len * 2;
-
- hexdigest = xmalloc(len + 1); /* +1 is for '\0' */
- algo->end_func(pctx, hexdigest);
-
- obj = rb_str_new(hexdigest, len);
+ str = rb_str_new(0, algo->digest_len * 2);
+ algo->end_func(pctx, RSTRING(str)->ptr);
- free(hexdigest);
-
- return obj;
+ return str;
}
static VALUE
-rb_digest_base_copy(copy, obj)
- VALUE copy, obj;
+rb_digest_base_copy(VALUE copy, VALUE obj)
{
algo_t *algo;
void *pctx1, *pctx2;
@@ -161,8 +139,7 @@ rb_digest_base_copy(copy, obj)
}
static VALUE
-rb_digest_base_update(self, str)
- VALUE self, str;
+rb_digest_base_update(VALUE self, VALUE str)
{
algo_t *algo;
void *pctx;
@@ -177,10 +154,7 @@ rb_digest_base_update(self, str)
}
static VALUE
-rb_digest_base_init(argc, argv, self)
- int argc;
- VALUE* argv;
- VALUE self;
+rb_digest_base_init(int argc, VALUE *argv, VALUE self)
{
VALUE arg;
@@ -192,8 +166,7 @@ rb_digest_base_init(argc, argv, self)
}
static VALUE
-rb_digest_base_digest(self)
- VALUE self;
+rb_digest_base_digest(VALUE self)
{
algo_t *algo;
void *pctx1, *pctx2;
@@ -204,58 +177,43 @@ rb_digest_base_digest(self)
algo = get_digest_base_metadata(rb_obj_class(self));
Data_Get_Struct(self, void, pctx1);
- len = algo->ctx_size;
+ str = rb_str_new(0, algo->digest_len);
+ len = algo->ctx_size;
pctx2 = xmalloc(len);
memcpy(pctx2, pctx1, len);
- len = algo->digest_len;
-
- digest = xmalloc(len);
- algo->final_func(digest, pctx2);
-
- str = rb_str_new(digest, len);
-
- free(digest);
+ algo->final_func(RSTRING(str)->ptr, pctx2);
free(pctx2);
return str;
}
static VALUE
-rb_digest_base_hexdigest(self)
- VALUE self;
+rb_digest_base_hexdigest(VALUE self)
{
algo_t *algo;
void *pctx1, *pctx2;
- unsigned char *hexdigest;
size_t len;
VALUE str;
algo = get_digest_base_metadata(rb_obj_class(self));
Data_Get_Struct(self, void, pctx1);
- len = algo->ctx_size;
+ str = rb_str_new(0, algo->digest_len * 2);
+ len = algo->ctx_size;
pctx2 = xmalloc(len);
memcpy(pctx2, pctx1, len);
- len = algo->digest_len * 2;
-
- hexdigest = xmalloc(len + 1); /* +1 is for '\0' */
- algo->end_func(pctx2, hexdigest);
-
- str = rb_str_new(hexdigest, len);
-
- free(hexdigest);
+ algo->end_func(pctx2, RSTRING(str)->ptr);
free(pctx2);
return str;
}
static VALUE
-rb_digest_base_equal(self, other)
- VALUE self, other;
+rb_digest_base_equal(VALUE self, VALUE other)
{
algo_t *algo;
VALUE klass;
@@ -282,7 +240,7 @@ rb_digest_base_equal(self, other)
str1 = rb_digest_base_hexdigest(self);
if (RSTRING(str1)->len == RSTRING(str2)->len
- && rb_str_cmp(str1, str2) == 0)
+ && rb_str_cmp(str1, str2) == 0)
return Qtrue;
return Qfalse;
diff --git a/ext/digest/digest.h b/ext/digest/digest.h
index 5e846df040e..878aaddd025 100644
--- a/ext/digest/digest.h
+++ b/ext/digest/digest.h
@@ -15,11 +15,11 @@
#include "ruby.h"
-typedef void (*hash_init_func_t) _((void *));
-typedef void (*hash_update_func_t) _((void *, unsigned char *, size_t));
-typedef void (*hash_end_func_t) _((void *, unsigned char *));
-typedef void (*hash_final_func_t) _((unsigned char *, void *));
-typedef int (*hash_equal_func_t) _((void *, void *));
+typedef void (*hash_init_func_t)(void *);
+typedef void (*hash_update_func_t)(void *, unsigned char *, size_t);
+typedef void (*hash_end_func_t)(void *, unsigned char *);
+typedef void (*hash_final_func_t)(unsigned char *, void *);
+typedef int (*hash_equal_func_t)(void *, void *);
typedef struct {
size_t digest_len;
diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index 94196e066a0..ac95735549c 100644
--- a/ext/etc/etc.c
+++ b/ext/etc/etc.c
@@ -521,6 +521,7 @@ Init_etc()
rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0);
rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0);
+ rb_global_variable(&sPasswd);
sPasswd = rb_struct_define("Passwd",
"name", "passwd", "uid", "gid",
#ifdef HAVE_ST_PW_GECOS
@@ -546,14 +547,13 @@ Init_etc()
"expire",
#endif
NULL);
- rb_global_variable(&sPasswd);
#ifdef HAVE_GETGRENT
+ rb_global_variable(&sGroup);
sGroup = rb_struct_define("Group", "name",
#ifdef HAVE_ST_GR_PASSWD
"passwd",
#endif
"gid", "mem", NULL);
- rb_global_variable(&sGroup);
#endif
}
diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c
index a1aa484c684..cebbd912fe9 100644
--- a/ext/iconv/iconv.c
+++ b/ext/iconv/iconv.c
@@ -1083,8 +1083,8 @@ Init_iconv(void)
id_transliterate = rb_intern("transliterate");
id_discard_ilseq = rb_intern("discard_ilseq");
- charset_map = rb_hash_new();
rb_gc_register_address(&charset_map);
+ charset_map = rb_hash_new();
rb_define_singleton_method(rb_cIconv, "charset_map", charset_map_get, 0);
}
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c
index 32d92b639ed..fde5d2d456b 100644
--- a/ext/win32ole/win32ole.c
+++ b/ext/win32ole/win32ole.c
@@ -6904,8 +6904,8 @@ folevariant_value(self)
void
Init_win32ole()
{
- ary_ole_event = rb_ary_new();
rb_global_variable(&ary_ole_event);
+ ary_ole_event = rb_ary_new();
id_events = rb_intern("events");
com_vtbl.QueryInterface = QueryInterface;
@@ -6915,8 +6915,8 @@ Init_win32ole()
com_vtbl.GetTypeInfo = GetTypeInfo;
com_vtbl.GetIDsOfNames = GetIDsOfNames;
com_vtbl.Invoke = Invoke;
- com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
rb_global_variable(&com_hash);
+ com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
diff --git a/gc.c b/gc.c
index 887551444af..46523dcdc46 100644
--- a/gc.c
+++ b/gc.c
@@ -106,6 +106,12 @@ rb_memerror(void)
rb_exc_raise(nomem_error);
}
+#ifdef RUBY_GC_DEBUG
+int always_gc = 0;
+#else
+# define always_gc 0
+#endif
+
void *
ruby_xmalloc(size_t size)
{
@@ -117,7 +123,7 @@ ruby_xmalloc(size_t size)
if (size == 0) size = 1;
malloc_increase += size;
- if (malloc_increase > malloc_limit) {
+ if (always_gc || malloc_increase > malloc_limit) {
garbage_collect();
}
RUBY_CRITICAL(mem = malloc(size));
@@ -165,6 +171,7 @@ ruby_xrealloc(void *ptr, size_t size)
if (!ptr) return ruby_xmalloc(size);
if (size == 0) size = 1;
malloc_increase += size;
+ if (always_gc) garbage_collect();
RUBY_CRITICAL(mem = realloc(ptr, size));
if (!mem) {
if (garbage_collect()) {
@@ -394,7 +401,7 @@ rb_newobj(void)
{
VALUE obj;
- if (!freelist && !garbage_collect())
+ if ((always_gc || !freelist) && !garbage_collect())
rb_memerror();
obj = (VALUE)freelist;
@@ -1018,6 +1025,7 @@ gc_sweep(void)
unsigned long live = 0;
mark_source_filename(ruby_sourcefile);
+ if (source_filenames)
st_foreach(source_filenames, sweep_source_filename, 0);
freelist = 0;
diff --git a/io.c b/io.c
index f8395f144e1..dc91b41f74a 100644
--- a/io.c
+++ b/io.c
@@ -5482,9 +5482,9 @@ Init_IO(void)
rb_output_fs = Qnil;
rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter);
+ rb_global_variable(&rb_default_rs);
rb_rs = rb_default_rs = rb_str_new2("\n");
rb_output_rs = Qnil;
- rb_global_variable(&rb_default_rs);
OBJ_FREEZE(rb_default_rs); /* avoid modifying RS_default */
rb_define_hooked_variable("$/", &rb_rs, 0, rb_str_setter);
rb_define_hooked_variable("$-0", &rb_rs, 0, rb_str_setter);
diff --git a/main.c b/main.c
index 16cd6ca2ea4..3c1903ab33a 100644
--- a/main.c
+++ b/main.c
@@ -24,6 +24,10 @@ static void objcdummyfunction( void ) { objc_msgSend(); }
int
main(int argc, char **argv, char **envp)
{
+#ifdef RUBY_GC_DEBUG
+ extern int always_gc;
+ always_gc = getenv("RUBY_ALWAYS_GC") != NULL;
+#endif
#ifdef _WIN32
NtInitialize(&argc, &argv);
#endif
diff --git a/ruby.c b/ruby.c
index 71d69625ac6..353040f89d4 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1159,8 +1159,8 @@ ruby_prog_init(void)
rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0);
- rb_argv = rb_ary_new();
rb_define_readonly_variable("$*", &rb_argv);
+ rb_argv = rb_ary_new();
rb_define_global_const("ARGV", rb_argv);
rb_define_readonly_variable("$-a", &do_split);
rb_global_variable(&rb_argv0);
diff --git a/signal.c b/signal.c
index 2bbf9e84b9b..9a1044c991b 100644
--- a/signal.c
+++ b/signal.c
@@ -944,10 +944,14 @@ Init_signal(void)
#endif
#ifdef SIGBUS
+# ifndef RUBY_GC_DEBUG
install_sighandler(SIGBUS, sigbus);
+# endif
#endif
#ifdef SIGSEGV
+# ifndef RUBY_GC_DEBUG
install_sighandler(SIGSEGV, sigsegv);
+# endif
#endif
#ifdef SIGPIPE
install_sighandler(SIGPIPE, sigpipe);
diff --git a/variable.c b/variable.c
index 565a1f2b17d..c6e54c3d105 100644
--- a/variable.c
+++ b/variable.c
@@ -424,7 +424,9 @@ mark_global_entry(ID key, struct global_entry *entry)
void
rb_gc_mark_global_tbl(void)
{
- st_foreach_safe(rb_global_tbl, mark_global_entry, 0);
+ if (rb_global_tbl) {
+ st_foreach(rb_global_tbl, mark_global_entry, 0);
+ }
}
static ID