ffi tests
This commit is contained in:
parent
662b23d808
commit
12631cb142
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,3 +10,6 @@ perf.*
|
|||||||
/Singeli
|
/Singeli
|
||||||
/local/
|
/local/
|
||||||
CBQNHeapDump
|
CBQNHeapDump
|
||||||
|
/test/ffi/ffiTest.o
|
||||||
|
/test/ffi/test.got
|
||||||
|
/test/ffi/lib.so
|
||||||
|
|||||||
@ -22,7 +22,7 @@ static BQNV makeX(B x) {
|
|||||||
void bqn_free(BQNV v) {
|
void bqn_free(BQNV v) {
|
||||||
dec(getB(v));
|
dec(getB(v));
|
||||||
}
|
}
|
||||||
static void freeTagged (BQNV v) { }
|
static void freeTagged(BQNV v) { }
|
||||||
#define DIRECT_BQNV 1
|
#define DIRECT_BQNV 1
|
||||||
|
|
||||||
double bqn_toF64 (BQNV v) { double r = o2fu(getB(v)); freeTagged(v); return r; }
|
double bqn_toF64 (BQNV v) { double r = o2fu(getB(v)); freeTagged(v); return r; }
|
||||||
@ -444,7 +444,7 @@ usz genObj(BQNFFIEnt ent, B c, bool anyMut) {
|
|||||||
if (!isArr(c)) thrF("FFI: Expected array corresponding to \"*%S\"", sty_names[o2cu(e)]);
|
if (!isArr(c)) thrF("FFI: Expected array corresponding to \"*%S\"", sty_names[o2cu(e)]);
|
||||||
usz ia = a(c)->ia;
|
usz ia = a(c)->ia;
|
||||||
bool mut = t->a[0].mutPtr;
|
bool mut = t->a[0].mutPtr;
|
||||||
switch(o2cu(e)) { default: thrF("FFI: Unimplemented pointer to \"%S\"", sty_names[o2cu(e)]);
|
switch(o2cu(e)) { default: thrF("FFI: \"*%S\" argument type NYI", sty_names[o2cu(e)]);
|
||||||
case sty_i8: cG = mut? taga(cpyI8Arr (c)) : toI8Any (c); break;
|
case sty_i8: cG = mut? taga(cpyI8Arr (c)) : toI8Any (c); break;
|
||||||
case sty_i16: cG = mut? taga(cpyI16Arr(c)) : toI16Any(c); break;
|
case sty_i16: cG = mut? taga(cpyI16Arr(c)) : toI16Any(c); break;
|
||||||
case sty_i32: cG = mut? taga(cpyI32Arr(c)) : toI32Any(c); break;
|
case sty_i32: cG = mut? taga(cpyI32Arr(c)) : toI32Any(c); break;
|
||||||
|
|||||||
@ -12,4 +12,5 @@ test/moreCfgs.sh path/to/mlochbaum/BQN // run "2+2" in a bunch of configurations
|
|||||||
./BQN test/bitcpy.bqn // fuzz-test bit_cpy; requires a CBQN build with -DTEST_BITCPY
|
./BQN test/bitcpy.bqn // fuzz-test bit_cpy; requires a CBQN build with -DTEST_BITCPY
|
||||||
./BQN test/squeeze.bqn // fuzz-test squeezing; requires a CBQN build with -DEEQUAL_NEGZERO
|
./BQN test/squeeze.bqn // fuzz-test squeezing; requires a CBQN build with -DEEQUAL_NEGZERO
|
||||||
./BQN test/random.bqn // various random tests
|
./BQN test/random.bqn // various random tests
|
||||||
|
make -C test/ffi // test FFI functionality
|
||||||
```
|
```
|
||||||
85
test/ffi/ffiTest.c
Normal file
85
test/ffi/ffiTest.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../../src/ffi.h"
|
||||||
|
|
||||||
|
void do_nothing() { }
|
||||||
|
|
||||||
|
BQNV timesTen(BQNV v) {
|
||||||
|
size_t len = bqn_bound(v);
|
||||||
|
int32_t* buf = malloc(len*4);
|
||||||
|
bqn_readI32Arr(v, buf);
|
||||||
|
for (int i = 0; i < len; i++) buf[i] = buf[i] * 10;
|
||||||
|
BQNV res = bqn_makeI32Vec(len, buf);
|
||||||
|
free(buf);
|
||||||
|
bqn_free(v);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
BQNV add_args(BQNV t, BQNV x) {
|
||||||
|
return bqn_makeF64(bqn_toF64(t) + bqn_toF64(x));
|
||||||
|
}
|
||||||
|
BQNV bind_add(BQNV x) {
|
||||||
|
BQNV r = bqn_makeBoundFn1(add_args, x);
|
||||||
|
bqn_free(x);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void printArgs(int8_t i8, int16_t i16, int32_t i32, uint8_t u8, uint16_t u16, uint32_t u32, float f, double d) {
|
||||||
|
printf("args: %d %d %d %u %u %u %.18f %.18f\n", i8, i16, i32, u8, u16, u32, f, d);
|
||||||
|
}
|
||||||
|
void noopArgs(int8_t i8, int16_t i16, int32_t i32, uint8_t u8, uint16_t u16, uint32_t u32, float f, double d) { }
|
||||||
|
|
||||||
|
void printPtrArgs(int8_t* i8, int16_t* i16, int32_t* i32, uint8_t* u8, uint16_t* u16, uint32_t* u32, float* f, double* d) {
|
||||||
|
printf("args: %d %d %d %u %u %u %.18f %.18f\n", *i8, *i16, *i32, *u8, *u16, *u32, *f, *d);
|
||||||
|
}
|
||||||
|
|
||||||
|
float printU64s(uint64_t a, uint64_t* b) {
|
||||||
|
printf("%llx %llx %llx %llx\n", (long long)a, (long long)b[0], (long long)b[1], (long long)b[2]);
|
||||||
|
return 12345678;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int32_t multiplyI32Ptrs(int32_t* a, int32_t* b, int32_t len) {
|
||||||
|
int32_t r = 0;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
r+= a[i]*b[i];
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
float sumF32Arr(float* f, int len) {
|
||||||
|
float r = 0;
|
||||||
|
for (int i = 0; i < len; i++) r+= f[i];
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incI32s(int32_t* a, int32_t len) {
|
||||||
|
for (int i = 0; i < len; i++) a[i]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void incInts(int32_t* a, int16_t* b, int8_t* c) {
|
||||||
|
printf("%d %d %d\n", *a, *b, *c);
|
||||||
|
(*a)++;
|
||||||
|
(*b)++;
|
||||||
|
(*c)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ident_u64(uint64_t x) { return x; }
|
||||||
|
double ident_f64(double a) { return a; }
|
||||||
|
|
||||||
|
void* pick_ptr(void** arr, int idx) {
|
||||||
|
return arr[idx];
|
||||||
|
}
|
||||||
|
uint64_t pick_u64(uint64_t* arr, int idx) {
|
||||||
|
return arr[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int plusone(int x) {
|
||||||
|
return x + 1;
|
||||||
|
}
|
||||||
7
test/ffi/makefile
Normal file
7
test/ffi/makefile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
test: build
|
||||||
|
@../../BQN test.bqn > test.got
|
||||||
|
@diff --color -su test.expected test.got
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(CC) -O3 -g -c -fpic ffiTest.c -o ffiTest.o
|
||||||
|
$(CC) -shared -olib.so ffiTest.o
|
||||||
71
test/ffi/test.bqn
Normal file
71
test/ffi/test.bqn
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
f←@
|
||||||
|
Section ← {•Out 𝕩∾˜@+10}
|
||||||
|
|
||||||
|
f ↩ "lib.so" •FFI ""‿"do_nothing" ⋄ •Show F ⟨⟩
|
||||||
|
|
||||||
|
Section "# ""a"""
|
||||||
|
f ↩ "lib.so" •FFI "a"‿"timesTen"‿"a" ⋄ •Show F ⟨↕10⟩
|
||||||
|
bind ← "lib.so" •FFI "a"‿"bind_add"‿">a" ⋄ g ← Bind 4 ⋄ •Show G 123
|
||||||
|
|
||||||
|
Section "# print args"
|
||||||
|
f ↩ "lib.so" •FFI ""‿"printArgs"‿"i8"‿"i16"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64" ⋄ •Show F ¯123‿¯12323‿¯212312312‿250‿50000‿3123456789‿π∾⋆1
|
||||||
|
f ↩ "lib.so" •FFI ""‿ "noopArgs"‿"i8"‿"i16"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64" ⋄ •Show F ¯123‿¯12323‿¯212312312‿250‿50000‿3123456789‿π∾⋆1
|
||||||
|
f ↩ "lib.so" •FFI ""‿"printPtrArgs"‿"*i8"‿"*i16"‿"*i32"‿"*u8"‿"*u16"‿"*u32"‿"*f32"‿"*f64" ⋄ •Show F ⥊¨¯123‿¯12323‿¯212312312‿250‿50000‿3123456789‿π∾⋆1
|
||||||
|
f ↩ "lib.so" •FFI ""‿"printPtrArgs"‿"&i8"‿"&i16"‿"&i32"‿"&u8"‿"&u16"‿"&u32"‿"&f32"‿"&f64" ⋄ •Show F ⥊¨¯123‿¯12323‿¯212312312‿250‿50000‿3123456789‿π∾⋆1
|
||||||
|
|
||||||
|
f ↩ "lib.so" •FFI "f32"‿"printU64s"‿"u64:c8"‿"*u64:c8" ⋄ •Show F ⟨"hellowor", "aaaaaaaa12345678texttext"⟩
|
||||||
|
f ↩ "lib.so" •FFI "f32"‿"printU64s"‿"u64:u1"‿"*u64:u1" ⋄ •Show F ⟨64↑∾×∘↕¨↕12, 192↑∾×∘↕¨↕21⟩
|
||||||
|
|
||||||
|
! 3 ≡ •Type "lib.so" •FFI ""‿"printArgs"‿"i8"‿"i16:c8"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64"
|
||||||
|
! 3 ≡ •Type "lib.so" •FFI ""‿"printArgs"‿"i8"‿"i16:c16"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64"
|
||||||
|
! 3 ≡ •Type "lib.so" •FFI ""‿"printArgs"‿"i8:c8"‿"i16"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64"
|
||||||
|
|
||||||
|
Section "# read pointers"
|
||||||
|
f ↩ "lib.so" •FFI "i32"‿"multiplyI32Ptrs"‿"*i32"‿"*i32"‿"i32" ⋄ •Show F ⟨↕10 ⋄ •Show ⌽↕10 ⋄ •Show 10⟩
|
||||||
|
f ↩ "lib.so" •FFI "f32"‿"sumF32Arr"‿"*f32:i32"‿"i32" ⋄ •Show F ⟨1065353216‿1073741824‿1077936128‿1082130432‿1084227584‿1086324736‿1088421888‿1090519040‿1091567616‿1092616192,10⟩
|
||||||
|
|
||||||
|
Section "# mutate i32*"
|
||||||
|
f ↩ "lib.so" •FFI ⟨"","incI32s","&u32", "i32"⟩ ⋄ •Show F ⟨1e8×20+↕10 ⋄ 10⟩
|
||||||
|
f ↩ "lib.so" •FFI ⟨"","incI32s","&i32:u1", "i32"⟩ ⋄ •Show ⊑F ⟨1‿0‿1‿0‿1‿0‿1‿0‿0‿1‿0‿1‿0‿0‿1‿1‿0‿1‿1‿0‿0‿0‿0‿1‿0‿1‿0‿1‿0‿0‿1‿0‿0‿0‿1‿0‿0‿0‿1‿0‿0‿0‿1‿1‿1‿0‿1‿1‿1‿1‿1‿1‿0‿0‿1‿1‿0‿0‿1‿0‿0‿1‿0‿0, 2⟩
|
||||||
|
f ↩ "lib.so" •FFI ⟨"","incI32s","&i32:c8", "i32"⟩ ⋄ •Show ⊑F ⟨"helloworld", 2⟩
|
||||||
|
f ↩ "lib.so" •FFI ⟨"","incI32s",">𝕨&i32:c8",">i32"⟩ ⋄ •Show ⊑ "helloworld" F 2
|
||||||
|
|
||||||
|
f ↩ "lib.so" •FFI ⟨"", "incI32s", "&i32:c8", "i32"⟩ ⋄ •Show ⊑F ⟨"helloworld", 2⟩
|
||||||
|
f ↩ "lib.so" •FFI ⟨"", "incI32s", "&i32:c8", "𝕨i32"⟩ ⋄ •Show ⊑ ⟨2⟩ F ⟨"helloworld"⟩
|
||||||
|
f ↩ "lib.so" •FFI ⟨"", "incI32s", "&i32:c8",">𝕨i32"⟩ ⋄ •Show ⊑ 2 F ⟨"helloworld"⟩
|
||||||
|
f ↩ "lib.so" •FFI ⟨"", "incI32s", ">&i32:c8",">𝕨i32"⟩ ⋄ •Show ⊑ 2 F "helloworld"
|
||||||
|
f ↩ "lib.so" •FFI ⟨"", "incI32s",">𝕨&i32:c8", ">i32"⟩ ⋄ •Show ⊑ "helloworld" F 2
|
||||||
|
f ↩ "lib.so" •FFI ⟨"", "incI32s", "&i32:c8", "i32"⟩ ⋄ •Show F ⟨"helloworld", 2⟩
|
||||||
|
f ↩ "lib.so" •FFI ⟨"&","incI32s", "&i32:c8", "i32"⟩ ⋄ •Show F ⟨"helloworld", 2⟩
|
||||||
|
|
||||||
|
Section "# mutate i32*, i16*, i8*"
|
||||||
|
f ↩ "lib.so" •FFI ⟨"","incInts","&i32", "&i16","&i8"⟩ ⋄ •Show F ⥊¨ 10‿20‿30
|
||||||
|
f ↩ "lib.so" •FFI ⟨"","incInts","&i32", "𝕨&i16","&i8"⟩ ⋄ •Show ⟨⥊20⟩ F ⥊¨ 10‿30
|
||||||
|
f ↩ "lib.so" •FFI ⟨"","incInts","&i32",">𝕨&i16","&i8"⟩ ⋄ •Show ⟨20⟩ F ⥊¨ 10‿30
|
||||||
|
|
||||||
|
Section "# u64 tests"
|
||||||
|
f ↩ "lib.so" •FFI ⟨"u64", "ident_u64",">u64:i32"⟩ ⋄ •Show F 1234‿12
|
||||||
|
f ↩ "lib.so" •FFI ⟨"u64", "ident_u64",">u64" ⟩ ⋄ •Show F +´2⋆52‿20
|
||||||
|
f ↩ "lib.so" •FFI ⟨"u64:i32","ident_u64",">u64" ⟩ ⋄ •Show F 123456789123456
|
||||||
|
f ↩ "lib.so" •FFI ⟨"u64:u1", "ident_u64",">u64:c8" ⟩ ⋄ •Show F "hellowor"
|
||||||
|
|
||||||
|
Section "# malloc test"
|
||||||
|
f ↩ "lib.so" •FFI "*:i32"‿"malloc"‿">u64" ⋄ •Show (•internal.Info⋈≠) malloc ← F 123
|
||||||
|
f ↩ "lib.so" •FFI ""‿"free"‿">*:i32" ⋄ F malloc
|
||||||
|
|
||||||
|
Section "# pick item"
|
||||||
|
f ↩ "lib.so" •FFI "*:i8"‿"pick_ptr"‿">**:i8"‿">𝕨i32" ⋄ •Show @+0 F "helloworfoobarba"-@
|
||||||
|
f ↩ "lib.so" •FFI "*:c8"‿"pick_ptr"‿">**:c8"‿">𝕨i32" ⋄ •Show 0 F "helloworfoobarba"
|
||||||
|
f ↩ "lib.so" •FFI ⟨"u64:i8","pick_u64",">*u64:i8",">𝕨i32"⟩ ⋄ •Show @+2 F "000000001234560011122100abacabad"-@
|
||||||
|
f ↩ "lib.so" •FFI ⟨"u64:i8","pick_u64",">*u64:i8",">𝕨i32"⟩ ⋄ •Show @+3 F "000000001234560011122100abacabad"-@
|
||||||
|
f ↩ "lib.so" •FFI ⟨"u64", "pick_u64",">*u64:i8",">𝕨i32"⟩ ⋄ •Show 1 F "000000001234560011122100"-'0'
|
||||||
|
|
||||||
|
|
||||||
|
# erroring:
|
||||||
|
|
||||||
|
# "local/lib.so" •FFI ""‿"printArgs"‿"i8"‿"i16:c32"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64"
|
||||||
|
# "local/lib.so" •FFI ""‿"testArgs"‿"i8:c16"‿"i16"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64"
|
||||||
|
# "local/lib.so" •FFI ""‿"testArgs"‿"i8:c32"‿"i16"‿"i32"‿"u8"‿"u16"‿"u32"‿"f32"‿"f64"
|
||||||
|
|
||||||
|
# f ↩ "local/lib.so" •FFI "u64"‿"ident_u64"‿">u64:i32" ⋄ •Show F 1234‿12344444
|
||||||
|
# f ↩ "local/lib.so" •FFI "u64"‿"ident_u64"‿">u64" ⋄ •Show F +´2⋆53‿20
|
||||||
61
test/ffi/test.expected
Normal file
61
test/ffi/test.expected
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
@
|
||||||
|
|
||||||
|
# "a"
|
||||||
|
⟨ 0 10 20 30 40 50 60 70 80 90 ⟩
|
||||||
|
127
|
||||||
|
|
||||||
|
# print args
|
||||||
|
args: -123 -12323 -212312312 250 50000 3123456789 3.141592741012573242 2.718281828459045091
|
||||||
|
@
|
||||||
|
@
|
||||||
|
args: -123 -12323 -212312312 250 50000 3123456789 3.141592741012573242 2.718281828459045091
|
||||||
|
@
|
||||||
|
args: -123 -12323 -212312312 250 50000 3123456789 3.141592741012573242 2.718281828459045091
|
||||||
|
⟨ ⟨ ¯123 ⟩ ⟨ ¯12323 ⟩ ⟨ ¯212312312 ⟩ ⟨ 250 ⟩ ⟨ 50000 ⟩ ⟨ 3123456789 ⟩ ⟨ 3.141592741012573 ⟩ ⟨ 2.718281828459045 ⟩ ⟩
|
||||||
|
726f776f6c6c6568 6161616161616161 3837363534333231 7478657474786574
|
||||||
|
12345678
|
||||||
|
ff7fdfefefdf7bb4 ff7fdfefefdf7bb4 fefffdfff7ffbffb bffff7fffdfffeff
|
||||||
|
12345678
|
||||||
|
|
||||||
|
# read pointers
|
||||||
|
⟨ 9 8 7 6 5 4 3 2 1 0 ⟩
|
||||||
|
10
|
||||||
|
120
|
||||||
|
55
|
||||||
|
|
||||||
|
# mutate i32*
|
||||||
|
⟨ ⟨ 2000000001 2100000001 2200000001 2300000001 2400000001 2500000001 2600000001 2700000001 2800000001 2900000001 ⟩ ⟩
|
||||||
|
⟨ 0 1 1 0 1 0 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 0 0 1 1 0 0 1 0 0 1 0 0 ⟩
|
||||||
|
"iellpworld"
|
||||||
|
"iellpworld"
|
||||||
|
"iellpworld"
|
||||||
|
"iellpworld"
|
||||||
|
"iellpworld"
|
||||||
|
"iellpworld"
|
||||||
|
"iellpworld"
|
||||||
|
⟨ "iellpworld" ⟩
|
||||||
|
"iellpworld"
|
||||||
|
|
||||||
|
# mutate i32*, i16*, i8*
|
||||||
|
10 20 30
|
||||||
|
⟨ ⟨ 11 ⟩ ⟨ 21 ⟩ ⟨ 31 ⟩ ⟩
|
||||||
|
10 20 30
|
||||||
|
⟨ ⟨ 11 ⟩ ⟨ 21 ⟩ ⟨ 31 ⟩ ⟩
|
||||||
|
10 20 30
|
||||||
|
⟨ ⟨ 11 ⟩ ⟨ 21 ⟩ ⟨ 31 ⟩ ⟩
|
||||||
|
|
||||||
|
# u64 tests
|
||||||
|
51539608786
|
||||||
|
4503599628419072
|
||||||
|
⟨ ¯2045800064 28744 ⟩
|
||||||
|
⟨ 0 0 0 1 0 1 1 0 1 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 1 1 1 0 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 0 1 1 0 0 1 0 0 1 1 1 0 ⟩
|
||||||
|
|
||||||
|
# malloc test
|
||||||
|
⟨ "fff7: refc:2 type:26=i32arr alloc:128" 2 ⟩
|
||||||
|
|
||||||
|
# pick item
|
||||||
|
"hellowor"
|
||||||
|
"hellowor"
|
||||||
|
"11122100"
|
||||||
|
"abacabad"
|
||||||
|
6618611909121
|
||||||
Loading…
Reference in New Issue
Block a user