<div>Dear Marc,</div><div><br></div><div>Below A B C D are Scheme procedures and f g h are C procedures.</div><div><br></div><div>In case of nested Scheme->C calls, i.e. if A calls f which calls B which calls g which calls C which calls h which calls D etc., then for the application not to enter an undefined state, returning the C calls _MUST_ be done in the exact reverse order in order, right?</div>

<div>     I.e., D must return to h which must return to C which must return to g which must return to B which must return to f which must return to A.</div><div>     If any mixing of this order is done - i.e. D returns to g, or B returns to h, etc., then the application enters an undefined state, right, or how is it?</div>

<div><br></div><div>That is,</div><div> * Gambit in itself does not implement any blocking feature such that while g and h are still on the stack, a return from f to A would block until D returned to h and C returned to G</div>

<div> * Gambit does not implement any exception handling for trying to return in the wrong order, but if returning in the wrong order the application simply terminates at some point</div><div> * Gambit uses one ordinary C stack for all Scheme->C and C->Scheme calling, so it does not allocate a new C stack dynamically on the heap, or alike, for any Scheme->C call.</div>

<div><br></div><div>I experimented a bit with returning C->Scheme calls in the wrong order, and what happened was that at the LAST return I made, the application terminated. I suppose this is consistent with how it should be - the Gambit app may behave just about any way if you returned C->Scheme calls in the wrong order, as this messed up the C stack and the app is about to 'blow' just about any second. (I had A call f which called B which called g which called C which called h which called D, then D returned to g which returned to B which returned to h - and at h's return to Scheme the app terminated)</div>

<div><br></div><div>Also I suppose this is in line with the "19.7 Continuations and the C-interface" manual section and your paper <a href="http://www.iro.umontreal.ca/~feeley/papers/FeeleySW00.pdf"><font color="red"><b>MailScanner soupçonne le lien suivant d'être une tentative de fraude de la part de "www.iro.umontreal.ca" </b></font> http:/www.iro.umontreal.ca/~feeley/papers/FeeleySW00.pdf</a> , which I suppose Gambit implements.</div>

<div><br></div><div>Looking forward to get clear on this one :-)</div><div><br></div><div>Kind regards,</div><div>Mikael</div><div><br></div><div>test_c_stack_rewinding.scm :</div><div><div><br></div><div><div>(c-define (c-run thunk) (scheme-object) void "c_run" ""</div>

<div> (print "c-run entered for " thunk ".\n")</div><div> (thunk)</div><div> (print "c-run returned for " thunk ".\n"))</div><div><br></div><div>(define run-through-c (c-lambda (scheme-object) void "c_run(___arg1);"))</div>

<div><br></div><div>(define (thread-go id sleep-seconds)</div><div>  (thread-start!</div><div>   (make-thread (lambda ()</div><div>                  (print "thread " id " entered.\n")</div><div>                  (run-through-c (lambda ()</div>

<div>                                   (print "thread " id "'s c thunk entered.\n")</div><div>                                   (thread-sleep! sleep-seconds)</div><div>                                   (print "thread " id "'s c thunk returning.\n")))</div>

<div>                              (print "thread " id " returned.\n")))))</div></div><div><br></div><div><br></div><div>REPL interaction:<br><div>$ gsc</div><div>Gambit v4.5.3</div><div><br></div><div>

> (compile-file "test_c_stack_rewinding.scm")</div><div>> (load "test_c_stack_rewinding")</div><div><br></div><div><br></div><div>;; Test one simultaneous Scheme->C->Scheme call:</div><div>

> (thread-go 1 5)</div></div><div><div>#<thread #2></div><div>> thread 1 entered.</div><div>c-run entered for #<procedure #3>.</div><div>thread 1's c thunk entered.</div><div>1</div><div>1</div><div>

> thread 1's c thunk returning.</div><div>c-run returned for #<procedure #3>.</div><div>thread 1 returned.</div><div><br></div></div><div><br></div><div><br></div><div><div>;; Scheme->C->Scheme calls can be made many at a time, as long as the last one made returns first:</div>

<div>> (thread-go 3 10) (thread-sleep! 1) (thread-go 4 5)</div><div>#<thread #8></div><div>> thread 3 entered.</div><div>c-run entered for #<procedure #9>.</div><div>thread 3's c thunk entered.</div>

<div>> #<thread #10></div><div>> thread 4 entered.</div><div>c-run entered for #<procedure #11>.</div><div>thread 4's c thunk entered.</div><div>thread 4's c thunk returning.</div><div>c-run returned for #<procedure #11>.</div>

<div>thread 4 returned.</div><div><br></div><div><br></div><div>thread 3's c thunk returning.</div><div>c-run returned for #<procedure #9>.</div><div>thread 3 returned.</div><div><br></div></div><div><br></div>
<div>
<br></div><div><div>>  (thread-go 8 15) (thread-sleep! 1) (thread-go 9 10)  (thread-sleep! 1) (thread-go 10 5)</div><div>#<thread #2></div><div>> thread 8 entered.</div><div>c-run entered for #<procedure #3>.</div>

<div>thread 8's c thunk entered.</div><div>> #<thread #4></div><div>> thread 9 entered.</div><div>c-run entered for #<procedure #5>.</div><div>thread 9's c thunk entered.</div><div>> #<thread #6></div>

<div>> thread 10 entered.</div><div>c-run entered for #<procedure #7>.</div><div>thread 10's c thunk entered.</div><div>thread 10's c thunk returning.</div><div>c-run returned for #<procedure #7>.</div>

<div>thread 10 returned.</div><div>thread 9's c thunk returning.</div><div>c-run returned for #<procedure #5>.</div><div>thread 9 returned.</div><div>thread 8's c thunk returning.</div><div>c-run returned for #<procedure #3>.</div>

<div>thread 8 returned.</div><div><br></div></div><div><br></div><div><br></div><div>;; If C->Scheme calls return in another order then the app terminates</div><div><div>> (thread-go 5 5) (thread-sleep! 1) (thread-go 6 10)</div>

<div>#<thread #12></div><div>> thread 5 entered.</div><div>c-run entered for #<procedure #13>.</div><div>thread 5's c thunk entered.</div><div>> #<thread #14></div><div>></div><div>thread 6 entered.</div>

<div>c-run entered for #<procedure #15>.</div><div>thread 6's c thunk entered.</div><div>1</div><div>1</div><div>> thread 5's c thunk returning.</div><div>c-run returned for #<procedure #13>.</div>
<div>
thread 5 returned.</div><div><br></div><div><br></div><div>0</div><div>0</div><div>> thread 6's c thunk returning.</div><div>c-run returned for #<procedure #15>.</div></div><div>$</div><div><br></div></div><div>

<br></div><div><br></div><div><br></div><div><div>>  (thread-go 1 6) (thread-sleep! 1) (thread-go 2 12)  (thread-sleep! 1) (thread-go 3 9) (thread-sleep! 1) (thread-go 4 5)</div><div>#<thread #2></div><div>> thread 1 entered.</div>

<div>c-run entered for #<procedure #3>.</div><div>thread 1's c thunk entered.</div><div>> #<thread #4></div><div>> thread 2 entered.</div><div>c-run entered for #<procedure #5>.</div><div>thread 2's c thunk entered.</div>

<div>> #<thread #6></div><div>> thread 3 entered.</div><div>c-run entered for #<procedure #7>.</div><div>thread 3's c thunk entered.</div><div>> #<thread #8></div><div>> thread 4 entered.</div>

<div>c-run entered for #<procedure #9>.</div><div>thread 4's c thunk entered.</div><div>thread 1's c thunk returning.</div><div>c-run returned for #<procedure #3>.</div><div>thread 1 returned.</div><div>

thread 4's c thunk returning.</div><div>c-run returned for #<procedure #9>.</div></div><div>$</div><div><br></div>