ref: 54d75741fe4eac0b8499476185d362c5808871e9
parent: 28d1ddb809f02713298df7da0f61e0b51c688683
author: Lennart Augustsson <lennart@augustsson.net>
date: Fri Mar 1 17:59:59 EST 2024
Add some FunPtr stuff.
--- a/lib/Foreign/Ptr.hs
+++ b/lib/Foreign/Ptr.hs
@@ -1,4 +1,8 @@
-module Foreign.Ptr(module Foreign.Ptr, Ptr) where
+module Foreign.Ptr(
+ module Foreign.Ptr,
+ Ptr,
+ FunPtr,
+ ) where
import Prelude() -- do not import Prelude
import Primitives
import Data.Word
@@ -23,3 +27,7 @@
minusPtr :: forall a b . Ptr a -> Ptr b -> Int
minusPtr = primPtrSub
+
+--instance forall a . Show (FunPtr a) where
+-- showsPrec _ p = showString "FUNPTR#" . showsPrec 0 (primPtrToWord p)
+
--- a/lib/Primitives.hs
+++ b/lib/Primitives.hs
@@ -31,6 +31,7 @@
data IO a
data Word
data Ptr a
+data FunPtr a
data IOArray a
data () = () -- Parser hacks allows () to be used
--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -156,7 +156,7 @@
#endif /* WANT_STDIO */
#endif /* !define(ERR) */
-enum node_tag { T_FREE, T_IND, T_AP, T_INT, T_DBL, T_PTR, T_BADDYN, T_ARR,+enum node_tag { T_FREE, T_IND, T_AP, T_INT, T_DBL, T_PTR, T_FUNPTR, T_BADDYN, T_ARR,T_S, T_K, T_I, T_B, T_C,
T_A, T_Y, T_SS, T_BB, T_CC, T_P, T_R, T_O, T_U, T_Z,
T_K2, T_K3, T_K4, T_CCB,
@@ -219,6 +219,8 @@
struct ioarray;
struct ustring;
+typedef void (*HsFunPtr)(void);
+
typedef struct node { union {struct node *uufun;
@@ -231,6 +233,7 @@
struct ustring *uustring;
const char *uucstring;
void *uuptr;
+ HsFunPtr uufunptr;
struct ioarray *uuarray;
} uarg;
} node;
@@ -248,6 +251,7 @@
#define STR(p) (p)->uarg.uustring
#define CSTR(p) (p)->uarg.uucstring
#define PTR(p) (p)->uarg.uuptr
+#define FUNPTR(p) (p)->uarg.uufunptr
#define ARR(p) (p)->uarg.uuarray
#define INDIR(p) ARG(p)
#define NODE_SIZE sizeof(node)
@@ -1601,6 +1605,9 @@
else
ERR("Cannot serialize pointers");break;
+ case T_FUNPTR:
+ ERR("Cannot serialize function pointers");+ break;
case T_STR:
print_string(f, STR(n));
break;
@@ -1815,6 +1822,15 @@
return n;
}
+NODEPTR
+mkFunPtr(void (*p)(void))
+{+ NODEPTR n;
+ n = alloc_node(T_FUNPTR);
+ FUNPTR(n) = p;
+ return n;
+}
+
static INLINE NODEPTR
mkNil(void)
{@@ -1931,6 +1947,19 @@
return PTR(n);
}
+/* Evaluate to a T_PTR */
+void *
+evalfunptr(NODEPTR n)
+{+ n = evali(n);
+#if SANITY
+ if (GETTAG(n) != T_FUNPTR) {+ ERR1("evalfunptr, bad tag %d", GETTAG(n));+ }
+#endif
+ return FUNPTR(n);
+}
+
/* Evaluate a string, returns a newly allocated buffer. */
/* XXX this is cheating, should use continuations */
/* XXX the malloc()ed string is leaked if we yield in here. */
@@ -2009,6 +2038,7 @@
value_t x, y;
flt_t xd, yd;
void *f, *g;
+ void (*ff)(void), (*fg)(void);
NODEPTR p, q;
NODEPTR *ap, *aq;
enum node_tag ptag, qtag;
@@ -2075,6 +2105,14 @@
if (f > g)
CRET(1);
break;
+ case T_FUNPTR:
+ ff = FUNPTR(p);
+ fg = FUNPTR(q);
+ if ((intptr_t)ff < (intptr_t)fg)
+ CRET(-1);
+ if ((intptr_t)ff > (intptr_t)fg)
+ CRET(1);
+ break;
case T_ARR:
if (ARR(p) < ARR(q))
CRET(-1);
@@ -2180,6 +2218,7 @@
#define SETINT(n,r) do { SETTAG((n), T_INT); SETVALUE((n), (r)); } while(0) #define SETDBL(n,d) do { SETTAG((n), T_DBL); SETDBLVALUE((n), (d)); } while(0) #define SETPTR(n,r) do { SETTAG((n), T_PTR); PTR(n) = (r); } while(0)+#define SETFUNPTR(n,r) do { SETTAG((n), T_FUNPTR); FUNPTR(n) = (r); } while(0) #define OPINT1(e) do { CHECK(1); xi = evalint(ARG(TOP(0))); e; POP(1); n = TOP(-1); } while(0); #define OPPTR2(e) do { CHECK(2); xp = evalptr(ARG(TOP(0))); yp = evalptr(ARG(TOP(1))); e; POP(2); n = TOP(-1); } while(0); #define CMPP(op) do { OPPTR2(r = xp op yp); GOIND(r ? combTrue : combFalse); } while(0)@@ -2203,6 +2242,7 @@
case T_INT: RET;
case T_DBL: RET;
case T_PTR: RET;
+ case T_FUNPTR: RET;
case T_ARR: RET;
case T_BADDYN: ERR1("FFI unknown %s", CSTR(n));@@ -3185,6 +3225,7 @@
MHS_FROM(mhs_from_Word, SETINT, uvalue_t);
MHS_FROM(mhs_from_Word8, SETINT, uvalue_t);
MHS_FROM(mhs_from_Ptr, SETPTR, void*);
+MHS_FROM(mhs_from_FunPtr, SETFUNPTR, HsFunPtr);
MHS_FROM(mhs_from_CChar, SETINT, char);
MHS_FROM(mhs_from_CSChar, SETINT, signed char);
MHS_FROM(mhs_from_CUChar, SETINT, unsigned char);
@@ -3217,6 +3258,7 @@
MHS_TO(mhs_to_Word, evalint, uvalue_t);
MHS_TO(mhs_to_Word8, evalint, uint8_t);
MHS_TO(mhs_to_Ptr, evalptr, void*);
+MHS_TO(mhs_to_FunPtr, evalfunptr, HsFunPtr);
MHS_TO(mhs_to_CChar, evalint, char);
MHS_TO(mhs_to_CSChar, evalint, signed char);
MHS_TO(mhs_to_CUChar, evalint, unsigned char);
--
⑨