-USING: kernel math namespaces io tools.test sequences vectors
-continuations debugger parser memory arrays words
-kernel.private accessors eval ;
+USING: accessors arrays continuations debugger eval io kernel kernel.private
+math memory namespaces parser sequences system tools.test vectors words ;
IN: continuations.tests
: (callcc1-test) ( n obj -- n' obj )
! : callstack-overflow callstack-overflow f ;
! [ callstack-overflow ] must-fail
+! This tries to verify that enough bytes are cut off from the
+! callstack to run the error handler.
+: pre ( -- ) nano-count 0 = [ ] [ ] if ;
+
+: post ( -- ) ;
+
+: do-overflow ( -- )
+ pre do-overflow post ;
+
+: recurse ( -- ? )
+ [ do-overflow f ] [ ] recover
+ second ERROR-CALLSTACK-OVERFLOW = ;
+
+os windows? [
+ { t } [
+ 10 [ recurse ] replicate [ ] all?
+ ] unit-test
+] unless
+
: don't-compile-me ( -- ) ;
: foo ( -- ) callstack "c" set don't-compile-me ;
: bar ( -- a b ) 1 foo 2 ;
OBJ_IN_CALLBACK_P,
};
-static const cell stack_reserved = 1024;
+/* When the callstack fills up (e.g by to deep recursion), a callstack
+ overflow error is triggered. So before continuing executing on it
+ in general_error(), we chop of this many bytes to have some space
+ to work with. */
+static const cell stack_reserved = 4096;
struct context {
namespace factor {
void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
- if (!code->seg->in_segment_p(*pc) ||
- *sp < ctx->callstack_seg->start + stack_reserved) {
+
+ cell callstack_limit = ctx->callstack_seg->start + stack_reserved;
+ if (!code->seg->in_segment_p(*pc) || *sp < callstack_limit) {
/* Fault came from the VM, foreign code, a callstack overflow, or
we don't have enough callstack room to try the resumable
handler. Cut the callstack down to the shallowest Factor stack
cell frame_top = ctx->callstack_top;
- while (frame_top < ctx->callstack_bottom &&
- frame_top < ctx->callstack_seg->start + stack_reserved) {
+ while (frame_top < ctx->callstack_bottom && frame_top < callstack_limit) {
frame_top = frame_predecessor(frame_top);
}