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

ruby-changes:5995

From: nobu <ko1@a...>
Date: Sat, 21 Jun 2008 18:56:20 +0900 (JST)
Subject: [ruby-changes:5995] Ruby:r17504 (mvm): * elementaly MVM support.

nobu	2008-06-21 18:56:02 +0900 (Sat, 21 Jun 2008)

  New Revision: 17504

  Modified files:
    branches/mvm/configure.in
    branches/mvm/eval.c
    branches/mvm/io.c
    branches/mvm/main.c
    branches/mvm/thread.c
    branches/mvm/vm_core.h

  Log:
    * elementaly MVM support.

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/thread.c?r1=17504&r2=17503&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/vm_core.h?r1=17504&r2=17503&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/configure.in?r1=17504&r2=17503&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/main.c?r1=17504&r2=17503&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/io.c?r1=17504&r2=17503&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/eval.c?r1=17504&r2=17503&diff_format=u

Index: mvm/configure.in
===================================================================
--- mvm/configure.in	(revision 17503)
+++ mvm/configure.in	(revision 17504)
@@ -1157,7 +1157,13 @@
 fi
 if test x"$ac_cv_header_ucontext_h" = xyes; then
     if test x"$rb_with_pthread" = xyes; then
-	AC_CHECK_FUNCS(getcontext setcontext)
+	AC_CHECK_FUNCS(getcontext setcontext sigaltstack)
+	AC_CHECK_FUNCS(pthread_getattr_np pthread_attr_getstack)
+	AC_CHECK_FUNCS(pthread_attr_get_np)
+	AC_CHECK_FUNCS(pthread_get_stackaddr_np pthread_get_stacksize_np)
+	AC_CHECK_FUNCS(thr_stksegment)
+	AC_CHECK_FUNCS(pthread_stackseg_np)
+	AC_CHECK_HEADERS(pthread_np.h sys/signal.h)
     fi
 fi
 
Index: mvm/vm_core.h
===================================================================
--- mvm/vm_core.h	(revision 17503)
+++ mvm/vm_core.h	(revision 17504)
@@ -311,9 +311,16 @@
     unsigned long trace_flag;
     volatile int sleeper;
 
+    VALUE argf;
+
     /* object management */
     VALUE mark_object_ary;
 
+    struct {
+	VALUE *ptr;
+	long len;
+    } specific_storage;
+
     VALUE special_exceptions[ruby_special_error_count];
 
     /* load */
@@ -333,6 +340,10 @@
 
     VALUE verbose, debug, progname;
 
+#ifdef RUBY_DEBUG_ENV
+    int enable_coredump;
+#endif
+
 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
     struct rb_objspace *objspace;
 #endif
Index: mvm/io.c
===================================================================
--- mvm/io.c	(revision 17503)
+++ mvm/io.c	(revision 17504)
@@ -124,8 +124,6 @@
 VALUE rb_output_rs;
 VALUE rb_default_rs;
 
-static VALUE argf;
-
 static ID id_write, id_read, id_getc, id_flush, id_encode, id_readpartial;
 static VALUE sym_mode, sym_perm, sym_extenc, sym_intenc, sym_encoding, sym_open_args;
 
@@ -155,7 +153,8 @@
 
 
 #define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
-#define ARGF argf_of(argf)
+#define ruby_vm_argf(vm) ((vm)->argf)
+#define ARGF argf_of(ruby_vm_argf(GET_VM()))
 
 #ifdef _STDIO_USES_IOSTREAM  /* GNU libc */
 #  ifdef _IO_fpos_t
@@ -5225,23 +5224,12 @@
 }
 
 #undef rb_argv
-#define filename          ARGF.filename
-#define current_file      ARGF.current_file
-#define gets_lineno       ARGF.gets_lineno
-#define init_p            ARGF.init_p
-#define next_p            ARGF.next_p
-#define lineno            ARGF.lineno
-#define ruby_inplace_mode ARGF.inplace
-#define argf_binmode      ARGF.binmode
-#define argf_enc          ARGF.enc
-#define argf_enc2         ARGF.enc2
-#define rb_argv           ARGF.argv
 
 static VALUE
 argf_initialize(VALUE argf, VALUE argv)
 {
-    memset(&ARGF, 0, sizeof(ARGF));
-    argf_init(&ARGF, argv);
+    memset(&argf_of(argf), 0, sizeof(argf_of(argf)));
+    argf_init(&argf_of(argf), argv);
 
     return argf;
 }
@@ -5249,12 +5237,12 @@
 static VALUE
 argf_initialize_copy(VALUE argf, VALUE orig)
 {
-    ARGF = argf_of(orig);
-    rb_argv = rb_obj_dup(rb_argv);
-    if (ARGF.inplace) {
-	const char *inplace = ARGF.inplace;
-	ARGF.inplace = 0;
-	ARGF.inplace = ruby_strdup(inplace);
+    argf_of(argf) = argf_of(orig);
+    argf_of(argf).argv = rb_obj_dup(argf_of(argf).argv);
+    if (argf_of(argf).inplace) {
+	const char *inplace = argf_of(argf).inplace;
+	argf_of(argf).inplace = 0;
+	argf_of(argf).inplace = ruby_strdup(inplace);
     }
     return argf;
 }
@@ -5262,26 +5250,26 @@
 static VALUE
 argf_set_lineno(VALUE argf, VALUE val)
 {
-    gets_lineno = NUM2INT(val);
-    lineno = INT2FIX(gets_lineno);
+    argf_of(argf).gets_lineno = NUM2INT(val);
+    argf_of(argf).lineno = INT2FIX(argf_of(argf).gets_lineno);
     return Qnil;
 }
 
 static VALUE
 argf_lineno(VALUE argf)
 {
-    return lineno;
+    return argf_of(argf).lineno;
 }
 
 static VALUE
 argf_forward(int argc, VALUE *argv, VALUE argf)
 {
-    return rb_funcall3(current_file, rb_frame_this_func(), argc, argv);
+    return rb_funcall3(argf_of(argf).current_file, rb_frame_this_func(), argc, argv);
 }
 
 #define next_argv() argf_next_argv(argf)
 #define ARGF_GENERIC_INPUT_P() \
-    (current_file == rb_stdin && TYPE(current_file) != T_FILE)
+    (argf_of(argf).current_file == rb_stdin && TYPE(argf_of(argf).current_file) != T_FILE)
 #define ARGF_FORWARD(argc, argv) do {\
     if (ARGF_GENERIC_INPUT_P())\
 	return argf_forward(argc, argv, argf);\
@@ -5310,26 +5298,26 @@
             stdout_binmode = 1;
     }
 
-    if (init_p == 0) {
-	if (!NIL_P(rb_argv) && RARRAY_LEN(rb_argv) > 0) {
-	    next_p = 1;
+    if (argf_of(argf).init_p == 0) {
+	if (!NIL_P(argf_of(argf).argv) && RARRAY_LEN(argf_of(argf).argv) > 0) {
+	    argf_of(argf).next_p = 1;
 	}
 	else {
-	    next_p = -1;
+	    argf_of(argf).next_p = -1;
 	}
-	init_p = 1;
-	gets_lineno = 0;
+	argf_of(argf).init_p = 1;
+	argf_of(argf).gets_lineno = 0;
     }
 
-    if (next_p == 1) {
-	next_p = 0;
+    if (argf_of(argf).next_p == 1) {
+	argf_of(argf).next_p = 0;
       retry:
-	if (RARRAY_LEN(rb_argv) > 0) {
-	    filename = rb_ary_shift(rb_argv);
-	    fn = StringValueCStr(filename);
+	if (RARRAY_LEN(argf_of(argf).argv) > 0) {
+	    argf_of(argf).filename = rb_ary_shift(argf_of(argf).argv);
+	    fn = StringValueCStr(argf_of(argf).filename);
 	    if (strlen(fn) == 1 && fn[0] == '-') {
-		current_file = rb_stdin;
-		if (ruby_inplace_mode) {
+		argf_of(argf).current_file = rb_stdin;
+		if (argf_of(argf).inplace) {
 		    rb_warn("Can't do inplace edit for stdio; skipping");
 		    goto retry;
 		}
@@ -5337,7 +5325,7 @@
 	    else {
 		int fr = rb_sysopen(fn, O_RDONLY, 0);
 
-		if (ruby_inplace_mode) {
+		if (argf_of(argf).inplace) {
 		    struct stat st;
 #ifndef NO_SAFE_RENAME
 		    struct stat st2;
@@ -5349,12 +5337,12 @@
 			rb_io_close(rb_stdout);
 		    }
 		    fstat(fr, &st);
-		    if (*ruby_inplace_mode) {
+		    if (*argf_of(argf).inplace) {
 			str = rb_str_new2(fn);
 #ifdef NO_LONG_FNAME
-                        ruby_add_suffix(str, ruby_inplace_mode);
+                        ruby_add_suffix(str, argf_of(argf).inplace);
 #else
-			rb_str_cat2(str, ruby_inplace_mode);
+			rb_str_cat2(str, argf_of(argf).inplace);
 #endif
 #ifdef NO_SAFE_RENAME
 			(void)close(fr);
@@ -5397,26 +5385,26 @@
 		    rb_stdout = prep_io(fw, FMODE_WRITABLE, rb_cFile, fn);
 		    if (stdout_binmode) rb_io_binmode(rb_stdout);
 		}
-		current_file = prep_io(fr, FMODE_READABLE, rb_cFile, fn);
+		argf_of(argf).current_file = prep_io(fr, FMODE_READABLE, rb_cFile, fn);
 	    }
-	    if (argf_binmode) rb_io_binmode(current_file);
-	    if (argf_enc) {
+	    if (argf_of(argf).binmode) rb_io_binmode(argf_of(argf).current_file);
+	    if (argf_of(argf).enc) {
 		rb_io_t *fptr;
 
-		GetOpenFile(current_file, fptr);
-		fptr->enc = argf_enc;
-		fptr->enc2 = argf_enc2;
+		GetOpenFile(argf_of(argf).current_file, fptr);
+		fptr->enc = argf_of(argf).enc;
+		fptr->enc2 = argf_of(argf).enc2;
 	    }
 	}
 	else {
-	    next_p = 1;
+	    argf_of(argf).next_p = 1;
 	    return Qfalse;
 	}
     }
-    else if (next_p == -1) {
-	current_file = rb_stdin;
-	filename = rb_str_new2("-");
-	if (ruby_inplace_mode) {
+    else if (argf_of(argf).next_p == -1) {
+	argf_of(argf).current_file = rb_stdin;
+	argf_of(argf).filename = rb_str_new2("-");
+	if (argf_of(argf).inplace) {
 	    rb_warn("Can't do inplace edit for stdio");
 	    rb_stdout = orig_stdout;
 	}
@@ -5432,24 +5420,24 @@
   retry:
     if (!next_argv()) return Qnil;
     if (ARGF_GENERIC_INPUT_P()) {
-	line = rb_funcall3(current_file, rb_intern("gets"), argc, argv);
+	line = rb_funcall3(argf_of(argf).current_file, rb_intern("gets"), argc, argv);
     }
     else {
 	if (argc == 0 && rb_rs == rb_default_rs) {
-	    line = rb_io_gets(current_file);
+	    line = rb_io_gets(argf_of(argf).current_file);
 	}
 	else {
-	    line = rb_io_getline(argc, argv, current_file);
+	    line = rb_io_getline(argc, argv, argf_of(argf).current_file);
 	}
-	if (NIL_P(line) && next_p != -1) {
-	    argf_close(current_file);
-	    next_p = 1;
+	if (NIL_P(line) && argf_of(argf).next_p != -1) {
+	    argf_close(argf_of(argf).current_file);
+	    argf_of(argf).next_p = 1;
 	    goto retry;
 	}
     }
     if (!NIL_P(line)) {
-	gets_lineno++;
-	lineno = INT2FIX(gets_lineno);
+	argf_of(argf).gets_lineno++;
+	argf_of(argf).lineno = INT2FIX(argf_of(argf).gets_lineno);
     }
     return line;
 }
@@ -5458,7 +5446,7 @@
 argf_lineno_getter(ID id, VALUE *var)
 {
     VALUE argf = *var;
-    return lineno;
+    return argf_of(argf).lineno;
 }
 
 static void
@@ -5466,8 +5454,8 @@
 {
     VALUE argf = *var;
     int n = NUM2INT(val);
-    gets_lineno = n;
-    lineno = INT2FIX(n);
+    argf_of(argf).gets_lineno = n;
+    argf_of(argf).lineno = INT2FIX(n);
 }
 
 static VALUE argf_gets(int, VALUE *, VALUE);
@@ -5508,6 +5496,7 @@
 static VALUE
 rb_f_gets(int argc, VALUE *argv, VALUE recv)
 {
+    VALUE argf = ruby_vm_argf(GET_VM());
     if (recv == argf) {
 	return argf_gets(argc, argv, argf);
     }
@@ -5528,6 +5517,7 @@
 rb_gets(void)
 {
     VALUE line;
+    VALUE argf = ruby_vm_argf(GET_VM());
 
     if (rb_rs != rb_default_rs) {
 	return rb_f_gets(0, 0, argf);
@@ -5535,16 +5525,16 @@
 
   retry:
     if (!next_argv()) return Qnil;
-    line = rb_io_gets(current_file);
-    if (NIL_P(line) && next_p != -1) {
-	rb_io_close(current_file);
-	next_p = 1;
+    line = rb_io_gets(argf_of(argf).current_file);
+    if (NIL_P(line) && argf_of(argf).next_p != -1) {
+	rb_io_close(argf_of(argf).current_file);
+	argf_of(argf).next_p = 1;
 	goto retry;
     }
     rb_lastline_set(line);
     if (!NIL_P(line)) {
-	gets_lineno++;
-	lineno = INT2FIX(gets_lineno);
+	argf_of(argf).gets_lineno++;
+	argf_of(argf).lineno = INT2FIX(argf_of(argf).gets_lineno);
     }
 
     return line;
@@ -5565,6 +5555,7 @@
 static VALUE
 rb_f_readline(int argc, VALUE *argv, VALUE recv)
 {
+    VALUE argf = ruby_vm_argf(GET_VM());
     if (recv == argf) {
 	return argf_readline(argc, argv, argf);
     }
@@ -5601,6 +5592,7 @@
 static VALUE
 rb_f_readlines(int argc, VALUE *argv, VALUE recv)
 {
+    VALUE argf = ruby_vm_argf(GET_VM());
     if (recv == argf) {
 	return argf_readlines(argc, argv, argf);
     }
@@ -6778,6 +6770,7 @@
     VALUE src_io, dst_io;
     rb_io_t *src_fptr = 0, *dst_fptr = 0;
     int src_fd, dst_fd;
+    VALUE argf = ruby_vm_argf(GET_VM());
 
     stp->th = GET_THREAD();
 
@@ -7033,19 +7026,19 @@
 static VALUE
 argf_external_encoding(VALUE argf)
 {
-    if (!RTEST(current_file)) {
+    if (!RTEST(argf_of(argf).current_file)) {
 	return rb_enc_from_encoding(rb_default_external_encoding());
     }
-    return rb_io_external_encoding(rb_io_check_io(current_file));
+    return rb_io_external_encoding(rb_io_check_io(argf_of(argf).current_file));
 }
 
 static VALUE
 argf_internal_encoding(VALUE argf)
 {
-    if (!RTEST(current_file)) {
+    if (!RTEST(argf_of(argf).current_file)) {
 	return rb_enc_from_encoding(rb_default_external_encoding());
     }
-    return rb_io_internal_encoding(rb_io_check_io(current_file));
+    return rb_io_internal_encoding(rb_io_check_io(argf_of(argf).current_file));
 }
 
 static VALUE
@@ -7056,10 +7049,10 @@
     if (!next_argv()) {
 	rb_raise(rb_eArgError, "no stream to set encoding");
     }
-    rb_io_set_encoding(argc, argv, current_file);
-    GetOpenFile(current_file, fptr);
-    argf_enc = fptr->enc;
-    argf_enc2 = fptr->enc2;
+    rb_io_set_encoding(argc, argv, argf_of(argf).current_file);
+    GetOpenFile(argf_of(argf).current_file, fptr);
+    argf_of(argf).enc = fptr->enc;
+    argf_of(argf).enc2 = fptr->enc2;
     return argf;
 }
 
@@ -7070,7 +7063,7 @@
 	rb_raise(rb_eArgError, "no stream to tell");
     }
     ARGF_FORWARD(0, 0);
-    return rb_io_tell(current_file);
+    return rb_io_tell(argf_of(argf).current_file);
 }
 
 static VALUE
@@ -7080,7 +7073,7 @@
 	rb_raise(rb_eArgError, "no stream to seek");
     }
     ARGF_FORWARD(argc, argv);
-    return rb_io_seek_m(argc, argv, current_file);
+    return rb_io_seek_m(argc, argv, argf_of(argf).current_file);
 }
 
 static VALUE
@@ -7090,7 +7083,7 @@
 	rb_raise(rb_eArgError, "no stream to set position");
     }
     ARGF_FORWARD(1, &offset);
-    return rb_io_set_pos(current_file, offset);
+    return rb_io_set_pos(argf_of(argf).current_file, offset);
 }
 
 static VALUE
@@ -7100,7 +7093,7 @@
 	rb_raise(rb_eArgError, "no stream to rewind");
     }
     ARGF_FORWARD(0, 0);
-    return rb_io_rewind(current_file);
+    return rb_io_rewind(argf_of(argf).current_file);
 }
 
 static VALUE
@@ -7110,7 +7103,7 @@
 	rb_raise(rb_eArgError, "no stream");
     }
     ARGF_FORWARD(0, 0);
-    return rb_io_fileno(current_file);
+    return rb_io_fileno(argf_of(argf).current_file);
 }
 
 static VALUE
@@ -7118,16 +7111,16 @@
 {
     next_argv();
     ARGF_FORWARD(0, 0);
-    return current_file;
+    return argf_of(argf).current_file;
 }
 
 static VALUE
 argf_eof(VALUE argf)
 {
-    if (current_file) {
-	if (init_p == 0) return Qtrue;
+    if (argf_of(argf).current_file) {
+	if (argf_of(argf).init_p == 0) return Qtrue;
 	ARGF_FORWARD(0, 0);
-	if (rb_io_eof(current_file)) {
+	if (rb_io_eof(argf_of(argf).current_file)) {
 	    return Qtrue;
 	}
     }
@@ -7158,14 +7151,14 @@
 	tmp = argf_forward(argc, argv, argf);
     }
     else {
-	tmp = io_read(argc, argv, current_file);
+	tmp = io_read(argc, argv, argf_of(argf).current_file);
     }
     if (NIL_P(str)) str = tmp;
     else if (!NIL_P(tmp)) rb_str_append(str, tmp);
     if (NIL_P(tmp) || NIL_P(length)) {
-	if (next_p != -1) {
-	    argf_close(current_file);
-	    next_p = 1;
+	if (argf_of(argf).next_p != -1) {
+	    argf_close(argf_of(argf).current_file);
+	    argf_of(argf).next_p = 1;
 	    goto retry;
 	}
     }
@@ -7217,15 +7210,15 @@
 			 RUBY_METHOD_FUNC(0), Qnil, rb_eEOFError, (VALUE)0);
     }
     else {
-        tmp = io_getpartial(argc, argv, current_file, 0);
+        tmp = io_getpartial(argc, argv, argf_of(argf).current_file, 0);
     }
     if (NIL_P(tmp)) {
-        if (next_p == -1) {
+        if (argf_of(argf).next_p == -1) {
             rb_eof_error();
         }
-        argf_close(current_file);
-        next_p = 1;
-        if (RARRAY_LEN(rb_argv) == 0)
+        argf_close(argf_of(argf).current_file);
+        argf_of(argf).next_p = 1;
+        if (RARRAY_LEN(argf_of(argf).argv) == 0)
             rb_eof_error();
         if (NIL_P(str))
             str = rb_str_new(NULL, 0);
@@ -7242,14 +7235,14 @@
   retry:
     if (!next_argv()) return Qnil;
     if (ARGF_GENERIC_INPUT_P()) {
-	ch = rb_funcall3(current_file, rb_intern("getc"), 0, 0);
+	ch = rb_funcall3(argf_of(argf).current_file, rb_intern("getc"), 0, 0);
     }
     else {
-	ch = rb_io_getc(current_file);
+	ch = rb_io_getc(argf_of(argf).current_file);
     }
-    if (NIL_P(ch) && next_p != -1) {
-	argf_close(current_file);
-	next_p = 1;
+    if (NIL_P(ch) && argf_of(argf).next_p != -1) {
+	argf_close(argf_of(argf).current_file);
+	argf_of(argf).next_p = 1;
 	goto retry;
     }
 
@@ -7263,15 +7256,15 @@
 
   retry:
     if (!next_argv()) return Qnil;
-    if (TYPE(current_file) != T_FILE) {
-	ch = rb_funcall3(current_file, rb_intern("getbyte"), 0, 0);
+    if (TYPE(argf_of(argf).current_file) != T_FILE) {
+	ch = rb_funcall3(argf_of(argf).current_file, rb_intern("getbyte"), 0, 0);
     }
     else {
-	ch = rb_io_getbyte(current_file);
+	ch = rb_io_getbyte(argf_of(argf).current_file);
     }
-    if (NIL_P(ch) && next_p != -1) {
-	argf_close(current_file);
-	next_p = 1;
+    if (NIL_P(ch) && argf_of(argf).next_p != -1) {
+	argf_close(argf_of(argf).current_file);
+	argf_of(argf).next_p = 1;
 	goto retry;
     }
 
@@ -7285,15 +7278,15 @@
 
   retry:
     if (!next_argv()) rb_eof_error();
-    if (TYPE(current_file) != T_FILE) {
-	ch = rb_funcall3(current_file, rb_intern("getc"), 0, 0);
+    if (TYPE(argf_of(argf).current_file) != T_FILE) {
+	ch = rb_funcall3(argf_of(argf).current_file, rb_intern("getc"), 0, 0);
     }
     else {
-	ch = rb_io_getc(current_file);
+	ch = rb_io_getc(argf_of(argf).current_file);
     }
-    if (NIL_P(ch) && next_p != -1) {
-	argf_close(current_file);
-	next_p = 1;
+    if (NIL_P(ch) && argf_of(argf).next_p != -1) {
+	argf_close(argf_of(argf).current_file);
+	argf_of(argf).next_p = 1;
 	goto retry;
     }
 
@@ -7319,8 +7312,8 @@
     RETURN_ENUMERATOR(argf, argc, argv);
     for (;;) {
 	if (!next_argv()) return Qnil;
-	rb_block_call(current_file, rb_intern("each_line"), 0, 0, rb_yield, 0);
-	next_p = 1;
+	rb_block_call(argf_of(argf).current_file, rb_intern("each_line"), 0, 0, rb_yield, 0);
+	argf_of(argf).next_p = 1;
     }
     return argf;
 }
@@ -7331,8 +7324,8 @@
     RETURN_ENUMERATOR(argf, 0, 0);
     for (;;) {
 	if (!next_argv()) return Qnil;
-	rb_block_call(current_file, rb_intern("each_byte"), 0, 0, rb_yield, 0);
-	next_p = 1;
+	rb_block_call(argf_of(argf).current_file, rb_intern("each_byte"), 0, 0, rb_yield, 0);
+	argf_of(argf).next_p = 1;
     }
 }
 
@@ -7342,8 +7335,8 @@
     RETURN_ENUMERATOR(argf, 0, 0);
     for (;;) {
 	if (!next_argv()) return Qnil;
-	rb_block_call(current_file, rb_intern("each_char"), 0, 0, rb_yield, 0);
-	next_p = 1;
+	rb_block_call(argf_of(argf).current_file, rb_intern("each_char"), 0, 0, rb_yield, 0);
+	argf_of(argf).next_p = 1;
     }
 }
 
@@ -7351,7 +7344,7 @@
 argf_filename(VALUE argf)
 {
     next_argv();
-    return filename;
+    return argf_of(argf).filename;
 }
 
 static VALUE
@@ -7364,25 +7357,25 @@
 argf_file(VALUE argf)
 {
     next_argv();
-    return current_file;
+    return argf_of(argf).current_file;
 }
 
 static VALUE
 argf_binmode_m(VALUE argf)
 {
-    argf_binmode = 1;
+    argf_of(argf).binmode = 1;
     next_argv();
     ARGF_FORWARD(0, 0);
-    rb_io_binmode(current_file);
+    rb_io_binmode(argf_of(argf).current_file);
     return argf;
 }
 
 static VALUE
 argf_skip(VALUE argf)
 {
-    if (next_p != -1) {
-	argf_close(current_file);
-	next_p = 1;
+    if (argf_of(argf).next_p != -1) {
+	argf_close(argf_of(argf).current_file);
+	argf_of(argf).next_p = 1;
     }
     return argf;
 }
@@ -7391,11 +7384,11 @@
 argf_close_m(VALUE argf)
 {
     next_argv();
-    argf_close(current_file);
-    if (next_p != -1) {
-	next_p = 1;
+    argf_close(argf_of(argf).current_file);
+    if (argf_of(argf).next_p != -1) {
+	argf_of(argf).next_p = 1;
     }
-    gets_lineno = 0;
+    argf_of(argf).gets_lineno = 0;
     return argf;
 }
 
@@ -7404,7 +7397,7 @@
 {
     next_argv();
     ARGF_FORWARD(0, 0);
-    return rb_io_closed(current_file);
+    return rb_io_closed(argf_of(argf).current_file);
 }
 
 static VALUE
@@ -7416,8 +7409,8 @@
 static VALUE
 argf_inplace_mode_get(VALUE argf)
 {
-    if (!ruby_inplace_mode) return Qnil;
-    return rb_str_new2(ruby_inplace_mode);
+    if (!argf_of(argf).inplace) return Qnil;
+    return rb_str_new2(argf_of(argf).inplace);
 }
 
 static VALUE
@@ -7430,14 +7423,14 @@
 argf_inplace_mode_set(VALUE argf, VALUE val)
 {
     if (!RTEST(val)) {
-	if (ruby_inplace_mode) free(ruby_inplace_mode);
-	ruby_inplace_mode = 0;
+	if (argf_of(argf).inplace) free(argf_of(argf).inplace);
+	argf_of(argf).inplace = 0;
     }
     else {
 	StringValue(val);
-	if (ruby_inplace_mode) free(ruby_inplace_mode);
-	ruby_inplace_mode = 0;
-	ruby_inplace_mode = strdup(RSTRING_PTR(val));
+	if (argf_of(argf).inplace) free(argf_of(argf).inplace);
+	argf_of(argf).inplace = 0;
+	argf_of(argf).inplace = strdup(RSTRING_PTR(val));
     }
     return argf;
 }
@@ -7449,23 +7442,23 @@
 }
 
 const char *
-ruby_get_inplace_mode(void)
+ruby_vm_get_inplace_mode(rb_vm_t *vm)
 {
-    return ruby_inplace_mode;
+    return argf_of(vm->argf).inplace;
 }
 
 void
-ruby_set_inplace_mode(const char *suffix)
+ruby_vm_set_inplace_mode(rb_vm_t *vm, const char *suffix)
 {
-    if (ruby_inplace_mode) free(ruby_inplace_mode);
-    ruby_inplace_mode = 0;
-    if (suffix) ruby_inplace_mode = strdup(suffix);
+    if (argf_of(vm->argf).inplace) free(argf_of(vm->argf).inplace);
+    argf_of(vm->argf).inplace = 0;
+    if (suffix) argf_of(vm->argf).inplace = strdup(suffix);
 }
 
 static VALUE
 argf_argv(VALUE argf)
 {
-    return rb_argv;
+    return argf_of(argf).argv;
 }
 
 static VALUE
@@ -7475,9 +7468,15 @@
 }
 
 VALUE
+ruby_vm_get_argv(rb_vm_t *vm)
+{
+    return argf_of(vm->argf).argv;
+}
+
+VALUE
 rb_get_argv(void)
 {
-    return rb_argv;
+    return ruby_vm_get_argv(GET_VM());
 }
 
 /*
@@ -7562,6 +7561,7 @@
 #undef rb_intern
 
     VALUE rb_cARGF;
+    VALUE *argfp = &GET_VM()->argf;
 #ifdef __CYGWIN__
 #include <sys/cygwin.h>
     static struct __cygwin_perfile pf[] =
@@ -7787,17 +7787,17 @@
     rb_define_method(rb_cARGF, "internal_encoding", argf_internal_encoding, 0);
     rb_define_method(rb_cARGF, "set_encoding", argf_set_encoding, -1);
 
-    argf = rb_class_new_instance(0, 0, rb_cARGF);
+    *argfp = rb_class_new_instance(0, 0, rb_cARGF);
 
-    rb_define_readonly_variable("$<", &argf);
-    rb_define_global_const("ARGF", argf);
+    rb_define_readonly_variable("$<", argfp);
+    rb_define_global_const("ARGF", *argfp);
 
-    rb_define_hooked_variable("$.", &argf, argf_lineno_getter, argf_lineno_setter);
-    rb_define_hooked_variable("$FILENAME", &argf, argf_filename_getter, 0);
-    filename = rb_str_new2("-");
+    rb_define_hooked_variable("$.", argfp, argf_lineno_getter, argf_lineno_setter);
+    rb_define_hooked_variable("$FILENAME", argfp, argf_filename_getter, 0);
+    argf_of(*argfp).filename = rb_str_new2("-");
 
-    rb_define_hooked_variable("$-i", &argf, opt_i_get, opt_i_set);
-    rb_define_hooked_variable("$*", &argf, argf_argv_getter, 0);
+    rb_define_hooked_variable("$-i", argfp, opt_i_get, opt_i_set);
+    rb_define_hooked_variable("$*", argfp, argf_argv_getter, 0);
 
 #if defined (_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__)
     atexit(pipe_atexit);
Index: mvm/thread.c
===================================================================
--- mvm/thread.c	(revision 17503)
+++ mvm/thread.c	(revision 17504)
@@ -265,11 +265,19 @@
 rb_thread_terminate_all(void)
 {
     rb_thread_t *th = GET_THREAD(); /* main thread */
-    rb_vm_t *vm = th->vm;
+    rb_vm_t *vm = GET_VM();
+
     if (vm->main_thread != th) {
 	rb_bug("rb_thread_terminate_all: called by child thread (%p, %p)", vm->main_thread, th);
     }
+    rb_vm_thread_terminate_all(vm);
+}
 
+void
+rb_vm_thread_terminate_all(rb_vm_t *vm)
+{
+    rb_thread_t *th = vm->main_thread;
+
     /* unlock all locking mutexes */
     if (th->keeping_mutexes) {
 	rb_mutex_unlock_all(th->keeping_mutexes);
@@ -883,6 +891,9 @@
 		TH_JUMP_TAG(th, TAG_FATAL);
 	    }
 	    else {
+		if (TYPE(err) == T_CLASS) {
+		    err = rb_make_exception(1, &err);
+		}
 		rb_exc_raise(err);
 	    }
 	}
@@ -2372,6 +2383,8 @@
     VALUE next_mutex;
 } mutex_t;
 
+static VALUE rb_eMutex_OrphanLock;
+
 #define GetMutexPtr(obj, tobj) \
   Data_Get_Struct(obj, mutex_t, tobj)
 
@@ -2393,8 +2406,12 @@
 {
     if (ptr) {
 	mutex_t *mutex = ptr;
-	if (mutex->th) {
-	    /* rb_warn("free locked mutex"); */
+	volatile rb_thread_t *th = mutex->th;
+	if (th) {
+	    if (!th->thrown_errinfo) {
+		th->thrown_errinfo = rb_eMutex_OrphanLock;
+	    }
+	    RUBY_VM_SET_INTERRUPT(th);
 	    mutex_unlock(mutex);
 	}
 	native_mutex_destroy(&mutex->lock);
@@ -2670,8 +2687,8 @@
 
     while (mutexes) {
 	GetMutexPtr(mutexes, mutex);
-	/* rb_warn("mutex #<%s:%p> remains to be locked by terminated thread",
-		rb_obj_classname(mutexes), (void*)mutexes); */
+	rb_warn("mutex #<%s:%p> remains to be locked by terminated thread",
+		rb_obj_classname(mutexes), (void*)mutexes);
 	mutexes = mutex->next_mutex;
 	err = mutex_unlock(mutex);
 	if (err) rb_bug("invalid keeping_mutexes: %s", err);
@@ -3074,9 +3091,8 @@
 }
 
 int
-rb_remove_event_hook(rb_event_hook_func_t func)
+rb_vm_remove_event_hook(rb_vm_t *vm, rb_event_hook_func_t func)
 {
-    rb_vm_t *vm = GET_VM();
     rb_event_hook_t *hook = vm->event_hooks;
     int ret = remove_event_hook(&vm->event_hooks, func);
 
@@ -3087,6 +3103,12 @@
     return ret;
 }
 
+int
+rb_remove_event_hook(rb_event_hook_func_t func)
+{
+    return rb_vm_remove_event_hook(GET_VM(), func);
+}
+
 static int
 clear_trace_func_i(st_data_t key, st_data_t val, st_data_t flag)
 {
@@ -3097,10 +3119,16 @@
 }
 
 void
+rb_vm_clear_trace_func(rb_vm_t *vm)
+{
+    st_foreach(vm->living_threads, clear_trace_func_i, (st_data_t) 0);
+    rb_vm_remove_event_hook(vm, 0);
+}
+
+void
 rb_clear_trace_func(void)
 {
-    st_foreach(GET_VM()->living_threads, clear_trace_func_i, (st_data_t) 0);
-    rb_remove_event_hook(0);
+    rb_vm_clear_trace_func(GET_VM());
 }
 
 static void call_trace_func(rb_event_flag_t, VALUE data, VALUE self, ID id, VALUE klass);
@@ -3402,6 +3430,7 @@
 
     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);
 
     /* trace */
     rb_define_global_function("set_trace_func", set_trace_func, 1);
@@ -3503,3 +3532,40 @@
 	rb_thread_raise(2, argv, vm->main_thread);
     }
 }
+
+static struct {
+    rb_thread_lock_t lock;
+    int last;
+} specific_key;
+
+int
+rb_vm_key_create(void)
+{
+    int key;
+    native_mutex_lock(&specific_key.lock);
+    key = specific_key.last++;
+    native_mutex_unlock(&specific_key.lock);
+    return key;
+}
+
+VALUE *
+ruby_vm_specific_ptr(rb_vm_t *vm, int key)
+{
+    VALUE *ptr;
+
+    native_mutex_lock(&vm->global_vm_lock);
+    ptr = vm->specific_storage.ptr;
+    if (!ptr || vm->specific_storage.len <= key) {
+	ptr = realloc(vm->specific_storage.ptr, sizeof(VALUE) * (key + 1));
+	vm->specific_storage.ptr = ptr;
+	vm->specific_storage.len = key + 1;
+    }
+    native_mutex_unlock(&vm->global_vm_lock);
+    return &ptr[key];
+}
+
+VALUE *
+rb_vm_specific_ptr(int key)
+{
+    return ruby_vm_specific_ptr(GET_VM(), key);
+}
Index: mvm/main.c
===================================================================
--- mvm/main.c	(revision 17503)
+++ mvm/main.c	(revision 17504)
@@ -29,8 +29,9 @@
 
     ruby_sysinit(&argc, &argv);
     {
+	rb_vm_t *vm;
 	RUBY_INIT_STACK;
-	ruby_init();
-	return ruby_run_node(ruby_options(argc, argv));
+	vm = ruby_vm_new();
+	return ruby_vm_run(vm, ruby_vm_parse_options(vm, argc, argv));
     }
 }
Index: mvm/eval.c
===================================================================
--- mvm/eval.c	(revision 17503)
+++ mvm/eval.c	(revision 17504)
@@ -88,28 +88,35 @@
 
 extern void rb_clear_trace_func(void);
 
-void *
-ruby_options(int argc, char **argv)
+VALUE
+ruby_vm_parse_options(rb_vm_t *vm, int argc, char **argv)
 {
     int state;
-    void *tree = 0;
+    VALUE code = 0;
 
     Init_stack((void *)&state);
     PUSH_TAG();
     if ((state = EXEC_TAG()) == 0) {
-	SAVE_ROOT_JMPBUF(GET_THREAD(), tree = ruby_process_options(argc, argv));
+	SAVE_ROOT_JMPBUF(vm->main_thread,
+			 code = ruby_vm_process_options(vm, argc, argv));
     }
     else {
-	rb_clear_trace_func();
+	rb_vm_clear_trace_func(vm);
 	state = error_handle(state);
-	tree = (void *)INT2FIX(state);
+	code = INT2FIX(state);
     }
     POP_TAG();
-    return tree;
+    return code;
 }
 
+void *
+ruby_options(int argc, char **argv)
+{
+    return (void *)ruby_vm_parse_options(GET_VM(), argc, argv);
+}
+
 static void
-ruby_finalize_0(void)
+ruby_finalize_0(rb_vm_t *vm)
 {
     PUSH_TAG();
     if (EXEC_TAG() == 0) {
@@ -121,28 +128,29 @@
 }
 
 static void
-ruby_finalize_1(void)
+ruby_finalize_1(rb_vm_t *vm)
 {
     ruby_sig_finalize();
-    GET_THREAD()->errinfo = Qnil;
+    vm->main_thread->errinfo = Qnil;
     rb_gc_call_finalizer_at_exit();
 }
 
 void
 ruby_finalize(void)
 {
-    ruby_finalize_0();
-    ruby_finalize_1();
+    rb_vm_t *vm = GET_VM();
+    ruby_finalize_0(vm);
+    ruby_finalize_1(vm);
 }
 
 void rb_thread_stop_timer_thread(void);
 
 int
-ruby_cleanup(int ex)
+ruby_vm_cleanup(rb_vm_t *vm, int ex)
 {
     int state;
     volatile VALUE errs[2];
-    rb_thread_t *th = GET_THREAD();
+    rb_thread_t *th = vm->main_thread;
     int nerr;
 
     errs[1] = th->errinfo;
@@ -151,21 +159,21 @@
 
     PUSH_TAG();
     if ((state = EXEC_TAG()) == 0) {
-	SAVE_ROOT_JMPBUF(th, ruby_finalize_0());
+	SAVE_ROOT_JMPBUF(th, ruby_finalize_0(vm));
     }
     POP_TAG();
 
     errs[0] = th->errinfo;
     PUSH_TAG();
     if ((state = EXEC_TAG()) == 0) {
-	SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
+	SAVE_ROOT_JMPBUF(th, rb_vm_thread_terminate_all(vm));
     }
     else if (ex == 0) {
 	ex = state;
     }
     th->errinfo = errs[1];
     ex = error_handle(ex);
-    ruby_finalize_1();
+    ruby_finalize_1(vm);
     POP_TAG();
     rb_thread_stop_timer_thread();
 
@@ -204,13 +212,17 @@
 }
 
 int
-ruby_exec_node(void *n, const char *file)
+ruby_cleanup(int ex)
 {
+    return ruby_vm_cleanup(GET_VM(), ex);
+}
+
+static int
+th_exec_iseq(rb_thread_t *th, VALUE iseq, const char *file)
+{
     int state;
-    VALUE iseq = (VALUE)n;
-    rb_thread_t *th = GET_THREAD();
 
-    if (!n) return 0;
+    if (!iseq) return 0;
 
     PUSH_TAG();
     if ((state = EXEC_TAG()) == 0) {
@@ -223,6 +235,12 @@
     return state;
 }
 
+int
+ruby_exec_node(void *n, const char *file)
+{
+    return th_exec_iseq(GET_THREAD(), (VALUE)n, file);
+}
+
 void
 ruby_stop(int ex)
 {
@@ -230,10 +248,8 @@
 }
 
 int
-ruby_run_node(void *n)
+ruby_vm_run(rb_vm_t *vm, VALUE v)
 {
-    VALUE v = (VALUE)n;
-
     switch (v) {
       case Qtrue:  return EXIT_SUCCESS;
       case Qfalse: return EXIT_FAILURE;
@@ -241,10 +257,16 @@
     if (FIXNUM_P(v)) {
 	return FIX2INT(v);
     }
-    Init_stack((void *)&n);
-    return ruby_cleanup(ruby_exec_node(n, 0));
+    Init_stack((void *)&v);
+    return ruby_vm_cleanup(vm, th_exec_iseq(vm->main_thread, v, 0));
 }
 
+int
+ruby_run_node(void *n)
+{
+    return ruby_vm_run(GET_VM(), (VALUE)n);
+}
+
 /*
  *  call-seq:
  *     Module.nesting    => array

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

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