summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h1
-rw-r--r--mrblib/array.rb13
-rw-r--r--mrblib/hash.rb20
-rw-r--r--mrblib/kernel.rb5
-rw-r--r--src/backtrace.c3
-rw-r--r--src/error.c1
-rw-r--r--src/vm.c2
7 files changed, 35 insertions, 10 deletions
diff --git a/include/mruby.h b/include/mruby.h
index d91e024d1..5c99052c1 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -385,6 +385,7 @@ void mrb_print_error(mrb_state *mrb);
#define E_SYNTAX_ERROR (mrb_class_get(mrb, "SyntaxError"))
#define E_LOCALJUMP_ERROR (mrb_class_get(mrb, "LocalJumpError"))
#define E_REGEXP_ERROR (mrb_class_get(mrb, "RegexpError"))
+#define E_SYSSTACK_ERROR (mrb_class_get(mrb, "SystemStackError"))
#define E_NOTIMP_ERROR (mrb_class_get(mrb, "NotImplementedError"))
#define E_FLOATDOMAIN_ERROR (mrb_class_get(mrb, "FloatDomainError"))
diff --git a/mrblib/array.rb b/mrblib/array.rb
index 3218aa858..bd8d5930f 100644
--- a/mrblib/array.rb
+++ b/mrblib/array.rb
@@ -84,13 +84,20 @@ class Array
self
end
+ def _inspect
+ return "[]" if self.size == 0
+ "["+self.map{|x|x.inspect}.join(", ")+"]"
+ end
##
- # Private method for Array creation.
+ # Return the contents of this array as a string.
#
# ISO 15.2.12.5.31 (x)
def inspect
- return "[]" if self.size == 0
- "["+self.map{|x|x.inspect}.join(", ")+"]"
+ begin
+ self._inspect
+ rescue SystemStackError
+ "[...]"
+ end
end
# ISO 15.2.12.5.32 (x)
alias to_s inspect
diff --git a/mrblib/hash.rb b/mrblib/hash.rb
index 9bb146b27..e7c51fb1f 100644
--- a/mrblib/hash.rb
+++ b/mrblib/hash.rb
@@ -192,16 +192,24 @@ class Hash
h
end
- ##
- # Return the contents of this hash as a string.
- #
- # ISO 15.2.13.4.30 (x)
- def inspect
+ # internal method for Hash inspection
+ def _inspect
return "{}" if self.size == 0
"{"+self.map {|k,v|
- k.inspect + "=>" + v.inspect
+ k._inspect + "=>" + v._inspect
}.join(", ")+"}"
end
+ ##
+ # Return the contents of this hash as a string.
+ #
+ # ISO 15.2.13.4.30 (x)
+ def inspect
+ begin
+ self._inspect
+ rescue SystemStackError
+ "{...}"
+ end
+ end
# ISO 15.2.13.4.31 (x)
alias to_s inspect
diff --git a/mrblib/kernel.rb b/mrblib/kernel.rb
index d0fe47300..476ec8e18 100644
--- a/mrblib/kernel.rb
+++ b/mrblib/kernel.rb
@@ -39,6 +39,11 @@ module Kernel
!(self =~ y)
end
+ # internal method for inspect
+ def _inspect
+ self.inspect
+ end
+
def to_enum(*a)
raise NotImplementedError.new("fiber required for enumerator")
end
diff --git a/src/backtrace.c b/src/backtrace.c
index 1e1f9fa1a..737a350a9 100644
--- a/src/backtrace.c
+++ b/src/backtrace.c
@@ -147,6 +147,9 @@ exc_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun
void
mrb_print_backtrace(mrb_state *mrb)
{
+ if (mrb->exc || mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), E_SYSSTACK_ERROR)) {
+ return;
+ }
exc_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr);
}
diff --git a/src/error.c b/src/error.c
index dcb6063f8..d472f7f95 100644
--- a/src/error.c
+++ b/src/error.c
@@ -455,4 +455,5 @@ mrb_init_exception(mrb_state *mrb)
mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str(mrb, runtime_error, mrb_str_new_lit(mrb, "Out of memory")));
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);
}
diff --git a/src/vm.c b/src/vm.c
index 20a51eff4..33e8eefb3 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -160,7 +160,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_RUNTIME_ERROR, "stack level too deep. (limit=" TO_STR(MRB_STACK_MAX) ")");
+ mrb_raise(mrb, E_SYSSTACK_ERROR, "stack level too deep. (limit=" TO_STR(MRB_STACK_MAX) ")");
}
}