From ca7e62d09f01def420c0061724164f8f741cd947 Mon Sep 17 00:00:00 2001 From: dzaima Date: Tue, 2 Jan 2024 18:29:46 +0200 Subject: [PATCH] =?UTF-8?q?fix=20=E2=80=A2FFI=20with=20various=20arguments?= =?UTF-8?q?=20while=20mutable=20ones=20are=20present=20more?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ffi.c | 18 ++++++++++++++---- test/cases/ffi.bqn | 4 ++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/ffi.c b/src/ffi.c index 357c41ce..e19b193d 100644 --- a/src/ffi.c +++ b/src/ffi.c @@ -780,7 +780,7 @@ B readAny(BQNFFIEnt e, u8* ptr) { B buildObj(BQNFFIEnt ent, bool anyMut, B* objs, usz* objPos) { if (isC32(ent.o)) return m_f64(0); // scalar BQNFFIType* t = c(BQNFFIType, ent.o); - if (t->ty==cty_ptr) { // *any / &any + if (t->ty==cty_ptr || t->ty==cty_tlarr) { // *any / &any B e = t->a[0].o; B f = objs[(*objPos)++]; if (t->a[0].mutPtr) { @@ -815,7 +815,14 @@ B buildObj(BQNFFIEnt ent, bool anyMut, B* objs, usz* objPos) { B f = objs[(*objPos)++]; if (!t2->a[0].mutPtr) return m_f64(0); return inc(f); - } else thrM("FFI: Unimplemented type (buildObj)"); + } else if (t->ty==cty_struct || t->ty==cty_starr) { + assert(!anyMut); // Structs currently cannot contain mutable references + + usz ia = t->ia-1; + for (usz i = 0; i < ia; i++) buildObj(t->a[i], false, objs, objPos); // just to forward objPos + + return m_f64(0); + } else thrF("FFI: Unimplemented type (buildObj: %i)", (i32)t->ty); } B libffiFn_c2(B t, B w, B x) { @@ -900,17 +907,20 @@ B libffiFn_c2(B t, B w, B x) { if (resSingle) { for (usz i = 0; i < argn; i++) { BQNFFIEnt e = ents[i+1]; - if (e.mutates) r = buildObj(e, e.mutates, harr_ptr(ffiObjs), &objPos); + B c = buildObj(e, e.mutates, harr_ptr(ffiObjs), &objPos); + if (e.mutates) r = c; } } else { M_HARR(ra, mutArgs+(resVoid? 0 : 1)); if (!resVoid) HARR_ADDA(ra, r); for (usz i = 0; i < argn; i++) { BQNFFIEnt e = ents[i+1]; - if (e.mutates) HARR_ADDA(ra, buildObj(e, e.mutates, harr_ptr(ffiObjs), &objPos)); + B c = buildObj(e, e.mutates, harr_ptr(ffiObjs), &objPos); + if (e.mutates) HARR_ADDA(ra, c); } r = HARR_FV(ra); } + assert(objPos == IA(ffiObjs)); } dec(w); dec(x); dec(ffiObjs); diff --git a/test/cases/ffi.bqn b/test/cases/ffi.bqn index d550ad00..68c4ce3d 100644 --- a/test/cases/ffi.bqn +++ b/test/cases/ffi.bqn @@ -174,3 +174,7 @@ # 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⟩⟩ \ No newline at end of file