[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / rts / Interpreter.c
index 79b883b..cd7ab13 100644 (file)
@@ -4,12 +4,7 @@
  * Copyright (c) The GHC Team, 1994-2002.
  * ---------------------------------------------------------------------------*/
 
-#if !defined(SMP)
 #include "PosixSource.h"
-#else
-/* Hack and slash.. */
-#include "Stg.h"
-#endif
 #include "Rts.h"
 #include "RtsAPI.h"
 #include "RtsUtils.h"
 #include "Storage.h"
 #include "Updates.h"
 #include "Sanity.h"
+#include "Liveness.h"
 
 #include "Bytecodes.h"
 #include "Printer.h"
 #include "Disassembler.h"
 #include "Interpreter.h"
 
+#include <string.h>     /* for memcpy */
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
 
 /* --------------------------------------------------------------------------
  * The bytecode interpreter
    return (retcode);
 
 
-static inline StgPtr
+STATIC_INLINE StgPtr
 allocate_UPD (int n_words)
 {
    return allocate(stg_max(sizeofW(StgHeader)+MIN_UPD_SIZE, n_words));
 }
 
-static inline StgPtr
+STATIC_INLINE StgPtr
 allocate_NONUPD (int n_words)
 {
     return allocate(stg_max(sizeofW(StgHeader)+MIN_NONUPD_SIZE, n_words));
@@ -160,7 +161,6 @@ static StgWord app_ptrs_itbl[] = {
     (W_)&stg_ap_pppp_info,
     (W_)&stg_ap_ppppp_info,
     (W_)&stg_ap_pppppp_info,
-    (W_)&stg_ap_ppppppp_info
 };
 
 StgThreadReturnCode
@@ -274,7 +274,7 @@ eval_obj:
        break;
        
     case BCO:
-       ASSERT(BCO_ARITY(obj) > 0);
+       ASSERT(((StgBCO *)obj)->arity > 0);
        break;
 
     case AP:   /* Copied from stg_AP_entry. */
@@ -395,9 +395,6 @@ do_return:
        if (info == (StgInfoTable *)&stg_ap_pppppp_info) {
            n = 6; m = 6; goto do_apply;
        }
-       if (info == (StgInfoTable *)&stg_ap_ppppppp_info) {
-           n = 7; m = 7; goto do_apply;
-       }
        goto do_return_unrecognised;
     }
 
@@ -576,7 +573,7 @@ do_apply:
            nat arity, i;
 
            Sp++;
-           arity = BCO_ARITY(obj);
+           arity = ((StgBCO *)obj)->arity;
            ASSERT(arity > 0);
            if (arity < n) {
                // n must be greater than 1, and the only kinds of
@@ -718,7 +715,7 @@ run_BCO:
     {
        register int       bciPtr     = 1; /* instruction pointer */
        register StgBCO*   bco        = (StgBCO*)obj;
-       register StgWord16* instrs    = (StgWord16*)(BCO_INSTRS(bco));
+       register StgWord16* instrs    = (StgWord16*)(bco->instrs->payload);
        register StgWord*  literals   = (StgWord*)(&bco->literals->payload[0]);
        register StgPtr*   ptrs       = (StgPtr*)(&bco->ptrs->payload[0]);
        register StgInfoTable** itbls = (StgInfoTable**)
@@ -810,7 +807,7 @@ run_BCO:
 
        case bci_PUSH_ALTS: {
            int o_bco  = BCO_NEXT;
-           Sp[-2] = (W_)&stg_ctoi_ret_R1p_info;
+           Sp[-2] = (W_)&stg_ctoi_R1p_info;
            Sp[-1] = BCO_PTR(o_bco);
            Sp -= 2;
            goto nextInsn;
@@ -818,7 +815,7 @@ run_BCO:
 
        case bci_PUSH_ALTS_P: {
            int o_bco  = BCO_NEXT;
-           Sp[-2] = (W_)&stg_ctoi_ret_R1unpt_info;
+           Sp[-2] = (W_)&stg_ctoi_R1unpt_info;
            Sp[-1] = BCO_PTR(o_bco);
            Sp -= 2;
            goto nextInsn;
@@ -826,7 +823,7 @@ run_BCO:
 
        case bci_PUSH_ALTS_N: {
            int o_bco  = BCO_NEXT;
-           Sp[-2] = (W_)&stg_ctoi_ret_R1n_info;
+           Sp[-2] = (W_)&stg_ctoi_R1n_info;
            Sp[-1] = BCO_PTR(o_bco);
            Sp -= 2;
            goto nextInsn;
@@ -834,7 +831,7 @@ run_BCO:
 
        case bci_PUSH_ALTS_F: {
            int o_bco  = BCO_NEXT;
-           Sp[-2] = (W_)&stg_ctoi_ret_F1_info;
+           Sp[-2] = (W_)&stg_ctoi_F1_info;
            Sp[-1] = BCO_PTR(o_bco);
            Sp -= 2;
            goto nextInsn;
@@ -842,7 +839,7 @@ run_BCO:
 
        case bci_PUSH_ALTS_D: {
            int o_bco  = BCO_NEXT;
-           Sp[-2] = (W_)&stg_ctoi_ret_D1_info;
+           Sp[-2] = (W_)&stg_ctoi_D1_info;
            Sp[-1] = BCO_PTR(o_bco);
            Sp -= 2;
            goto nextInsn;
@@ -850,7 +847,7 @@ run_BCO:
 
        case bci_PUSH_ALTS_L: {
            int o_bco  = BCO_NEXT;
-           Sp[-2] = (W_)&stg_ctoi_ret_L1_info;
+           Sp[-2] = (W_)&stg_ctoi_L1_info;
            Sp[-1] = BCO_PTR(o_bco);
            Sp -= 2;
            goto nextInsn;
@@ -858,7 +855,7 @@ run_BCO:
 
        case bci_PUSH_ALTS_V: {
            int o_bco  = BCO_NEXT;
-           Sp[-2] = (W_)&stg_ctoi_ret_V_info;
+           Sp[-2] = (W_)&stg_ctoi_V_info;
            Sp[-1] = BCO_PTR(o_bco);
            Sp -= 2;
            goto nextInsn;
@@ -897,9 +894,6 @@ run_BCO:
        case bci_PUSH_APPLY_PPPPPP:
            Sp--; Sp[0] = (W_)&stg_ap_pppppp_info;
            goto nextInsn;
-       case bci_PUSH_APPLY_PPPPPPP:
-           Sp--; Sp[0] = (W_)&stg_ap_ppppppp_info;
-           goto nextInsn;
            
        case bci_PUSH_UBX: {
            int i;
@@ -926,7 +920,7 @@ run_BCO:
 
        case bci_ALLOC_AP: {
            StgAP* ap; 
-           int n_payload = BCO_NEXT - 1;
+           int n_payload = BCO_NEXT;
            int request   = PAP_sizeW(n_payload);
            ap = (StgAP*)allocate_UPD(request);
            Sp[-1] = (W_)ap;
@@ -939,7 +933,7 @@ run_BCO:
        case bci_ALLOC_PAP: {
            StgPAP* pap; 
            int arity = BCO_NEXT;
-           int n_payload = BCO_NEXT - 1;
+           int n_payload = BCO_NEXT;
            int request   = PAP_sizeW(n_payload);
            pap = (StgPAP*)allocate_NONUPD(request);
            Sp[-1] = (W_)pap;
@@ -953,7 +947,7 @@ run_BCO:
        case bci_MKAP: {
            int i;
            int stkoff = BCO_NEXT;
-           int n_payload = BCO_NEXT - 1;
+           int n_payload = BCO_NEXT;
            StgAP* ap = (StgAP*)Sp[stkoff];
            ASSERT((int)ap->n_args == n_payload);
            ap->fun = (StgClosure*)Sp[0];
@@ -1013,7 +1007,7 @@ run_BCO:
            int discr  = BCO_NEXT;
            int failto = BCO_NEXT;
            StgClosure* con = (StgClosure*)Sp[0];
-           if (constrTag(con) >= discr) {
+           if (GET_TAG(con) >= discr) {
                bciPtr = failto;
            }
            goto nextInsn;
@@ -1023,7 +1017,7 @@ run_BCO:
            int discr  = BCO_NEXT;
            int failto = BCO_NEXT;
            StgClosure* con = (StgClosure*)Sp[0];
-           if (constrTag(con) != discr) {
+           if (GET_TAG(con) != discr) {
                bciPtr = failto;
            }
            goto nextInsn;
@@ -1157,6 +1151,9 @@ run_BCO:
            int stk_offset            = BCO_NEXT;
            int o_itbl                = BCO_NEXT;
            void(*marshall_fn)(void*) = (void (*)(void*))BCO_LIT(o_itbl);
+           int ret_dyn_size = 
+               RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE
+               + sizeofW(StgRetDyn);
 
 #ifdef RTS_SUPPORTS_THREADS
            // Threaded RTS:
@@ -1164,12 +1161,14 @@ run_BCO:
            // collection might move the TSO as soon as we call
            // suspendThread below.
 
-           void *arguments;
+           W_ arguments[stk_offset];
            
-           arguments = stgMallocWords(stk_offset,"bci_CCALL");
            memcpy(arguments, Sp, sizeof(W_) * stk_offset);
 #endif
-               
+
+           // Restore the Haskell thread's current value of errno
+           errno = cap->r.rCurrentTSO->saved_errno;
+
            // There are a bunch of non-ptr words on the stack (the
            // ccall args, the ccall fun address and space for the
            // result), which we need to cover with an info table
@@ -1180,12 +1179,12 @@ run_BCO:
            // CCALL instruction.   So we build a RET_DYN stack frame
            // on the stack frame to describe this chunk of stack.
            //
-           Sp -= RET_DYN_SIZE + sizeofW(StgRetDyn);
-           ((StgRetDyn *)Sp)->liveness = ALL_NON_PTRS | N_NONPTRS(stk_offset);
+           Sp -= ret_dyn_size;
+           ((StgRetDyn *)Sp)->liveness = NO_PTRS | N_NONPTRS(stk_offset);
            ((StgRetDyn *)Sp)->info = (StgInfoTable *)&stg_gc_gen_info;
 
            SAVE_STACK_POINTERS;
-           tok = suspendThread(&cap->r,rtsFalse);
+           tok = suspendThread(&cap->r);
 
 #ifndef RTS_SUPPORTS_THREADS
            // Careful:
@@ -1193,27 +1192,28 @@ run_BCO:
            // around (stack squeezing), so we have to grab the real
            // Sp out of the TSO to find the ccall args again.
 
-           marshall_fn ( (void*)(cap->r.rCurrentTSO->sp + RET_DYN_SIZE + sizeofW(StgRetDyn)) );
+           marshall_fn ( (void*)(cap->r.rCurrentTSO->sp + ret_dyn_size) );
 #else
            // Threaded RTS:
-           // We already made a malloced copy of the arguments above.
+           // We already made a copy of the arguments above.
 
            marshall_fn ( arguments );
 #endif
 
            // And restart the thread again, popping the RET_DYN frame.
-           cap = (Capability *)((void *)resumeThread(tok,rtsFalse) - sizeof(StgFunTable));
+           cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - sizeof(StgFunTable)));
            LOAD_STACK_POINTERS;
-           Sp += RET_DYN_SIZE + sizeofW(StgRetDyn);
-
+           Sp += ret_dyn_size;
            
+           // Save the Haskell thread's current value of errno
+           cap->r.rCurrentTSO->saved_errno = errno;
+               
 #ifdef RTS_SUPPORTS_THREADS
            // Threaded RTS:
            // Copy the "arguments", which might include a return value,
            // back to the TSO stack. It would of course be enough to
            // just copy the return value, but we don't know the offset.
            memcpy(Sp, arguments, sizeof(W_) * stk_offset);
-           free(arguments);
 #endif
 
            goto nextInsn;