Changes needed to support foreign export (dynamic) in combined mode.
* Hugs version 1.4, December 1997
*
* $RCSfile: interface.c,v $
- * $Revision: 1.32 $
- * $Date: 2000/02/24 12:34:18 $
+ * $Revision: 1.33 $
+ * $Date: 2000/03/02 10:10:33 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
Sym(prog_argv) \
Sym(prog_argc) \
Sym(resetNonBlockingFd) \
+ Sym(getStablePtr) \
+ Sym(stable_ptr_table) \
+ Sym(createAdjThunk) \
\
/* needed by libHS_cbits */ \
SymX(malloc) \
hugsprimPmFail = error "Pattern Match Failure"
-- used in desugaring Foreign functions
+-- Note: hugsprimMkIO is used as a wrapper to translate a Hugs-created
+-- bit of code of type RealWorld -> (a,RealWorld) into a proper IO value.
+-- What follows is the version for standalone mode. ghc/lib/std/PrelHugs.lhs
+-- contains a version used in combined mode. That version takes care of
+-- switching between the GHC and Hugs IO representations, which are different.
hugsprimMkIO :: (RealWorld -> (a,RealWorld)) -> IO a
hugsprimMkIO = ST
* included in the distribution.
*
* $RCSfile: storage.h,v $
- * $Revision: 1.29 $
- * $Date: 2000/02/25 10:53:54 $
+ * $Revision: 1.30 $
+ * $Date: 2000/03/02 10:10:33 $
* ------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------
#define isPrelude(m) (m==modulePrelude)
-#define N_PRELUDE_SCRIPTS (combined ? 30 : 1)
+#define N_PRELUDE_SCRIPTS (combined ? 32 : 1)
/* --------------------------------------------------------------------------
* Type constructor names:
* included in the distribution.
*
* $RCSfile: translate.c,v $
- * $Revision: 1.24 $
- * $Date: 1999/12/10 15:59:56 $
+ * $Revision: 1.25 $
+ * $Date: 2000/03/02 10:10:33 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
descriptor->arg_tys++;
descriptor->num_args--;
}
-
-
}
/* Generate code:
*
- * \ fun s0 ->
+ * \ fun ->
let e1 = A# "...."
e3 = C# 'c' -- (ccall), or 's' (stdcall)
- in primMkAdjThunk fun e1 e3 s0
+ in primMkAdjThunk fun e1 e3
we require, and check that,
fun :: prim_arg* -> IO prim_result
assert(length(resultTys) == 1);
resultTys = hd(resultTys);
} else {
- ERRMSG(name(n).line) "foreign export doesn't return an IO type" ETHEN
+ ERRMSG(name(n).line) "function to be exported doesn't return an IO type: " ETHEN
ERRTEXT " \"" ETHEN ERRTYPE(t);
ERRTEXT "\""
EEND;
else
internal ( "implementForeignExport: unknown calling convention");
-
{
List tdList;
Text tdText;
tdList = cons(foreignOutboundTy(resultTys),tdList);
tdText = findText(charListToString ( tdList ));
- args = makeArgs(2);
+ args = makeArgs(1);
e1 = mkStgVar(
mkStgCon(nameMkA,singleton(ap(STRCELL,tdText))),
NIL
tripleton(e1,e2,e3),
mkStgApp(
nameCreateAdjThunk,
- cons(hd(args),cons(e2,cons(e3,cons(hd(tl(args)),NIL))))
+ cons(hd(args),cons(e2,cons(e3,NIL)))
)
)
);
hugsprimPmFail = error "Pattern Match Failure"
-- used in desugaring Foreign functions
+-- Note: hugsprimMkIO is used as a wrapper to translate a Hugs-created
+-- bit of code of type RealWorld -> (a,RealWorld) into a proper IO value.
+-- What follows is the version for standalone mode. ghc/lib/std/PrelHugs.lhs
+-- contains a version used in combined mode. That version takes care of
+-- switching between the GHC and Hugs IO representations, which are different.
hugsprimMkIO :: (RealWorld -> (a,RealWorld)) -> IO a
hugsprimMkIO = ST
import PrelRead(Read,ReadS,lex,reads)
import PrelFloat(Double)
import PrelReal(Fractional,fromRational,toRational)
-import PrelAddr(Addr)
+import PrelAddr(Addr(..),nullAddr)
+import PrelStable(StablePtr,makeStablePtr)
import PrelErr(error)
import PrelPack(unpackCString)
+import List(length)
-- Stuff needed by Hugs for desugaring. Do not mess with these!
-- They need to correspond exactly to versions written in
+-- StgAddr createAdjThunk ( StgStablePtr stableptr,
+-- StgAddr typestr,
+-- StgChar callconv )
+foreign import "createAdjThunk" hugsCreateAdjThunk
+ :: StablePtr (a -> b) -> Addr{-mallocville String-} -> Char -> IO Addr
+foreign import "malloc" malloc
+ :: Int -> IO Addr
hugsprimCreateAdjThunk :: (a -> b) -> String -> Char -> IO Addr
hugsprimCreateAdjThunk fun typestr callconv
- = error "hugsprimCreateAdjThunk in combined mode: unimplemented"
+ = do sp <- makeStablePtr fun
+ p <- copy_String_to_cstring typestr -- is never freed
+ a <- hugsCreateAdjThunk sp p callconv
+ return a
+ where
+ copy_String_to_cstring :: String -> IO Addr
+ copy_String_to_cstring s
+ = malloc (1 + length s) >>= \ptr0 ->
+ let loop off [] = writeCharOffAddr ptr0 off (chr 0)
+ >> return ptr0
+ loop off (c:cs) = writeCharOffAddr ptr0 off c
+ >> loop (off+1) cs
+ in
+ if isNullAddr ptr0
+ then error "copy_String_to_cstring: malloc failed"
+ else loop 0 s
+
+ isNullAddr a = a == nullAddr
+
+ writeCharOffAddr :: Addr -> Int -> Char -> IO ()
+ writeCharOffAddr (A# buf#) (I# n#) (C# c#)
+ = IO ( \ s# ->
+ case (writeCharOffAddr# buf# n# c# s#) of
+ s2# -> (# s2#, () #) )
+
+
fromDouble :: Fractional a => Double -> a
fromDouble n = fromRational (toRational n)
/* -----------------------------------------------------------------------------
- * $Id: ForeignCall.c,v 1.11 1999/11/08 15:30:37 sewardj Exp $
+ * $Id: ForeignCall.c,v 1.12 2000/03/02 10:10:34 sewardj Exp $
*
* (c) The GHC Team 1994-1999.
*
for a given function by name. Useful but a hack. Sigh.
*/
extern void* getHugs_AsmObject_for ( char* s );
-
+extern int /*Bool*/ combined;
/* ----------------------------------------------------------------*
* The implementation for x86_ccall and x86_stdcall.
}
argp++;
}
-
- node = rts_apply (
- asmClosureOfObject(getHugs_AsmObject_for("primRunST")),
- node );
-
- sstat = rts_eval ( node, &nodeOut );
+fprintf(stderr,"before rts_evalIO\n");
+ if (combined) {
+ sstat = rts_evalIO ( node, &nodeOut );
+ } else {
+ node = rts_apply (
+ asmClosureOfObject(getHugs_AsmObject_for("primRunST")),
+ node );
+ sstat = rts_eval ( node, &nodeOut );
+ }
+fprintf(stderr, "after rts_evalIO\n");
if (sstat != Success)
barf ("unpackArgsAndCallHaskell_x86_nocallconv: eval failed");
StgStablePtr stableptr, char* tydesc, char* args
)
{
- HaskellObj nodeOut
- = unpackArgsAndCallHaskell_x86_nocallconv_wrk (
- stableptr, tydesc, args
- );
+ HaskellObj nodeOut;
+ nodeOut = unpackArgsAndCallHaskell_x86_nocallconv_wrk (
+ stableptr, tydesc, args
+ );
/* A complete hack. We know that all these returns will be
put into %eax (and %edx, if it is a 64-bit return), and
the adjustor thunk will then itself return to the original