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

ruby-changes:68048

From: Samuel <ko1@a...>
Date: Mon, 20 Sep 2021 15:31:03 +0900 (JST)
Subject: [ruby-changes:68048] 88ba5fe547 (master): Expose `rb_fiber_raise` and tidy up the internal implementation.

https://git.ruby-lang.org/ruby.git/commit/?id=88ba5fe547

From 88ba5fe547cae2370eccbe230754f59e1d5cbaf3 Mon Sep 17 00:00:00 2001
From: Samuel Williams <samuel.williams@o...>
Date: Wed, 14 Jul 2021 13:42:18 +1200
Subject: Expose `rb_fiber_raise` and tidy up the internal implementation.

---
 cont.c                              | 165 ++++++++++++++++++++----------------
 include/ruby/internal/intern/cont.h |   2 +
 2 files changed, 96 insertions(+), 71 deletions(-)

diff --git a/cont.c b/cont.c
index 164e9c7..b947c61 100644
--- a/cont.c
+++ b/cont.c
@@ -235,7 +235,7 @@ struct rb_fiber_struct { https://github.com/ruby/ruby/blob/trunk/cont.c#L235
     rb_context_t cont;
     VALUE first_proc;
     struct rb_fiber_struct *prev;
-    VALUE resuming_fiber;
+    struct rb_fiber_struct *resuming_fiber;
 
     BITFIELD(enum fiber_status, status, 2);
     /* Whether the fiber is allowed to implicitly yield. */
@@ -2174,7 +2174,7 @@ return_fiber(bool terminate) https://github.com/ruby/ruby/blob/trunk/cont.c#L2174
 
     if (prev) {
         fiber->prev = NULL;
-        prev->resuming_fiber = Qnil;
+        prev->resuming_fiber = NULL;
         return prev;
     }
     else {
@@ -2188,9 +2188,7 @@ return_fiber(bool terminate) https://github.com/ruby/ruby/blob/trunk/cont.c#L2188
         VM_ASSERT(root_fiber != NULL);
 
         // search resuming fiber
-        for (fiber = root_fiber;
-             RTEST(fiber->resuming_fiber);
-             fiber = fiber_ptr(fiber->resuming_fiber)) {
+        for (fiber = root_fiber; fiber->resuming_fiber; fiber = fiber->resuming_fiber) {
         }
 
         return fiber;
@@ -2231,7 +2229,7 @@ fiber_store(rb_fiber_t *next_fiber, rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/cont.c#L2229
 }
 
 static inline VALUE
-fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, VALUE resuming_fiber, bool yielding)
+fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, rb_fiber_t *resuming_fiber, bool yielding)
 {
     VALUE value;
     rb_context_t *cont = &fiber->cont;
@@ -2278,8 +2276,9 @@ fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, VALUE https://github.com/ruby/ruby/blob/trunk/cont.c#L2276
 
     rb_fiber_t *current_fiber = fiber_current();
 
-    VM_ASSERT(!RTEST(current_fiber->resuming_fiber));
-    if (RTEST(resuming_fiber)) {
+    VM_ASSERT(!current_fiber->resuming_fiber);
+
+    if (resuming_fiber) {
         current_fiber->resuming_fiber = resuming_fiber;
         fiber->prev = fiber_current();
         fiber->yielding = 0;
@@ -2302,7 +2301,7 @@ fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, VALUE https://github.com/ruby/ruby/blob/trunk/cont.c#L2301
 
     // We cannot free the stack until the pthread is joined:
 #ifndef COROUTINE_PTHREAD_CONTEXT
-    if (RTEST(resuming_fiber) && FIBER_TERMINATED_P(fiber)) {
+    if (resuming_fiber && FIBER_TERMINATED_P(fiber)) {
         fiber_stack_release(fiber);
     }
 #endif
@@ -2324,7 +2323,7 @@ fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, VALUE https://github.com/ruby/ruby/blob/trunk/cont.c#L2323
 VALUE
 rb_fiber_transfer(VALUE fiber_value, int argc, const VALUE *argv)
 {
-    return fiber_switch(fiber_ptr(fiber_value), argc, argv, RB_NO_KEYWORDS, Qfalse, false);
+    return fiber_switch(fiber_ptr(fiber_value), argc, argv, RB_NO_KEYWORDS, NULL, false);
 }
 
 /*
@@ -2399,15 +2398,14 @@ rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt, VALUE error) https://github.com/ruby/ruby/blob/trunk/cont.c#L2398
     if (need_interrupt) RUBY_VM_SET_INTERRUPT(&next_fiber->cont.saved_ec);
 
     if (RTEST(error))
-        fiber_switch(next_fiber, -1, &error, RB_NO_KEYWORDS, Qfalse, false);
+        fiber_switch(next_fiber, -1, &error, RB_NO_KEYWORDS, NULL, false);
     else
-        fiber_switch(next_fiber, 1, &value, RB_NO_KEYWORDS, Qfalse, false);
+        fiber_switch(next_fiber, 1, &value, RB_NO_KEYWORDS, NULL, false);
 }
 
-VALUE
-rb_fiber_resume_kw(VALUE fiber_value, int argc, const VALUE *argv, int kw_splat)
+static VALUE
+fiber_resume_kw(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat)
 {
-    rb_fiber_t *fiber = fiber_ptr(fiber_value);
     rb_fiber_t *current_fiber = fiber_current();
 
     if (argc == -1 && FIBER_CREATED_P(fiber)) {
@@ -2422,7 +2420,7 @@ rb_fiber_resume_kw(VALUE fiber_value, int argc, const VALUE *argv, int kw_splat) https://github.com/ruby/ruby/blob/trunk/cont.c#L2420
     else if (fiber->prev != NULL) {
         rb_raise(rb_eFiberError, "attempt to resume a resumed fiber (double resume)");
     }
-    else if (RTEST(fiber->resuming_fiber)) {
+    else if (fiber->resuming_fiber) {
         rb_raise(rb_eFiberError, "attempt to resume a resuming fiber");
     }
     else if (fiber->prev == NULL &&
@@ -2430,27 +2428,33 @@ rb_fiber_resume_kw(VALUE fiber_value, int argc, const VALUE *argv, int kw_splat) https://github.com/ruby/ruby/blob/trunk/cont.c#L2428
         rb_raise(rb_eFiberError, "attempt to resume a transferring fiber");
     }
 
-    VALUE result = fiber_switch(fiber, argc, argv, kw_splat, fiber_value, false);
+    VALUE result = fiber_switch(fiber, argc, argv, kw_splat, fiber, false);
 
     return result;
 }
 
 VALUE
-rb_fiber_resume(VALUE fiber_value, int argc, const VALUE *argv)
+rb_fiber_resume_kw(VALUE self, int argc, const VALUE *argv, int kw_splat)
 {
-    return rb_fiber_resume_kw(fiber_value, argc, argv, RB_NO_KEYWORDS);
+    return fiber_resume_kw(fiber_ptr(self), argc, argv, kw_splat);
+}
+
+VALUE
+rb_fiber_resume(VALUE self, int argc, const VALUE *argv)
+{
+    return fiber_resume_kw(fiber_ptr(self), argc, argv, RB_NO_KEYWORDS);
 }
 
 VALUE
 rb_fiber_yield_kw(int argc, const VALUE *argv, int kw_splat)
 {
-    return fiber_switch(return_fiber(false), argc, argv, kw_splat, Qfalse, true);
+    return fiber_switch(return_fiber(false), argc, argv, kw_splat, NULL, true);
 }
 
 VALUE
 rb_fiber_yield(int argc, const VALUE *argv)
 {
-    return fiber_switch(return_fiber(false), argc, argv, RB_NO_KEYWORDS, Qfalse, true);
+    return fiber_switch(return_fiber(false), argc, argv, RB_NO_KEYWORDS, NULL, true);
 }
 
 void
@@ -2498,43 +2502,6 @@ rb_fiber_m_resume(int argc, VALUE *argv, VALUE fiber) https://github.com/ruby/ruby/blob/trunk/cont.c#L2502
 
 /*
  *  call-seq:
- *     fiber.raise                                 -> obj
- *     fiber.raise(string)                         -> obj
- *     fiber.raise(exception [, string [, array]]) -> obj
- *
- *  Raises an exception in the fiber at the point at which the last
- *  +Fiber.yield+ was called. If the fiber has not been started or has
- *  already run to completion, raises +FiberError+. If the fiber is
- *  yielding, it is resumed. If it is transferring, it is transferred into.
- *  But if it is resuming, raises +FiberError+.
- *
- *  With no arguments, raises a +RuntimeError+. With a single +String+
- *  argument, raises a +RuntimeError+ with the string as a message.  Otherwise,
- *  the first parameter should be the name of an +Exception+ class (or an
- *  object that returns an +Exception+ object when sent an +exception+
- *  message). The optional second parameter sets the message associated with
- *  the exception, and the third parameter is an array of callback information.
- *  Exceptions are caught by the +rescue+ clause of <code>begin...end</code>
- *  blocks.
- */
-static VALUE
-rb_fiber_raise(int argc, VALUE *argv, VALUE fiber_value)
-{
-    rb_fiber_t *fiber = fiber_ptr(fiber_value);
-    VALUE exc = rb_make_exception(argc, argv);
-    if (RTEST(fiber->resuming_fiber)) {
-        rb_raise(rb_eFiberError, "attempt to raise a resuming fiber");
-    }
-    else if (FIBER_SUSPENDED_P(fiber) && !fiber->yielding) {
-        return rb_fiber_transfer_kw(fiber_value, -1, &exc, RB_NO_KEYWORDS);
-    }
-    else {
-        return rb_fiber_resume_kw(fiber_value, -1, &exc, RB_NO_KEYWORDS);
-    }
-}
-
-/*
- *  call-seq:
  *     fiber.backtrace -> array
  *     fiber.backtrace(start) -> array
  *     fiber.backtrace(start, count) -> array
@@ -2693,22 +2660,29 @@ rb_fiber_backtrace_locations(int argc, VALUE *argv, VALUE fiber) https://github.com/ruby/ruby/blob/trunk/cont.c#L2660
  *
  */
 static VALUE
-rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fiber_value)
+rb_fiber_m_transfer(int argc, VALUE *argv, VALUE self)
 {
-    return rb_fiber_transfer_kw(fiber_value, argc, argv, rb_keyword_given_p());
+    return rb_fiber_transfer_kw(self, argc, argv, rb_keyword_given_p());
+}
+
+static VALUE
+fiber_transfer_kw(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat)
+{
+  if (fiber->resuming_fiber) {
+      rb_raise(rb_eFiberError, "attempt to transfer to a resuming fiber");
+  }
+
+  if (fiber->yielding) {
+      rb_raise(rb_eFiberError, "attempt to transfer to a yielding fiber");
+  }
+
+  return fiber_switch(fiber, argc, argv, kw_splat, NULL, false);
 }
 
 VALUE
-rb_fiber_transfer_kw(VALUE fiber_value, int argc, const VALUE *argv, int kw_splat)
+rb_fiber_transfer_kw(VALUE self, int argc, const VALUE *argv, int kw_splat)
 {
-    rb_fiber_t *fiber = fiber_ptr(fiber_value);
-    if (RTEST(fiber->resuming_fiber)) {
-        rb_raise(rb_eFiberError, "attempt to transfer to a resuming fiber");
-    }
-    if (fiber->yielding) {
-        rb_raise(rb_eFiberError, "attempt to transfer to a yielding fiber");
-    }
-    return fiber_switch(fiber, argc, argv, kw_splat, Qfalse, false);
+    return fiber_transfer_kw(fiber_ptr(self), argc, argv, kw_splat);
 }
 
 /*
@@ -2727,6 +2701,55 @@ rb_fiber_s_yield(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/cont.c#L2701
     return rb_fiber_yield_kw(argc, argv, rb_keyword_given_p());
 }
 
+static VALUE
+fiber_raise(rb_fiber_t *fiber, int argc, VALUE *argv)
+{
+    VALUE exception = rb_make_exception(argc, argv);
+
+    if (fiber->resuming_fiber) {
+        rb_raise(rb_eFiberError, "attempt to raise a resuming fiber");
+    }
+    else if (FIBER_SUSPENDED_P(fiber) && !fiber->yielding) {
+        ret (... truncated)

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

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