Commit 6642714e authored by sewardj's avatar sewardj
Browse files

[project @ 1999-10-26 17:27:25 by sewardj]

Add foreign import/export implementations for x86 stdcall convention.

Make parser notice calling conventions on f-i and f-x declarations,
check they are supported on the platform Hugs is compiled on.  Pass
them all the way through the code generator to the interpreter.

Allow f-i/f-x decls to omit the calling convention, in which case
ccall is used.  Remove calling convention from all such decls
in the Prelude so it will work on any platform.
parent 37cb07db
/* -----------------------------------------------------------------------------
* $Id: Assembler.h,v 1.9 1999/10/19 11:41:35 sewardj Exp $
* $Id: Assembler.h,v 1.10 1999/10/26 17:27:35 sewardj Exp $
*
* (c) The GHC Team 1994-1998.
*
......@@ -243,8 +243,10 @@ extern void asmEndMkPAP ( AsmBCO bco, AsmVar v, AsmSp start );
* C-call and H-call
* ------------------------------------------------------------------------*/
extern const AsmPrim ccall_Id;
extern const AsmPrim ccall_IO;
extern const AsmPrim ccall_ccall_Id;
extern const AsmPrim ccall_ccall_IO;
extern const AsmPrim ccall_stdcall_Id;
extern const AsmPrim ccall_stdcall_IO;
typedef struct {
unsigned int num_args;
......
......@@ -8,8 +8,8 @@
* included in the distribution.
*
* $RCSfile: connect.h,v $
* $Revision: 1.12 $
* $Date: 1999/10/20 02:15:59 $
* $Revision: 1.13 $
* $Date: 1999/10/26 17:27:41 $
* ------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------
......@@ -78,6 +78,9 @@ 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 */
extern Text textCcall; /* used to process foreign import */
extern Text textStdcall; /* ... and foreign export */
#if NPLUSK
extern Text textPlus; /* Used to recognise n+k patterns */
#endif
......@@ -474,10 +477,10 @@ extern Type typeException;
extern Type typeIO;
extern Type typeST;
extern Void foreignImport Args((Cell,Pair,Cell,Cell));
extern Void foreignImport Args((Cell,Text,Pair,Cell,Cell));
extern List foreignImports; /* foreign import declarations */
extern Void implementForeignImport Args((Name));
extern Void foreignExport Args((Cell,Cell,Cell,Cell));
extern Void foreignExport Args((Cell,Text,Cell,Cell,Cell));
extern List foreignExports; /* foreign export declarations */
extern Void implementForeignExport Args((Name));
......
......@@ -9,8 +9,8 @@
* included in the distribution.
*
* $RCSfile: dynamic.c,v $
* $Revision: 1.9 $
* $Date: 1999/10/22 10:00:19 $
* $Revision: 1.10 $
* $Date: 1999/10/26 17:27:39 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
......@@ -52,6 +52,16 @@ String symbol; {
return GetProcAddress(instance,symbol);
}
Bool stdcallAllowed ( void )
{
return TRUE;
}
#elif HAVE_DLFCN_H /* eg LINUX, SOLARIS, ULTRIX */
#include <stdio.h>
......@@ -91,6 +101,16 @@ String symbol; {
EEND;
}
Bool stdcallAllowed ( void )
{
return FALSE;
}
#elif HAVE_DL_H /* eg HPUX */
#include <dl.h>
......@@ -107,6 +127,16 @@ String symbol; {
return (0 == shl_findsym(&instance,symbol,TYPE_PROCEDURE,&r)) ? r : 0;
}
Bool stdcallAllowed ( void )
{
return FALSE;
}
#else /* Dynamic loading not available */
void* getDLLSymbol(dll,symbol) /* load dll and lookup symbol */
......@@ -120,5 +150,10 @@ String symbol; {
#endif
}
Bool stdcallAllowed ( void )
{
return FALSE;
}
#endif /* Dynamic loading not available */
void* getDLLSymbol Args((String,String));
void* lookupSymbol Args((ObjectFile file, String symbol));
ObjectFile loadLibrary Args((String fn));
extern void* getDLLSymbol Args((String,String));
extern void* lookupSymbol Args((ObjectFile file, String symbol));
extern ObjectFile loadLibrary Args((String fn));
extern Bool stdcallAllowed Args((void));
......@@ -9,8 +9,8 @@
* included in the distribution.
*
* $RCSfile: input.c,v $
* $Revision: 1.9 $
* $Date: 1999/10/15 23:52:00 $
* $Revision: 1.10 $
* $Date: 1999/10/26 17:27:39 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
......@@ -136,6 +136,9 @@ static Text textHiding, textQualified, textAsMod;
static Text textExport, textDynamic, textUUExport;
static Text textUnsafe, textUUAll;
Text textCcall; /* ccall */
Text textStdcall; /* stdcall */
Text textNum; /* Num */
Text textPrelude; /* Prelude */
Text textPlus; /* (+) */
......@@ -1493,6 +1496,8 @@ static Int local yylex() { /* Read next input token ... */
if (it==textImport) return IMPORT;
if (it==textExport) return EXPORT;
if (it==textDynamic) return DYNAMIC;
if (it==textCcall) return CCALL;
if (it==textStdcall) return STDCALL;
if (it==textUUExport) return UUEXPORT;
if (it==textHiding) return HIDING;
if (it==textQualified) return QUALIFIED;
......@@ -1709,6 +1714,8 @@ Int what; {
textInstImport = findText("__instimport");
textExport = findText("export");
textDynamic = findText("dynamic");
textCcall = findText("ccall");
textStdcall = findText("stdcall");
textUUExport = findText("__export");
textImport = findText("import");
textHiding = findText("hiding");
......
......@@ -114,6 +114,7 @@ module Prelude (
-- debugging hacks
--,ST(..)
,primIntToAddr
) where
-- Standard value bindings {Prelude} ----------------------------------------
......@@ -1549,11 +1550,11 @@ primPmFail = error "Pattern Match Failure"
primMkIO :: (RealWorld -> (a,RealWorld)) -> IO a
primMkIO = ST
primCreateAdjThunk :: (a -> b) -> String -> IO Addr
primCreateAdjThunk fun typestr
primCreateAdjThunk :: (a -> b) -> String -> Char -> IO Addr
primCreateAdjThunk fun typestr callconv
= do sp <- makeStablePtr fun
p <- copy_String_to_cstring typestr -- is never freed
a <- primCreateAdjThunkARCH sp p
a <- primCreateAdjThunkARCH sp p callconv
return a
-- The following primitives are only needed if (n+k) patterns are enabled:
......@@ -1702,24 +1703,24 @@ data IOResult = IOResult deriving (Show)
type FILE_STAR = Int -- FILE *
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 :: 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 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 :: Addr -> IO Addr
foreign import "nHandle.so" "nh_stdin" nh_stdin :: IO FILE_STAR
foreign import "nHandle.so" "nh_stdout" nh_stdout :: IO FILE_STAR
foreign import "nHandle.so" "nh_stderr" nh_stderr :: IO FILE_STAR
foreign import "nHandle.so" "nh_write" nh_write :: FILE_STAR -> Int -> IO ()
foreign import "nHandle.so" "nh_read" nh_read :: FILE_STAR -> IO Int
foreign import "nHandle.so" "nh_open" nh_open :: Addr -> Int -> IO FILE_STAR
foreign import "nHandle.so" "nh_flush" nh_flush :: FILE_STAR -> IO ()
foreign import "nHandle.so" "nh_close" nh_close :: FILE_STAR -> IO ()
foreign import "nHandle.so" "nh_errno" nh_errno :: IO Int
foreign import "nHandle.so" "nh_malloc" nh_malloc :: Int -> IO Addr
foreign import "nHandle.so" "nh_free" nh_free :: Addr -> IO ()
foreign import "nHandle.so" "nh_store" nh_store :: Addr -> Int -> IO ()
foreign import "nHandle.so" "nh_load" nh_load :: Addr -> IO Int
foreign import "nHandle.so" "nh_argc" nh_argc :: IO Int
foreign import "nHandle.so" "nh_argvb" nh_argvb :: Int -> Int -> IO Int
foreign import "nHandle.so" "nh_getenv" nh_getenv :: Addr -> IO Addr
copy_String_to_cstring :: String -> IO Addr
copy_String_to_cstring s
......
......@@ -12,8 +12,8 @@
* included in the distribution.
*
* $RCSfile: parser.y,v $
* $Revision: 1.11 $
* $Date: 1999/10/20 02:16:02 $
* $Revision: 1.12 $
* $Date: 1999/10/26 17:27:37 $
* ------------------------------------------------------------------------*/
%{
......@@ -97,7 +97,7 @@ static Void local noIP Args((String));
%token '[' ';' ']' '`' '.'
%token TMODULE IMPORT HIDING QUALIFIED ASMOD
%token EXPORT UUEXPORT INTERFACE REQUIRES UNSAFE
%token INSTIMPORT DYNAMIC
%token INSTIMPORT DYNAMIC CCALL STDCALL
%%
/*- Top level script/module structure -------------------------------------*/
......@@ -631,12 +631,14 @@ derivs : derivs ',' qconid {$$ = gc3(cons($3,$1));}
/*- Processing definitions of primitives ----------------------------------*/
topDecl : FOREIGN IMPORT callconv ext_loc ext_name unsafe_flag var COCO type
{foreignImport($1,pair($4,$5),$7,$9); sp-=9;}
{foreignImport($1,$3,pair($4,$5),$7,$9); sp-=9;}
| FOREIGN EXPORT callconv DYNAMIC qvarid COCO type
{foreignExport($1,$4,$5,$7); sp-=7;}
{foreignExport($1,$3,$4,$5,$7); sp-=7;}
;
callconv : var {$$ = gc1(NIL); /* ignored */ }
callconv : CCALL {$$ = gc1(textCcall);}
| STDCALL {$$ = gc1(textStdcall);}
| /* empty */ {$$ = gc0(NIL);}
;
ext_loc : STRINGLIT {$$ = $1;}
;
......
......@@ -9,8 +9,8 @@
* included in the distribution.
*
* $RCSfile: static.c,v $
* $Revision: 1.12 $
* $Date: 1999/10/19 12:05:27 $
* $Revision: 1.13 $
* $Date: 1999/10/26 17:27:45 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
......@@ -3138,8 +3138,10 @@ static Void local checkDefaultDefns() { /* check that default types are */
* what "foreign export static" would mean in an interactive setting.
* ------------------------------------------------------------------------*/
Void foreignImport(line,extName,intName,type) /* Handle foreign imports */
Void foreignImport(line,callconv,extName,intName,type)
/* Handle foreign imports */
Cell line;
Text callconv;
Pair extName;
Cell intName;
Cell type; {
......@@ -3153,10 +3155,11 @@ Cell type; {
ERRMSG(l) "Redeclaration of foreign \"%s\"", textToStr(t)
EEND;
}
name(n).line = l;
name(n).defn = extName;
name(n).type = type;
foreignImports = cons(n,foreignImports);
name(n).line = l;
name(n).defn = extName;
name(n).type = type;
name(n).callconv = callconv;
foreignImports = cons(n,foreignImports);
}
static Void local checkForeignImport(p) /* Check foreign import */
......@@ -3173,8 +3176,10 @@ Name p; {
implementForeignImport(p);
}
Void foreignExport(line,extName,intName,type)/* Handle foreign exports */
Void foreignExport(line,callconv,extName,intName,type)
/* Handle foreign exports */
Cell line;
Text callconv;
Cell extName;
Cell intName;
Cell type; {
......@@ -3188,10 +3193,11 @@ Cell type; {
ERRMSG(l) "Redeclaration of foreign \"%s\"", textToStr(t)
EEND;
}
name(n).line = l;
name(n).defn = NIL; /* nothing to say */
name(n).type = type;
foreignExports = cons(n,foreignExports);
name(n).line = l;
name(n).defn = NIL; /* nothing to say */
name(n).type = type;
name(n).callconv = callconv;
foreignExports = cons(n,foreignExports);
}
static Void local checkForeignExport(p) /* Check foreign export */
......
......@@ -9,8 +9,8 @@
* included in the distribution.
*
* $RCSfile: storage.c,v $
* $Revision: 1.13 $
* $Date: 1999/10/20 02:16:05 $
* $Revision: 1.14 $
* $Date: 1999/10/26 17:27:43 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
......@@ -438,6 +438,7 @@ Cell parent; {
name(nameHw).inlineMe = FALSE;
name(nameHw).simplified = FALSE;
name(nameHw).isDBuilder = FALSE;
name(nameHw).callconv = NIL;
name(nameHw).type = NIL;
name(nameHw).primop = 0;
name(nameHw).mod = currentModule;
......
......@@ -10,8 +10,8 @@
* included in the distribution.
*
* $RCSfile: storage.h,v $
* $Revision: 1.10 $
* $Date: 1999/10/16 02:17:25 $
* $Revision: 1.11 $
* $Date: 1999/10/26 17:27:42 $
* ------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------
......@@ -555,6 +555,7 @@ struct strName {
Bool inlineMe; /* self-evident */
Bool simplified; /* TRUE => already simplified */
Bool isDBuilder; /* TRUE => is a dictionary builder */
Text callconv; /* for foreign import/export */
const void* primop; /* really StgPrim* */
Name nextNameHash;
};
......
......@@ -10,8 +10,8 @@
* included in the distribution.
*
* $RCSfile: translate.c,v $
* $Revision: 1.10 $
* $Date: 1999/10/19 11:01:24 $
* $Revision: 1.11 $
* $Date: 1999/10/26 17:27:36 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
......@@ -529,7 +529,7 @@ List scs; { /* in incr order of strict comps. */
name(c).inlineMe = TRUE;
name(c).stgSize = stgSize(stgVarBody(name(c).stgVar));
stgGlobals = cons(pair(c,name(c).stgVar),stgGlobals);
//printStg(stderr, name(c).stgVar); fprintf(stderr,"\n\n");
/* printStg(stderr, name(c).stgVar); fprintf(stderr,"\n\n"); */
}
/* --------------------------------------------------------------------------
......@@ -570,6 +570,7 @@ static Cell foreignTy ( Bool outBound, Type t )
else if (t == typeAddr) return mkChar(ADDR_REP);
else if (t == typeFloat) return mkChar(FLOAT_REP);
else if (t == typeDouble) return mkChar(DOUBLE_REP);
else if (t == typeStable) return mkChar(STABLE_REP);
#ifdef PROVIDE_FOREIGN
else if (t == typeForeign)return mkChar(FOREIGN_REP);
/* ToDo: argty only! */
......@@ -705,7 +706,6 @@ static StgRhs unboxVars( String reps, List b_args, List u_args, StgExpr e )
if (nonNull(b_args)) {
StgVar b_arg = hd(b_args); /* boxed arg */
StgVar u_arg = hd(u_args); /* unboxed arg */
//StgRep k = mkStgRep(*reps);
Name box = repToBox(*reps);
e = unboxVars(reps+1,tl(b_args),tl(u_args),e);
if (isNull(box)) {
......@@ -853,11 +853,25 @@ Void implementForeignImport ( Name n )
descriptor = mkDescriptor(charListToString(argTys),
charListToString(resultTys));
if (!descriptor) {
ERRMSG(0) "Can't allocate memory for call descriptor"
ERRMSG(name(n).line) "Can't allocate memory for call descriptor"
EEND;
}
name(n).primop = addState ? &ccall_IO : &ccall_Id;
/* ccall is the default convention, if it wasn't specified */
if (isNull(name(n).callconv)
|| name(n).callconv == textCcall) {
name(n).primop = addState ? &ccall_ccall_IO : &ccall_ccall_Id;
}
else if (name(n).callconv == textStdcall) {
if (!stdcallAllowed()) {
ERRMSG(name(n).line) "stdcall is not supported on this platform"
EEND;
}
name(n).primop = addState ? &ccall_stdcall_IO : &ccall_stdcall_Id;
}
else
internal ( "implementForeignImport: unknown calling convention");
{
Pair extName = name(n).defn;
void* funPtr = getDLLSymbol(textToStr(textOf(fst(extName))),
......@@ -867,7 +881,7 @@ Void implementForeignImport ( Name n )
descriptor->result_tys);
StgVar v = mkStgVar(rhs,NIL);
if (funPtr == 0) {
ERRMSG(0) "Could not find foreign function \"%s\" in \"%s\"",
ERRMSG(name(n).line) "Could not find foreign function \"%s\" in \"%s\"",
textToStr(textOf(snd(extName))),
textToStr(textOf(fst(extName)))
EEND;
......@@ -886,7 +900,8 @@ Void implementForeignImport ( Name n )
*
* \ fun s0 ->
let e1 = A# "...."
in primMkAdjThunk fun s0 e1
e3 = C# 'c' -- (ccall), or 's' (stdcall)
in primMkAdjThunk fun e1 e3 s0
we require, and check that,
fun :: prim_arg* -> IO prim_result
......@@ -896,11 +911,12 @@ Void implementForeignExport ( Name n )
Type t = name(n).type;
List argTys = NIL;
List resultTys = NIL;
Char cc_char;
if (getHead(t)==typeArrow && argCount==2) {
t = arg(fun(t));
} else {
ERRMSG(0) "foreign export has illegal type" ETHEN
ERRMSG(name(n).line) "foreign export has illegal type" ETHEN
ERRTEXT " \"" ETHEN ERRTYPE(t);
ERRTEXT "\""
EEND;
......@@ -918,7 +934,7 @@ Void implementForeignExport ( Name n )
assert(length(resultTys) == 1);
resultTys = hd(resultTys);
} else {
ERRMSG(0) "foreign export doesn't return an IO type" ETHEN
ERRMSG(name(n).line) "foreign export doesn't return an IO type" ETHEN
ERRTEXT " \"" ETHEN ERRTYPE(t);
ERRTEXT "\""
EEND;
......@@ -927,11 +943,27 @@ Void implementForeignExport ( Name n )
mapOver(foreignInboundTy,argTys);
/* ccall is the default convention, if it wasn't specified */
if (isNull(name(n).callconv)
|| name(n).callconv == textCcall) {
cc_char = 'c';
}
else if (name(n).callconv == textStdcall) {
if (!stdcallAllowed()) {
ERRMSG(name(n).line) "stdcall is not supported on this platform"
EEND;
}
cc_char = 's';
}
else
internal ( "implementForeignExport: unknown calling convention");
{
List tdList;
Text tdText;
List args;
StgVar e1, e2, v;
StgVar e1, e2, e3, v;
StgExpr fun;
tdList = cons(mkChar(':'),argTys);
......@@ -944,24 +976,27 @@ Void implementForeignExport ( Name n )
mkStgCon(nameMkA,singleton(ap(STRCELL,tdText))),
NIL
);
e2 = mkStgVar(
e2 = mkStgVar(
mkStgApp(nameUnpackString,singleton(e1)),
NIL
);
e3 = mkStgVar(
mkStgCon(nameMkC,singleton(mkChar(cc_char))),
NIL
);
fun = mkStgLambda(
args,
mkStgLet(
doubleton(e1,e2),
tripleton(e1,e2,e3),
mkStgApp(
nameCreateAdjThunk,
tripleton(hd(args),e2,hd(tl(args)))
cons(hd(args),cons(e2,cons(e3,cons(hd(tl(args)),NIL))))
)
)
);
v = mkStgVar(fun,NIL);
/* ppStg(v); */
ppStg(v);
name(n).defn = NIL;
name(n).stgVar = v;
......
......@@ -114,6 +114,7 @@ module Prelude (
-- debugging hacks
--,ST(..)
,primIntToAddr
) where
-- Standard value bindings {Prelude} ----------------------------------------
......@@ -1549,11 +1550,11 @@ primPmFail = error "Pattern Match Failure"
primMkIO :: (RealWorld -> (a,RealWorld)) -> IO a
primMkIO = ST
primCreateAdjThunk :: (a -> b) -> String -> IO Addr
primCreateAdjThunk fun typestr
primCreateAdjThunk :: (a -> b) -> String -> Char -> IO Addr
primCreateAdjThunk fun typestr callconv
= do sp <- makeStablePtr fun
p <- copy_String_to_cstring typestr -- is never freed
a <- primCreateAdjThunkARCH sp p
a <- primCreateAdjThunkARCH sp p callconv
return a
-- The following primitives are only needed if (n+k) patterns are enabled:
......@@ -1702,24 +1703,24 @@ data IOResult = IOResult deriving (Show)
type FILE_STAR = Int -- FILE *
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 :: 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 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 :: Addr -> IO Addr
foreign import "nHandle.so" "nh_stdin" nh_stdin :: IO FILE_STAR
foreign import "nHandle.so" "nh_stdout" nh_stdout :: IO FILE_STAR
foreign import "nHandle.so" "nh_stderr" nh_stderr :: IO FILE_STAR
foreign import "nHandle.so" "nh_write" nh_write :: FILE_STAR -> Int -> IO ()
foreign import "nHandle.so" "nh_read" nh_read :: FILE_STAR -> IO Int
foreign import "nHandle.so" "nh_open" nh_open :: Addr -> Int -> IO FILE_STAR
foreign import "nHandle.so" "nh_flush" nh_flush :: FILE_STAR -> IO ()
foreign import "nHandle.so" "nh_close" nh_close :: FILE_STAR -> IO ()
foreign import "nHandle.so" "nh_errno" nh_errno :: IO Int
foreign import "nHandle.so" "nh_malloc" nh_malloc :: Int -> IO Addr
foreign import "nHandle.so" "nh_free" nh_free :: Addr -> IO ()
foreign import "nHandle.so" "nh_store" nh_store :: Addr -> Int -> IO ()
foreign import "nHandle.so" "nh_load" nh_load :: Addr -> IO Int
foreign import "nHandle.so" "nh_argc" nh_argc :: IO Int
foreign import "nHandle.so" "nh_argvb" nh_argvb :: Int -> Int -> IO Int
foreign import "nHandle.so" "nh_getenv" nh_getenv :: Addr -> IO Addr
copy_String_to_cstring :: String -> IO Addr
copy_String_to_cstring s
......