else
{
SCM string = char_pointer_to_string (*ptr);
- set_alien_address ((ARG_REF (1)), (ptr + 1)); /* No more aborts! */
+ set_alien_address ((ARG_REF (1)), (ptr + 1));
PRIMITIVE_RETURN (string);
}
}
/* All the smarts are in the trampolines. */
PRIMITIVE_HEADER (LEXPR);
- canonicalize_primitive_context ();
{
CalloutTrampOut tramp;
callout_seal (CalloutTrampIn tramp)
{
/* Used in a callout part1 trampoline. Arrange for subsequent
- aborts to start part2.
-
- Seal the CStack, substitute the C-CALL-CONTINUE primitive for
- the C-CALL primitive, and back out. The tramp can then execute
- the toolkit function safely, even if there is a callback. */
+ aborts to start part2. */
if (c_call_continue == SHARP_F)
{
CSTACK_PUSH (int, cstack_depth);
CSTACK_PUSH (CalloutTrampIn, tramp);
- /* Back out of C-CALL-CONTINUE. */
SET_PRIMITIVE (c_call_continue);
- back_out_of_primitive ();
alienate_float_environment ();
}
callout_continue (CalloutTrampIn tramp)
{
/* Re-seal the CStack frame over the C results (again, pushing the
- cstack_depth and callout-part2) and abort. Restart as
- C-CALL-CONTINUE and run callout-part2. */
+ cstack_depth and callout-part2) and call the restartable tramp.
+ If it aborts, it restarts as C-CALL-CONTINUE and retries
+ part2. */
+ SCM val;
+
CSTACK_PUSH (int, cstack_depth);
CSTACK_PUSH (CalloutTrampIn, tramp);
-#if 1
- PRIMITIVE_ABORT (PRIM_POP_RETURN);
- /* NOTREACHED */
-#else
- /* Just call; do not actually abort. */
-
- /* This is fubared by a GC during a callback. callback_run_kernel
- probably needs to use something like apply_compiled_from_
- primitive for this to work... */
-
- /* Remove stack sealant created by callout_seal (which used
- back_out_of_primitive), as if removed by pop_return in Interp()
- after the abort. */
- SET_PRIMITIVE (SHARP_F); /* PROCEED_AFTER_PRIMITIVE (); */
- RESTORE_CONT ();
- assert (RC_INTERNAL_APPLY == (OBJECT_DATUM(GET_RET)));
- SET_LEXPR_ACTUALS (APPLY_FRAME_N_ARGS ());
- stack_pointer = (APPLY_FRAME_ARGS ());
- SET_EXP (APPLY_FRAME_PROCEDURE ());
- /* APPLY_PRIMITIVE_FROM_INTERPRETER (Function); */
- /* Prim_c_call_continue(); */
- return (tramp ());
-#endif
+ val = tramp ();
+ return (val);
}
DEFINE_PRIMITIVE ("C-CALL-CONTINUE", Prim_c_call_continue, 1, LEXPR, 0)
/* Callbacks */
static SCM run_callback = SHARP_F;
-static SCM return_to_c = SHARP_F;
+extern SCHEME_OBJECT Re_Enter_Interpreter (void);
+#ifdef CC_IS_NATIVE
+extern void * C_Frame_Pointer;
+extern void * C_Stack_Pointer;
+#endif
void
callback_run_kernel (long callback_id, CallbackKernel kernel)
{
- /* Used by callback trampolines.
-
- Expect the args on the CStack. Push a couple primitive apply
- frames on the Scheme stack and seal the CStack. Then call
- Interpret(). Cannot abort. */
+ /* Used by callback trampolines after saving the callback args on
+ the CStack. */
+ SCM primitive, prim_lexpr, * sp;
+ SCM * callers_last_return_code;
+#ifdef CC_IS_NATIVE
+ void * cfp = C_Frame_Pointer;
+ void * csp = C_Stack_Pointer;
+#endif
if (run_callback == SHARP_F)
{
run_callback = find_primitive_cname ("RUN-CALLBACK", false, false, 0);
- return_to_c = find_primitive_cname ("RETURN-TO-C", false, false, 0);
- if (run_callback == SHARP_F || return_to_c == SHARP_F)
+ if (run_callback == SHARP_F)
{
outf_error_line
("\nWarning: punted callback #%ld. Missing primitives!",
}
}
- /* Need to push 2 each of prim+header+continuation. */
- if (! CAN_PUSH_P (2 * (1 + 1 + CONTINUATION_SIZE)))
- {
- outf_error_line
- ("\nWarning: punted callback #%ld. No room on stack!", callback_id);
- SET_VAL (FIXNUM_ZERO);
- return;
- }
-
cstack_depth += 1;
CSTACK_PUSH (int, cstack_depth);
CSTACK_PUSH (CallbackKernel, kernel);
- STACK_PUSH (return_to_c);
- PUSH_APPLY_FRAME_HEADER (0);
- SET_RC (RC_INTERNAL_APPLY);
- SAVE_CONT();
+ primitive = GET_PRIMITIVE;
+ prim_lexpr = GET_LEXPR_ACTUALS;
+ callers_last_return_code = last_return_code;
+
+ if (! (PRIMITIVE_P (primitive)))
+ abort_to_interpreter (ERR_CANNOT_RECURSE);
+ /*NOTREACHED*/
+ assert (primitive == c_call_continue);
+ sp = stack_pointer;
+
+ Will_Push ((2 * CONTINUATION_SIZE) + STACK_ENV_EXTRA_SLOTS + 1);
+ SET_RC (RC_END_OF_COMPUTATION);
+ SET_EXP (primitive);
+ SAVE_CONT ();
STACK_PUSH (run_callback);
PUSH_APPLY_FRAME_HEADER (0);
- SAVE_CONT();
- Interpret (1);
- alienate_float_environment ();
+ SET_RC (RC_INTERNAL_APPLY);
+ SET_EXP (SHARP_F);
+ SAVE_CONT ();
+ Pushed ();
+ Re_Enter_Interpreter ();
+
+ if (stack_pointer != sp)
+ signal_error_from_primitive (ERR_STACK_HAS_SLIPPED);
+ /*NOTREACHED*/
+
+ last_return_code = callers_last_return_code;
+ SET_LEXPR_ACTUALS (prim_lexpr);
+ SET_PRIMITIVE (primitive);
+#ifdef CC_IS_NATIVE
+ C_Frame_Pointer = cfp;
+ C_Stack_Pointer = csp;
+#endif
+
cstack_depth -= 1;
}
}
}
-DEFINE_PRIMITIVE ("RETURN-TO-C", Prim_return_to_c, 0, 0, 0)
-{
- /* Callbacks are possible while stopped. The PRIM_RETURN_TO_C abort
- expects this primitive to clean up its stack frame. */
-
- PRIMITIVE_HEADER (0);
- canonicalize_primitive_context ();
- {
- SCM primitive;
- long nargs;
-
- primitive = GET_PRIMITIVE;
- assert (PRIMITIVE_P (primitive));
- nargs = (PRIMITIVE_N_ARGUMENTS (primitive));
- POP_PRIMITIVE_FRAME (nargs);
- SET_EXP (SHARP_F);
- PRIMITIVE_ABORT (PRIM_RETURN_TO_C);
- /* NOTREACHED */
- PRIMITIVE_RETURN (UNSPECIFIC);
- }
-}
-
/* This is mainly for src/glib/glibio.c, so it does not need to include
prim.h, scheme.h and everything. */
void