fix nested •FFI calls, more FFI testing

This commit is contained in:
dzaima 2024-01-02 18:57:05 +02:00
parent ca7e62d09f
commit 20185b57c5
5 changed files with 59 additions and 13 deletions

View File

@ -558,8 +558,6 @@ static usz ffiTmpAlign(usz n) {
return n;
}
static B ffiObjs;
static NOINLINE B toW(u8 reT, u8 reW, B x) {
switch(reW) { default: UD;
case 0: ffi_checkRange(x, 2, "u1", 0, 1); return taga(toBitArr(x)); break;
@ -615,6 +613,7 @@ NOINLINE B readU16Bits(B x) { usz ia=IA(x); u16* xp=tyarr_ptr(x); i32* rp; B r=m
NOINLINE B readU32Bits(B x) { usz ia=IA(x); u32* xp=tyarr_ptr(x); f64* rp; B r=m_f64arrv(&rp, ia); for (usz i=0; i<ia; i++) rp[i]=xp[i]; return num_squeeze(r); }
NOINLINE B readF32Bits(B x) { usz ia=IA(x); f32* xp=tyarr_ptr(x); f64* rp; B r=m_f64arrv(&rp, ia); for (usz i=0; i<ia; i++) rp[i]=xp[i]; return r; }
static B ffiObjsGlobal;
void genObj(B o, B c, bool anyMut, void* ptr) {
// printFFIType(stdout,o); printf(" = "); printI(c); printf("\n");
if (isC32(o)) { // scalar
@ -660,7 +659,7 @@ void genObj(B o, B c, bool anyMut, void* ptr) {
case sty_f32: ffi_checkRange(c, mut, "f64", 0, 0); cG = cpyF32Bits(c); break; // no direct f32 type, so no direct reference option
}
ffiObjs = vec_addN(ffiObjs, cG);
ffiObjsGlobal = vec_addN(ffiObjsGlobal, cG);
*(void**)ptr = tyany_ptr(cG);
} else { // *{...} / &{...} / *[n]any
BQNFFIType* t2 = c(BQNFFIType, e);
@ -674,7 +673,7 @@ void genObj(B o, B c, bool anyMut, void* ptr) {
SGetU(c)
for (usz i = 0; i < ia; i++) genObj(t->a[0].o, GetU(c, i), anyMut, dataStruct + elSz*i);
*(void**)ptr = dataStruct;
ffiObjs = vec_addN(ffiObjs, tag(TOBJ(dataAll), OBJ_TAG));
ffiObjsGlobal = vec_addN(ffiObjsGlobal, tag(TOBJ(dataAll), OBJ_TAG));
}
} else if (t->ty==cty_repr) { // any:any
B o2 = t->a[0].o;
@ -712,7 +711,7 @@ void genObj(B o, B c, bool anyMut, void* ptr) {
cG = taga(cGp);
} else cG = toW(reT, reW, c);
*(void**)ptr = tyany_ptr(cG);
ffiObjs = vec_addN(ffiObjs, cG);
ffiObjsGlobal = vec_addN(ffiObjsGlobal, cG);
}
} else if (t->ty==cty_struct || t->ty==cty_starr) {
if (!isArr(c)) thrM("FFI: Expected array corresponding to a struct");
@ -826,8 +825,6 @@ B buildObj(BQNFFIEnt ent, bool anyMut, B* objs, usz* objPos) {
}
B libffiFn_c2(B t, B w, B x) {
ffiObjs = emptyHVec();
BoundFn* bf = c(BoundFn,t);
B argObj = c(HArr,bf->obj)->a[0];
@ -859,6 +856,7 @@ B libffiFn_c2(B t, B w, B x) {
usz argn = cif->nargs;
BQNFFIEnt* ents = c(BQNFFIType,argObj)->a;
ffiObjsGlobal = emptyHVec(); // implicit parameter to genObj
for (usz i = 0; i < argn; i++) {
BQNFFIEnt e = ents[i+1];
B o;
@ -869,6 +867,7 @@ B libffiFn_c2(B t, B w, B x) {
}
genObj(e.o, o, e.extra2, tmpAlloc + e.staticOffset);
}
B ffiObjs = ffiObjsGlobal; // load the global before ffi_call to prevent issues on recursive calls
for (usz i = 0; i < argn; i++) argPtrs[i] = tmpAlloc + ents[i+1].staticOffset;
void* res = tmpAlloc + ents[0].staticOffset;
@ -923,7 +922,7 @@ B libffiFn_c2(B t, B w, B x) {
assert(objPos == IA(ffiObjs));
}
dec(w); dec(x); dec(ffiObjs);
dec(w); dec(x); decG(ffiObjs);
return r;
}
B libffiFn_c1(B t, B x) { return libffiFn_c2(t, bi_N, x); }

View File

@ -173,8 +173,4 @@
!"FFI: Pointer element type not implemented" % f@•FFI"""bqn_init"">**u64" F 2
# unchecked stuff
# !"FFI: Bad array corresponding to ""i64:c8"": expected 8 elements, got 1" % f←@•FFI""‿"bqn_init"‿">i64:c8" ⋄ F 8⥊2
# TODO test somewhere with appropriate signatures
# f←@•FFI"&"‿"foo"‿"{f32,*i8,[5]i8}"‿"*[7]i8"‿"[4]i8"‿"&i8" ⋄ F ⟨⟨1.2, ↕10, ↕5⟩, ⟨↕7, ↕7⟩, ↕4, ⟨123⟩⟩ %% ⟨123⟩
# f←@•FFI ""‿"foo"‿"{f32,*i8,[5]i8}"‿"*[7]i8"‿"[4]i8"‿"&i8" ⋄ F ⟨⟨1.2, ↕10, ↕5⟩, ⟨↕7, ↕7⟩, ↕4, ⟨123⟩⟩ %% ⟨⟨123⟩⟩
# !"FFI: Bad array corresponding to ""i64:c8"": expected 8 elements, got 1" % f←@•FFI""‿"bqn_init"‿">i64:c8" ⋄ F 8⥊2

View File

@ -290,4 +290,33 @@ void arrstruct2Inc(ArrStruct2* b) {
b[i].c[1]++;
b[i].c[2]++;
}
}
int32_t callWithinMutated(BQNV v, int32_t* data) {
data[3] = 30;
BQNV r = bqn_call1(v, v);
bqn_free(v);
bqn_free(r);
return 123;
}
typedef struct {
float a0_0;
int8_t* a0_1;
int8_t a0_2[5];
} ManyArgs0;
void manyargs(ManyArgs0 a0, int8_t (*a1)[7], int8_t a2[4], int8_t* mut) {
mut++;
*mut++ = (int8_t) a0.a0_0;
*mut++ = a0.a0_1[0];
*mut++ = a0.a0_1[9];
*mut++ = a0.a0_2[0];
*mut++ = a0.a0_2[4];
*mut++ = a1[0][0];
*mut++ = a1[0][6];
*mut++ = a1[1][0];
*mut++ = a1[1][6];
*mut++ = a2[0];
*mut++ = a2[3];
}

View File

@ -108,6 +108,22 @@ as2 ← "{[1]i32,[2]"∾as1∾",[3]f64}"
f "lib.so"•FFI as2, "arrstruct2", as2, "*"as2 •Out •Repr F 4 ¨12 1.22.33.4, 5 ¨1020 5.16.17.1
f "lib.so"•FFI "&", "arrstruct2Inc", ">&"as2 •Out •Repr F (50+) 10 ¨1112 131415
f "lib.so"•FFI "&""manyargs""{f32,*i8,[5]i8}""*[7]i8""[4]i8""&i8" •Show F 31, 10+10, 5+5, 14+7, 21+7, 40+4, 100+13 # ⟨100, 31, 10,19, 5,9 ⋄ 14,20, 21,27, 40,43, 112⟩
f "lib.so"•FFI """manyargs""{f32,*i8,[5]i8}""*[7]i8""[4]i8""&i8" •Show F 31, 10+10, 5+5, 14+7, 21+7, 40+4, 100+13
Section "# nested"
{
f "lib.so"•FFI "i32""callWithinMutated""a""&i32"
g @ •FFI "*:i8""memcpy""&i8""*i8""u64"
Fn {
! 𝕩fn
•Show 1G 50, 3+5, 4
"hello"
}
•Show F fn, 10
}
# erroring:
# "lib.so" •FFI ""‿"printArgs"‿"i8"‿"i16:c32"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64"

View File

@ -127,3 +127,9 @@ text
30
⟨⟨9⟩,⟨⟨⟨21⟩⟩,⟨⟨12⟩⟩⟩,1‿2‿17.799999999999997⟩
⟨⟨⟨11⟩,⟨⟨⟨11⟩⟩,⟨⟨13⟩⟩⟩,13‿15‿16⟩,⟨⟨61⟩,⟨⟨⟨61⟩⟩,⟨⟨63⟩⟩⟩,63‿65‿66⟩⟩
⟨ 100 31 10 19 5 9 14 20 21 27 40 43 112 ⟩
⟨ ⟨ 100 31 10 19 5 9 14 20 21 27 40 43 112 ⟩ ⟩
# nested
⟨ 3 4 5 6 0 ⟩
⟨ 123 ⟨ 0 1 2 30 4 5 6 7 8 9 ⟩ ⟩