[project @ 2000-02-29 12:54:51 by sewardj]
authorsewardj <unknown>
Tue, 29 Feb 2000 12:54:52 +0000 (12:54 +0000)
committersewardj <unknown>
Tue, 29 Feb 2000 12:54:52 +0000 (12:54 +0000)
Make foreign import work in combined mode:
-- Allow interpreter to do ccall primops even in combined mode
-- Implement hugsprimMkIO in combined mode, so as to wrap up a
   an IO value created by Hugs in a form compatible with GHC's IO
   representation.

ghc/lib/std/PrelHugs.lhs
ghc/rts/Evaluator.c

index 6df8cc6..6138c53 100644 (file)
@@ -33,7 +33,7 @@ import PrelReal(Integral)
 import Prelude(fromIntegral)
 import IO(putStr,hFlush,stdout,stderr)
 import PrelException(catch,catchException)
-import PrelIOBase(IO,unsafePerformIO)
+import PrelIOBase(IO(..),unsafePerformIO)
 import PrelShow(show,shows,showString,showChar,Show,ShowS)
 import PrelRead(Read,ReadS,lex,reads)
 import PrelFloat(Double)
@@ -46,12 +46,33 @@ import PrelPack(unpackCString)
 -- They need to correspond exactly to versions written in 
 -- the Hugs standalone Prelude.
 
---hugs doesn't know about RealWorld and so throws this
---away if the original type signature is used
---hugsprimMkIO :: (RealWorld -> (a,RealWorld)) -> IO a
+-- hugs doesn't know about RealWorld and so throws this
+-- away if the original type signature is used
+-- hugsprimMkIO :: (RealWorld -> (a,RealWorld)) -> IO a
+--
+-- The first arg is an IO value created by Hugs, without the
+-- newtype ST wrapper.  What we do here place a wrapper around
+-- it, so that it can be called from GHC-land, which uses a
+-- different IO representation.
+--
+-- This is all very delicate and relies crucially on the non-inlined
+-- connectWorlds fn to create an artificial dependency of the hugs_ioaction
+-- on the grealworld.  That's needed to stop the simplifier floating
+-- the case outside of the \ grealworld.
 hugsprimMkIO :: (rw -> (a,rw)) -> IO a
-hugsprimMkIO
-   = error "hugsprimMkIO in combined mode: unimplemented"
+hugsprimMkIO hugs_ioaction 
+   = IO ( \ grealworld -> case hugs_ioaction 
+                                  (connectWorlds grealworld) of
+                             (res, hrealworld') -> (# grealworld, res #)
+        )
+
+{-# NOINLINE connectWorlds #-}
+connectWorlds :: State# RealWorld -> a    -- really, -> Hugs' RealWorld
+connectWorlds hrealworld
+   = error "connectWorlds: hugs entered the RealWorld"
+
+
+
 
 hugsprimCreateAdjThunk :: (a -> b) -> String -> Char -> IO Addr
 hugsprimCreateAdjThunk fun typestr callconv
index 7522bed..c67ff2c 100644 (file)
@@ -5,8 +5,8 @@
  * Copyright (c) 1994-1998.
  *
  * $RCSfile: Evaluator.c,v $
- * $Revision: 1.35 $
- * $Date: 2000/02/24 17:26:12 $
+ * $Revision: 1.36 $
+ * $Date: 2000/02/29 12:54:51 $
  * ---------------------------------------------------------------------------*/
 
 #include "Rts.h"
@@ -2665,8 +2665,14 @@ static void* enterBCO_primop2 ( int primop2code,
                                 StgBCO** bco,
                                 Capability* cap )
 {
-        if (combined)
-           barf("enterBCO_primop1 in combined mode");
+        if (combined) {
+          /* A small concession: we need to allow ccalls, 
+              even in combined mode.
+           */
+           if (primop2code != i_ccall_ccall_IO &&
+               primop2code != i_ccall_stdcall_IO)
+              barf("enterBCO_primop2 in combined mode");
+        }
 
         switch (primop2code) {
         case i_raise:  /* raise#{err} */