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

ruby-changes:7737

From: nobu <ko1@a...>
Date: Tue, 9 Sep 2008 00:56:26 +0900 (JST)
Subject: [ruby-changes:7737] Ruby:r19258 (mvm): * eval.c (ruby_vm_init): split from ruby_init.

nobu	2008-09-09 00:55:39 +0900 (Tue, 09 Sep 2008)

  New Revision: 19258

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

  Log:
    * eval.c (ruby_vm_init): split from ruby_init.
    
    * eval.c (ruby_vm_run): cleans up VM always.
    
    * inits.c (rb_call_inits): separated per-process and per-VM
      intializations.
    
    * parse.y (sym_str_new): creates VM-neutral string.

  Modified files:
    branches/mvm/ChangeLog
    branches/mvm/array.c
    branches/mvm/bignum.c
    branches/mvm/compar.c
    branches/mvm/complex.c
    branches/mvm/cont.c
    branches/mvm/dir.c
    branches/mvm/dmyext.c
    branches/mvm/encoding.c
    branches/mvm/enum.c
    branches/mvm/enumerator.c
    branches/mvm/error.c
    branches/mvm/eval.c
    branches/mvm/eval_jump.c
    branches/mvm/ext/ripper/eventids2.c
    branches/mvm/ext/ripper/tools/generate.rb
    branches/mvm/file.c
    branches/mvm/gc.c
    branches/mvm/hash.c
    branches/mvm/inits.c
    branches/mvm/io.c
    branches/mvm/iseq.c
    branches/mvm/load.c
    branches/mvm/marshal.c
    branches/mvm/math.c
    branches/mvm/numeric.c
    branches/mvm/object.c
    branches/mvm/pack.c
    branches/mvm/parse.y
    branches/mvm/prec.c
    branches/mvm/private_object.h
    branches/mvm/proc.c
    branches/mvm/process.c
    branches/mvm/random.c
    branches/mvm/range.c
    branches/mvm/rational.c
    branches/mvm/re.c
    branches/mvm/signal.c
    branches/mvm/string.c
    branches/mvm/struct.c
    branches/mvm/thread.c
    branches/mvm/time.c
    branches/mvm/transcode.c
    branches/mvm/variable.c
    branches/mvm/version.c
    branches/mvm/vm.c

Index: mvm/complex.c
===================================================================
--- mvm/complex.c	(revision 19257)
+++ mvm/complex.c	(revision 19258)
@@ -1335,8 +1335,6 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
-    assert(fprintf(stderr, "assert() is now active\n"));
-
     id_Unify = rb_intern("Unify");
     id_abs = rb_intern("abs");
     id_abs2 = rb_intern("abs2");
@@ -1365,7 +1363,13 @@
     id_to_r = rb_intern("to_r");
     id_to_s = rb_intern("to_s");
     id_truncate = rb_intern("truncate");
+}
 
+void
+InitVM_Complex(rb_vm_t *vm)
+{
+    assert(fprintf(stderr, "assert() is now active\n"));
+
     rb_cComplex = rb_define_class(COMPLEX_NAME, rb_cNumeric);
 
     rb_define_alloc_func(rb_cComplex, nucomp_s_alloc);
Index: mvm/array.c
===================================================================
--- mvm/array.c	(revision 19257)
+++ mvm/array.c	(revision 19258)
@@ -3513,6 +3513,12 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
+    id_cmp = rb_intern("<=>");
+}
+
+void
+InitVM_Array(rb_vm_t *vm)
+{
     rb_cArray  = rb_define_class("Array", rb_cObject);
     rb_include_module(rb_cArray, rb_mEnumerable);
 
@@ -3610,6 +3616,4 @@
     rb_define_method(rb_cArray, "take_while", rb_ary_take_while, 0);
     rb_define_method(rb_cArray, "drop", rb_ary_drop, 1);
     rb_define_method(rb_cArray, "drop_while", rb_ary_drop_while, 0);
-
-    id_cmp = rb_intern("<=>");
 }
Index: mvm/encoding.c
===================================================================
--- mvm/encoding.c	(revision 19257)
+++ mvm/encoding.c	(revision 19258)
@@ -1184,11 +1184,16 @@
 {
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
+
+    id_base_encoding = rb_intern("#base_encoding");
+}
+
+void
+InitVM_Encoding(rb_vm_t *vm)
+{
     VALUE list;
     int i;
 
-    id_base_encoding = rb_intern("#base_encoding");
-
     rb_cEncoding = rb_define_class("Encoding", rb_cObject);
     rb_undef_alloc_func(rb_cEncoding);
     rb_define_method(rb_cEncoding, "to_s", enc_name, 0);
Index: mvm/math.c
===================================================================
--- mvm/math.c	(revision 19257)
+++ mvm/math.c	(revision 19258)
@@ -662,6 +662,11 @@
 void
 Init_Math(void)
 {
+}
+
+void
+InitVM_Math(rb_vm_t *vm)
+{
     rb_mMath = rb_define_module("Math");
 
 #ifdef M_PI
Index: mvm/time.c
===================================================================
--- mvm/time.c	(revision 19257)
+++ mvm/time.c	(revision 19258)
@@ -2384,7 +2384,11 @@
     id_divmod = rb_intern("divmod");
     id_mul = rb_intern("*");
     id_submicro = rb_intern("submicro");
+}
 
+void
+InitVM_Time(rb_vm_t *vm)
+{
     rb_cTime = rb_define_class("Time", rb_cObject);
     rb_include_module(rb_cTime, rb_mComparable);
 
Index: mvm/re.c
===================================================================
--- mvm/re.c	(revision 19257)
+++ mvm/re.c	(revision 19258)
@@ -2427,18 +2427,20 @@
     return re;
 }
 
-static VALUE reg_cache;
+static int vmkey_reg_cache;
+#define vm_reg_cache (*rb_vm_specific_ptr(vmkey_reg_cache))
 
 VALUE
 rb_reg_regcomp(VALUE str)
 {
     volatile VALUE save_str = str;
+    VALUE reg_cache = vm_reg_cache;
     if (reg_cache && RREGEXP_SRC_LEN(reg_cache) == RSTRING_LEN(str)
 	&& ENCODING_GET(reg_cache) == ENCODING_GET(str)
 	&& memcmp(RREGEXP_SRC_PTR(reg_cache), RSTRING_PTR(str), RSTRING_LEN(str)) == 0)
 	return reg_cache;
 
-    return reg_cache = rb_reg_new_str(save_str, 0);
+    return vm_reg_cache = rb_reg_new_str(save_str, 0);
 }
 
 /*
@@ -3338,13 +3340,19 @@
 void
 Init_Regexp(void)
 {
-    rb_eRegexpError = rb_define_class("RegexpError", rb_eStandardError);
+    vmkey_reg_cache = rb_vm_key_create();
 
     onigenc_set_default_caseconv_table((UChar*)casetable);
     onigenc_set_default_encoding(ONIG_ENCODING_ASCII);
     onig_set_warn_func(re_warn);
     onig_set_verb_warn_func(re_warn);
+}
 
+void
+InitVM_Regexp(rb_vm_t *vm)
+{
+    rb_eRegexpError = rb_define_class("RegexpError", rb_eStandardError);
+
     rb_define_virtual_variable("$~", match_getter, match_setter);
     rb_define_virtual_variable("$&", last_match_getter, 0);
     rb_define_virtual_variable("$`", prematch_getter, 0);
@@ -3387,8 +3395,6 @@
     rb_define_const(rb_cRegexp, "EXTENDED", INT2FIX(ONIG_OPTION_EXTEND));
     rb_define_const(rb_cRegexp, "MULTILINE", INT2FIX(ONIG_OPTION_MULTILINE));
 
-    rb_global_variable(&reg_cache);
-
     rb_cMatch  = rb_define_class("MatchData", rb_cObject);
     rb_define_alloc_func(rb_cMatch, match_alloc);
     rb_undef_method(CLASS_OF(rb_cMatch), "new");
Index: mvm/ChangeLog
===================================================================
--- mvm/ChangeLog	(revision 19257)
+++ mvm/ChangeLog	(revision 19258)
@@ -1,5 +1,14 @@
-Tue Sep  9 00:37:45 2008  Nobuyoshi Nakada  <nobu@r...>
+Tue Sep  9 00:55:34 2008  Nobuyoshi Nakada  <nobu@r...>
 
+	* eval.c (ruby_vm_init): split from ruby_init.
+
+	* eval.c (ruby_vm_run): cleans up VM always.
+
+	* inits.c (rb_call_inits): separated per-process and per-VM
+	  intializations.
+
+	* parse.y (sym_str_new): creates VM-neutral string.
+
 	* vm_core.h (struct rb_vm_struct): includes method cache.
 
 	* vm.c (vm_init2): initializes method cache.
Index: mvm/enumerator.c
===================================================================
--- mvm/enumerator.c	(revision 19257)
+++ mvm/enumerator.c	(revision 19258)
@@ -757,6 +757,12 @@
 void
 Init_Enumerator(void)
 {
+    sym_each = ID2SYM(rb_intern_const("each"));
+}
+
+void
+InitVM_Enumerator(rb_vm_t *vm)
+{
     rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1);
     rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1);
 
@@ -795,7 +801,5 @@
     rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
     rb_define_method(rb_cYielder, "<<", yielder_yield, -2);
 
-    sym_each = ID2SYM(rb_intern("each"));
-
     rb_provide("enumerator.so");	/* for backward compatibility */
 }
Index: mvm/variable.c
===================================================================
--- mvm/variable.c	(revision 19257)
+++ mvm/variable.c	(revision 19258)
@@ -24,15 +24,19 @@
 void
 Init_var_tables(void)
 {
-    rb_vm_t *vm = GET_VM();
-    vm->mark_object_ary = rb_ary_new();
-    vm->global_tbl = st_init_numtable();
     CONST_ID(autoload, "__autoload__");
     CONST_ID(classpath, "__classpath__");
     CONST_ID(tmp_classpath, "__tmp_classpath__");
     CONST_ID(id_const_missing, "const_missing");
 }
 
+void
+InitVM_var_tables(rb_vm_t *vm)
+{
+    vm->mark_object_ary = rb_ary_new();
+    vm->global_tbl = st_init_numtable();
+}
+
 struct fc_result {
     ID name;
     VALUE klass;
Index: mvm/iseq.c
===================================================================
--- mvm/iseq.c	(revision 19257)
+++ mvm/iseq.c	(revision 19258)
@@ -1316,6 +1316,11 @@
 void
 Init_ISeq(void)
 {
+}
+
+void
+InitVM_ISeq(rb_vm_t *vm)
+{
     /* declare ::VM::InstructionSequence */
     rb_cISeq = rb_define_class_under(rb_cRubyVM, "InstructionSequence", rb_cObject);
     rb_define_alloc_func(rb_cISeq, iseq_alloc);
Index: mvm/enum.c
===================================================================
--- mvm/enum.c	(revision 19257)
+++ mvm/enum.c	(revision 19258)
@@ -1805,6 +1805,16 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
+    id_eqq  = rb_intern("===");
+    id_each = rb_intern("each");
+    id_cmp  = rb_intern("<=>");
+    id_next = rb_intern("next");
+    id_size = rb_intern("size");
+}
+
+void
+InitVM_Enumerable(rb_vm_t *vm)
+{
     rb_mEnumerable = rb_define_module("Enumerable");
 
     rb_define_method(rb_mEnumerable, "to_a", enum_to_a, -1);
@@ -1847,11 +1857,4 @@
     rb_define_method(rb_mEnumerable, "drop", enum_drop, 1);
     rb_define_method(rb_mEnumerable, "drop_while", enum_drop_while, 0);
     rb_define_method(rb_mEnumerable, "cycle", enum_cycle, -1);
-
-    id_eqq  = rb_intern("===");
-    id_each = rb_intern("each");
-    id_cmp  = rb_intern("<=>");
-    id_next = rb_intern("next");
-    id_size = rb_intern("size");
 }
-
Index: mvm/string.c
===================================================================
--- mvm/string.c	(revision 19257)
+++ mvm/string.c	(revision 19258)
@@ -1869,7 +1869,7 @@
     static unsigned int hashseed;
 
     if (!hashseed_init) {
-        hashseed = rb_genrand_int32();
+        /*hashseed = rb_genrand_int32();*/
         hashseed_init = 1;
     }
 
@@ -6657,6 +6657,12 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
+    id_to_s = rb_intern("to_s");
+}
+
+void
+InitVM_String(rb_vm_t *vm)
+{
     rb_cString  = rb_define_class("String", rb_cObject);
     rb_include_module(rb_cString, rb_mComparable);
     rb_define_alloc_func(rb_cString, str_alloc);
@@ -6779,8 +6785,6 @@
     rb_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);
     rb_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);
 
-    id_to_s = rb_intern("to_s");
-
     rb_fs = Qnil;
     rb_define_variable("$;", &rb_fs);
     rb_define_variable("$-F", &rb_fs);
Index: mvm/object.c
===================================================================
--- mvm/object.c	(revision 19257)
+++ mvm/object.c	(revision 19258)
@@ -2445,11 +2445,24 @@
 void
 Init_Object(void)
 {
-    int i;
-
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
+    int i;
 
+    id_eq = rb_intern("==");
+    id_eql = rb_intern("eql?");
+    id_match = rb_intern("=~");
+    id_inspect = rb_intern("inspect");
+    id_init_copy = rb_intern("initialize_copy");
+
+    for (i=0; conv_method_names[i].method; i++) {
+	conv_method_names[i].id = rb_intern(conv_method_names[i].method);
+    }
+}
+
+void
+InitVM_Object(rb_vm_t *vm)
+{
     VALUE metaclass;
 
     rb_cBasicObject = boot_defclass("BasicObject", 0);
@@ -2620,14 +2633,4 @@
     rb_undef_alloc_func(rb_cFalseClass);
     rb_undef_method(CLASS_OF(rb_cFalseClass), "new");
     rb_define_global_const("FALSE", Qfalse);
-
-    id_eq = rb_intern("==");
-    id_eql = rb_intern("eql?");
-    id_match = rb_intern("=~");
-    id_inspect = rb_intern("inspect");
-    id_init_copy = rb_intern("initialize_copy");
-
-    for (i=0; conv_method_names[i].method; i++) {
-	conv_method_names[i].id = rb_intern(conv_method_names[i].method);
-    }
 }
Index: mvm/io.c
===================================================================
--- mvm/io.c	(revision 19257)
+++ mvm/io.c	(revision 19258)
@@ -83,6 +83,7 @@
 #endif
 
 extern void Init_File(void);
+extern void InitVM_File(rb_vm_t *);
 
 #ifdef __BEOS__
 # ifndef NOFILE
@@ -8275,6 +8276,12 @@
 void
 Init_IO(void)
 {
+    Init_File();
+}
+
+void
+InitVM_IO(rb_vm_t *vm)
+{
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
@@ -8536,7 +8543,7 @@
     atexit(pipe_atexit);
 #endif
 
-    Init_File();
+    InitVM_File(vm);
 
     rb_define_method(rb_cFile, "initialize",  rb_file_initialize, -1);
 
Index: mvm/dmyext.c
===================================================================
--- mvm/dmyext.c	(revision 19257)
+++ mvm/dmyext.c	(revision 19258)
@@ -1,3 +1,5 @@
+#include "ruby/mvm.h"
+
 void
 Init_ext(void)
 {
@@ -2 +4,6 @@
 }
+
+void
+InitVM_ext(rb_vm_t *vm)
+{
+}
Index: mvm/pack.c
===================================================================
--- mvm/pack.c	(revision 19257)
+++ mvm/pack.c	(revision 19258)
@@ -2124,6 +2124,11 @@
 void
 Init_pack(void)
 {
+}
+
+void
+InitVM_pack(rb_vm_t *vm)
+{
     rb_define_method(rb_cArray, "pack", pack_pack, 1);
     rb_define_method(rb_cString, "unpack", pack_unpack, 1);
 }
Index: mvm/load.c
===================================================================
--- mvm/load.c	(revision 19257)
+++ mvm/load.c	(revision 19258)
@@ -675,9 +675,11 @@
 void
 Init_load()
 {
-#undef rb_intern
-#define rb_intern(str) rb_intern2(str, strlen(str))
-    rb_vm_t *vm = GET_VM();
+}
+
+void
+InitVM_load(rb_vm_t *vm)
+{
     static const char var_load_path[] = "$:";
     ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1);
 
Index: mvm/range.c
===================================================================
--- mvm/range.c	(revision 19257)
+++ mvm/range.c	(revision 19258)
@@ -906,7 +906,11 @@
     id_beg = rb_intern("begin");
     id_end = rb_intern("end");
     id_excl = rb_intern("excl");
+}
 
+void
+InitVM_Range(rb_vm_t *vm)
+{
     rb_cRange = rb_struct_define_without_accessor(
         "Range", rb_cObject, range_alloc,
         "begin", "end", "excl", NULL);
Index: mvm/proc.c
===================================================================
--- mvm/proc.c	(revision 19257)
+++ mvm/proc.c	(revision 19258)
@@ -1744,6 +1744,11 @@
 void
 Init_Proc(void)
 {
+}
+
+void
+InitVM_Proc(rb_vm_t *vm)
+{
     /* Proc */
     rb_cProc = rb_define_class("Proc", rb_cObject);
     rb_undef_alloc_func(rb_cProc);
@@ -1862,6 +1867,11 @@
 void
 Init_Binding(void)
 {
+}
+
+void
+InitVM_Binding(rb_vm_t *vm)
+{
     rb_cBinding = rb_define_class("Binding", rb_cObject);
     rb_undef_alloc_func(rb_cBinding);
     rb_undef_method(CLASS_OF(rb_cBinding), "new");
Index: mvm/thread.c
===================================================================
--- mvm/thread.c	(revision 19257)
+++ mvm/thread.c	(revision 19258)
@@ -3686,6 +3686,12 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
+    recursive_key = rb_intern("__recursive_key__");
+}
+
+void
+InitVM_Thread(rb_vm_t *vm)
+{
     VALUE cThGroup;
 
     rb_define_singleton_method(rb_cThread, "new", thread_s_new, -1);
@@ -3752,7 +3758,6 @@
     rb_define_method(rb_cMutex, "unlock", rb_mutex_unlock, 0);
     rb_define_method(rb_cMutex, "sleep", mutex_sleep, -1);
 
-    recursive_key = rb_intern("__recursive_key__");
     rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);
     rb_eMutex_OrphanLock = rb_define_class_under(rb_cMutex, "OrphanLock", rb_eThreadError);
 
Index: mvm/dir.c
===================================================================
--- mvm/dir.c	(revision 19257)
+++ mvm/dir.c	(revision 19258)
@@ -2378,6 +2378,11 @@
 void
 Init_Dir(void)
 {
+}
+
+void
+InitVM_Dir(rb_vm_t *vm)
+{
     rb_cDir = rb_define_class("Dir", rb_cObject);
 
     rb_include_module(rb_cDir, rb_mEnumerable);
Index: mvm/eval_jump.c
===================================================================
--- mvm/eval_jump.c	(revision 19257)
+++ mvm/eval_jump.c	(revision 19258)
@@ -123,5 +123,10 @@
 void
 Init_jump(void)
 {
+}
+
+void
+InitVM_jump(rb_vm_t *vm)
+{
     rb_define_global_function("at_exit", rb_f_at_exit, 0);
 }
Index: mvm/struct.c
===================================================================
--- mvm/struct.c	(revision 19257)
+++ mvm/struct.c	(revision 19258)
@@ -871,6 +871,11 @@
 void
 Init_Struct(void)
 {
+}
+
+void
+InitVM_Struct(rb_vm_t *vm)
+{
     rb_cStruct = rb_define_class("Struct", rb_cObject);
     rb_include_module(rb_cStruct, rb_mEnumerable);
 
Index: mvm/eval.c
===================================================================
--- mvm/eval.c	(revision 19257)
+++ mvm/eval.c	(revision 19258)
@@ -33,6 +33,10 @@
 void Init_heap(void);
 void Init_ext(void);
 void Init_BareVM(void);
+void rb_vm_call_inits(rb_vm_t *vm);
+void InitVM_heap(rb_vm_t *vm);
+void InitVM_ext(rb_vm_t *vm);
+void ruby_vm_prog_init(rb_vm_t *vm);
 
 VALUE ruby_vm_process_options(rb_vm_t *vm, int argc, char **argv);
 
@@ -60,7 +64,6 @@
 
     Init_stack((void *)&state);
     Init_BareVM();
-    Init_heap();
 
     PUSH_TAG();
     if ((state = EXEC_TAG()) == 0) {
@@ -71,8 +74,6 @@
 #elif defined(__VMS)
 	_vmsruby_init();
 #endif
-
-	ruby_prog_init();
     }
     POP_TAG();
 
@@ -80,7 +81,28 @@
 	error_print();
 	exit(EXIT_FAILURE);
     }
+}
+
+int
+ruby_vm_init(rb_vm_t *vm)
+{
+    int state;
+
+    InitVM_heap(vm);
+
+    PUSH_TAG();
+    if ((state = EXEC_TAG()) == 0) {
+	rb_vm_call_inits(vm);
+	ruby_vm_prog_init(vm);
+    }
+    POP_TAG();
+
+    if (state) {
+	error_print();
+	return state;
+    }
     GET_VM()->running = 1;
+    return 0;
 }
 
 static VALUE
@@ -132,18 +154,20 @@
     rb_thread_set_current_raw(vm->main_thread);
 
     ruby_init();
-    iseq = vm_parse_options(vm);
+    if ((status = ruby_vm_init(vm)) == 0) {
+	iseq = vm_parse_options(vm);
 
-    switch (iseq) {
-      case Qtrue:  return EXIT_SUCCESS; /* -v */
-      case Qfalse: return EXIT_FAILURE;
+	switch (iseq) {
+	  case Qtrue:  status = EXIT_SUCCESS; break; /* -v */
+	  case Qfalse: status = EXIT_FAILURE; break;
+	  default:
+	    if (FIXNUM_P(iseq)) {
+		status = FIX2INT(iseq);
+		break;
+	    }
+	    status = th_exec_iseq(vm->main_thread, iseq);
+	}
     }
-
-    if (FIXNUM_P(iseq)) {
-	return FIX2INT(iseq);
-    }
-
-    status = th_exec_iseq(vm->main_thread, iseq);
     return ruby_vm_cleanup(vm, status);
 }
 
@@ -1138,6 +1162,11 @@
 void
 Init_eval(void)
 {
+}
+
+void
+InitVM_eval(rb_vm_t *vm)
+{
     rb_define_virtual_variable("$@", errat_getter, errat_setter);
     rb_define_virtual_variable("$!", errinfo_getter, 0);
 
Index: mvm/gc.c
===================================================================
--- mvm/gc.c	(revision 19257)
+++ mvm/gc.c	(revision 19258)
@@ -370,6 +370,8 @@
 
 #define need_call_final 	(finalizer_table && finalizer_table->num_entries)
 
+static void init_heap(rb_objspace_t *objspace);
+
 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
 rb_objspace_t *
 rb_objspace_alloc(void)
@@ -378,6 +380,7 @@
     memset(objspace, 0, sizeof(*objspace));
     malloc_limit = GC_MALLOC_LIMIT;
     ruby_gc_stress = ruby_initial_gc_stress;
+    init_heap(objspace);
 
     return objspace;
 }
@@ -884,11 +887,11 @@
 
 #define RANY(o) ((RVALUE*)(o))
 
-static VALUE
+VALUE
 rb_newobj_from_heap(rb_objspace_t *objspace)
 {
     VALUE obj;
-	
+
     if ((ruby_gc_stress && !ruby_disable_gc_stress) || !freelist) {
     	if (!heaps_increment(objspace) && !garbage_collect(objspace)) {
 	    during_gc = 0;
@@ -2092,9 +2095,16 @@
 void
 Init_heap(void)
 {
-    init_heap(&rb_objspace);
 }
 
+void
+InitVM_heap(rb_vm_t *vm)
+{
+#if !(defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE)
+    init_heap(vm->objspace);
+#endif
+}
+
 static VALUE
 os_obj_of(rb_objspace_t *objspace, VALUE of)
 {
@@ -2800,6 +2810,11 @@
 void
 Init_GC(void)
 {
+}
+
+void
+InitVM_GC(rb_vm_t *vm)
+{
     VALUE rb_mObSpace;
     VALUE rb_mProfiler;
 
Index: mvm/parse.y
===================================================================
--- mvm/parse.y	(revision 19257)
+++ mvm/parse.y	(revision 19258)
@@ -19,6 +19,7 @@
 #include "ruby/node.h"
 #include "ruby/st.h"
 #include "ruby/encoding.h"
+#include "eval_intern.h"
 #include "id.h"
 #include "regenc.h"
 #include <stdio.h>
@@ -9091,11 +9092,16 @@
     ID last_id;
     st_table *sym_id;
     st_table *id_str;
-    st_table *ivar2_id;
-    st_table *id_ivar2;
     VALUE op_sym[tLAST_TOKEN];
+    rb_thread_lock_t lock;
+    struct rb_objspace_t *objspace;
 } global_symbols = {tLAST_ID};
 
+struct ivar_symbols {
+    st_table *ivar2_id;
+    st_table *id_ivar2;
+};
+
 static const struct st_hash_type symhash = {
     rb_str_hash_cmp,
     rb_str_hash,
@@ -9107,6 +9113,30 @@
 };
 
 static int
+ivar2_key_mark(st_data_t key, st_data_t val, st_data_t arg)
+{
+    struct ivar2_key *k = (struct ivar2_key *)key;
+    rb_gc_mark(k->klass);
+    return ST_CONTINUE;
+}
+
+static void
+ivar2_mark(void *ptr)
+{
+    struct ivar_symbols *isym = ptr;
+    if (isym->ivar2_id) st_foreach(isym->ivar2_id, ivar2_key_mark, 0);
+}
+
+static void
+ivar2_free(void *ptr)
+{
+    struct ivar_symbols *isym = ptr;
+    if (isym->ivar2_id) st_free_table(isym->ivar2_id);
+    if (isym->id_ivar2) st_free_table(isym->id_ivar2);
+    xfree(isym);
+}
+
+static int
 ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2)
 {
     if (key1->id == key2->id && key1->klass == key2->klass) {
@@ -9129,20 +9159,34 @@
 void
 Init_sym(void)
 {
+    struct rb_objspace_t *rb_objspace_alloc(void);
+    ruby_native_thread_lock_initialize(&global_symbols.lock);
+    ruby_native_thread_lock(&global_symbols.lock);
+    global_symbols.objspace = rb_objspace_alloc();
     global_symbols.sym_id = st_init_table_with_size(&symhash, 1000);
     global_symbols.id_str = st_init_numtable_with_size(1000);
-    global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
-    global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
-
     Init_id();
+    ruby_native_thread_unlock(&global_symbols.lock);
 }
 
 void
+InitVM_sym(rb_vm_t *vm)
+{
+    struct ivar_symbols *isym = ALLOC(struct ivar_symbols);
+    VALUE iw = Data_Wrap_Struct(0, ivar2_mark, ivar2_free, isym);
+    isym->ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
+    isym->id_ivar2 = st_init_numtable_with_size(1000);
+    *(VALUE *)ruby_vm_specific_ptr(vm, rb_vmkey_ivar_symbols) = iw;
+}
+
+void
 rb_gc_mark_symbols(void)
 {
+#if 0
     rb_mark_tbl(global_symbols.id_str);
     rb_gc_mark_locations(global_symbols.op_sym,
 			 global_symbols.op_sym + tLAST_TOKEN);
+#endif
 }
 
 static ID
@@ -9279,11 +9323,24 @@
     return *m ? Qfalse : Qtrue;
 }
 
+static VALUE
+sym_str_new(const char *name, long len, rb_encoding *enc)
+{
+    extern VALUE rb_newobj_from_heap(struct rb_objspace_t *);
+    VALUE str = rb_newobj_from_heap(global_symbols.objspace);
+
+    RSTRING(str)->basic.flags = T_STRING;
+    RSTRING(str)->basic.klass = 0;
+    rb_enc_associate(str, enc);
+    rb_str_cat(str, name, len);
+    OBJ_FREEZE(str);
+    return str;
+}
+
 static ID
 register_symid(ID id, const char *name, long len, rb_encoding *enc)
 {
-    VALUE str = rb_enc_str_new(name, len, enc);
-    OBJ_FREEZE(str);
+    VALUE str = sym_str_new(name, len, enc);
     st_add_direct(global_symbols.sym_id, (st_data_t)str, id);
     st_add_direct(global_symbols.id_str, id, (st_data_t)str);
     return id;
@@ -9299,17 +9356,18 @@
     ID id;
     int last;
     int mb;
+    st_data_t data;
     struct RString fake_str;
     fake_str.basic.flags = T_STRING|RSTRING_NOEMBED|FL_FREEZE;
-    fake_str.basic.klass = rb_cString;
+    fake_str.basic.klass = 0;
     fake_str.as.heap.len = len;
     fake_str.as.heap.ptr = (char *)name;
     fake_str.as.heap.aux.capa = len;
     str = (VALUE)&fake_str;
     rb_enc_associate(str, enc);
 
-    if (st_lookup(global_symbols.sym_id, str, (st_data_t *)&id))
-	return id;
+    if (st_lookup(global_symbols.sym_id, str, &data))
+	return (ID)data;
 
     if (rb_cString && !rb_enc_asciicompat(enc)) {
 	id = ID_JUNK;
@@ -9448,8 +9506,7 @@
 		char name[2];
 		name[0] = (char)id;
 		name[1] = 0;
-		str = rb_usascii_str_new(name, 1);
-		OBJ_FREEZE(str);
+		str = sym_str_new(name, 1, rb_usascii_encoding());
 		global_symbols.op_sym[i] = str;
 	    }
 	    return str;
@@ -9458,8 +9515,8 @@
 	    if (op_tbl[i].token == id) {
 		VALUE str = global_symbols.op_sym[i];
 		if (!str) {
-		    str = rb_usascii_str_new2(op_tbl[i].name);
-		    OBJ_FREEZE(str);
+		    const char *name = op_tbl[i].name;
+		    str = sym_str_new(name, strlen(name), rb_usascii_encoding());
 		    global_symbols.op_sym[i] = str;
 		}
 		return str;
@@ -10243,6 +10300,17 @@
 void
 Init_ripper(void)
 {
+    ripper_id_gets = rb_intern("gets");
+    /* ensure existing in symbol table */
+    rb_intern("||");
+    rb_intern("&&");
+    ripper_init_eventids1();
+    ripper_init_eventids2();
+}
+
+void
+InitVM_ripper(rb_vm_t *vm)
+{
     VALUE Ripper;
 
     Ripper = rb_define_class("Ripper", rb_cObject);
@@ -10262,11 +10330,7 @@
     rb_define_method(rb_mKernel, "validate_object", ripper_validate_object, 1);
 #endif
 
-    ripper_id_gets = rb_intern("gets");
-    ripper_init_eventids1(Ripper);
-    ripper_init_eventids2(Ripper);
-    /* ensure existing in symbol table */
-    rb_intern("||");
-    rb_intern("&&");
+    ripper_init_eventids1_table(Ripper);
+    ripper_init_eventids2_table(Ripper);
 }
 #endif /* RIPPER */
Index: mvm/process.c
===================================================================
--- mvm/process.c	(revision 19257)
+++ mvm/process.c	(revision 19258)
@@ -5068,6 +5068,11 @@
 void
 Init_process(void)
 {
+}
+
+void
+InitVM_process(rb_vm_t *vm)
+{
     VALUE rb_mProcUID;
     VALUE rb_mProcGID;
     VALUE rb_mProcID_Syscall;
Index: mvm/ext/ripper/tools/generate.rb
===================================================================
--- mvm/ext/ripper/tools/generate.rb	(revision 19257)
+++ mvm/ext/ripper/tools/generate.rb	(revision 19258)
@@ -74,14 +74,18 @@
   end
   buf << %Q[\n]
   buf << %Q[static void\n]
-  buf << %Q[ripper_init_eventids1(VALUE self)\n]
+  buf << %Q[ripper_init_eventids1(void)\n]
   buf << %Q[{\n]
-  buf << %Q[    VALUE h;\n]
-  buf << %Q[    ID id;\n]
   ids.each do |id, arity|
     buf << %Q[    ripper_id_#{id} = rb_intern_const("on_#{id}");\n]
   end
+  buf << %Q[}\n]
   buf << %Q[\n]
+  buf << %Q[static void\n]
+  buf << %Q[ripper_init_eventids1_table(VALUE self)\n]
+  buf << %Q[{\n]
+  buf << %Q[    VALUE h;\n]
+  buf << %Q[    ID id;\n]
   buf << %Q[    h = rb_hash_new();\n]
   buf << %Q[    rb_define_const(self, "PARSER_EVENT_TABLE", h);\n]
   ids.each do |id, arity|
Index: mvm/ext/ripper/eventids2.c
===================================================================
--- mvm/ext/ripper/eventids2.c	(revision 19257)
+++ mvm/ext/ripper/eventids2.c	(revision 19258)
@@ -59,7 +59,7 @@
 #include "eventids2table.c"
 
 static void
-ripper_init_eventids2(VALUE self)
+ripper_init_eventids2(void)
 {
     ripper_id_backref = rb_intern_const("on_backref");
     ripper_id_backtick = rb_intern_const("on_backtick");
@@ -108,8 +108,6 @@
     ripper_id_heredoc_end = rb_intern_const("on_heredoc_end");
     ripper_id___end__ = rb_intern_const("on___end__");
     ripper_id_CHAR = rb_intern_const("on_CHAR");
-
-    ripper_init_eventids2_table(self);
 }
 
 static const struct token_assoc {
Index: mvm/hash.c
===================================================================
--- mvm/hash.c	(revision 19257)
+++ mvm/hash.c	(revision 19258)
@@ -2593,7 +2593,11 @@
     id_hash = rb_intern("hash");
     id_yield = rb_intern("yield");
     id_default = rb_intern("default");
+}
 
+void
+InitVM_Hash(rb_vm_t *vm)
+{
     rb_cHash = rb_define_class("Hash", rb_cObject);
 
     rb_include_module(rb_cHash, rb_mEnumerable);
Index: mvm/prec.c
===================================================================
--- mvm/prec.c	(revision 19257)
+++ mvm/prec.c	(revision 19258)
@@ -125,12 +125,16 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
+    prc_pr = rb_intern("prec");
+    prc_if = rb_intern("induced_from");
+}
+
+void
+InitVM_Precision(rb_vm_t *vm)
+{
     rb_mPrecision = rb_define_module("Precision");
     rb_define_singleton_method(rb_mPrecision, "included", prec_included, 1);
     rb_define_method(rb_mPrecision, "prec", prec_prec, 1);
     rb_define_method(rb_mPrecision, "prec_i", prec_prec_i, 0);
     rb_define_method(rb_mPrecision, "prec_f", prec_prec_f, 0);
-
-    prc_pr = rb_intern("prec");
-    prc_if = rb_intern("induced_from");
 }
Index: mvm/error.c
===================================================================
--- mvm/error.c	(revision 19257)
+++ mvm/error.c	(revision 19258)
@@ -980,6 +980,11 @@
 void
 Init_Exception(void)
 {
+}
+
+void
+InitVM_Exception(rb_vm_t *vm)
+{
     rb_eException   = rb_define_class("Exception", rb_cObject);
     rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
     rb_define_method(rb_eException, "exception", exc_exception, -1);
@@ -1144,6 +1149,11 @@
 void
 Init_syserr(void)
 {
+}
+
+void
+InitVM_syserr(rb_vm_t *vm)
+{
 #ifdef EPERM
     set_syserr(EPERM, "EPERM");
 #endif
Index: mvm/numeric.c
===================================================================
--- mvm/numeric.c	(revision 19257)
+++ mvm/numeric.c	(revision 19258)
@@ -3113,7 +3113,11 @@
     id_coerce = rb_intern("coerce");
     id_to_i = rb_intern("to_i");
     id_eq = rb_intern("==");
+}
 
+void
+InitVM_Numeric(rb_vm_t *vm)
+{
     rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError);
     rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError);
     rb_cNumeric = rb_define_class("Numeric", rb_cObject);
Index: mvm/cont.c
===================================================================
--- mvm/cont.c	(revision 19257)
+++ mvm/cont.c	(revision 19258)
@@ -748,6 +748,11 @@
 void
 Init_Cont(void)
 {
+}
+
+void
+InitVM_Cont(rb_vm_t *vm)
+{
     rb_cFiber = rb_define_class("Fiber", rb_cObject);
     rb_undef_alloc_func(rb_cFiber);
     rb_eFiberError = rb_define_class("FiberError", rb_eStandardError);
Index: mvm/compar.c
===================================================================
--- mvm/compar.c	(revision 19257)
+++ mvm/compar.c	(revision 19258)
@@ -199,6 +199,12 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
+    cmp = rb_intern("<=>");
+}
+
+void
+InitVM_Comparable(rb_vm_t *vm)
+{
     rb_mComparable = rb_define_module("Comparable");
     rb_define_method(rb_mComparable, "==", cmp_equal, 1);
     rb_define_method(rb_mComparable, ">", cmp_gt, 1);
@@ -206,6 +212,4 @@
     rb_define_method(rb_mComparable, "<", cmp_lt, 1);
     rb_define_method(rb_mComparable, "<=", cmp_le, 1);
     rb_define_method(rb_mComparable, "between?", cmp_between, 2);
-
-    cmp = rb_intern("<=>");
 }
Index: mvm/vm.c
===================================================================
--- mvm/vm.c	(revision 19257)
+++ mvm/vm.c	(revision 19258)
@@ -1582,7 +1582,7 @@
 }
 
 static void
-th_init2(rb_thread_t *th, VALUE self)
+th_init(rb_thread_t *th, VALUE self)
 {
     th->self = self;
 
@@ -1607,12 +1607,6 @@
 #endif
 }
 
-static void
-th_init(rb_thread_t *th, VALUE self)
-{
-    th_init2(th, self);
-}
-
 static VALUE
 ruby_thread_init(VALUE self)
 {
@@ -1790,6 +1784,11 @@
 void
 Init_VM(void)
 {
+}
+
+void
+InitVM_VM(rb_vm_t *vm)
+{
     VALUE opts;
     VALUE klass;
     VALUE fcore;
@@ -1920,15 +1919,14 @@
 	exit(EXIT_FAILURE);
     }
     MEMZERO(th, rb_thread_t, 1);
+    th->vm = vm;
+    rb_thread_set_current_raw(th);
     vm_init2(vm);
     vm->main_thread = th;
 
-    rb_thread_set_current_raw(th);
-    {
-	th->vm = vm;
-	th_init2(th, 0);
-	ruby_thread_init_stack(th);
-    }
+    th_init(th, 0);
+    ruby_thread_init_stack(th);
+
     rb_thread_set_current_raw(old_th);
 
     return vm;
@@ -1957,8 +1955,11 @@
 void
 Init_top_self(void)
 {
-    rb_vm_t *vm = GET_VM();
+}
 
+void
+InitVM_top_self(rb_vm_t *vm)
+{
     vm->top_self = rb_obj_alloc(rb_cObject);
     rb_define_singleton_method(rb_vm_top_self(), "to_s", main_to_s, 0);
 }
Index: mvm/version.c
===================================================================
--- mvm/version.c	(revision 19257)
+++ mvm/version.c	(revision 19258)
@@ -27,6 +27,11 @@
 void
 Init_version(void)
 {
+}
+
+void
+InitVM_version(rb_vm_t *vm)
+{
     rb_define_global_const("RUBY_VERSION", MKSTR(version));
     rb_define_global_const("RUBY_RELEASE_DATE", MKSTR(release_date));
     rb_define_global_const("RUBY_PLATFORM", MKSTR(platform));
Index: mvm/inits.c
===================================================================
--- mvm/inits.c	(revision 19257)
+++ mvm/inits.c	(revision 19258)
@@ -9,96 +9,64 @@
 
 **********************************************************************/
 
+#ifndef INIT_FOR_VM
 #include "ruby/ruby.h"
 
-void Init_Array(void);
-void Init_Bignum(void);
-void Init_Binding(void);
-void Init_Comparable(void);
-void Init_Complex(void);
-void Init_transcode(void);
-void Init_Dir(void);
-void Init_Enumerable(void);
-void Init_Enumerator(void);
-void Init_Exception(void);
-void Init_syserr(void);
-void Init_eval(void);
-void Init_load(void);
-void Init_Proc(void);
-void Init_File(void);
-void Init_GC(void);
-void Init_Hash(void);
-void Init_IO(void);
-void Init_Math(void);
-void Init_marshal(void);
-void Init_Numeric(void);
-void Init_Object(void);
-void Init_pack(void);
-void Init_Precision(void);
-void Init_sym(void);
-void Init_process(void);
-void Init_RandomSeed(void);
-void Init_Random(void);
-void Init_Range(void);
-void Init_Rational(void);
-void Init_Regexp(void);
-void Init_signal(void);
-void Init_String(void);
-void Init_Struct(void);
-void Init_Time(void);
-void Init_var_tables(void);
-void Init_version(void);
-void Init_ISeq(void);
-void Init_VM(void);
-void Init_Thread(void);
-void Init_Cont(void);
-void Init_top_self(void);
-void Init_Encoding(void);
+#define INIT_FOR_VM 1
+#include "inits.c"
+#define CALL(n) {void Init_##n(void); Init_##n();}
+#define rb_call_inits() rb_call_inits(void)
+#else
+#define CALL(n) {void InitVM_##n(rb_vm_t *); InitVM_##n(vm);}
+#define rb_call_inits() rb_vm_call_inits(rb_vm_t *vm)
+#endif
 
 void
 rb_call_inits()
 {
-    Init_RandomSeed();
-    Init_sym();
-    Init_var_tables();
-    Init_Object();
-    Init_top_self();
-    Init_Encoding();
-    Init_Comparable();
-    Init_Enumerable();
-    Init_Precision();
-    Init_String();
-    Init_Exception();
-    Init_eval();
-    Init_jump();
-    Init_Numeric();
-    Init_Bignum();
-    Init_syserr();
-    Init_Array();
-    Init_Hash();
-    Init_Struct();
-    Init_Regexp();
-    Init_pack();
-    Init_transcode();
-    Init_marshal();
-    Init_Range();
-    Init_IO();
-    Init_Dir();
-    Init_Time();
-    Init_Random();
-    Init_signal();
-    Init_process();
-    Init_load();
-    Init_Proc();
-    Init_Binding();
-    Init_Math();
-    Init_GC();
-    Init_Enumerator();
-    Init_VM();
-    Init_ISeq();
-    Init_Thread();
-    Init_Cont();
-    Init_Rational();
-    Init_Complex();
-    Init_version();
+    CALL(RandomSeed);
+    CALL(sym);
+    CALL(var_tables);
+    CALL(Object);
+    CALL(top_self);
+    CALL(Encoding);
+    CALL(Comparable);
+    CALL(Enumerable);
+    CALL(Precision);
+    CALL(String);
+    CALL(Exception);
+    CALL(eval);
+    CALL(jump);
+    CALL(Numeric);
+    CALL(Bignum);
+    CALL(syserr);
+    CALL(Array);
+    CALL(Hash);
+    CALL(Struct);
+    CALL(Regexp);
+    CALL(pack);
+    CALL(transcode);
+    CALL(marshal);
+    CALL(Range);
+    CALL(IO);
+    CALL(Dir);
+    CALL(Time);
+    CALL(Random);
+    CALL(signal);
+    CALL(process);
+    CALL(load);
+    CALL(Proc);
+    CALL(Binding);
+    CALL(Math);
+    CALL(GC);
+    CALL(Enumerator);
+    CALL(VM);
+    CALL(ISeq);
+    CALL(Thread);
+    CALL(Cont);
+    CALL(Rational);
+    CALL(Complex);
+    CALL(version);
 }
+#undef rb_call_inits
+#undef CALL
Index: mvm/private_object.h
===================================================================
--- mvm/private_object.h	(revision 19257)
+++ mvm/private_object.h	(revision 19258)
@@ -62,6 +62,8 @@
     rb_vmkey_big2str_power_cache,
 #define rb_big2str_power_cache (*rb_vm_specific_ptr(rb_vmkey_big2str_power_cache))
 
+    rb_vmkey_ivar_symbols,
+
     ruby_builtin_object_count,
     ruby_private_object_count = ruby_builtin_object_count - ruby_private_object_vmkey_begin + 1
 };
Index: mvm/bignum.c
===================================================================
--- mvm/bignum.c	(revision 19257)
+++ mvm/bignum.c	(revision 19258)
@@ -2681,6 +2681,11 @@
 void
 Init_Bignum(void)
 {
+}
+
+void
+InitVM_Bignum(rb_vm_t *vm)
+{
     rb_cBignum = rb_define_class("Bignum", rb_cInteger);
 
     rb_define_method(rb_cBignum, "to_s", rb_big_to_s, -1);
Index: mvm/marshal.c
===================================================================
--- mvm/marshal.c	(revision 19257)
+++ mvm/marshal.c	(revision 19258)
@@ -1704,8 +1704,6 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
-    VALUE rb_mMarshal = rb_define_module("Marshal");
-
     s_dump = rb_intern("_dump");
     s_load = rb_intern("_load");
     s_mdump = rb_intern("marshal_dump");
@@ -1717,7 +1715,13 @@
     s_read = rb_intern("read");
     s_write = rb_intern("write");
     s_binmode = rb_intern("binmode");
+}
 
+void
+InitVM_marshal(rb_vm_t *vm)
+{
+    VALUE rb_mMarshal = rb_define_module("Marshal");
+
     rb_define_module_function(rb_mMarshal, "dump", marshal_dump, -1);
     rb_define_module_function(rb_mMarshal, "load", marshal_load, -1);
     rb_define_module_function(rb_mMarshal, "restore", marshal_load, -1);
Index: mvm/rational.c
===================================================================
--- mvm/rational.c	(revision 19257)
+++ mvm/rational.c	(revision 19258)
@@ -1020,7 +1020,7 @@
     return q + r;
 }
 
-static long ml;
+#define ml DBL_MAX_EXP
 
 static VALUE
 nurat_to_f(VALUE self)
@@ -1251,20 +1251,15 @@
     vmkey_an_underscore = rb_vm_key_create();
 
     rat_pat = rb_reg_new(rat_pat_source, sizeof rat_pat_source - 1, 0);
-    rb_global_variable(&rat_pat);
 
     an_e_pat = rb_reg_new(an_e_pat_source, sizeof an_e_pat_source - 1, 0);
-    rb_global_variable(&an_e_pat);
 
     a_dot_pat = rb_reg_new(a_dot_pat_source, sizeof a_dot_pat_source - 1, 0);
-    rb_global_variable(&a_dot_pat);
 
     underscores_pat = rb_reg_new(underscores_pat_source,
 				 sizeof underscores_pat_source - 1, 0);
-    rb_global_variable(&underscores_pat);
 
     an_underscore = rb_str_new2("_");
-    rb_global_variable(&an_underscore);
 }
 
 #define id_match rb_intern("match")
@@ -1476,8 +1471,6 @@
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
-    assert(fprintf(stderr, "assert() is now active\n"));
-
     id_Unify = rb_intern("Unify");
     id_abs = rb_intern("abs");
     id_cmp = rb_intern("<=>");
@@ -1495,8 +1488,12 @@
     id_to_i = rb_intern("to_i");
     id_to_s = rb_intern("to_s");
     id_truncate = rb_intern("truncate");
+}
 
-    ml = (long)(log(DBL_MAX) / log(2.0) - 1);
+void
+InitVM_Rational(rb_vm_t *vm)
+{
+    assert(fprintf(stderr, "assert() is now active\n"));
 
     rb_cRational = rb_define_class(RATIONAL_NAME, rb_cNumeric);
 
Index: mvm/signal.c
===================================================================
--- mvm/signal.c	(revision 19257)
+++ mvm/signal.c	(revision 19258)
@@ -1094,17 +1094,7 @@
 Init_signal(void)
 {
 #ifndef MACOS_UNUSE_SIGNAL
-    VALUE mSignal = rb_define_module("Signal");
 
-    rb_define_global_function("trap", sig_trap, -1);
-    rb_define_module_function(mSignal, "trap", sig_trap, -1);
-    rb_define_module_function(mSignal, "list", sig_list, 0);
-
-    rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
-    rb_define_method(rb_eSignal, "signo", esignal_signo, 0);
-    rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
-    rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
-
     install_sighandler(SIGINT, sighandler);
 #ifdef SIGHUP
     install_sighandler(SIGHUP, sighandler);
@@ -1149,3 +1139,20 @@
 
 #endif /* MACOS_UNUSE_SIGNAL */
 }
+
+void
+InitVM_signal(rb_vm_t *vm)
+{
+#ifndef MACOS_UNUSE_SIGNAL
+    VALUE mSignal = rb_define_module("Signal");
+
+    rb_define_global_function("trap", sig_trap, -1);
+    rb_define_module_function(mSignal, "trap", sig_trap, -1);
+    rb_define_module_function(mSignal, "list", sig_list, 0);
+
+    rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
+    rb_define_method(rb_eSignal, "signo", esignal_signo, 0);
+    rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
+    rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
+#endif /* MACOS_UNUSE_SIGNAL */
+}
Index: mvm/file.c
===================================================================
--- mvm/file.c	(revision 19257)
+++ mvm/file.c	(revision 19258)
@@ -4712,6 +4712,11 @@
 void
 Init_File(void)
 {
+}
+
+void
+InitVM_File(rb_vm_t *vm)
+{
     VALUE separator;
 
     rb_mFileTest = rb_define_module("FileTest");
Index: mvm/random.c
===================================================================
--- mvm/random.c	(revision 19257)
+++ mvm/random.c	(revision 19258)
@@ -203,8 +203,16 @@
     struct RandSeed seed;
 };
 
-static struct Random default_mt;
+static int vmkey_default_mt;
+#define default_mt (*(struct Random *)DATA_PTR(*rb_vm_specific_ptr(vmkey_default_mt)))
 
+static void
+random_mark(void *ptr)
+{
+    struct Random *r = ptr;
+    rb_gc_mark(r->seed.value);
+}
+
 unsigned long
 rb_genrand_int32(void)
 {
@@ -355,6 +363,7 @@
 rb_f_srand(int argc, VALUE *argv, VALUE obj)
 {
     VALUE seed, old;
+    struct Random *r = &default_mt;
 
     rb_secure(4);
     if (argc == 0) {
@@ -363,8 +372,8 @@
     else {
 	rb_scan_args(argc, argv, "01", &seed);
     }
-    old = default_mt.seed.value;
-    default_mt.seed.value = rand_init(&default_mt.mt, seed);
+    old = r->seed.value;
+    r->seed.value = rand_init(&r->mt, seed);
 
     return old;
 }
@@ -532,29 +541,44 @@
 void
 Init_RandomSeed(void)
 {
-    fill_random_seed(default_mt.seed.initial);
-    init_by_array(&default_mt.mt, default_mt.seed.initial, DEFAULT_SEED_CNT);
+    vmkey_default_mt = rb_vm_key_create();
 }
 
+void
+InitVM_RandomSeed(rb_vm_t *vm)
+{
+}
+
 static void
-Init_RandomSeed2(void)
+InitVM_RandomSeed2(rb_vm_t *vm)
 {
-    default_mt.seed.value = make_seed_value(default_mt.seed.initial);
-    memset(default_mt.seed.initial, 0, DEFAULT_SEED_LEN);
+    struct Random *r;
+    VALUE rv = Data_Make_Struct(rb_cData, struct Random, random_mark, -1, r);
+
+    *(VALUE *)ruby_vm_specific_ptr(vm, vmkey_default_mt) = rv;
+    fill_random_seed(r->seed.initial);
+    init_by_array(&r->mt, r->seed.initial, DEFAULT_SEED_CNT);
+    r->seed.value = make_seed_value(r->seed.initial);
+    memset(r->seed.initial, 0, DEFAULT_SEED_LEN);
 }
 
 void
 rb_reset_random_seed(void)
 {
-    uninit_genrand(&default_mt.mt);
-    default_mt.seed.value = INT2FIX(0);
+    struct Random *r = &default_mt;
+    uninit_genrand(&r->mt);
+    r->seed.value = INT2FIX(0);
 }
 
 void
 Init_Random(void)
 {
-    Init_RandomSeed2();
+}
+
+void
+InitVM_Random(rb_vm_t *vm)
+{
+    InitVM_RandomSeed2(vm);
     rb_define_global_function("srand", rb_f_srand, -1);
     rb_define_global_function("rand", rb_f_rand, -1);
-    rb_global_variable(&default_mt.seed.value);
 }
Index: mvm/transcode.c
===================================================================
--- mvm/transcode.c	(revision 19257)
+++ mvm/transcode.c	(revision 19258)
@@ -3532,9 +3532,6 @@
 void
 Init_transcode(void)
 {
-    rb_eConversionUndefined = rb_define_class_under(rb_cEncoding, "ConversionUndefined", rb_eStandardError);
-    rb_eInvalidByteSequence = rb_define_class_under(rb_cEncoding, "InvalidByteSequence", rb_eStandardError);
-    rb_eNoConverter = rb_define_class_under(rb_cEncoding, "NoConverter", rb_eStandardError);
 
     transcoder_table = st_init_strcasetable();
 
@@ -3558,6 +3555,16 @@
     sym_cr_newline_encoder = ID2SYM(rb_intern("cr_newline_encoder"));
     sym_partial_input = ID2SYM(rb_intern("partial_input"));
 
+    Init_newline();
+}
+
+void
+InitVM_transcode(rb_vm_t *vm)
+{
+    rb_eConversionUndefined = rb_define_class_under(rb_cEncoding, "ConversionUndefined", rb_eStandardError);
+    rb_eInvalidByteSequence = rb_define_class_under(rb_cEncoding, "InvalidByteSequence", rb_eStandardError);
+    rb_eNoConverter = rb_define_class_under(rb_cEncoding, "NoConverter", rb_eStandardError);
+
     rb_define_method(rb_cString, "encode", str_encode, -1);
     rb_define_method(rb_cString, "encode!", str_encode_bang, -1);
 
@@ -3605,6 +3612,4 @@
     rb_define_method(rb_eInvalidByteSequence, "error_bytes", ecerr_error_bytes, 0);
     rb_define_method(rb_eInvalidByteSequence, "readagain_bytes", ecerr_readagain_bytes, 0);
     rb_define_method(rb_eInvalidByteSequence, "incomplete_input?", ecerr_incomplete_input, 0);
-
-    Init_newline();
 }

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

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