+
+/* -----------------------------------------------------------------------------
+ Entry Code for an AP (a PAP with arity zero).
+
+ The entry code is very similar to a PAP, except there are no
+ further arguments on the stack to worry about, so the stack check
+ is simpler. We must also push an update frame on the stack before
+ applying the function.
+ -------------------------------------------------------------------------- */
+
+INFO_TABLE(stg_AP_info,stg_AP_entry,/*special layout*/0,0,AP,,EF_,"AP","AP");
+STGFUN(stg_AP_entry)
+{
+ nat Words;
+ P_ p;
+ nat i;
+ StgAP *ap;
+
+ FB_
+
+ ap = (StgAP *) R1.p;
+
+ Words = ap->n_args;
+
+ // Check for stack overflow. IMPORTANT: use a _NP check here,
+ // because if the check fails, we might end up blackholing this very
+ // closure, in which case we must enter the blackhole on return rather
+ // than continuing to evaluate the now-defunct closure.
+ STK_CHK_NP(Words+sizeofW(StgUpdateFrame),);
+
+ PUSH_UPD_FRAME(R1.p, 0);
+ Sp -= sizeofW(StgUpdateFrame) + Words;
+
+ TICK_ENT_AP(ap);
+ LDV_ENTER(ap);
+
+ // Enter PAP cost centre -- lexical scoping only
+ ENTER_CCS_PAP_CL(ap); /* ToDo: ENTER_CC_AP_CL */
+
+ R1.cl = ap->fun;
+ p = (P_)(ap->payload);
+
+ // Reload the stack
+ for (i=0; i<Words; i++) Sp[i] = (W_) *p++;
+
+ // Off we go!
+ TICK_ENT_VIA_NODE();
+
+#ifdef NO_ARG_REGS
+ JMP_(GET_ENTRY(R1.cl));
+#else
+ {
+ StgFunInfoTable *info;
+ info = get_fun_itbl(R1.cl);
+ if (info->fun_type == ARG_GEN || info->fun_type == ARG_GEN_BIG) {
+ JMP_(info->slow_apply);
+ } else if (info->fun_type == ARG_BCO) {
+ Sp -= 2;
+ Sp[1] = R1.w;
+ Sp[0] = (W_)&stg_apply_interp_info;
+ JMP_(stg_yield_to_interpreter);
+ } else {
+ JMP_(stg_ap_stack_entries[info->fun_type]);
+ }
+ }
+#endif
+ FE_
+}
+
+/* -----------------------------------------------------------------------------
+ Entry Code for an AP_STACK.
+
+ Very similar to a PAP and AP. The layout is the same as PAP
+ and AP, except that the payload is a chunk of stack instead of
+ being described by the function's info table. Like an AP,
+ there are no further arguments on the stack to worry about.
+ However, the function closure (ap->fun) does not necessarily point
+ directly to a function, so we have to enter it using stg_ap_0.
+ -------------------------------------------------------------------------- */
+
+INFO_TABLE(stg_AP_STACK_info,stg_AP_STACK_entry,/*special layout*/0,0,AP_STACK,,EF_,"AP_STACK","AP_STACK");
+STGFUN(stg_AP_STACK_entry)
+{
+ nat Words;
+ P_ p;
+ nat i;
+ StgAP_STACK *ap;
+
+ FB_
+
+ ap = (StgAP_STACK *) R1.p;
+
+ Words = ap->size;
+
+ // Check for stack overflow. IMPORTANT: use a _NP check here,
+ // because if the check fails, we might end up blackholing this very
+ // closure, in which case we must enter the blackhole on return rather
+ // than continuing to evaluate the now-defunct closure.
+ STK_CHK_NP(Words+sizeofW(StgUpdateFrame),);
+
+ PUSH_UPD_FRAME(R1.p, 0);
+ Sp -= sizeofW(StgUpdateFrame) + Words;
+
+ TICK_ENT_AP(ap);
+ LDV_ENTER(ap);
+
+ // Enter PAP cost centre -- lexical scoping only */
+ ENTER_CCS_PAP_CL(ap); /* ToDo: ENTER_CC_AP_STACK_CL */
+
+ R1.cl = ap->fun;
+ p = (P_)(ap->payload);
+
+ // Reload the stack
+ for (i=0; i<Words; i++) Sp[i] = (W_) *p++;
+
+ // Off we go!
+ TICK_ENT_VIA_NODE();
+ ENTER();
+ FE_
+}