#include <errno.h>
#endif
-#ifdef USE_LIBFFI
-#include <ffi.h>
-#endif
+#include "ffi.h"
/* --------------------------------------------------------------------------
* The bytecode interpreter
SpLim = cap->r.rCurrentTSO->stack + RESERVED_STACK_WORDS;
#define SAVE_STACK_POINTERS \
+ ASSERT(Sp > SpLim); \
cap->r.rCurrentTSO->sp = Sp
#define RETURN_TO_SCHEDULER(todo,retcode) \
goto defer_apply_to_sched;
}
+ // Stack check: we're about to unpack the PAP onto the
+ // stack. The (+1) is for the (arity < n) case, where we
+ // also need space for an extra info pointer.
+ if (Sp - (pap->n_args + 1) < SpLim) {
+ Sp -= 2;
+ Sp[1] = (W_)tagged_obj;
+ Sp[0] = (W_)&stg_enter_info;
+ RETURN_TO_SCHEDULER(ThreadInterpret, StackOverflow);
+ }
+
Sp++;
arity = pap->arity;
ASSERT(arity > 0);
So we make a copy of the argument block.
*/
-#ifdef USE_LIBFFI
#define ROUND_UP_WDS(p) ((((StgWord)(p)) + sizeof(W_)-1)/sizeof(W_))
ffi_cif *cif = (ffi_cif *)marshall_fn;
// this is the function we're going to call
fn = (void(*)(void))Sp[ret_size];
-#else
- W_ arguments[stk_offset];
- memcpy(arguments, Sp, sizeof(W_) * stk_offset);
-#endif
// Restore the Haskell thread's current value of errno
errno = cap->r.rCurrentTSO->saved_errno;
tok = suspendThread(&cap->r);
// We already made a copy of the arguments above.
-#ifdef USE_LIBFFI
ffi_call(cif, fn, ret, argptrs);
-#else
- marshall_fn ( arguments );
-#endif
// And restart the thread again, popping the RET_DYN frame.
cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - sizeof(StgFunTable)));
// Copy the return value back to the TSO stack. It is at
// most 2 words large, and resides at arguments[0].
-#ifdef USE_LIBFFI
memcpy(Sp, ret, sizeof(W_) * stg_min(stk_offset,ret_size));
-#else
- memcpy(Sp, arguments, sizeof(W_) * stg_min(stk_offset,2));
-#endif
goto nextInsn;
}