summaryrefslogtreecommitdiff
path: root/ghc/interpreter
diff options
context:
space:
mode:
authorsewardj <unknown>1999-10-15 11:03:10 +0000
committersewardj <unknown>1999-10-15 11:03:10 +0000
commitdfb12323d9fd0c8fb717b8e548592f20163b4ed0 (patch)
tree7900eb0f51b03a254425cd3f978eb1e245071e11 /ghc/interpreter
parentf5fd4677bc522dba98447c6b3451441e8ab8e33e (diff)
downloadhaskell-dfb12323d9fd0c8fb717b8e548592f20163b4ed0.tar.gz
[project @ 1999-10-15 11:02:06 by sewardj]
Added basic support for foreign export dynamic. Many aspects of it are still broken: * Only supports x86-linux. * The range of allowable types is small: Char Int Float Double Addr and Word. * Adjustor thunks are never freed. * Returning Doubles or Floats doesn't work at all. I expect to fix some of these shortly. foreign import also needs redoing, so it can accept any number of arguments of any type. Also: * Fixed setRtsFlags in Evaluator.c to make it endian-independent. * Fixed raisePrim in Evaluator.c so things like division by zero, array index errors, etc, throw an exception instead of terminating StgHugs. raisePrim is renamed makeErrorCall.
Diffstat (limited to 'ghc/interpreter')
-rw-r--r--ghc/interpreter/Makefile6
-rw-r--r--ghc/interpreter/connect.h5
-rw-r--r--ghc/interpreter/free.c6
-rw-r--r--ghc/interpreter/hugs.c8
-rw-r--r--ghc/interpreter/input.c17
-rw-r--r--ghc/interpreter/lib/Prelude.hs247
-rw-r--r--ghc/interpreter/link.c20
-rw-r--r--ghc/interpreter/link.h5
-rw-r--r--ghc/interpreter/parser.y11
-rw-r--r--ghc/interpreter/static.c60
-rw-r--r--ghc/interpreter/storage.c14
-rw-r--r--ghc/interpreter/translate.c151
-rw-r--r--ghc/interpreter/type.c9
13 files changed, 228 insertions, 331 deletions
diff --git a/ghc/interpreter/Makefile b/ghc/interpreter/Makefile
index 60933d74ea..b82c13de7b 100644
--- a/ghc/interpreter/Makefile
+++ b/ghc/interpreter/Makefile
@@ -1,6 +1,6 @@
# ----------------------------------------------------------------------------- #
-# $Id: Makefile,v 1.10 1999/07/06 15:24:35 sewardj Exp $ #
+# $Id: Makefile,v 1.11 1999/10/15 11:02:09 sewardj Exp $ #
# ----------------------------------------------------------------------------- #
TOP = ../..
@@ -27,7 +27,7 @@ C_SRCS = link.c type.c static.c storage.c derive.c input.c compiler.c subst.c \
translate.c codegen.c lift.c free.c stgSubst.c optimise.c output.c \
hugs.c dynamic.c stg.c sainteger.c interface.c
-SRC_CC_OPTS = -g -I$(GHC_DIR)/interpreter -I$(GHC_DIR)/includes -I$(GHC_DIR)/rts -D__HUGS__ -DCOMPILING_RTS -Wall -Wstrict-prototypes -DDEBUG -DDEBUG_EXTRA
+SRC_CC_OPTS = -g -O -I$(GHC_DIR)/interpreter -I$(GHC_DIR)/includes -I$(GHC_DIR)/rts -D__HUGS__ -DCOMPILING_RTS -Wall -Wstrict-prototypes -Wno-unused -DDEBUG -DDEBUG_EXTRA -Winline
GHC_LIBS_NEEDED = $(TOP)/ghc/rts/libHSrts.a
@@ -39,7 +39,7 @@ hugs: $(C_OBJS) ../rts/Sanity.o ../rts/Assembler.o ../rts/Disassembler.o \
../rts/StgCRun.o nHandle.so
$(CC) -o $@ -rdynamic $(CC_OPTS) $^ $(GHC_LIBS_NEEDED) -lbfd -liberty -ldl -lm
-nHandle.so:
+nHandle.so: nHandle.c
gcc -O -fPIC -shared -o nHandle.so nHandle.c
$(TOP)/ghc/rts/libHSrts.a:
diff --git a/ghc/interpreter/connect.h b/ghc/interpreter/connect.h
index 41dc004919..c2c782aee5 100644
--- a/ghc/interpreter/connect.h
+++ b/ghc/interpreter/connect.h
@@ -7,8 +7,8 @@
* in the distribution for details.
*
* $RCSfile: connect.h,v $
- * $Revision: 1.7 $
- * $Date: 1999/06/07 17:22:45 $
+ * $Revision: 1.8 $
+ * $Date: 1999/10/15 11:02:09 $
* ------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------
@@ -74,6 +74,7 @@ extern Name nameReturn, nameBind; /* for translating monad comps */
extern Name nameMFail;
extern Name nameListMonad; /* builder function for List Monad */
extern Name namePrint; /* printing primitive */
+extern Name nameCreateAdjThunk; /* f-x-dyn: create adjustor thunk */
extern Text textPrelude;
extern Text textNum; /* used to process default decls */
#if NPLUSK
diff --git a/ghc/interpreter/free.c b/ghc/interpreter/free.c
index d58635bb18..18966d96d0 100644
--- a/ghc/interpreter/free.c
+++ b/ghc/interpreter/free.c
@@ -7,8 +7,8 @@
* Hugs version 1.4, December 1997
*
* $RCSfile: free.c,v $
- * $Revision: 1.4 $
- * $Date: 1999/04/27 10:06:52 $
+ * $Revision: 1.5 $
+ * $Date: 1999/10/15 11:02:09 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
@@ -116,7 +116,7 @@ static List freeVarsExpr( List acc, StgExpr e )
case NAME:
return acc; /* Names are never free vars */
default:
-printf("\n\n");
+printf("\n");
ppStgExpr(e);
printf("\n");
internal("freeVarsExpr");
diff --git a/ghc/interpreter/hugs.c b/ghc/interpreter/hugs.c
index 8485df4c83..cf5a99498a 100644
--- a/ghc/interpreter/hugs.c
+++ b/ghc/interpreter/hugs.c
@@ -8,8 +8,8 @@
* in the distribution for details.
*
* $RCSfile: hugs.c,v $
- * $Revision: 1.10 $
- * $Date: 1999/10/11 12:22:58 $
+ * $Revision: 1.11 $
+ * $Date: 1999/10/15 11:02:10 $
* ------------------------------------------------------------------------*/
#include <setjmp.h>
@@ -811,7 +811,8 @@ static Void local makeStackEntry ( ScriptInfo* ent, String iname )
);
if (!ok) {
ERRMSG(0)
- "Can't file source or object+interface for module \"%s\"",
+ /* "Can't file source or object+interface for module \"%s\"", */
+ "Can't file source for module \"%s\"",
iname
EEND;
}
@@ -825,7 +826,6 @@ static Void local makeStackEntry ( ScriptInfo* ent, String iname )
? (oAvail && iAvail && timeEarlier(sTime,oTime))
: TRUE;
*/
-
fromObj = FALSE;
/* ToDo: namesUpto overflow */
diff --git a/ghc/interpreter/input.c b/ghc/interpreter/input.c
index afae01fd1f..a979f25adc 100644
--- a/ghc/interpreter/input.c
+++ b/ghc/interpreter/input.c
@@ -8,8 +8,8 @@
* in the distribution for details.
*
* $RCSfile: input.c,v $
- * $Revision: 1.6 $
- * $Date: 1999/06/07 17:22:32 $
+ * $Revision: 1.7 $
+ * $Date: 1999/10/15 11:02:12 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
@@ -124,7 +124,8 @@ static Text textWildcard;
static Text textModule, textImport, textInterface, textInstImport;
static Text textHiding, textQualified, textAsMod;
-static Text textExport, textUnsafe, text__All;
+static Text textExport, textDynamic, textUUExport;
+static Text textUnsafe, textUUAll;
Text textNum; /* Num */
Text textPrelude; /* Prelude */
@@ -1470,12 +1471,14 @@ static Int local yylex() { /* Read next input token ... */
if (it==textInstImport) return INSTIMPORT;
if (it==textImport) return IMPORT;
if (it==textExport) return EXPORT;
+ if (it==textDynamic) return DYNAMIC;
+ if (it==textUUExport) return UUEXPORT;
if (it==textHiding) return HIDING;
if (it==textQualified) return QUALIFIED;
if (it==textAsMod) return ASMOD;
if (it==textWildcard) return '_';
if (it==textAll && !haskell98) return ALL;
- if (it==text__All) return ALL;
+ if (it==textUUAll) return ALL;
if (it==textRepeat && reading==KEYBOARD)
return repeatLast();
@@ -1671,14 +1674,16 @@ Int what; {
textModule = findText("module");
textInterface = findText("__interface");
textInstImport = findText("__instimport");
- textExport = findText("__export");
+ textExport = findText("export");
+ textDynamic = findText("dynamic");
+ textUUExport = findText("__export");
textImport = findText("import");
textHiding = findText("hiding");
textQualified = findText("qualified");
textAsMod = findText("as");
textWildcard = findText("_");
textAll = findText("forall");
- text__All = findText("__forall");
+ textUUAll = findText("__forall");
varMinus = mkVar(textMinus);
varPlus = mkVar(textPlus);
varBang = mkVar(textBang);
diff --git a/ghc/interpreter/lib/Prelude.hs b/ghc/interpreter/lib/Prelude.hs
index f1fe9a742b..ebee5b4e2f 100644
--- a/ghc/interpreter/lib/Prelude.hs
+++ b/ghc/interpreter/lib/Prelude.hs
@@ -60,7 +60,8 @@ module Prelude (
-- module Ratio,
Ratio, Rational, (%), numerator, denominator, approxRational,
-- Non-standard exports
- IO(..), IOResult(..), Addr,
+ IO(..), IOResult(..), Addr, StablePtr,
+ makeStablePtr, freeStablePtr, deRefStablePtr,
Bool(False, True),
Maybe(Nothing, Just),
@@ -111,8 +112,8 @@ module Prelude (
,nh_free,nh_close,nh_errno,nh_flush,nh_read,primIntToChar
,unsafeInterleaveIO,nh_write,primCharToInt
- -- ToDo: rm -- these are only for debugging
- ,primPlusInt,primEqChar,primRunIO
+ -- debugging hacks
+ ,ST(..)
) where
-- Standard value bindings {Prelude} ----------------------------------------
@@ -1383,7 +1384,7 @@ nonnull p s = [(cs,t) | (cs@(_:_),t) <- [span p s]]
lexLitChar :: ReadS String
lexLitChar ('\\':s) = [('\\':esc, t) | (esc,t) <- lexEsc s]
where
- lexEsc (c:s) | c `elem` "abfnrtv\\\"'" = [([c],s)]
+ lexEsc (c:s) | c `elem` "abfnrtv\\\"'" = [([c],s)] -- "
lexEsc ('^':c:s) | c >= '@' && c <= '_' = [(['^',c],s)]
lexEsc s@(d:_) | isDigit d = lexDigits s
lexEsc s@(c:_) | isUpper c
@@ -1548,6 +1549,13 @@ primPmFail = error "Pattern Match Failure"
primMkIO :: (RealWorld -> (a,RealWorld)) -> IO a
primMkIO = ST
+primCreateAdjThunk :: (a -> b) -> String -> IO Addr
+primCreateAdjThunk fun typestr
+ = do sp <- makeStablePtr fun
+ p <- copy_String_to_cstring typestr -- is never freed
+ a <- primCreateAdjThunkARCH sp p
+ return a
+
-- The following primitives are only needed if (n+k) patterns are enabled:
primPmNpk :: Integral a => Int -> a -> Maybe a
primPmNpk n x = if n'<=x then Just (x-n') else Nothing
@@ -1655,7 +1663,6 @@ writeFile fname contents
then (ioError.IOError) ("writeFile: can't create file " ++ fname)
else writetohandle fname h contents
-
appendFile :: FilePath -> String -> IO ()
appendFile fname contents
= copy_String_to_cstring fname >>= \ptr ->
@@ -1694,46 +1701,43 @@ instance Show Exception where
data IOResult = IOResult deriving (Show)
type FILE_STAR = Int -- FILE *
-type Ptr = Int -- char *
foreign import stdcall "nHandle.so" "nh_stdin" nh_stdin :: IO FILE_STAR
foreign import stdcall "nHandle.so" "nh_stdout" nh_stdout :: IO FILE_STAR
foreign import stdcall "nHandle.so" "nh_stderr" nh_stderr :: IO FILE_STAR
foreign import stdcall "nHandle.so" "nh_write" nh_write :: FILE_STAR -> Int -> IO ()
foreign import stdcall "nHandle.so" "nh_read" nh_read :: FILE_STAR -> IO Int
-foreign import stdcall "nHandle.so" "nh_open" nh_open :: Int -> Int -> IO FILE_STAR
+foreign import stdcall "nHandle.so" "nh_open" nh_open :: Addr -> Int -> IO FILE_STAR
foreign import stdcall "nHandle.so" "nh_flush" nh_flush :: FILE_STAR -> IO ()
foreign import stdcall "nHandle.so" "nh_close" nh_close :: FILE_STAR -> IO ()
foreign import stdcall "nHandle.so" "nh_errno" nh_errno :: IO Int
-foreign import stdcall "nHandle.so" "nh_malloc" nh_malloc :: Int -> IO Ptr
-foreign import stdcall "nHandle.so" "nh_free" nh_free :: Ptr -> IO ()
-foreign import stdcall "nHandle.so" "nh_store" nh_store :: Ptr -> Int -> IO ()
-foreign import stdcall "nHandle.so" "nh_load" nh_load :: Ptr -> IO Int
+foreign import stdcall "nHandle.so" "nh_malloc" nh_malloc :: Int -> IO Addr
+foreign import stdcall "nHandle.so" "nh_free" nh_free :: Addr -> IO ()
+foreign import stdcall "nHandle.so" "nh_store" nh_store :: Addr -> Int -> IO ()
+foreign import stdcall "nHandle.so" "nh_load" nh_load :: Addr -> IO Int
foreign import stdcall "nHandle.so" "nh_argc" nh_argc :: IO Int
foreign import stdcall "nHandle.so" "nh_argvb" nh_argvb :: Int -> Int -> IO Int
-foreign import stdcall "nHandle.so" "nh_getenv" nh_getenv :: Ptr -> IO Ptr
+foreign import stdcall "nHandle.so" "nh_getenv" nh_getenv :: Addr -> IO Addr
-copy_String_to_cstring :: String -> IO Ptr
+copy_String_to_cstring :: String -> IO Addr
copy_String_to_cstring s
= nh_malloc (1 + length s) >>= \ptr0 ->
let loop ptr [] = nh_store ptr 0 >> return ptr0
- loop ptr (c:cs) = --trace ("Out `" ++ [c] ++ "'") (
- nh_store ptr (primCharToInt c) >> loop (ptr+1) cs
- --)
+ loop ptr (c:cs) = nh_store ptr (primCharToInt c) >> loop (incAddr ptr) cs
in
- loop ptr0 s
+ if isNullAddr ptr0
+ then error "copy_String_to_cstring: malloc failed"
+ else loop ptr0 s
-copy_cstring_to_String :: Ptr -> IO String
+copy_cstring_to_String :: Addr -> IO String
copy_cstring_to_String ptr
= nh_load ptr >>= \ci ->
if ci == 0
then return []
- else copy_cstring_to_String (ptr+1) >>= \cs ->
- --trace ("In " ++ show ci) (
+ else copy_cstring_to_String (incAddr ptr) >>= \cs ->
return ((primIntToChar ci) : cs)
- --)
readfromhandle :: FILE_STAR -> IO String
readfromhandle h
@@ -1772,7 +1776,7 @@ primGetEnv v
= copy_String_to_cstring v >>= \ptr ->
nh_getenv ptr >>= \ptr2 ->
nh_free ptr >>
- if ptr2 == 0
+ if isNullAddr ptr2
then return []
else
copy_cstring_to_String ptr2 >>= \result ->
@@ -1799,12 +1803,12 @@ primRunST m = fst (unST m theWorld)
unST (ST a) = a
instance Functor (ST s) where
- fmap f x = x >>= (return . f)
+ fmap f x = x >>= (return . f)
instance Monad (ST s) where
- m >> k = m >>= \ _ -> k
- return x = ST $ \ s -> (x,s)
- m >>= k = ST $ \s -> case unST m s of { (a,s') -> unST (k a) s' }
+ m >> k = ST (\s -> case unST m s of { (a,s') -> unST k s' })
+ return x = ST (\s -> (x,s))
+ m >>= k = ST (\s -> case unST m s of { (a,s') -> unST (k a) s' })
-- used when Hugs invokes top level function
@@ -1812,7 +1816,7 @@ primRunIO :: IO () -> ()
primRunIO m
= protect (fst (unST m realWorld))
where
- realWorld = error "panic: Hugs entered the real world"
+ realWorld = error "primRunIO: entered the RealWorld"
protect :: () -> ()
protect comp
= primCatch comp (\e -> fst (unST (putStr (show e ++ "\n")) realWorld))
@@ -1829,12 +1833,14 @@ unsafeInterleaveIO = unsafeInterleaveST
------------------------------------------------------------------------------
--- Word, Addr, ForeignObj, Prim*Array ----------------------------------------
+-- Word, Addr, StablePtr, Prim*Array -----------------------------------------
------------------------------------------------------------------------------
data Addr
-nullAddr = primIntToAddr 0
+nullAddr = primIntToAddr 0
+incAddr a = primIntToAddr (1 + primAddrToInt a)
+isNullAddr a = 0 == primAddrToInt a
instance Eq Addr where
(==) = primEqAddr
@@ -1860,9 +1866,14 @@ instance Ord Word where
(>) = primGtWord
---data ForeignObj
---makeForeignObj :: Addr -> IO ForeignObj
---makeForeignObj = primMakeForeignObj
+data StablePtr a
+
+makeStablePtr :: a -> IO (StablePtr a)
+makeStablePtr = primMakeStablePtr
+deRefStablePtr :: StablePtr a -> IO a
+deRefStablePtr = primDeRefStablePtr
+freeStablePtr :: StablePtr a -> IO ()
+freeStablePtr = primFreeStablePtr
data PrimArray a -- immutable arrays with Int indices
@@ -1874,172 +1885,6 @@ data PrimMutableByteArray s
-------------------------------------------------------------------------------
--- hooks to call libHS_cbits -------------------------------------------------
-------------------------------------------------------------------------------
-{-
-type FILE_OBJ = ForeignObj -- as passed into functions
-type CString = PrimByteArray
-type How = Int
-type Binary = Int
-type OpenFlags = Int
-type IOFileAddr = Addr -- as returned from functions
-type FD = Int
-type OpenStdFlags = Int
-type Readable = Int -- really Bool
-type Exclusive = Int -- really Bool
-type RC = Int -- standard return code
-type Bytes = PrimMutableByteArray RealWorld
-type Flush = Int -- really Bool
-
-foreign import stdcall "libHS_cbits.so" "freeStdFileObject"
- freeStdFileObject :: ForeignObj -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "freeFileObject"
- freeFileObject :: ForeignObj -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "setBuf"
- prim_setBuf :: FILE_OBJ -> Addr -> Int -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "getBufSize"
- prim_getBufSize :: FILE_OBJ -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "inputReady"
- prim_inputReady :: FILE_OBJ -> Int -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "fileGetc"
- prim_fileGetc :: FILE_OBJ -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "fileLookAhead"
- prim_fileLookAhead :: FILE_OBJ -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "readBlock"
- prim_readBlock :: FILE_OBJ -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "readLine"
- prim_readLine :: FILE_OBJ -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "readChar"
- prim_readChar :: FILE_OBJ -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "writeFileObject"
- prim_writeFileObject :: FILE_OBJ -> Int -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "filePutc"
- prim_filePutc :: FILE_OBJ -> Char -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "getBufStart"
- prim_getBufStart :: FILE_OBJ -> Int -> IO Addr
-
-foreign import stdcall "libHS_cbits.so" "getWriteableBuf"
- prim_getWriteableBuf :: FILE_OBJ -> IO Addr
-
-foreign import stdcall "libHS_cbits.so" "getBufWPtr"
- prim_getBufWPtr :: FILE_OBJ -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "setBufWPtr"
- prim_setBufWPtr :: FILE_OBJ -> Int -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "closeFile"
- prim_closeFile :: FILE_OBJ -> Flush -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "fileEOF"
- prim_fileEOF :: FILE_OBJ -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "setBuffering"
- prim_setBuffering :: FILE_OBJ -> Int -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "flushFile"
- prim_flushFile :: FILE_OBJ -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "getBufferMode"
- prim_getBufferMode :: FILE_OBJ -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "seekFileP"
- prim_seekFileP :: FILE_OBJ -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "setTerminalEcho"
- prim_setTerminalEcho :: FILE_OBJ -> Int -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "getTerminalEcho"
- prim_getTerminalEcho :: FILE_OBJ -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "isTerminalDevice"
- prim_isTerminalDevice :: FILE_OBJ -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "setConnectedTo"
- prim_setConnectedTo :: FILE_OBJ -> FILE_OBJ -> Int -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "ungetChar"
- prim_ungetChar :: FILE_OBJ -> Char -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "readChunk"
- prim_readChunk :: FILE_OBJ -> Addr -> Int -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "writeBuf"
- prim_writeBuf :: FILE_OBJ -> Addr -> Int -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "getFileFd"
- prim_getFileFd :: FILE_OBJ -> IO FD
-
-foreign import stdcall "libHS_cbits.so" "fileSize_int64"
- prim_fileSize_int64 :: FILE_OBJ -> Bytes -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "getFilePosn"
- prim_getFilePosn :: FILE_OBJ -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "setFilePosn"
- prim_setFilePosn :: FILE_OBJ -> Int -> IO Int
-
-foreign import stdcall "libHS_cbits.so" "getConnFileFd"
- prim_getConnFileFd :: FILE_OBJ -> IO FD
-
-foreign import stdcall "libHS_cbits.so" "allocMemory__"
- prim_allocMemory__ :: Int -> IO Addr
-
-foreign import stdcall "libHS_cbits.so" "getLock"
- prim_getLock :: FD -> Exclusive -> IO RC
-
-foreign import stdcall "libHS_cbits.so" "openStdFile"
- prim_openStdFile :: FD -> OpenStdFlags -> Readable -> IO IOFileAddr
-
-foreign import stdcall "libHS_cbits.so" "openFile"
- prim_openFile :: CString -> How -> Binary -> OpenFlags -> IO IOFileAddr
-
-foreign import stdcall "libHS_cbits.so" "freeFileObject"
- prim_freeFileObject :: FILE_OBJ -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "freeStdFileObject"
- prim_freeStdFileObject :: FILE_OBJ -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "const_BUFSIZ"
- const_BUFSIZ :: Int
-
-foreign import stdcall "libHS_cbits.so" "setConnNonBlockingIOFlag__"
- prim_setConnNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "clearConnNonBlockingIOFlag__"
- prim_clearConnNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "setNonBlockingIOFlag__"
- prim_setNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "clearNonBlockingIOFlag__"
- prim_clearNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
-
-foreign import stdcall "libHS_cbits.so" "getErrStr__"
- prim_getErrStr__ :: IO Addr
-
-foreign import stdcall "libHS_cbits.so" "getErrNo__"
- prim_getErrNo__ :: IO Int
-
-foreign import stdcall "libHS_cbits.so" "getErrType__"
- prim_getErrType__ :: IO Int
-
---foreign import stdcall "libHS_cbits.so" "seekFile_int64"
--- prim_seekFile_int64 :: FILE_OBJ -> Int -> Int64 -> IO RC
--}
-
-- showFloat ------------------------------------------------------------------
showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
@@ -2194,12 +2039,6 @@ floatToDigits base x =
in gen [] (r * bk) s (mUp * bk) (mDn * bk)
in (map toInt (reverse rds), k)
-{-
--- Exponentiation with(out) a cache for the most common numbers.
-expt :: Integer -> Int -> Integer
-expt base n = base^n
--}
-
-- Exponentiation with a cache for the most common numbers.
minExpt = 0::Int
diff --git a/ghc/interpreter/link.c b/ghc/interpreter/link.c
index 6fc348c39b..f5bfdfd3de 100644
--- a/ghc/interpreter/link.c
+++ b/ghc/interpreter/link.c
@@ -7,8 +7,8 @@
* Hugs version 1.4, December 1997
*
* $RCSfile: link.c,v $
- * $Revision: 1.7 $
- * $Date: 1999/04/27 10:06:54 $
+ * $Revision: 1.8 $
+ * $Date: 1999/10/15 11:02:15 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
@@ -35,9 +35,7 @@ Type typePrimMutableArray;
Type typePrimMutableByteArray;
Type typeFloat;
Type typeDouble;
-#ifdef PROVIDE_STABLE
Type typeStable;
-#endif
#ifdef PROVIDE_WEAK
Type typeWeak;
#endif
@@ -113,9 +111,11 @@ Name namePmLe;
Name namePmSubtract;
Name namePmFromInteger;
Name nameMkIO;
+Name nameRunST;
Name nameUnpackString;
Name nameError;
Name nameInd;
+Name nameCreateAdjThunk;
Name nameAnd;
Name nameConCmp;
@@ -165,9 +165,7 @@ Name nameMkPrimByteArray;
Name nameMkRef;
Name nameMkPrimMutableArray;
Name nameMkPrimMutableByteArray;
-#ifdef PROVIDE_STABLE
Name nameMkStable; /* StablePtr# a -> StablePtr a */
-#endif
#ifdef PROVIDE_WEAK
Name nameMkWeak; /* Weak# a -> Weak a */
#endif
@@ -290,9 +288,7 @@ Void linkPreludeTC(void) { /* Hook to tycons and classes in */
typePrimMutableByteArray = linkTycon("PrimMutableByteArray");
typeFloat = linkTycon("Float");
typeDouble = linkTycon("Double");
-#ifdef PROVIDE_STABLE
typeStable = linkTycon("StablePtr");
-#endif
#ifdef PROVIDE_WEAK
typeWeak = linkTycon("Weak");
#endif
@@ -342,9 +338,7 @@ Void linkPreludeTC(void) { /* Hook to tycons and classes in */
nameMkA = addPrimCfunREP(findText("A#"),1,0,ADDR_REP);
nameMkF = addPrimCfunREP(findText("F#"),1,0,FLOAT_REP);
nameMkD = addPrimCfunREP(findText("D#"),1,0,DOUBLE_REP);
-#ifdef PROVIDE_STABLE
nameMkStable = addPrimCfunREP(findText("Stable#"),1,0,STABLE_REP);
-#endif
nameMkInteger = addPrimCfunREP(findText("Integer#"),1,0,0);
#ifdef PROVIDE_FOREIGN
nameMkForeign = addPrimCfunREP(findText("Foreign#"),1,0,0);
@@ -477,6 +471,8 @@ Void linkPreludeNames(void) { /* Hook to names defined in Prelude */
implementPrim(n);
}
+ nameRunST = linkName("primRunST");
+
/* static(tidyInfix) */
nameNegate = linkName("negate");
/* user interface */
@@ -492,6 +488,7 @@ Void linkPreludeNames(void) { /* Hook to names defined in Prelude */
/* translator */
nameEqChar = linkName("primEqChar");
nameEqInt = linkName("primEqInt");
+nameCreateAdjThunk = linkName("primCreateAdjThunk");
#if !OVERLOADED_CONSTANTS
nameEqInteger = linkName("primEqInteger");
#endif /* !OVERLOADED_CONSTANTS */
@@ -565,6 +562,9 @@ Int what; {
pFun(nameError, "error");
pFun(nameUnpackString, "primUnpackString");
+ // /* foreign export dynamic */
+ //pFun(nameCreateAdjThunk, "primCreateAdjThunk");
+
/* hooks for handwritten bytecode */
pFun(namePrimSeq, "primSeq");
pFun(namePrimCatch, "primCatch");
diff --git a/ghc/interpreter/link.h b/ghc/interpreter/link.h
index b87a0e7b25..ce766b434b 100644
--- a/ghc/interpreter/link.h
+++ b/ghc/interpreter/link.h
@@ -16,9 +16,7 @@ extern Name nameMkW;
extern Name nameMkA;
extern Name nameMkF;
extern Name nameMkD;
-#ifdef PROVIDE_STABLE
extern Name nameMkStable;
-#endif
/* The following data constructors are used to make boxed but
* unpointed values pointed and require no special treatment
@@ -58,9 +56,7 @@ extern Type typePrimMutableArray;
extern Type typePrimMutableByteArray;
extern Type typeFloat;
extern Type typeDouble;
-#ifdef PROVIDE_STABLE
extern Type typeStable;
-#endif
#ifdef PROVIDE_WEAK
extern Type typeWeak;
#endif
@@ -106,6 +102,7 @@ extern Name namePmLe;
extern Name namePmSubtract;
extern Name namePmFromInteger;
extern Name nameMkIO;
+extern Name nameRunST;
extern Name nameUnpackString;
extern Name namePrimSeq;
extern Name nameMap;
diff --git a/ghc/interpreter/parser.y b/ghc/interpreter/parser.y
index 4b860aaf81..9c73280891 100644
--- a/ghc/interpreter/parser.y
+++ b/ghc/interpreter/parser.y
@@ -11,8 +11,8 @@
* in the distribution for details.
*
* $RCSfile: parser.y,v $
- * $Revision: 1.7 $
- * $Date: 1999/07/06 15:24:40 $
+ * $Revision: 1.8 $
+ * $Date: 1999/10/15 11:02:20 $
* ------------------------------------------------------------------------*/
%{
@@ -89,7 +89,8 @@ static Void local noTREX Args((String));
%token '!' IMPLIES '(' ',' ')'
%token '[' ';' ']' '`' '.'
%token TMODULE IMPORT HIDING QUALIFIED ASMOD
-%token EXPORT INTERFACE REQUIRES UNSAFE INSTIMPORT
+%token EXPORT UUEXPORT INTERFACE REQUIRES UNSAFE
+%token INSTIMPORT DYNAMIC
%%
/*- Top level script/module structure -------------------------------------*/
@@ -139,7 +140,7 @@ ifDecl
| INSTIMPORT CONID {$$=gc2(NIL);}
- | EXPORT CONID ifEntities { addGHCExports($2,$3);
+ | UUEXPORT CONID ifEntities { addGHCExports($2,$3);
$$=gc3(NIL);}
| NUMLIT INFIXL optDigit varid_or_conid
@@ -623,7 +624,7 @@ derivs : derivs ',' qconid {$$ = gc3(cons($3,$1));}
topDecl : FOREIGN IMPORT callconv ext_loc ext_name unsafe_flag var COCO type
{foreignImport($1,pair($4,$5),$7,$9); sp-=9;}
- | FOREIGN EXPORT callconv ext_name qvarid COCO type
+ | FOREIGN EXPORT callconv DYNAMIC qvarid COCO type
{foreignExport($1,$4,$5,$7); sp-=7;}
;
diff --git a/ghc/interpreter/static.c b/ghc/interpreter/static.c
index c6f9a7ebbc..38e179da88 100644
--- a/ghc/interpreter/static.c
+++ b/ghc/interpreter/static.c
@@ -8,8 +8,8 @@
* in the distribution for details.
*
* $RCSfile: static.c,v $
- * $Revision: 1.8 $
- * $Date: 1999/07/06 15:24:41 $
+ * $Revision: 1.9 $
+ * $Date: 1999/10/15 11:02:22 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
@@ -2789,7 +2789,6 @@ static Void local checkDefaultDefns() { /* check that default types are */
}
-/*-- from STG --*/
/* --------------------------------------------------------------------------
* Foreign import declarations are Hugs' equivalent of GHC's ccall mechanism.
* They are used to "import" C functions into a module.
@@ -2869,61 +2868,6 @@ Name p; {
-
-#if 0
-/*-- from 98 --*/
-/* --------------------------------------------------------------------------
- * Primitive definitions are usually only included in the first script
- * file read - the prelude. A primitive definition associates a variable
- * name with a string (which identifies a built-in primitive) and a type.
- * ------------------------------------------------------------------------*/
-
-Void primDefn(line,prims,type) /* Handle primitive definitions */
-Cell line;
-List prims;
-Cell type; {
- primDefns = cons(triple(line,prims,type),primDefns);
-}
-
-static List local checkPrimDefn(pd) /* Check primitive definition */
-Triple pd; {
- Int line = intOf(fst3(pd));
- List prims = snd3(pd);
- Type type = thd3(pd);
- emptySubstitution();
- type = checkSigType(line,"primitive definition",fst(hd(prims)),type);
- for (; nonNull(prims); prims=tl(prims)) {
- Cell p = hd(prims);
- Bool same = isVar(p);
- Text pt = textOf(same ? p : fst(p));
- String pr = textToStr(textOf(same ? p : snd(p)));
- hd(prims) = addNewPrim(line,pt,pr,type);
- }
- return snd3(pd);
-}
-
-static Name local addNewPrim(l,vn,s,t) /* make binding of variable vn to */
-Int l; /* primitive function referred */
-Text vn; /* to by s, with given type t */
-String s;
-Cell t;{
- Name n = findName(vn);
-
- if (isNull(n)) {
- n = newName(vn,NIL);
- } else if (name(n).defn!=PREDEFINED) {
- duplicateError(l,name(n).mod,vn,"primitive");
- }
-
- addPrim(l,n,s,t);
- return n;
-}
-#endif
-
-
-
-
-
/* --------------------------------------------------------------------------
* Static analysis of patterns:
*
diff --git a/ghc/interpreter/storage.c b/ghc/interpreter/storage.c
index 7de66abd5a..2015905d98 100644
--- a/ghc/interpreter/storage.c
+++ b/ghc/interpreter/storage.c
@@ -8,8 +8,8 @@
* in the distribution for details.
*
* $RCSfile: storage.c,v $
- * $Revision: 1.8 $
- * $Date: 1999/07/06 15:24:43 $
+ * $Revision: 1.9 $
+ * $Date: 1999/10/15 11:02:26 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
@@ -503,6 +503,16 @@ Name nameFromStgVar ( StgVar v )
return NIL;
}
+void* getHugs_AsmObject_for ( char* s )
+{
+ StgVar v;
+ Name n = findName(findText(s));
+ if (isNull(n)) internal("getHugs_AsmObject_for(1)");
+ v = name(n).stgVar;
+ if (!isStgVar(v) || !isPtr(stgVarInfo(v)))
+ internal("getHugs_AsmObject_for(2)");
+ return ptrOf(stgVarInfo(v));
+}
/* --------------------------------------------------------------------------
* Primitive functions:
diff --git a/ghc/interpreter/translate.c b/ghc/interpreter/translate.c
index 53647c21f5..8c11034a8f 100644
--- a/ghc/interpreter/translate.c
+++ b/ghc/interpreter/translate.c
@@ -8,8 +8,8 @@
* Hugs version 1.4, December 1997
*
* $RCSfile: translate.c,v $
- * $Revision: 1.7 $
- * $Date: 1999/04/27 10:07:08 $
+ * $Revision: 1.8 $
+ * $Date: 1999/10/15 11:02:35 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
@@ -534,11 +534,15 @@ List scs; { /* in incr order of strict comps. */
* Foreign function calls and primops
* ------------------------------------------------------------------------*/
-static String charListToString( List cs );
-static Cell foreignResultTy( Type t );
-static Cell foreignArgTy( Type t );
-static Name repToBox Args(( char c ));
-static StgRhs makeStgPrim Args(( Name,Bool,List,String,String ));
+/* Outbound denotes data moving from Haskell world to elsewhere.
+ Inbound denotes data moving from elsewhere to Haskell world.
+*/
+static String charListToString ( List cs );
+static Cell foreignTy ( Bool outBound, Type t );
+static Cell foreignOutboundTy ( Type t );
+static Cell foreignInboundTy ( Type t );
+static Name repToBox ( char c );
+static StgRhs makeStgPrim ( Name,Bool,List,String,String );
static String charListToString( List cs )
{
@@ -553,11 +557,13 @@ static String charListToString( List cs )
return textToStr(findText(s));
}
-static Cell foreignResultTy( Type t )
+static Cell foreignTy ( Bool outBound, Type t )
{
if (t == typeChar) return mkChar(CHAR_REP);
else if (t == typeInt) return mkChar(INT_REP);
+#if 0
else if (t == typeInteger)return mkChar(INTEGER_REP);
+#endif
else if (t == typeWord) return mkChar(WORD_REP);
else if (t == typeAddr) return mkChar(ADDR_REP);
else if (t == typeFloat) return mkChar(FLOAT_REP);
@@ -566,6 +572,7 @@ static Cell foreignResultTy( Type t )
else if (t == typeForeign)return mkChar(FOREIGN_REP);
/* ToDo: argty only! */
#endif
+#if 0
else if (t == typePrimByteArray) return mkChar(BARR_REP);
/* ToDo: argty only! */
else if (whatIs(t) == AP) {
@@ -573,16 +580,29 @@ static Cell foreignResultTy( Type t )
if (h == typePrimMutableByteArray) return mkChar(MUTBARR_REP);
/* ToDo: argty only! */
}
+#endif
/* ToDo: decent line numbers! */
- ERRMSG(0) "Illegal foreign type" ETHEN
- ERRTEXT " \"" ETHEN ERRTYPE(t);
- ERRTEXT "\""
- EEND;
+ if (outBound) {
+ ERRMSG(0) "Illegal outbound (away from Haskell) type" ETHEN
+ ERRTEXT " \"" ETHEN ERRTYPE(t);
+ ERRTEXT "\""
+ EEND;
+ } else {
+ ERRMSG(0) "Illegal inbound (towards Haskell) type" ETHEN
+ ERRTEXT " \"" ETHEN ERRTYPE(t);
+ ERRTEXT "\""
+ EEND;
+ }
+}
+
+static Cell foreignOutboundTy ( Type t )
+{
+ return foreignTy ( TRUE, t );
}
-static Cell foreignArgTy( Type t )
+static Cell foreignInboundTy ( Type t )
{
- return foreignResultTy( t );
+ return foreignTy ( FALSE, t );
}
static Name repToBox( char c )
@@ -600,9 +620,7 @@ static Name repToBox( char c )
case REF_REP: return nameMkRef;
case MUTARR_REP: return nameMkPrimMutableArray;
case MUTBARR_REP: return nameMkPrimMutableByteArray;
-#ifdef PROVIDE_STABLE
case STABLE_REP: return nameMkStable;
-#endif
#ifdef PROVIDE_WEAK
case WEAK_REP: return nameMkWeak;
#endif
@@ -765,7 +783,7 @@ String r_reps; {
}
}
-Void implementPrim( n )
+Void implementPrim ( n )
Name n; {
const AsmPrim* p = name(n).primop;
StgRhs rhs = makeStgPrim(n,p->monad!=MONAD_Id,NIL,p->args,p->results);
@@ -797,9 +815,9 @@ Name n; {
* ::
* Addr -> (Int -> Float -> IO (Char,Addr))
*/
-Void implementForeignImport( Name n )
+Void implementForeignImport ( Name n )
{
- Type t = name(n).type;
+ Type t = name(n).type;
List argTys = NIL;
List resultTys = NIL;
CFunDescriptor* descriptor = 0;
@@ -828,8 +846,8 @@ Void implementForeignImport( Name n )
} else {
resultTys = singleton(resultTys);
}
- mapOver(foreignArgTy,argTys); /* allows foreignObj, byteArrays, etc */
- mapOver(foreignResultTy,resultTys); /* doesn't */
+ mapOver(foreignOutboundTy,argTys); /* allows foreignObj, byteArrays, etc */
+ mapOver(foreignInboundTy,resultTys); /* doesn't */
descriptor = mkDescriptor(charListToString(argTys),
charListToString(resultTys));
name(n).primop = addState ? &ccall_IO : &ccall_Id;
@@ -847,7 +865,7 @@ Void implementForeignImport( Name n )
textToStr(textOf(fst(extName)))
EEND;
}
- //ppStg(v);
+ /* ppStg(v); */
name(n).defn = NIL;
name(n).stgVar = v;
name(n).stgSize = stgSize(stgVarBody(v));
@@ -856,9 +874,94 @@ Void implementForeignImport( Name n )
}
}
-Void implementForeignExport( Name n )
+
+/* Generate code:
+ *
+ * \ fun s0 ->
+ let e1 = A# "...."
+ in primMkAdjThunk fun s0 e1
+
+ we require, and check that,
+ fun :: prim_arg* -> IO prim_result
+ */
+Void implementForeignExport ( Name n )
{
- internal("implementForeignExport: not implemented");
+ Type t = name(n).type;
+ List argTys = NIL;
+ List resultTys = NIL;
+
+ if (getHead(t)==typeArrow && argCount==2) {
+ t = arg(fun(t));
+ } else {
+ ERRMSG(0) "foreign export has illegal type" ETHEN
+ ERRTEXT " \"" ETHEN ERRTYPE(t);
+ ERRTEXT "\""
+ EEND;
+ }
+
+ while (getHead(t)==typeArrow && argCount==2) {
+ Type ta = fullExpand(arg(fun(t)));
+ Type tr = arg(t);
+ argTys = cons(ta,argTys);
+ t = tr;
+ }
+ argTys = rev(argTys);
+ if (getHead(t) == typeIO) {
+ resultTys = getArgs(t);
+ assert(length(resultTys) == 1);
+ resultTys = hd(resultTys);
+ } else {
+ ERRMSG(0) "foreign export doesn't return an IO type" ETHEN
+ ERRTEXT " \"" ETHEN ERRTYPE(t);
+ ERRTEXT "\""
+ EEND;
+ }
+ resultTys = fullExpand(resultTys);
+
+ mapOver(foreignInboundTy,argTys);
+
+ {
+ List tdList;
+ Text tdText;
+ List args;
+ StgVar e1, e2, v;
+ StgExpr fun;
+
+ tdList = cons(mkChar(':'),argTys);
+ if (resultTys != typeUnit)
+ tdList = cons(foreignOutboundTy(resultTys),tdList);
+
+ tdText = findText(charListToString ( tdList ));
+ args = makeArgs(2);
+ e1 = mkStgVar(
+ mkStgCon(nameMkA,singleton(ap(STRCELL,tdText))),
+ NIL
+ );
+ e2 = mkStgVar(
+ mkStgApp(nameUnpackString,singleton(e1)),
+ NIL
+ );
+
+ fun = mkStgLambda(
+ args,
+ mkStgLet(
+ doubleton(e1,e2),
+ mkStgApp(
+ nameCreateAdjThunk,
+ tripleton(hd(args),e2,hd(tl(args)))
+ )
+ )
+ );
+
+ v = mkStgVar(fun,NIL);
+ /* ppStg(v); */
+
+ name(n).defn = NIL;
+ name(n).stgVar = v;
+ name(n).stgSize = stgSize(stgVarBody(v));
+ name(n).inlineMe = FALSE;
+ stgGlobals = cons(pair(n,v),stgGlobals);
+ }
}
// ToDo: figure out how to set inlineMe for these (non-Name) things
diff --git a/ghc/interpreter/type.c b/ghc/interpreter/type.c
index ff794f7349..f5430d5a43 100644
--- a/ghc/interpreter/type.c
+++ b/ghc/interpreter/type.c
@@ -8,8 +8,8 @@
* in the distribution for details.
*
* $RCSfile: type.c,v $
- * $Revision: 1.7 $
- * $Date: 1999/06/07 17:22:31 $
+ * $Revision: 1.8 $
+ * $Date: 1999/10/15 11:02:40 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
@@ -2469,10 +2469,7 @@ Char k; {
case REF_REP: return ap2(typeRef,mkStateVar(),mkAlphaVar());
case MUTARR_REP: return ap2(typePrimMutableArray,mkStateVar(),mkAlphaVar());
case MUTBARR_REP: return ap(typePrimMutableByteArray,mkStateVar());
-#ifdef PROVIDE_STABLE
- case STABLE_REP:
- return ap(typeStable,mkAlphaVar());
-#endif
+ case STABLE_REP: return ap(typeStable,mkAlphaVar());
#ifdef PROVIDE_WEAK
case WEAK_REP:
return ap(typeWeak,mkAlphaVar());