summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-02-15 11:59:47 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-02-15 11:59:47 +0900
commit8efa7b00df2842eaff31cdabc95651a856e40549 (patch)
tree97463ecf5a55ab26a85303fc126f700dd557e9a5
parent0376d4d4c63140abfb45d119514a7049d286c141 (diff)
downloadmruby-8efa7b00df2842eaff31cdabc95651a856e40549.tar.gz
mruby-8efa7b00df2842eaff31cdabc95651a856e40549.zip
Preallocate SystemStackError; ref #3421
-rw-r--r--include/mruby.h2
-rw-r--r--src/backtrace.c2
-rw-r--r--src/error.c5
-rw-r--r--src/gc.c1
-rw-r--r--src/vm.c2
5 files changed, 7 insertions, 5 deletions
diff --git a/include/mruby.h b/include/mruby.h
index 6950cf904..8adce289b 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -221,6 +221,7 @@ typedef struct mrb_state {
struct RClass *eException_class;
struct RClass *eStandardError_class;
struct RObject *nomem_err; /* pre-allocated NoMemoryError */
+ struct RObject *stack_err; /* pre-allocated SysStackError */
#ifdef MRB_GC_FIXED_ARENA
struct RObject *arena_err; /* pre-allocated arena overfow error */
#endif
@@ -1110,7 +1111,6 @@ MRB_API void mrb_print_error(mrb_state *mrb);
#define E_SYNTAX_ERROR (mrb_exc_get(mrb, "SyntaxError"))
#define E_LOCALJUMP_ERROR (mrb_exc_get(mrb, "LocalJumpError"))
#define E_REGEXP_ERROR (mrb_exc_get(mrb, "RegexpError"))
-#define E_SYSSTACK_ERROR (mrb_exc_get(mrb, "SystemStackError"))
#define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError"))
#define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError"))
diff --git a/src/backtrace.c b/src/backtrace.c
index 051d5d4e0..529b0b1c9 100644
--- a/src/backtrace.c
+++ b/src/backtrace.c
@@ -263,7 +263,7 @@ mrb_print_backtrace(mrb_state *mrb)
{
mrb_value backtrace;
- if (!mrb->exc || mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), E_SYSSTACK_ERROR)) {
+ if (!mrb->exc) {
return;
}
diff --git a/src/error.c b/src/error.c
index a71ee548f..7916ca65b 100644
--- a/src/error.c
+++ b/src/error.c
@@ -532,7 +532,7 @@ mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt,
void
mrb_init_exception(mrb_state *mrb)
{
- struct RClass *exception, *runtime_error, *script_error;
+ struct RClass *exception, *runtime_error, *script_error, *stack_error;
mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION);
@@ -553,5 +553,6 @@ mrb_init_exception(mrb_state *mrb)
#endif
script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */
mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */
- mrb_define_class(mrb, "SystemStackError", exception);
+ stack_error = mrb_define_class(mrb, "SystemStackError", exception);
+ mrb->stack_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, stack_error, "stack level too deep"));
}
diff --git a/src/gc.c b/src/gc.c
index 1608dbcb2..63eab8e00 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -865,6 +865,7 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc)
}
/* mark pre-allocated exception */
mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err);
+ mrb_gc_mark(mrb, (struct RBasic*)mrb->stack_err);
#ifdef MRB_GC_FIXED_ARENA
mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err);
#endif
diff --git a/src/vm.c b/src/vm.c
index 8bb446fa9..91612a0da 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -162,7 +162,7 @@ stack_extend_alloc(mrb_state *mrb, int room, int keep)
to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */
if (size > MRB_STACK_MAX) {
init_new_stack_space(mrb, room, keep);
- mrb_raise(mrb, E_SYSSTACK_ERROR, "stack level too deep. (limit=" MRB_STRINGIZE(MRB_STACK_MAX) ")");
+ mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
}
}