From 7fe1ab930a952d397edf357d699ecfb11e2071b9 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sat, 5 Aug 2023 16:05:57 +0300 Subject: [PATCH] =?UTF-8?q?FFI:=20permit=20=F0=9D=95=A8=E2=89=A1=E2=9F=A8?= =?UTF-8?q?=E2=9F=A9,=20require=20=F0=9D=95=A9=E2=89=A1=E2=9F=A8=E2=9F=A9?= =?UTF-8?q?=20if=20no=20arguments=20are=20on=20=F0=9D=95=A9,=20check=20lis?= =?UTF-8?q?t=20rank?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ffi.c | 13 +++++++------ test/cases/ffi.bqn | 12 +++++++++--- test/ffi/test.bqn | 1 + test/ffi/test.expected | 1 + 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/ffi.c b/src/ffi.c index 2ee3c15f..f109736e 100644 --- a/src/ffi.c +++ b/src/ffi.c @@ -824,20 +824,22 @@ B libffiFn_c2(B t, B w, B x) { BoundFn* bf = c(BoundFn,t); B argObj = c(HArr,bf->obj)->a[0]; - #define PROC_ARG(L, U, S, NG) \ + #define PROC_ARG(ISX, L, U, S) \ Arr* L##a ONLY_GCC(=0); \ AS2B L##f ONLY_GCC(=0); \ if (bf->L##Len>0) { \ if (FFI_CHECKS) { \ - if (!isArr(L)) thrM("FFI: Expected array " S); \ + if (isAtm(L) || RNK(L)!=1) thrM("FFI: Expected list " S); \ if (bf->L##Len>0 && IA(L)!=bf->L##Len) thrF("FFI: Wrong argument count in " S ": expected %s, got %s", bf->L##Len, IA(L)); \ } \ L##a = a(L); \ L##f = TIv(L##a,getU); \ - } else { NG } + } else if (FFI_CHECKS && bf->L##Len==0 && (ISX? 1 : !q_N(w)) && (isAtm(L) || RNK(L)!=1 || IA(L)!=0)) { \ + thrF("FFI: " S " must %S", ISX? "be an empty list" : "either be an empty list, or not present"); \ + } - PROC_ARG(w, W, "𝕨", if (FFI_CHECKS && bf->wLen==0 && !q_N(w)) thrM("FFI: Unnecessary 𝕨 given");) - PROC_ARG(x, X, "𝕩", ) + PROC_ARG(0, w, W, "𝕨") + PROC_ARG(1, x, X, "𝕩") i32 idxs[2] = {0,0}; @@ -999,7 +1001,6 @@ B ffiload_c2(B t, B w, B x) { c(BQNFFIType,argObj)->staticAllocTotal = ffiTmpAlign(staticAlloc); if (count[0]>1 && whole[0]) thrM("FFI: Multiple arguments on 𝕩 specified, some with '>'"); if (count[1]>1 && whole[1]) thrM("FFI: Multiple arguments on 𝕨 specified, some with '>'"); - if (count[0]==0 && count[1]>0) thrM("FFI: At least one argument should be in 𝕩"); #else i32 mutCount = 0; for (usz i = 0; i < argn; i++) ffi_parseType(GetU(x,i+2), false); diff --git a/test/cases/ffi.bqn b/test/cases/ffi.bqn index 80ec73a7..2236698a 100644 --- a/test/cases/ffi.bqn +++ b/test/cases/ffi.bqn @@ -26,7 +26,6 @@ !"FFI: Too many arguments" % @•FFI""‿"bqn_init"∾70000⥊<"i32" # >/𝕨/𝕩 -!"FFI: At least one argument should be in 𝕩" % @•FFI""‿"bqn_init"‿"𝕨i32"‿"𝕨i32" !"FFI: Multiple occurrences of '>' within one argument" % @•FFI""‿"bqn_init"‿">>i32" !"FFI: Multiple occurrences of argument side specified" % @•FFI""‿"bqn_init"‿"𝕨𝕨i32" !"FFI: Multiple occurrences of argument side specified" % @•FFI""‿"bqn_init"‿"𝕩𝕩i32" @@ -82,6 +81,7 @@ %USE defs ⋄ f←@•FFI"&"‿"memcpy"‿"&i32"‿"*i16:u1"‿size_t ⋄ F ⟨⋈5, 32⥊1, 4⟩ %% ⋈¯1 %USE defs ⋄ f←@•FFI⟨"&","memcpy","&i8","*i8",size_t∾":u1"⟩ ⋄ F ⟨¯100+↕10, ↕10, size_tw↑0‿0‿1⟩ %% (↕4)∾4↓¯100+↕10 %USE defs ⋄ f←@•FFI"&"‿"memcpy"‿"&i16"‿"*i16:i32"‿size_t ⋄ F ⟨¯100+↕10, ⟨123+456×2⋆16, ¯2⟩, 8⟩ %% 123‿456‿¯2‿¯1∾4↓¯100+↕10 +%USE defs ⋄ f←@•FFI⟨size_t,"strlen","*i8"⟩ ⋄ ⟨⟩ F ⋈1‿2‿3‿0 %% 3 @@ -109,11 +109,17 @@ # bad overall argument separation -!"FFI: Expected array 𝕩" % f←@•FFI""‿"bqn_init"‿"i32"‿"i32" ⋄ F @ -!"FFI: Unnecessary 𝕨 given" % f←@•FFI""‿"bqn_init"‿"i32"‿"i32" ⋄ @ F 1‿2 +!"FFI: Expected list 𝕩" % f←@•FFI""‿"bqn_init"‿"i32"‿"i32" ⋄ F @ +!"FFI: Expected list 𝕩" % f←@•FFI""‿"bqn_init"‿"i32"‿"i32" ⋄ F ≍⟨↕2, ↕2⟩ +!"FFI: Expected list 𝕨" % f←@•FFI""‿"bqn_init"‿"𝕨i32"‿"𝕨i32" ⋄ (≍1‿2) F ⟨⟩ !"FFI: Wrong argument count in 𝕩: expected 2, got 3" % f←@•FFI""‿"bqn_init"‿"i32"‿"i32" ⋄ F ⟨↕2, ↕2, ↕2⟩ !"FFI: Wrong argument count in 𝕩: expected 2, got 1" % f←@•FFI""‿"bqn_init"‿"i32"‿"i32" ⋄ F ⟨↕2⟩ !"FFI: Wrong argument count in 𝕨: expected 2, got 3" % f←@•FFI""‿"bqn_init"‿"i32"‿"𝕨i32"‿"𝕨i32" ⋄ ⟨↕2, ↕2, ↕2⟩ F ⟨4⟩ +!"FFI: 𝕩 must be an empty list" % f←@•FFI""‿"bqn_init" ⋄ F ⟨1⟩ +!"FFI: 𝕩 must be an empty list" % f←@•FFI""‿"bqn_init" ⋄ F @ +!"FFI: 𝕩 must be an empty list" % f←@•FFI""‿"bqn_init"‿"𝕨i32"‿"𝕨i32" ⋄ 1‿2 F @ +!"FFI: 𝕨 must either be an empty list, or not present" % f←@•FFI""‿"bqn_init"‿"*i8" ⋄ ⟨1,2⟩ F 1‿2‿3‿0 +!"FFI: 𝕨 must either be an empty list, or not present" % f←@•FFI""‿"bqn_init"‿"*i8" ⋄ @ F 1‿2‿3‿0 diff --git a/test/ffi/test.bqn b/test/ffi/test.bqn index c9d89b03..a91ec5e0 100644 --- a/test/ffi/test.bqn +++ b/test/ffi/test.bqn @@ -18,6 +18,7 @@ bind ← "lib.so" •FFI "a"‿"bindAdd"‿">a" ⋄ g ← Bind 4 ⋄ •Show G 1 Section "# namespaces" f ↩ "lib.so" •FFI "a"‿"getField"‿">𝕨a"‿"a"‿"a" ⋄ •Show {ab⇐1‿2 ⋄ cd⇐3‿4} F ⟨"ab" ⋄ "default"⟩ f ↩ "lib.so" •FFI "a"‿"getField"‿">𝕨a"‿"a"‿"a" ⋄ •Show {ab⇐1‿2 ⋄ cd⇐3‿4} F ⟨"ef" ⋄ "default"⟩ +f ↩ "lib.so" •FFI "a"‿"getField"‿"𝕨a"‿"𝕨a"‿"𝕨a" ⋄ •Show ⟨{ab⇐1‿2 ⋄ cd⇐3‿4} ⋄ "ef" ⋄ "default"⟩ F ⟨⟩ Section "# print args" f ↩ "lib.so" •FFI ""‿"printArgs"‿"i8"‿"i16"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64" ⋄ •Show F ¯123‿¯12323‿¯212312312‿250‿50000‿3123456789‿π∾÷3 diff --git a/test/ffi/test.expected b/test/ffi/test.expected index e3a28aad..69ccdafe 100644 --- a/test/ffi/test.expected +++ b/test/ffi/test.expected @@ -31,6 +31,7 @@ # namespaces ⟨ 1 2 ⟩ "default" +"default" # print args args: -123 -12323 -212312312 250 50000 3123456789 3.141592741012573242 0.333333333333333315