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/