PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/kits/scc/callcc.c

http://github.com/pablomarx/Thomas
C | 179 lines | 102 code | 17 blank | 60 comment | 16 complexity | 8763d9575a4b553bdfc09550f282bc73 MD5 | raw file
  1. /* SCHEME->C */
  2. /* Copyright 1989 Digital Equipment Corporation
  3. * All Rights Reserved
  4. *
  5. * Permission to use, copy, and modify this software and its documentation is
  6. * hereby granted only under the following terms and conditions. Both the
  7. * above copyright notice and this permission notice must appear in all copies
  8. * of the software, derivative works or modified versions, and any portions
  9. * thereof, and both notices must appear in supporting documentation.
  10. *
  11. * Users of this software agree to the terms and conditions set forth herein,
  12. * and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
  13. * right and license under any changes, enhancements or extensions made to the
  14. * core functions of the software, including but not limited to those affording
  15. * compatibility with other hardware or software environments, but excluding
  16. * applications which incorporate this software. Users further agree to use
  17. * their best efforts to return to Digital any such changes, enhancements or
  18. * extensions that they make and inform Digital of noteworthy uses of this
  19. * software. Correspondence should be provided to Digital at:
  20. *
  21. * Director of Licensing
  22. * Western Research Laboratory
  23. * Digital Equipment Corporation
  24. * 250 University Avenue
  25. * Palo Alto, California 94301
  26. *
  27. * This software may be distributed (but not offered for sale or transferred
  28. * for compensation) to third parties, provided such third parties agree to
  29. * abide by the terms and conditions of this notice.
  30. *
  31. * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  32. * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  33. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  34. * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  35. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  36. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  37. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  38. * SOFTWARE.
  39. */
  40. /* The following procedures implement CALL-WITH-CURRENT-CONTINUATION.
  41. CALLCCCONTINUING is the function that is executed when a continuation is
  42. applied. It is called with the result to be returned and the procedure's
  43. closure which is the continuation created by the initial call to
  44. TSC_CALLWITHCURRENTCONTINUATION. It will unwind the stack until the right
  45. return point is found. If it is not found, then it will restore the stack
  46. from the continuation(s). Once the stack is known to have the right
  47. contents, it will restore the correct state with longjmp.
  48. */
  49. /* External declarations */
  50. #include "objects.h"
  51. #include "scinit.h"
  52. #include "heap.h"
  53. #include "callcc.h"
  54. #include "apply.h"
  55. #include "signal.h"
  56. #ifdef MIPS
  57. extern sc_setsp();
  58. #endif
  59. #ifdef VAX
  60. #define longjmp( x, y ) sc_longjmp( x, y )
  61. #define setjmp( x ) sc_setjmp( x )
  62. #endif
  63. extern TSCP dynwind_new_2dcall_2fcc();
  64. TSCP sc_clink; /* Pointer to inner most continuation on stack. */
  65. /* Static declarations for data structures internal to the module. These
  66. variables may be static as they are only used under MUTEX. */
  67. static TSCP callccresult, /* Passes result across longjmp. */
  68. callcccp; /* Preserves cp during stack rebuilding. */
  69. static int *fp, /* Temps for constructing continuation */
  70. *tp,
  71. *tos,
  72. rcount,
  73. count;
  74. static callcccontinuing( result, cp )
  75. TSCP result, cp;
  76. {
  77. MUTEXON;
  78. callccresult = result;
  79. callcccp = cp;
  80. /* Unwind CLINK to see if this continuation is currently on the
  81. stack. */
  82. while (sc_clink != EMPTYLIST) {
  83. if (sc_clink == cp)
  84. longjmp( (T_U(cp))->continuation.savedstate, 1 );
  85. sc_clink = (T_U(sc_clink))->continuation.continuation;
  86. }
  87. /* Continuation is not currently on the stack, so transfer to it and
  88. it will restore the stack. */
  89. #ifdef MIPS
  90. sc_setsp( (T_U(callcccp))->continuation.address );
  91. #endif
  92. longjmp( (T_U(callcccp))->continuation.savedstate, 1 );
  93. }
  94. /* Use the call-with-current-continuation provided by dynamic-wind. Make the
  95. old call-with-current-continuation available for use from dynamic-wind.
  96. */
  97. TSCP sc_ntinuation_1af38b9f_v;
  98. TSCP sc_ntinuation_1af38b9f( function )
  99. TSCP function;
  100. {
  101. return( dynwind_new_2dcall_2fcc( function ) );
  102. }
  103. TSCP sc_old_2dcall_2fcc( function )
  104. TSCP function;
  105. {
  106. SCP cp; /* Pointer to the continuation */
  107. int *save_fp, /* Save static values across heap allocate */
  108. save_count;
  109. MUTEXON;
  110. if (sc_clink == EMPTYLIST)
  111. fp = sc_stackbase;
  112. else
  113. fp = (T_U(sc_clink))->continuation.address;
  114. count = ((unsigned)(fp)-(unsigned)(STACKPTR))/4;
  115. save_fp = fp;
  116. save_count = count;
  117. cp = sc_allocateheap( NULLCONTINUATIONSIZE+count+2+sc_maxdisplay,
  118. CONTINUATIONTAG,
  119. NULLCONTINUATIONSIZE+count+sc_maxdisplay );
  120. fp = save_fp;
  121. count = save_count;
  122. tos = STACKPTR;
  123. cp->continuation.continuation = sc_clink;
  124. cp->continuation.stacktrace = sc_stacktrace;
  125. sc_clink = U_TX( cp );
  126. cp->continuation.address = tos;
  127. tp = &cp->continuation.word0;
  128. rcount = sc_maxdisplay;
  129. while (rcount--) *tp++ = (int)sc_display[ rcount ];
  130. while (count--) *tp++ = *tos++;
  131. MUTEXOFF;
  132. if (setjmp( cp->continuation.savedstate ) == 0) {
  133. callccresult = sc_apply_2dtwo( function,
  134. sc_cons( sc_makeprocedure( 1, 0,
  135. callcccontinuing,
  136. U_TX( cp ) ),
  137. EMPTYLIST ) );
  138. sc_clink = T_U( sc_clink )->continuation.continuation;
  139. return( callccresult );
  140. }
  141. /* Return here when the continuation is invoked. */
  142. if (sc_clink == EMPTYLIST) {
  143. sc_clink = callcccp;
  144. while (sc_clink != EMPTYLIST) {
  145. tp = (T_U(sc_clink))->continuation.address;
  146. fp = &(T_U(sc_clink))->continuation.word0+sc_maxdisplay;
  147. count = (T_U(sc_clink))->continuation.length-sc_maxdisplay-
  148. NULLCONTINUATIONSIZE;
  149. while (count--) *tp++ = *fp++;
  150. sc_clink = (T_U(sc_clink))->continuation.continuation;
  151. }
  152. }
  153. tp = &T_U( callcccp )->continuation.word0;
  154. rcount = sc_maxdisplay;
  155. while (rcount--) sc_display[ rcount ] = (TSCP)(*tp++);
  156. sc_clink = T_U( callcccp )->continuation.continuation;
  157. sc_stacktrace = T_U( callcccp )->continuation.stacktrace;
  158. /* Move result onto the stack under mutex */
  159. function = callccresult;
  160. MUTEXOFF;
  161. return( function );
  162. }