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

ruby-changes:46259

From: nobu <ko1@a...>
Date: Mon, 17 Apr 2017 11:31:40 +0900 (JST)
Subject: [ruby-changes:46259] nobu:r58380 (trunk): eval.c: copy special exceptions before raise

nobu	2017-04-17 11:31:35 +0900 (Mon, 17 Apr 2017)

  New Revision: 58380

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=58380

  Log:
    eval.c: copy special exceptions before raise
    
    * eval.c (setup_exception): consider if the exception is frozen,
      but not one of special exception objects.
    
    * gc.c (rb_memerror): copy minimum objects.
    
    * thread.c (rb_threadptr_execute_interrupts): prepare special
      exception queued by another thread to be raised.

  Modified files:
    trunk/eval.c
    trunk/gc.c
    trunk/thread.c
Index: thread.c
===================================================================
--- thread.c	(revision 58379)
+++ thread.c	(revision 58380)
@@ -2071,6 +2071,10 @@ rb_threadptr_execute_interrupts(rb_threa https://github.com/ruby/ruby/blob/trunk/thread.c#L2071
 		rb_threadptr_to_kill(th);
 	    }
 	    else {
+		if (err == th->vm->special_exceptions[ruby_error_stream_closed]) {
+		    /* the only special exception to be queued accross thread */
+		    err = ruby_vm_special_exception_copy(err);
+		}
 		/* set runnable if th was slept. */
 		if (th->status == THREAD_STOPPED ||
 		    th->status == THREAD_STOPPED_FOREVER)
Index: eval.c
===================================================================
--- eval.c	(revision 58379)
+++ eval.c	(revision 58380)
@@ -464,23 +464,6 @@ exc_setup_cause(VALUE exc, VALUE cause) https://github.com/ruby/ruby/blob/trunk/eval.c#L464
     return exc;
 }
 
-static inline int
-sysstack_error_p(VALUE exc)
-{
-    return exc == sysstack_error || (!SPECIAL_CONST_P(exc) && RBASIC_CLASS(exc) == rb_eSysStackError);
-}
-
-static inline int
-special_exception_p(rb_thread_t *th, VALUE exc)
-{
-    enum ruby_special_exceptions i;
-    const VALUE *exceptions = th->vm->special_exceptions;
-    for (i = 0; i < ruby_special_error_count; ++i) {
-	if (exceptions[i] == exc) return TRUE;
-    }
-    return FALSE;
-}
-
 static void
 setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
 {
@@ -498,9 +481,6 @@ setup_exception(rb_thread_t *th, int tag https://github.com/ruby/ruby/blob/trunk/eval.c#L481
 	mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
 	nocause = 0;
     }
-    else if (special_exception_p(th, mesg)) {
-	mesg = ruby_vm_special_exception_copy(mesg);
-    }
     if (cause != Qundef) {
 	exc_setup_cause(mesg, cause);
     }
@@ -514,33 +494,24 @@ setup_exception(rb_thread_t *th, int tag https://github.com/ruby/ruby/blob/trunk/eval.c#L494
     file = rb_source_loc(&line);
     if (file && !NIL_P(mesg)) {
 	VALUE at;
-	if (sysstack_error_p(mesg)) {
-	    if (NIL_P(rb_attr_get(mesg, idBt))) {
-		at = rb_threadptr_backtrace_object(th);
-		rb_ivar_set(mesg, idBt, at);
-		rb_ivar_set(mesg, idBt_locations, at);
-	    }
-	}
-	else {
-	    int status;
+	int status;
 
-	    TH_PUSH_TAG(th);
-	    if ((status = EXEC_TAG()) == 0) {
-		VALUE bt;
-		if (rb_threadptr_set_raised(th)) goto fatal;
-		bt = rb_get_backtrace(mesg);
-		if (NIL_P(bt)) {
-		    at = rb_threadptr_backtrace_object(th);
-		    if (OBJ_FROZEN(mesg)) {
-			mesg = rb_obj_dup(mesg);
-		    }
-		    rb_ivar_set(mesg, idBt_locations, at);
-		    set_backtrace(mesg, at);
+	TH_PUSH_TAG(th);
+	if ((status = EXEC_TAG()) == 0) {
+	    VALUE bt;
+	    if (rb_threadptr_set_raised(th)) goto fatal;
+	    bt = rb_get_backtrace(mesg);
+	    if (NIL_P(bt)) {
+		at = rb_threadptr_backtrace_object(th);
+		if (OBJ_FROZEN(mesg)) {
+		    mesg = rb_obj_dup(mesg);
 		}
-		rb_threadptr_reset_raised(th);
+		rb_ivar_set(mesg, idBt_locations, at);
+		set_backtrace(mesg, at);
 	    }
-	    TH_POP_TAG();
+	    rb_threadptr_reset_raised(th);
 	}
+	TH_POP_TAG();
     }
 
     if (!NIL_P(mesg)) {
@@ -738,7 +709,6 @@ make_exception(int argc, const VALUE *ar https://github.com/ruby/ruby/blob/trunk/eval.c#L709
 	exc = argv[0];
 	n = 1;
       exception_call:
-	if (sysstack_error_p(exc)) return exc;
 	mesg = rb_check_funcall(exc, idException, n, argv+1);
 	if (mesg == Qundef) {
 	    rb_raise(rb_eTypeError, "exception class/object expected");
Index: gc.c
===================================================================
--- gc.c	(revision 58379)
+++ gc.c	(revision 58380)
@@ -7624,21 +7624,25 @@ rb_memerror(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L7624
 {
     rb_thread_t *th = GET_THREAD();
     rb_objspace_t *objspace = rb_objspace_of(th->vm);
+    VALUE exc;
 
     if (during_gc) gc_exit(objspace, "rb_memerror");
 
-    if (!nomem_error ||
+    exc = nomem_error;
+    if (!exc ||
 	rb_thread_raised_p(th, RAISED_NOMEMORY)) {
 	fprintf(stderr, "[FATAL] failed to allocate memory\n");
 	exit(EXIT_FAILURE);
     }
     if (rb_thread_raised_p(th, RAISED_NOMEMORY)) {
 	rb_thread_raised_clear(th);
-	GET_THREAD()->errinfo = nomem_error;
-	TH_JUMP_TAG(th, TAG_RAISE);
     }
-    rb_thread_raised_set(th, RAISED_NOMEMORY);
-    rb_exc_raise(nomem_error);
+    else {
+	rb_thread_raised_set(th, RAISED_NOMEMORY);
+	exc = ruby_vm_special_exception_copy(exc);
+    }
+    th->errinfo = exc;
+    TH_JUMP_TAG(th, TAG_RAISE);
 }
 
 static void *

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

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