diff --git a/crates/lune-std-ffi/README.md b/crates/lune-std-ffi/README.md index 4470901c..c5fa3c8a 100644 --- a/crates/lune-std-ffi/README.md +++ b/crates/lune-std-ffi/README.md @@ -6,14 +6,10 @@ See [tests/ffi](../../tests/ffi/README.md) ## TODO +- Rewrite error messages - Deref - -- Big endianness / Little endianness variable (On process.endianness) - - CString - - Add buffer for owned data support - - Add math operation. > Provide related methods: `CTypeInfo:add(target, from1, from2, ...)` and `:sub` `:mul` `:div` `:mod` `:pow` `:max` `:min` `:gt` `:lt` @@ -28,9 +24,7 @@ See [tests/ffi](../../tests/ffi/README.md) > For windows API - Add varargs support - - Array argument in cfn - - Ref boundary fix ## Code structure diff --git a/tests/ffi/benchmark/external_call/init.luau b/tests/ffi/benchmark/external_call/init.luau index 64e86001..3c4eef6c 100644 --- a/tests/ffi/benchmark/external_call/init.luau +++ b/tests/ffi/benchmark/external_call/init.luau @@ -2,8 +2,8 @@ local ffi = require("@lune/ffi") local c = ffi.c local proc_clock = require("../../utility/proc_clock") -local before, after = proc_clock.new_box() -local get_clock = proc_clock.get_clock +local before, after = proc_clock.newBox() +local get_clock = proc_clock.getClock local testdir = "./tests/ffi/benchmark/external_call" local compile = require("../../utility/compile") @@ -26,7 +26,7 @@ local function bench_add(bench_scale: number) add_callable(a, a_ref, delta_ref) end get_clock(after) - print(proc_clock.get_offset(before, after)) + print(proc_clock.getOffset(before, after)) local result = c.int:readData(a) assert(result == bench_scale, `bench_add failed. result expected {bench_scale}, got {result}`) diff --git a/tests/ffi/external_closure/init.luau b/tests/ffi/external_closure/init.luau index f36b0340..f442b9e4 100644 --- a/tests/ffi/external_closure/init.luau +++ b/tests/ffi/external_closure/init.luau @@ -6,35 +6,47 @@ local compile = require("../utility/compile") compile(`{testdir}/lib.c`, `{testdir}/lib.so`) local lib = ffi.open(`{testdir}/lib.so`) -local function test_closure() - local callback_info = c.fn({ c.int, c.int }, c.int) - local callback_closure = callback_info:closure(function(ret, a, b) +local function test_callClosure() + local closureInfo = c.fn({ c.int, c.int }, c.int) + local closure = closureInfo:closure(function(ret, a, b) c.int:writeData(ret, c.int:readData(a) + c.int:readData(b)) end) - local closure_test_info = c.fn({ callback_info }, c.int) + local callClosure = c.fn({ closureInfo }, c.int):callable(lib:find("call_closure")) - local closure_test_callable = closure_test_info:callable(lib:find("closure")) - - local result_box = ffi.box(c.int.size) - closure_test_callable(result_box, callback_closure:ref()) - local result = c.int:readData(result_box) - assert(result == 72, `test_closure failed. result expected 20000, got {result}`) + local resultBox = ffi.box(c.int.size) + callClosure(resultBox, closure:ref()) + local result = c.int:readData(resultBox) + assert(result == 72, `test_callClosure failed. result expected 20000, got {result}`) end -test_closure() +test_callClosure() -local function test_hello_world() - local callback_info = c.fn({}, c.void) - local callback_closure = callback_info:closure(function() +local function test_helloWorld() + local helloWorldInfo = c.fn({}, c.void) + local helloWorld = helloWorldInfo:closure(function() print("Hello world in lua closure!") end) - local closure_test_info = c.fn({ callback_info }, c.void) + local callHelloWorld = c.fn({ helloWorldInfo }, c.void):callable(lib:find("call_hello_world")) + callHelloWorld(nil, helloWorld:ref()) +end + +test_helloWorld() + +local function test_closureWithPointer() + local closureWithPointerInfo = c.fn({ c.int, c.int:ptr() }, c.int) + local closureWithPointer = closureWithPointerInfo:closure(function(returnRef, aRef, bRef) + c.int:writeData(returnRef, c.int:readData(aRef) + c.int:readData(bRef:deref())) + end) - local closure_test_callable = closure_test_info:callable(lib:find("hello_world")) + local callClosureWithPointer = c.fn({ closureWithPointerInfo }, c.int) + :callable(lib:find("call_closure_with_pointer")) - closure_test_callable(nil, callback_closure:ref()) + local resultBox = ffi.box(c.int.size) + callClosureWithPointer(resultBox, closureWithPointer:ref()) + local result = c.int:readData(resultBox) + assert(result == 72, `test_closureWithPointer failed. result expected 20000, got {result}`) end -test_hello_world() +test_closureWithPointer() diff --git a/tests/ffi/external_closure/lib.c b/tests/ffi/external_closure/lib.c index f14f1002..a5e7a775 100644 --- a/tests/ffi/external_closure/lib.c +++ b/tests/ffi/external_closure/lib.c @@ -1,12 +1,17 @@ #include -typedef int (*lua_callback_t)(int, int); -typedef void (*lua_hello_world_callback_t)(); - -int closure(lua_callback_t lua_closure) { +typedef int (*lua_closure_t)(int, int); +int call_closure(lua_closure_t lua_closure) { return lua_closure(12, 24) * 2; } -void hello_world(lua_hello_world_callback_t lua_closure) { +typedef void (*lua_hello_world_t)(); +void call_hello_world(lua_hello_world_t lua_closure) { lua_closure(); } + +typedef int (*lua_closure_with_pointer_t)(int, int*); +int call_closure_with_pointer(lua_closure_with_pointer_t lua_closure) { + int b = 24; + return lua_closure(12, &b) * 2; +} diff --git a/tests/ffi/external_math/init.luau b/tests/ffi/external_math/init.luau index fe486b91..f4ce95ff 100644 --- a/tests/ffi/external_math/init.luau +++ b/tests/ffi/external_math/init.luau @@ -6,36 +6,32 @@ local compile = require("../utility/compile") compile(`{testdir}/lib.c`, `{testdir}/lib.so`) local lib = ffi.open(`{testdir}/lib.so`) -local function test_add_int() - local add_int_info = c.fn({ c.int, c.int }, c.int) +local function test_addInt() + local addInt = c.fn({ c.int, c.int }, c.int):callable(lib:find("add_int")) - local add_int_callable = add_int_info:callable(lib:find("add_int")) - - local result_box = ffi.box(c.int.size) + local resultBox = ffi.box(c.int.size) local arg1 = c.int:box(100) local arg2 = c.int:box(200) - add_int_callable(result_box, arg1:ref(), arg2:ref()) - local result = c.int:readData(result_box) + addInt(resultBox, arg1:ref(), arg2:ref()) + local result = c.int:readData(resultBox) - assert(result == 300, `add_int failed. result expected 300, got {result}`) + assert(result == 300, `test_addInt failed. result expected 300, got {result}`) end -test_add_int() - -local function test_mul_int() - local mul_int = c.fn({ c.int, c.int }, c.int) +test_addInt() - local mul_int_caller = mul_int:callable(lib:find("mul_int")) +local function test_mulInt() + local mulInt = c.fn({ c.int, c.int }, c.int):callable(lib:find("mul_int")) local resultBox = ffi.box(c.int.size) local arg1 = c.int:box(100) local arg2 = c.int:box(200) - mul_int_caller(resultBox, arg1:ref(), arg2:ref()) + mulInt(resultBox, arg1:ref(), arg2:ref()) local result = c.int:readData(resultBox) - assert(result == 20000, `mul_int failed. result expected 20000, got {result}`) + assert(result == 20000, `test_mulInt failed. result expected 20000, got {result}`) end -test_mul_int() +test_mulInt() diff --git a/tests/ffi/external_pointer/init.luau b/tests/ffi/external_pointer/init.luau index a78f7676..8e0e988f 100644 --- a/tests/ffi/external_pointer/init.luau +++ b/tests/ffi/external_pointer/init.luau @@ -6,18 +6,15 @@ local compile = require("../utility/compile") compile(`{testdir}/lib.c`, `{testdir}/lib.so`) local lib = ffi.open(`{testdir}/lib.so`) -local function test_pointer_write() - local pointer_write_info = c.fn({ c.int:ptr() }, c.void) +local function test_pointerWrite() + local pointerWrite = c.fn({ c.int:ptr() }, c.void):callable(lib:find("pointer_write")) - local pointer_write_callable = pointer_write_info:callable(lib:find("pointer_write")) + local aBox = ffi.box(c.int.size) + pointerWrite(nil, aBox:ref():ref()) - local a = ffi.box(c.int.size) - - pointer_write_callable(nil, a:ref():ref()) - - local result = c.int:readData(a) + local result = c.int:readData(aBox) assert(result == 123, `pointer failed. result expected 123, got {result}`) end -test_pointer_write() +test_pointerWrite() diff --git a/tests/ffi/external_struct/init.luau b/tests/ffi/external_struct/init.luau index d3ae98ab..109ff491 100644 --- a/tests/ffi/external_struct/init.luau +++ b/tests/ffi/external_struct/init.luau @@ -7,19 +7,19 @@ compile(`{testdir}/lib.c`, `{testdir}/lib.so`) local lib = ffi.open(`{testdir}/lib.so`) local function test_AB() - local ArgStruct = c.struct({ c.int, c.int:ptr() }) - local ResultStruct = c.struct({ c.int, c.int }) + local argStructInfo = c.struct({ c.int, c.int:ptr() }) + local resultStructInfo = c.struct({ c.int, c.int }) - local AB = c.fn({ ArgStruct }, ResultStruct) + local AB = c.fn({ argStructInfo }, resultStructInfo) local AB_callable = AB:callable(lib:find("AB")) - local resultBox = ffi.box(ResultStruct.size) + local resultBox = ffi.box(resultStructInfo.size) local b = c.int:box(200) - local arg = ArgStruct:box({ 100, b:ref() }) + local argStruct = argStructInfo:box({ 100, b:ref() }) - AB_callable(resultBox, arg:ref()) - local result = ResultStruct:readData(resultBox) + AB_callable(resultBox, argStruct:ref()) + local result = resultStructInfo:readData(resultBox) assert(result[1] == 300, `AB failed. result expected 300, got {result[1]}`) assert(result[2] == 20000, `AB failed. result expected 300, got {result[2]}`) diff --git a/tests/ffi/external_struct/lib.c b/tests/ffi/external_struct/lib.c index a9e076b9..b542d5d3 100644 --- a/tests/ffi/external_struct/lib.c +++ b/tests/ffi/external_struct/lib.c @@ -9,6 +9,6 @@ typedef struct { } ResultStruct; ResultStruct AB(ArgStruct t) { - ResultStruct result = { t.a+*t.b, t.a**t.b }; + ResultStruct result = { t.a+ * t.b, t.a * (*t.b) }; return result; } diff --git a/tests/ffi/utility/proc_clock/init.luau b/tests/ffi/utility/proc_clock/init.luau index 40744667..720cbd6a 100644 --- a/tests/ffi/utility/proc_clock/init.luau +++ b/tests/ffi/utility/proc_clock/init.luau @@ -2,10 +2,10 @@ local ffi = require("@lune/ffi") local process = require("@lune/process") -local is_windows = process.os == "windows" +local isWindows = process.os == "windows" local c = ffi.c -local proc_clock = {} +local procClock = {} local libdir = "./tests/ffi/utility/proc_clock" local compile = require("../compile") @@ -13,17 +13,17 @@ compile(`{libdir}/lib.c`, `{libdir}/lib.so`) local lib = ffi.open(`{libdir}/lib.so`) -- sizeof_clock -local sizeof_clock = c.fn({}, c.int):callable(lib:find("sizeof_clock")) -function proc_clock.sizeof_clock(): number +local sizeofClock = c.fn({}, c.int):callable(lib:find("sizeof_clock")) +function procClock.sizeofClock(): number local result = ffi.box(c.int.size) - sizeof_clock(result) + sizeofClock(result) return c.int:readData(result) end -- get_clock -local clock_t = if is_windows then ffi.f32 else ffi["u" .. (proc_clock.sizeof_clock() * 8)] +local clock_t = if isWindows then ffi.f32 else ffi["u" .. (procClock.sizeofClock() * 8)] assert(clock_t, "clock_t is unknown type") -proc_clock.get_clock = ( - if is_windows +procClock.getClock = ( + if isWindows then function(clock: ffi.BoxData | ffi.RefData) ffi.f32:writeData(clock, os.clock()) end @@ -31,19 +31,19 @@ proc_clock.get_clock = ( ) :: (ffi.BoxData | ffi.RefData) -> () -- get_offset -local get_offset: (ffi.BoxData, ffi.RefData, ffi.RefData) -> () = if is_windows +local getOffset: (ffi.BoxData, ffi.RefData, ffi.RefData) -> () = if isWindows then function(result: ffi.BoxData, before: ffi.RefData, after: ffi.RefData) ffi.f64:writeData(result, (ffi.f32:readData(after) - ffi.f32:readData(before))) end else c.fn({ clock_t, clock_t }, ffi.f64):callable(lib:find("get_offset")) -function proc_clock.get_offset(before: ffi.BoxData, after: ffi.BoxData): number +function procClock.getOffset(before: ffi.BoxData, after: ffi.BoxData): number local result = ffi.box(ffi.f64.size) - get_offset(result, before:ref(), after:ref()) + getOffset(result, before:ref(), after:ref()) return ffi.f64:readData(result) end -function proc_clock.new_box(): (ffi.BoxData, ffi.BoxData) +function procClock.newBox(): (ffi.BoxData, ffi.BoxData) return ffi.box(clock_t.size), ffi.box(clock_t.size) end -return proc_clock +return procClock