aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.mk1
-rw-r--r--error.c39
-rw-r--r--gc.c29
3 files changed, 46 insertions, 23 deletions
diff --git a/common.mk b/common.mk
index ff56a0c93f..236d40ed04 100644
--- a/common.mk
+++ b/common.mk
@@ -1942,6 +1942,7 @@ error.$(OBJEXT): $(CCAN_DIR)/list/list.h
error.$(OBJEXT): $(CCAN_DIR)/str/str.h
error.$(OBJEXT): $(hdrdir)/ruby.h
error.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+error.$(OBJEXT): $(hdrdir)/ruby/thread.h
error.$(OBJEXT): {$(VPATH)}assert.h
error.$(OBJEXT): {$(VPATH)}config.h
error.$(OBJEXT): {$(VPATH)}defines.h
diff --git a/error.c b/error.c
index e29910ae92..3a63a5f2a9 100644
--- a/error.c
+++ b/error.c
@@ -11,6 +11,7 @@
#include "ruby/encoding.h"
#include "ruby/st.h"
+#include "ruby/thread.h"
#include "internal.h"
#include "ruby_assert.h"
#include "vm_core.h"
@@ -2604,16 +2605,46 @@ rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
rb_exc_raise(rb_exc_new3(exc, mesg));
}
+struct rb_raise_tag {
+ VALUE exc;
+ const char *fmt;
+ va_list *args;
+};
+
+static void *
+rb_vraise(void *ptr)
+{
+ struct rb_raise_tag *argv = ptr;
+ VALUE msg = rb_vsprintf(argv->fmt, *argv->args);
+ VALUE exc = rb_exc_new3(argv->exc, msg);
+ rb_exc_raise(exc);
+ UNREACHABLE_RETURN(NULL);
+}
+
void
rb_raise(VALUE exc, const char *fmt, ...)
{
va_list args;
- VALUE mesg;
-
va_start(args, fmt);
- mesg = rb_vsprintf(fmt, args);
+ struct rb_raise_tag argv = {
+ exc, fmt, &args,
+ };
+
+ if (ruby_thread_has_gvl_p()) {
+ rb_vraise(&argv);
+ UNREACHABLE;
+ }
+ else if (ruby_native_thread_p()) {
+ rb_thread_call_with_gvl(rb_vraise, &argv);
+ UNREACHABLE;
+ }
+ else {
+ /* Not in a ruby thread */
+ vfprintf(stderr, fmt, args);
+ abort();
+ }
+
va_end(args);
- rb_exc_raise(rb_exc_new3(exc, mesg));
}
NORETURN(static void raise_loaderror(VALUE path, VALUE mesg));
diff --git a/gc.c b/gc.c
index f4292370a0..cc4ea12250 100644
--- a/gc.c
+++ b/gc.c
@@ -172,6 +172,9 @@ size_mul_or_raise(size_t x, size_t y, VALUE exc)
if (LIKELY(!t.left)) {
return t.right;
}
+ else if (rb_during_gc()) {
+ rb_memerror(); /* or...? */
+ }
else {
rb_raise(
exc,
@@ -195,6 +198,9 @@ size_mul_add_or_raise(size_t x, size_t y, size_t z, VALUE exc)
if (LIKELY(!t.left)) {
return t.right;
}
+ else if (rb_during_gc()) {
+ rb_memerror(); /* or...? */
+ }
else {
rb_raise(
exc,
@@ -219,6 +225,9 @@ size_mul_add_mul_or_raise(size_t x, size_t y, size_t z, size_t w, VALUE exc)
if (LIKELY(!t.left)) {
return t.right;
}
+ else if (rb_during_gc()) {
+ rb_memerror(); /* or...? */
+ }
else {
rb_raise(
exc,
@@ -9590,28 +9599,10 @@ objspace_reachable_objects_from_root(rb_objspace_t *objspace, void (func)(const
static void objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t size);
-static void *
-negative_size_allocation_error_with_gvl(void *ptr)
-{
- rb_raise(rb_eNoMemError, "%s", (const char *)ptr);
- return 0; /* should not be reached */
-}
-
static void
negative_size_allocation_error(const char *msg)
{
- if (ruby_thread_has_gvl_p()) {
- rb_raise(rb_eNoMemError, "%s", msg);
- }
- else {
- if (ruby_native_thread_p()) {
- rb_thread_call_with_gvl(negative_size_allocation_error_with_gvl, (void *)msg);
- }
- else {
- fprintf(stderr, "[FATAL] %s\n", msg);
- exit(EXIT_FAILURE);
- }
- }
+ rb_raise(rb_eNoMemError, "%s", msg);
}
static void *