[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:119

From: ko1 atdot.net
Date: 5 Oct 2005 12:25:41 -0000
Subject: [yarv-diff:119] r275 - trunk

Author: ko1
Date: 2005-10-05 21:25:40 +0900 (Wed, 05 Oct 2005)
New Revision: 275

Modified:
   trunk/ChangeLog
   trunk/compile.c
   trunk/compile.h
   trunk/error.c
   trunk/eval.c
   trunk/eval_error.h
   trunk/eval_jump.h
   trunk/eval_load.c
   trunk/eval_thread.c
   trunk/ruby.h
   trunk/test.rb
   trunk/thread.c
   trunk/thread_pthread.h
   trunk/thread_win32.h
   trunk/vm.c
   trunk/vm.h
   trunk/vm_dump.c
   trunk/yarvcore.c
   trunk/yarvcore.h
Log:
	* eva.c, eval_thread.c, ruby.h, eval_error.h, eval_jump.h, 
	eval_load.c, thread.c, error.c, compile.h : remove ruby_errinfo

	* thread_win32.h, thread_pthread.h : set stack size to 4KB

	* vm.c : fix making env routine

	* vm_dump.c, vm.h : support frame type "EVAL" and fix magic number

	* yarvcore.c : fix some mark/free routine

	* yarvcore.h : 



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/ChangeLog	2005-10-05 12:25:40 UTC (rev 275)
@@ -5,6 +5,22 @@
 #
 
 
+2005-10-05(Wed) 21:20:13 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* eva.c, eval_thread.c, ruby.h, eval_error.h, eval_jump.h, 
+	eval_load.c, thread.c, error.c, compile.h : remove ruby_errinfo
+
+	* thread_win32.h, thread_pthread.h : set stack size to 4KB
+
+	* vm.c : fix making env routine
+
+	* vm_dump.c, vm.h : support frame type "EVAL" and fix magic number
+
+	* yarvcore.c : fix some mark/free routine
+
+	* yarvcore.h : 
+
+
 2005-10-05(Wed) 09:08:11 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* eval.c, eval_intern.h, vm.c, eval_jump.h, yarvcore.h :

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/compile.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -3313,7 +3313,8 @@
     if(!poped){
       idx = get_dyna_var_idx(self, node->nd_vid, &lv, &ls);
       if(idx < 0){
-        COMPILE_ERROR(("unknown dvar"));
+        int *a = 0;
+        rb_bug("unknown dvar (%s)", rb_id2name(node->nd_vid));
       }
       ADD_INSN2(ret, nd_line(node), getdynamic, I2F(ls - idx), I2F(lv));
     }

Modified: trunk/compile.h
===================================================================
--- trunk/compile.h	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/compile.h	2005-10-05 12:25:40 UTC (rev 275)
@@ -174,12 +174,12 @@
 /* error */
 #define COMPILE_ERROR(strs)                        \
 {                                                  \
-  VALUE tmp = ruby_errinfo;                        \
+  VALUE tmp = GET_THREAD()->errinfo;               \
   if(CPDEBUG)rb_bug strs;                          \
-  ruby_errinfo = iseqobj->compile_data->err_info;  \
+  GET_THREAD()->errinfo = iseqobj->compile_data->err_info;  \
   rb_compile_error strs;                           \
-  iseqobj->compile_data->err_info = ruby_errinfo;  \
-  ruby_errinfo = tmp;                              \
+  iseqobj->compile_data->err_info = GET_THREAD()->errinfo; \
+  GET_THREAD()->errinfo = tmp;                     \
   ret = 0;                                         \
   break;                                           \
 }

Modified: trunk/error.c
===================================================================
--- trunk/error.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/error.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -1467,21 +1467,21 @@
     eNOERROR = set_syserr(0, "NOERROR");
 }
 
+#include "yarv.h"
+
 static void
 err_append(const char *s)
 {
-    extern VALUE ruby_errinfo;
-
     if (ruby_in_eval) {
-	if (NIL_P(ruby_errinfo)) {
-	    ruby_errinfo = rb_exc_new2(rb_eSyntaxError, s);
+	if (NIL_P(GET_THREAD()->errinfo)) {
+	    GET_THREAD()->errinfo = rb_exc_new2(rb_eSyntaxError, s);
 	}
 	else {
-	    VALUE str = rb_obj_as_string(ruby_errinfo);
+	    VALUE str = rb_obj_as_string(GET_THREAD()->errinfo);
 
 	    rb_str_cat2(str, "\n");
 	    rb_str_cat2(str, s);
-	    ruby_errinfo = rb_exc_new3(rb_eSyntaxError, str);
+	    GET_THREAD()->errinfo = rb_exc_new3(rb_eSyntaxError, str);
 	}
     }
     else {

Modified: trunk/eval.c
===================================================================
--- trunk/eval.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -39,8 +39,6 @@
 static ID added, singleton_added;
 static ID __id__, __send__, respond_to;
 
-VALUE ruby_errinfo = Qnil;
-
 VALUE rb_eLocalJumpError;
 VALUE rb_eSysStackError;
 
@@ -210,7 +208,7 @@
 ruby_finalize_1()
 {
     signal(SIGINT, SIG_DFL);
-    ruby_errinfo = 0;
+    GET_THREAD()->errinfo = 0;
     rb_gc_call_finalizer_at_exit();
     trace_func = 0;
     tracing = 0;
@@ -228,14 +226,14 @@
     int ex;
 {
     int state;
-    volatile VALUE err = ruby_errinfo;
+    volatile VALUE err = GET_THREAD()->errinfo;
 
     ruby_safe_level = 0;
     Init_stack((void*)&state);
     PUSH_THREAD_TAG();
     if ((state = EXEC_TAG()) == 0) {
 	ruby_finalize_0();
-	if (ruby_errinfo) err = ruby_errinfo;
+	if (GET_THREAD()->errinfo) err = GET_THREAD()->errinfo;
 	rb_thread_cleanup();
 	rb_thread_wait_other_threads();
     }
@@ -245,7 +243,7 @@
     else if (ex == 0) {
 	ex = state;
     }
-    ruby_errinfo = err;
+    GET_THREAD()->errinfo = err;
     ex = error_handle(ex);
     ruby_finalize_1();
     POP_THREAD_TAG();
@@ -885,10 +883,10 @@
     VALUE at;
 
     if (thread_set_raised()) {
-	ruby_errinfo = exception_error;
+	GET_THREAD()->errinfo = exception_error;
 	JUMP_TAG(TAG_FATAL);
     }
-    if (NIL_P(mesg)) mesg = ruby_errinfo;
+    if (NIL_P(mesg)) mesg = GET_THREAD()->errinfo;
     if (NIL_P(mesg)) {
 	mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
     }
@@ -902,25 +900,25 @@
 	}
     }
     if (!NIL_P(mesg)) {
-	ruby_errinfo = mesg;
+	GET_THREAD()->errinfo = mesg;
     }
 
-    if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo)
-	&& !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
-	VALUE e = ruby_errinfo;
+    if (RTEST(ruby_debug) && !NIL_P(GET_THREAD()->errinfo)
+	&& !rb_obj_is_kind_of(GET_THREAD()->errinfo, rb_eSystemExit)) {
+	VALUE e = GET_THREAD()->errinfo;
 	int status;
 
 	PUSH_TAG(PROT_NONE);
 	if ((status = EXEC_TAG()) == 0) {
 	    e = rb_obj_as_string(e);
 	    warn_printf("Exception `%s' at %s:%d - %s\n",
-			rb_obj_classname(ruby_errinfo),
+			rb_obj_classname(GET_THREAD()->errinfo),
 			ruby_sourcefile, ruby_sourceline,
 			RSTRING(e)->ptr);
 	}
 	POP_TAG();
-	if (status == TAG_FATAL && ruby_errinfo == exception_error) {
-	    ruby_errinfo = mesg;
+	if (status == TAG_FATAL && GET_THREAD()->errinfo == exception_error) {
+	    GET_THREAD()->errinfo = mesg;
 	}
 	else if (status) {
 	    thread_reset_raised();
@@ -1286,7 +1284,7 @@
 {
     int state;
     volatile VALUE result;
-    volatile VALUE e_info = ruby_errinfo;
+    volatile VALUE e_info = GET_THREAD()->errinfo;
     va_list args;
 
     PUSH_TAG(PROT_NONE);
@@ -1300,7 +1298,7 @@
 
 	va_init_list(args, data2);
 	while (eclass = va_arg(args, VALUE)) {
-	    if (rb_obj_is_kind_of(ruby_errinfo, eclass)) {
+	    if (rb_obj_is_kind_of(GET_THREAD()->errinfo, eclass)) {
 		handle = Qtrue;
 		break;
 	    }
@@ -1311,12 +1309,12 @@
 	    if (r_proc) {
 		PUSH_TAG(PROT_NONE);
 		if ((state = EXEC_TAG()) == 0) {
-		    result = (*r_proc)(data2, ruby_errinfo);
+		    result = (*r_proc)(data2, GET_THREAD()->errinfo);
 		}
 		POP_TAG();
 		if (state == TAG_RETRY) {
 		    state = 0;
-		    ruby_errinfo = Qnil;
+		    GET_THREAD()->errinfo = Qnil;
 		    goto retry_entry;
 		}
 	    }
@@ -1325,7 +1323,7 @@
 		state = 0;
 	    }
 	    if (state == 0) {
-		ruby_errinfo = e_info;
+		GET_THREAD()->errinfo = e_info;
 	    }
 	}
     }
@@ -1872,8 +1870,8 @@
       if (strcmp(file, "(eval)") == 0) {
         VALUE mesg, errat;
 
-        errat = get_backtrace(ruby_errinfo);
-        mesg  = rb_attr_get(ruby_errinfo, rb_intern("mesg"));
+        errat = get_backtrace(GET_THREAD()->errinfo);
+        mesg  = rb_attr_get(GET_THREAD()->errinfo, rb_intern("mesg"));
         if (!NIL_P(errat) && TYPE(errat) == T_ARRAY) {
           if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {
             rb_str_update(mesg, 0, 0, rb_str_new2(": "));
@@ -1882,7 +1880,7 @@
           RARRAY(errat)->ptr[0] = RARRAY(backtrace(-2))->ptr[0];
         }
       }
-      rb_exc_raise(ruby_errinfo);
+      rb_exc_raise(GET_THREAD()->errinfo);
     }
     JUMP_TAG(state);
   }
@@ -2521,7 +2519,7 @@
 errat_getter(id)
     ID id;
 {
-    return get_backtrace(ruby_errinfo);
+    return get_backtrace(GET_THREAD()->errinfo);
 }
 
 static void
@@ -2530,10 +2528,10 @@
     ID id;
     VALUE *var;
 {
-    if (NIL_P(ruby_errinfo)) {
+    if (NIL_P(GET_THREAD()->errinfo)) {
 	rb_raise(rb_eArgError, "$! not set");
     }
-    set_backtrace(ruby_errinfo, val);
+    set_backtrace(GET_THREAD()->errinfo, val);
 }
 
 /*
@@ -2549,6 +2547,9 @@
  *     local_variables   #=> ["fred", "i"]
  */
 
+int
+th_collect_local_variables_in_heap(yarv_thread_t *th, VALUE *dfp, VALUE ary);
+
 static VALUE
 rb_f_local_variables()
 {
@@ -2559,16 +2560,26 @@
   
   while(1){
     if(cfp->iseq){
-      for(i= (cfp->lfp == cfp->dfp); i<cfp->iseq->local_size; i++){
+      int start = 0;
+      if(cfp->lfp == cfp->dfp){
+        start = 1;
+      }
+      for(i= start; i<cfp->iseq->local_size; i++){
         rb_ary_push(ary, rb_str_new2(rb_id2name(cfp->iseq->local_tbl[i])));
       }
     }
     if(cfp->lfp != cfp->dfp){
       /* block */
       VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]);
-      while(cfp->dfp != dfp){
-        cfp = YARV_PREVIOUS_CONTROL_FRAME(cfp);
+
+      if(th_collect_local_variables_in_heap(th, dfp, ary)){
+        break;
       }
+      else{
+        while(cfp->dfp != dfp){
+          cfp = YARV_PREVIOUS_CONTROL_FRAME(cfp);
+        }
+      }
     }
     else{
       break;
@@ -2649,7 +2660,9 @@
     rb_global_variable((VALUE*)&ruby_eval_tree);
 
     rb_define_virtual_variable("$@", errat_getter, errat_setter);
+  /*
     rb_define_hooked_variable("$!", &ruby_errinfo, 0, errinfo_setter);
+   */
 
     rb_define_global_function("eval", rb_f_eval, -1);
     rb_define_global_function("iterator?", rb_f_block_given_p, 0);
@@ -2728,9 +2741,12 @@
      (iseq = th->base_block->iseq)){
     while(iseq->type == ISEQ_TYPE_BLOCK ||
           iseq->type == ISEQ_TYPE_RESCUE||
-          iseq->type == ISEQ_TYPE_ENSURE){
+          iseq->type == ISEQ_TYPE_ENSURE||
+          iseq->type == ISEQ_TYPE_EVAL){
       int i;
-      for(i=0; iseq->local_size; i++){
+      // printf("local size: %d\n", iseq->local_size);
+      for(i=0; i<iseq->local_size; i++){
+        // printf("id (%4d): %s\n", i, rb_id2name(iseq->local_tbl[i]));
         if(iseq->local_tbl[i] == id){
           return Qtrue;
         }

Modified: trunk/eval_error.h
===================================================================
--- trunk/eval_error.h	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval_error.h	2005-10-05 12:25:40 UTC (rev 275)
@@ -77,11 +77,11 @@
     char *einfo;
     long elen;
 
-    if (NIL_P(ruby_errinfo)) return;
+    if (NIL_P(GET_THREAD()->errinfo)) return;
 
     PUSH_TAG(PROT_NONE);
     if (EXEC_TAG() == 0) {
-	errat = get_backtrace(ruby_errinfo);
+	errat = get_backtrace(GET_THREAD()->errinfo);
     }
     else {
 	errat = Qnil;
@@ -106,9 +106,9 @@
 	}
     }
 
-    eclass = CLASS_OF(ruby_errinfo);
+    eclass = CLASS_OF(GET_THREAD()->errinfo);
     if (EXEC_TAG() == 0) {
-	e = rb_funcall(ruby_errinfo, rb_intern("message"), 0, 0);
+	e = rb_funcall(GET_THREAD()->errinfo, rb_intern("message"), 0, 0);
 	StringValue(e);
 	einfo = RSTRING(e)->ptr;
 	elen = RSTRING(e)->len;
@@ -237,8 +237,8 @@
 	break;
       case TAG_RAISE:
       case TAG_FATAL:
-	if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
-	    status = sysexit_status(ruby_errinfo);
+	if (rb_obj_is_kind_of(GET_THREAD()->errinfo, rb_eSystemExit)) {
+	    status = sysexit_status(GET_THREAD()->errinfo);
 	}
 	else {
 	    error_print();

Modified: trunk/eval_jump.h
===================================================================
--- trunk/eval_jump.h	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval_jump.h	2005-10-05 12:25:40 UTC (rev 275)
@@ -250,7 +250,7 @@
 {
     rb_secure(4);
     if (argc == 0) {
-	if (!NIL_P(ruby_errinfo)) {
+	if (!NIL_P(GET_THREAD()->errinfo)) {
 	    error_print();
 	}
 	rb_exit(EXIT_FAILURE);

Modified: trunk/eval_load.c
===================================================================
--- trunk/eval_load.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval_load.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -129,7 +129,7 @@
   }
   fname = tmp;
 
-  ruby_errinfo = Qnil;	/* ensure */
+  GET_THREAD()->errinfo = Qnil;	/* ensure */
   if (!wrap) {
     rb_secure(4);		/* should alter global state */
   }
@@ -149,15 +149,15 @@
   
   if (ruby_nerrs > 0) {
     ruby_nerrs = 0;
-    rb_exc_raise(ruby_errinfo);
+    rb_exc_raise(GET_THREAD()->errinfo);
   }
   if (state){
     jump_tag_but_local_jump(state, Qundef);
   }
 
-  if (!NIL_P(ruby_errinfo)){
+  if (!NIL_P(GET_THREAD()->errinfo)){
     /* exception during load */
-    rb_exc_raise(ruby_errinfo);
+    rb_exc_raise(GET_THREAD()->errinfo);
   }
 }
 
@@ -336,7 +336,7 @@
     int safe;
 {
     VALUE result = Qnil;
-    volatile VALUE errinfo = ruby_errinfo;
+    volatile VALUE errinfo = GET_THREAD()->errinfo;
     int state;
     struct {
 	NODE *node;
@@ -404,7 +404,7 @@
     if (NIL_P(result)) {
 	load_failed(fname);
     }
-    ruby_errinfo = errinfo;
+    GET_THREAD()->errinfo = errinfo;
 
     return result;
 }

Modified: trunk/eval_thread.c
===================================================================
--- trunk/eval_thread.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval_thread.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -482,7 +482,7 @@
     th->flags &= THREAD_FLAGS_MASK;
   //th->tag = prot_tag;
   // th->tracing = tracing;
-    th->errinfo = ruby_errinfo;
+    th->errinfo = GET_THREAD()->errinfo;
     th->last_status = rb_last_status;
     tval = rb_lastline_get();
     rb_lastline_set(th->last_line);
@@ -551,7 +551,7 @@
     rb_trap_immediate = 0;	/* inhibit interrupts from here */
   // prot_tag = th->tag;
   // tracing = th->tracing;
-    ruby_errinfo = th->errinfo;
+    GET_THREAD()->errinfo = th->errinfo;
     rb_last_status = th->last_status;
     ruby_safe_level = th->safe;
 
@@ -1491,14 +1491,14 @@
     int state;
     enum yarv_thread_status status;
 {
-    if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
+    if (state && status != THREAD_TO_KILL && !NIL_P(GET_THREAD()->errinfo)) {
 	th->flags |= THREAD_RAISED;
 	if (state == TAG_FATAL) {
 	    /* fatal error within this thread, need to stop whole script */
-	    main_thread->errinfo = ruby_errinfo;
+	    main_thread->errinfo = GET_THREAD()->errinfo;
 	    rb_thread_cleanup();
 	}
-	else if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
+	else if (rb_obj_is_kind_of(GET_THREAD()->errinfo, rb_eSystemExit)) {
 	    if (th->safe >= 4) {
 		char buf[32];
 
@@ -1507,15 +1507,15 @@
 	    }
 	    else {
 		/* delegate exception to main_thread */
-		rb_thread_main_jump(ruby_errinfo, RESTORE_RAISE);
+		rb_thread_main_jump(GET_THREAD()->errinfo, RESTORE_RAISE);
 	    }
 	}
 	else if (th->safe < 4 && (ruby_thread_abort || th->abort || RTEST(ruby_debug))) {
 	    /* exit on main_thread */
-	    rb_thread_main_jump(ruby_errinfo, RESTORE_EXIT);
+	    rb_thread_main_jump(GET_THREAD()->errinfo, RESTORE_EXIT);
 	}
 	else {
-	    th->errinfo = ruby_errinfo;
+	    th->errinfo = GET_THREAD()->errinfo;
 	}
     }
     rb_thread_schedule();

Modified: trunk/ruby.h
===================================================================
--- trunk/ruby.h	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/ruby.h	2005-10-05 12:25:40 UTC (rev 275)
@@ -652,7 +652,6 @@
 RUBY_EXTERN VALUE rb_eLoadError;
 
 RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;
-RUBY_EXTERN VALUE ruby_errinfo;
 
 static inline VALUE
 #if defined(HAVE_PROTOTYPES)

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/test.rb	2005-10-05 12:25:40 UTC (rev 275)
@@ -1,4 +1,50 @@
+a = 0
+def m b
+  eval('a+=1', b)
+  eval('p a', b)
+  eval('b = 0', b)
+  p b
+  p local_variables
+end
 
+m binding
+
+__END__
+x = :x
+def m
+  m1 = :m1
+  m2 = :m2
+  eval('a=1; b=2; c=3; eval("d=4; e=5; f=6; binding")')
+end
+
+eval('p local_variables;p [a,b,c,d,e,f]', m)
+
+__END__
+b = nil
+eval("b=binding; 1", b)
+eval("b=binding; a = 1", b)
+eval("b=binding; p local_variables", b)
+__END__
+b = binding
+loop{
+  print "> "
+  ans = eval("b=binding; #{gets}", b)
+  puts "ans: #{ans}"
+}
+__END__
+
+ts = []
+10000.times{|i|
+  p i
+  ts << Thread.new{
+  }
+}
+__END__
+Thread.new{
+  raise
+}.join
+
+__END__
 i=0
 def m
 end

Modified: trunk/thread.c
===================================================================
--- trunk/thread.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/thread.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -100,9 +100,10 @@
     TH_PUSH_TAG(th);
     if((state = EXEC_TAG()) == 0){
       th->value = th_invoke_proc(th, proc, RARRAY(args)->len, RARRAY(args)->ptr);
+      th->errinfo = Qnil;
     }
     else{
-      
+      th->value = Qnil;
     }
     TH_POP_TAG();
     th->status = THREAD_KILLED;
@@ -137,62 +138,75 @@
 static VALUE
 yarv_thread_join(int argc, VALUE *argv, VALUE self)
 {
+  yarv_thread_t *cur_th = GET_THREAD();
   yarv_thread_t *th;
   int err;
+
   GetThreadVal(self, th);
+  cur_th->wait_thread_value = self;
 
-  if(th->status == THREAD_KILLED){
-    return self;
-  }
-
+again:
   if(argc == 0){
     thread_debug("yarv_thread_join(0)\n");
-    
+
     GVL_UNLOCK_BEGIN();
     {
       err = native_thread_join(th->thread_id, 0);
     }
     GVL_UNLOCK_END();
 
+    if(errno == EINTR){
+      goto again;
+    }
+
     switch(err){
     case EDEADLK:
+      cur_th->wait_thread_value = Qnil;
       rb_raise(rb_eThreadError, "can't join current thread (cause dead lock)");
     }
   }
   else if(argc == 1){
     double limit = timeofday();
     struct timeval interval;
-    
+
     interval = rb_time_interval(argv[0]);
     limit += interval.tv_sec;
     limit += interval.tv_usec * 1e-6;
-    
+
     while(1){
       GVL_UNLOCK_BEGIN();
       {
         sleep_for_polling();
       }
       GVL_UNLOCK_END();
-      
+
       if(th->status == THREAD_KILLED){
         break;
       }
       if(timeofday() > limit){
         /* timeout */
-        return Qnil;
+        cur_th->wait_thread_value = Qnil;
+        return self;
       }
     }
   }
   else{
+    cur_th->wait_thread_value = Qnil;
     rb_raise(rb_eArgError, "wrong number of arguments");
   }
-  return Qnil;
+
+  cur_th->wait_thread_value = Qnil;
+  if(th->errinfo != Qnil){
+    rb_exc_raise(th->errinfo);
+  }
+  return self;
 }
 
 static VALUE
 yarv_thread_value(VALUE self)
 {
   yarv_thread_t *th;
+
   yarv_thread_join(0, 0, self);
   GetThreadVal(self, th);
   return th->value;

Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/thread_pthread.h	2005-10-05 12:25:40 UTC (rev 275)
@@ -60,7 +60,7 @@
 native_thread_crteate(yarv_thread_t *th)
 {
   pthread_attr_t attr;
-  size_t stack_size = 16 * 1024;
+  size_t stack_size = 4 * 1024 - sizeof(int); /* 4KB */
   int err;
 
   thread_debug("create: %p, stack size: %d\n", th, stack_size);

Modified: trunk/thread_win32.h
===================================================================
--- trunk/thread_win32.h	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/thread_win32.h	2005-10-05 12:25:40 UTC (rev 275)
@@ -179,7 +179,7 @@
 static int
 native_thread_crteate(yarv_thread_t *th)
 {
-  size_t stack_size = 16 * 1024;
+  size_t stack_size = 4 * 1024 - sizeof(int); /* 4KB */
   if((th->thread_id = (HANDLE)_beginthreadex(0, /* security */
                                              stack_size,
                                              thread_start_func_1,

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/vm.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -139,12 +139,15 @@
   /* for return */
   th_set_finish_env(th);
   th_set_env(th, iseq,
-             FRAME_MAGIC_BLOCK, block->self, GC_GUARDED_PTR(block->dfp),
+             FRAME_MAGIC_EVAL, block->self, GC_GUARDED_PTR(block->dfp),
              iseq->iseq_encoded, th->cfp->sp, block->lfp,
              iseq->local_size, 0, 0);
   return 0;
 }
 
+static int
+check_env(yarv_env_t *env);
+
 static VALUE
 th_make_env_each(yarv_thread_t *th, yarv_control_frame_t *cfp,
                  VALUE *envptr, VALUE *endptr)
@@ -155,18 +158,29 @@
   int i, local_size;
 
   if(ENV_IN_HEAP_P(envptr)){
+    printf("ENV_IN_HEAP!\n");
     return ENV_VAL(envptr);
   }
-
   if(envptr != endptr){
     VALUE *penvptr = GC_GUARDED_PTR_REF(*envptr);
     yarv_control_frame_t *pcfp = cfp;
-    while(pcfp->dfp != penvptr){
-      pcfp++;
+    if(ENV_IN_HEAP_P(penvptr)){
+      penvval = ENV_VAL(penvptr);
     }
-    penvval = th_make_env_each(th, pcfp, penvptr, endptr);
-    cfp->lfp = pcfp->lfp;
-    *envptr = GC_GUARDED_PTR(pcfp->dfp);
+    else{
+      while(pcfp->dfp != penvptr){
+        // printf("pcfp: %p (%p)\n", pcfp->dfp, penvptr);
+        pcfp++;
+        if(pcfp->dfp == 0){
+          SDR();
+          printf("[BUG] orz\n");
+          exit(0);
+        }
+      }
+      penvval = th_make_env_each(th, pcfp, penvptr, endptr);
+      cfp->lfp = pcfp->lfp;
+      *envptr = GC_GUARDED_PTR(pcfp->dfp);
+    }
   }
 
   /* allocate env */
@@ -208,13 +222,81 @@
   env->block.lfp  = cfp->lfp;
   env->block.dfp  = cfp->dfp;
   env->block.iseq = cfp->iseq;
+
   return envval;
 }
 
+static VALUE
+check_env_value(VALUE envval);
+
+static int
+check_env(yarv_env_t *env){
+  printf("---\n");
+  printf("envptr: %p\n", &env->block.dfp[0]);
+  printf("orphan: %p\n", env->block.dfp[1]);
+  printf("inheap: %p\n", env->block.dfp[2]);
+  printf("envval: %10p ", env->block.dfp[3]); dp(env->block.dfp[3]);
+  printf("penvv : %10p ", env->block.dfp[4]); dp(env->block.dfp[4]);
+  printf("lfp:    %10p\n", env->block.lfp);
+  printf("dfp:    %10p\n", env->block.dfp);
+  if(env->block.dfp[4]){
+    printf(">>\n");
+    check_env_value(env->block.dfp[4]);
+    printf("<<\n");
+  }
+  return 1;
+}
+
+static VALUE
+check_env_value(VALUE envval){
+  yarv_env_t *env;
+  GetEnvVal(envval, env);
+  
+  if(check_env(env)){
+    return envval;
+  }
+  rb_bug("invalid env\n");
+  return Qnil; /* unreachable */
+}
+
+static int
+collect_local_variables_in_env(yarv_env_t *env, VALUE ary){
+  int i;
+  if(env->block.lfp == env->block.dfp){
+    return 0;
+  }
+  for(i = 0; i<env->block.iseq->local_size; i++){
+    rb_ary_push(ary, rb_str_new2(rb_id2name(env->block.iseq->local_tbl[i])));
+  }
+  if(env->prev_envval){
+    GetEnvVal(env->prev_envval, env);
+    collect_local_variables_in_env(env, ary);
+  }
+  return 0;
+}
+
+int
+th_collect_local_variables_in_heap(yarv_thread_t *th, VALUE *dfp, VALUE ary)
+{
+  if(ENV_IN_HEAP_P(dfp)){
+    yarv_env_t *env;
+    GetEnvVal(ENV_VAL(dfp), env);
+    collect_local_variables_in_env(env, ary);
+    return 1;
+  }
+  else{
+    return 0;
+  }
+}
+
+
 VALUE
 th_make_env_object(yarv_thread_t *th, yarv_control_frame_t *cfp)
 {
-  return th_make_env_each(th, cfp, cfp->dfp, cfp->lfp);
+  VALUE envval;
+  envval = th_make_env_each(th, cfp, cfp->dfp, cfp->lfp);
+  /* check_env_value(envval); */
+  return envval;
 }
 
 static VALUE
@@ -1026,7 +1108,7 @@
     VALUE  *escape_dfp;
     VALUE type;
     
-    err = ruby_errinfo;
+    err = th->errinfo;
     if(state == TAG_RAISE){
       rb_ivar_set(err, idThrowState, state);
     }
@@ -1057,7 +1139,7 @@
 #else
           *th->cfp->sp++ = (GET_THROWOBJ_VAL(err));
 #endif
-          ruby_errinfo = Qnil;
+          th->errinfo = Qnil;
           goto vm_loop_start;
         }
       }
@@ -1097,7 +1179,7 @@
 
             if(cfp->dfp == escape_dfp){
               cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
-              ruby_errinfo = Qnil;
+              th->errinfo = Qnil;
               goto vm_loop_start;
             }
           }
@@ -1131,7 +1213,7 @@
               *th->cfp->sp++ = (GET_THROWOBJ_VAL(err));
 #endif
             }
-            ruby_errinfo = Qnil;
+            th->errinfo = Qnil;
             goto vm_loop_start;
           }
         }
@@ -1181,7 +1263,7 @@
                  catch_iseq->local_size - 1, 0, 0);
 
       state = 0;
-      ruby_errinfo = Qnil;
+      th->errinfo = Qnil;
       goto vm_loop_start;
     }
     else{
@@ -1196,7 +1278,7 @@
       }
       else{
         th->cfp++;
-        ruby_errinfo = err;
+        th->errinfo = err;
         TH_POP_TAG2();
         JUMP_TAG(state);
       }

Modified: trunk/vm.h
===================================================================
--- trunk/vm.h	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/vm.h	2005-10-05 12:25:40 UTC (rev 275)
@@ -226,19 +226,19 @@
 #define ENV_IN_HEAP(env)    ((env)[2] = Qundef)
 #define ORPHAN_ENV(env)     ((env)[1] = Qundef)
 
-#define FRAME_MAGIC_METHOD 0xfaffffa1
-#define FRAME_MAGIC_BLOCK  0xfaffffa2
-#define FRAME_MAGIC_CLASS  0xfaffffa3
-#define FRAME_MAGIC_TOP    0xfaffffa4
-#define FRAME_MAGIC_FINISH 0xfaffffa5
-#define FRAME_MAGIC_CFUNC  0xfaffffa6
-#define FRAME_MAGIC_PROC   0xfaffffa7
-#define FRAME_MAGIC_IFUNC  0xfaffffa8
+#define FRAME_MAGIC_METHOD 0xfaffff11
+#define FRAME_MAGIC_BLOCK  0xfaffff21
+#define FRAME_MAGIC_CLASS  0xfaffff31
+#define FRAME_MAGIC_TOP    0xfaffff41
+#define FRAME_MAGIC_FINISH 0xfaffff51
+#define FRAME_MAGIC_CFUNC  0xfaffff61
+#define FRAME_MAGIC_PROC   0xfaffff71
+#define FRAME_MAGIC_IFUNC  0xfaffff81
+#define FRAME_MAGIC_EVAL   0xfaffff91
 
-
 #define CHECK_FRAME_MAGIC(magic)                   \
 {                                                  \
-  if((magic & 0xfffffff0) != 0xfaffffa0){          \
+  if((magic & 0xffffff00) != 0xfaffff00){          \
     rb_bug("YARV Stack frame error: %08x", magic); \
   }                                                \
 }

Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/vm_dump.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -33,6 +33,7 @@
   case FRAME_MAGIC_CFUNC:  magic = "CFUNC";  break;
   case FRAME_MAGIC_PROC:   magic = "PROC";   break;
   case FRAME_MAGIC_IFUNC:  magic = "IFUNC";  break;
+  case FRAME_MAGIC_EVAL:   magic = "EVAL";   break;
   case 0:                  magic = "------"; break;
   default: magic = "(none)"; break;
   }

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/yarvcore.c	2005-10-05 12:25:40 UTC (rev 275)
@@ -251,7 +251,7 @@
 
   if(ruby_nerrs > 0){
     ruby_nerrs = 0;
-    rb_exc_raise(ruby_errinfo);
+    rb_exc_raise(GET_THREAD()->errinfo);
   }
 
   return (VALUE)node;
@@ -608,12 +608,15 @@
     }
     
     /* mark ruby objects */
-    MARK_UNLESS_NULL(th->vm_value);
     MARK_UNLESS_NULL(th->klass_nest_stack);
+
     MARK_UNLESS_NULL(th->first_proc);
     MARK_UNLESS_NULL(th->first_args);
-    MARK_UNLESS_NULL(th->stat_insn_usage);
 
+    MARK_UNLESS_NULL(th->wait_thread_value);
+    MARK_UNLESS_NULL(th->value);
+    MARK_UNLESS_NULL(th->errinfo);
+    
     rb_mark_tbl(th->local_storage);
 
     if(GET_THREAD() != th &&
@@ -622,6 +625,8 @@
       yarv_machine_stack_mark(th);
     }
   }
+  
+  MARK_UNLESS_NULL(th->stat_insn_usage);
   MARK_REPORT("<- thread", 0);
 }
 
@@ -631,12 +636,13 @@
 
   obj = Data_Make_Struct(klass, yarv_thread_t,
                          thread_mark, thread_free, th);
-  MEMZERO(th, yarv_thread_t, 1);
   return obj;
 }
 
 static void
 th_init2(yarv_thread_t *th){
+  MEMZERO(th, yarv_thread_t, 1);
+
   /* allocate thread stack */
   th->stack      = ALLOC_N(VALUE, YARV_THREAD_STACK_SIZE);
   th->stack_size = YARV_THREAD_STACK_SIZE;
@@ -650,8 +656,9 @@
   th->cfp->dfp = th->stack;
   th->cfp->self = Qnil;
   th->cfp->magic = 0;
-
+  
   th->status = THREAD_RUNNABLE;
+  th->errinfo = Qnil;
 }
 static void
 th_init(yarv_thread_t *th)
@@ -664,15 +671,12 @@
 thread_init(VALUE self)
 {
   yarv_thread_t *th;
-  yarv_vm_t *vm;
-  VALUE vmval = GET_VM()->self;
+  yarv_vm_t *vm = GET_VM();
   GetThreadVal(self, th);
-  GetVMVal(vmval, vm);
 
   th_init(th);
   th->self = self;
 
-  th->vm_value = vmval;
   th->vm       = vm;
   return self;
 }

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/yarvcore.h	2005-10-05 12:25:40 UTC (rev 275)
@@ -330,7 +330,6 @@
 
 typedef struct yarv_thread{
   VALUE self;
-  VALUE vm_value;
   yarv_vm_t *vm;
   
   /* execution information */
@@ -359,11 +358,11 @@
   yarv_thread_id_t thread_id;
   enum yarv_thread_status status;
   struct yarv_tag *tag;
+  
   VALUE value;
-  VALUE exception;
+  VALUE errinfo;
+  VALUE wait_thread_value;
 
-  struct yarv_thread *join_thread;
-
   VALUE first_proc;
   VALUE first_args;
 


--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]