mirror of
https://github.com/lune-org/lune.git
synced 2025-04-03 18:10:54 +01:00
Use camel case naming on ffi test (#243)
This commit is contained in:
parent
14d2b60f43
commit
00319f03e3
9 changed files with 93 additions and 89 deletions
|
@ -6,14 +6,10 @@ See [tests/ffi](../../tests/ffi/README.md)
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
|
- Rewrite error messages
|
||||||
- Deref
|
- Deref
|
||||||
|
|
||||||
- Big endianness / Little endianness variable (On process.endianness)
|
|
||||||
|
|
||||||
- CString
|
- CString
|
||||||
|
|
||||||
- Add buffer for owned data support
|
- Add buffer for owned data support
|
||||||
|
|
||||||
- Add math operation.
|
- Add math operation.
|
||||||
|
|
||||||
> Provide related methods: `CTypeInfo:add(target, from1, from2, ...)` and `:sub` `:mul` `:div` `:mod` `:pow` `:max` `:min` `:gt` `:lt`
|
> 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
|
> For windows API
|
||||||
|
|
||||||
- Add varargs support
|
- Add varargs support
|
||||||
|
|
||||||
- Array argument in cfn
|
- Array argument in cfn
|
||||||
|
|
||||||
- Ref boundary fix
|
- Ref boundary fix
|
||||||
|
|
||||||
## Code structure
|
## Code structure
|
||||||
|
|
|
@ -2,8 +2,8 @@ local ffi = require("@lune/ffi")
|
||||||
local c = ffi.c
|
local c = ffi.c
|
||||||
|
|
||||||
local proc_clock = require("../../utility/proc_clock")
|
local proc_clock = require("../../utility/proc_clock")
|
||||||
local before, after = proc_clock.new_box()
|
local before, after = proc_clock.newBox()
|
||||||
local get_clock = proc_clock.get_clock
|
local get_clock = proc_clock.getClock
|
||||||
|
|
||||||
local testdir = "./tests/ffi/benchmark/external_call"
|
local testdir = "./tests/ffi/benchmark/external_call"
|
||||||
local compile = require("../../utility/compile")
|
local compile = require("../../utility/compile")
|
||||||
|
@ -26,7 +26,7 @@ local function bench_add(bench_scale: number)
|
||||||
add_callable(a, a_ref, delta_ref)
|
add_callable(a, a_ref, delta_ref)
|
||||||
end
|
end
|
||||||
get_clock(after)
|
get_clock(after)
|
||||||
print(proc_clock.get_offset(before, after))
|
print(proc_clock.getOffset(before, after))
|
||||||
|
|
||||||
local result = c.int:readData(a)
|
local result = c.int:readData(a)
|
||||||
assert(result == bench_scale, `bench_add failed. result expected {bench_scale}, got {result}`)
|
assert(result == bench_scale, `bench_add failed. result expected {bench_scale}, got {result}`)
|
||||||
|
|
|
@ -6,35 +6,47 @@ local compile = require("../utility/compile")
|
||||||
compile(`{testdir}/lib.c`, `{testdir}/lib.so`)
|
compile(`{testdir}/lib.c`, `{testdir}/lib.so`)
|
||||||
local lib = ffi.open(`{testdir}/lib.so`)
|
local lib = ffi.open(`{testdir}/lib.so`)
|
||||||
|
|
||||||
local function test_closure()
|
local function test_callClosure()
|
||||||
local callback_info = c.fn({ c.int, c.int }, c.int)
|
local closureInfo = c.fn({ c.int, c.int }, c.int)
|
||||||
local callback_closure = callback_info:closure(function(ret, a, b)
|
local closure = closureInfo:closure(function(ret, a, b)
|
||||||
c.int:writeData(ret, c.int:readData(a) + c.int:readData(b))
|
c.int:writeData(ret, c.int:readData(a) + c.int:readData(b))
|
||||||
end)
|
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 resultBox = ffi.box(c.int.size)
|
||||||
|
callClosure(resultBox, closure:ref())
|
||||||
local result_box = ffi.box(c.int.size)
|
local result = c.int:readData(resultBox)
|
||||||
closure_test_callable(result_box, callback_closure:ref())
|
assert(result == 72, `test_callClosure failed. result expected 20000, got {result}`)
|
||||||
local result = c.int:readData(result_box)
|
|
||||||
assert(result == 72, `test_closure failed. result expected 20000, got {result}`)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test_closure()
|
test_callClosure()
|
||||||
|
|
||||||
local function test_hello_world()
|
local function test_helloWorld()
|
||||||
local callback_info = c.fn({}, c.void)
|
local helloWorldInfo = c.fn({}, c.void)
|
||||||
local callback_closure = callback_info:closure(function()
|
local helloWorld = helloWorldInfo:closure(function()
|
||||||
print("Hello world in lua closure!")
|
print("Hello world in lua closure!")
|
||||||
end)
|
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())
|
||||||
local closure_test_callable = closure_test_info:callable(lib:find("hello_world"))
|
|
||||||
|
|
||||||
closure_test_callable(nil, callback_closure:ref())
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test_hello_world()
|
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 callClosureWithPointer = c.fn({ closureWithPointerInfo }, c.int)
|
||||||
|
:callable(lib:find("call_closure_with_pointer"))
|
||||||
|
|
||||||
|
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_closureWithPointer()
|
||||||
|
|
15
tests/ffi/external_closure/lib.c
vendored
15
tests/ffi/external_closure/lib.c
vendored
|
@ -1,12 +1,17 @@
|
||||||
#include<stdio.h>
|
#include<stdio.h>
|
||||||
|
|
||||||
typedef int (*lua_callback_t)(int, int);
|
typedef int (*lua_closure_t)(int, int);
|
||||||
typedef void (*lua_hello_world_callback_t)();
|
int call_closure(lua_closure_t lua_closure) {
|
||||||
|
|
||||||
int closure(lua_callback_t lua_closure) {
|
|
||||||
return lua_closure(12, 24) * 2;
|
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();
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -6,36 +6,32 @@ local compile = require("../utility/compile")
|
||||||
compile(`{testdir}/lib.c`, `{testdir}/lib.so`)
|
compile(`{testdir}/lib.c`, `{testdir}/lib.so`)
|
||||||
local lib = ffi.open(`{testdir}/lib.so`)
|
local lib = ffi.open(`{testdir}/lib.so`)
|
||||||
|
|
||||||
local function test_add_int()
|
local function test_addInt()
|
||||||
local add_int_info = c.fn({ c.int, c.int }, c.int)
|
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 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)
|
|
||||||
|
|
||||||
assert(result == 300, `add_int 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)
|
|
||||||
|
|
||||||
local mul_int_caller = mul_int:callable(lib:find("mul_int"))
|
|
||||||
|
|
||||||
local resultBox = ffi.box(c.int.size)
|
local resultBox = ffi.box(c.int.size)
|
||||||
local arg1 = c.int:box(100)
|
local arg1 = c.int:box(100)
|
||||||
local arg2 = c.int:box(200)
|
local arg2 = c.int:box(200)
|
||||||
|
|
||||||
mul_int_caller(resultBox, arg1:ref(), arg2:ref())
|
addInt(resultBox, arg1:ref(), arg2:ref())
|
||||||
local result = c.int:readData(resultBox)
|
local result = c.int:readData(resultBox)
|
||||||
|
|
||||||
assert(result == 20000, `mul_int failed. result expected 20000, got {result}`)
|
assert(result == 300, `test_addInt failed. result expected 300, got {result}`)
|
||||||
end
|
end
|
||||||
|
|
||||||
test_mul_int()
|
test_addInt()
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
mulInt(resultBox, arg1:ref(), arg2:ref())
|
||||||
|
local result = c.int:readData(resultBox)
|
||||||
|
|
||||||
|
assert(result == 20000, `test_mulInt failed. result expected 20000, got {result}`)
|
||||||
|
end
|
||||||
|
|
||||||
|
test_mulInt()
|
||||||
|
|
|
@ -6,18 +6,15 @@ local compile = require("../utility/compile")
|
||||||
compile(`{testdir}/lib.c`, `{testdir}/lib.so`)
|
compile(`{testdir}/lib.c`, `{testdir}/lib.so`)
|
||||||
local lib = ffi.open(`{testdir}/lib.so`)
|
local lib = ffi.open(`{testdir}/lib.so`)
|
||||||
|
|
||||||
local function test_pointer_write()
|
local function test_pointerWrite()
|
||||||
local pointer_write_info = c.fn({ c.int:ptr() }, c.void)
|
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)
|
local result = c.int:readData(aBox)
|
||||||
|
|
||||||
pointer_write_callable(nil, a:ref():ref())
|
|
||||||
|
|
||||||
local result = c.int:readData(a)
|
|
||||||
|
|
||||||
assert(result == 123, `pointer failed. result expected 123, got {result}`)
|
assert(result == 123, `pointer failed. result expected 123, got {result}`)
|
||||||
end
|
end
|
||||||
|
|
||||||
test_pointer_write()
|
test_pointerWrite()
|
||||||
|
|
|
@ -7,19 +7,19 @@ compile(`{testdir}/lib.c`, `{testdir}/lib.so`)
|
||||||
local lib = ffi.open(`{testdir}/lib.so`)
|
local lib = ffi.open(`{testdir}/lib.so`)
|
||||||
|
|
||||||
local function test_AB()
|
local function test_AB()
|
||||||
local ArgStruct = c.struct({ c.int, c.int:ptr() })
|
local argStructInfo = c.struct({ c.int, c.int:ptr() })
|
||||||
local ResultStruct = c.struct({ c.int, c.int })
|
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 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 b = c.int:box(200)
|
||||||
local arg = ArgStruct:box({ 100, b:ref() })
|
local argStruct = argStructInfo:box({ 100, b:ref() })
|
||||||
|
|
||||||
AB_callable(resultBox, arg:ref())
|
AB_callable(resultBox, argStruct:ref())
|
||||||
local result = ResultStruct:readData(resultBox)
|
local result = resultStructInfo:readData(resultBox)
|
||||||
|
|
||||||
assert(result[1] == 300, `AB failed. result expected 300, got {result[1]}`)
|
assert(result[1] == 300, `AB failed. result expected 300, got {result[1]}`)
|
||||||
assert(result[2] == 20000, `AB failed. result expected 300, got {result[2]}`)
|
assert(result[2] == 20000, `AB failed. result expected 300, got {result[2]}`)
|
||||||
|
|
2
tests/ffi/external_struct/lib.c
vendored
2
tests/ffi/external_struct/lib.c
vendored
|
@ -9,6 +9,6 @@ typedef struct {
|
||||||
} ResultStruct;
|
} ResultStruct;
|
||||||
|
|
||||||
ResultStruct AB(ArgStruct t) {
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
local ffi = require("@lune/ffi")
|
local ffi = require("@lune/ffi")
|
||||||
local process = require("@lune/process")
|
local process = require("@lune/process")
|
||||||
local is_windows = process.os == "windows"
|
local isWindows = process.os == "windows"
|
||||||
local c = ffi.c
|
local c = ffi.c
|
||||||
|
|
||||||
local proc_clock = {}
|
local procClock = {}
|
||||||
|
|
||||||
local libdir = "./tests/ffi/utility/proc_clock"
|
local libdir = "./tests/ffi/utility/proc_clock"
|
||||||
local compile = require("../compile")
|
local compile = require("../compile")
|
||||||
|
@ -13,17 +13,17 @@ compile(`{libdir}/lib.c`, `{libdir}/lib.so`)
|
||||||
local lib = ffi.open(`{libdir}/lib.so`)
|
local lib = ffi.open(`{libdir}/lib.so`)
|
||||||
|
|
||||||
-- sizeof_clock
|
-- sizeof_clock
|
||||||
local sizeof_clock = c.fn({}, c.int):callable(lib:find("sizeof_clock"))
|
local sizeofClock = c.fn({}, c.int):callable(lib:find("sizeof_clock"))
|
||||||
function proc_clock.sizeof_clock(): number
|
function procClock.sizeofClock(): number
|
||||||
local result = ffi.box(c.int.size)
|
local result = ffi.box(c.int.size)
|
||||||
sizeof_clock(result)
|
sizeofClock(result)
|
||||||
return c.int:readData(result)
|
return c.int:readData(result)
|
||||||
end
|
end
|
||||||
-- get_clock
|
-- 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")
|
assert(clock_t, "clock_t is unknown type")
|
||||||
proc_clock.get_clock = (
|
procClock.getClock = (
|
||||||
if is_windows
|
if isWindows
|
||||||
then function(clock: ffi.BoxData | ffi.RefData)
|
then function(clock: ffi.BoxData | ffi.RefData)
|
||||||
ffi.f32:writeData(clock, os.clock())
|
ffi.f32:writeData(clock, os.clock())
|
||||||
end
|
end
|
||||||
|
@ -31,19 +31,19 @@ proc_clock.get_clock = (
|
||||||
) :: (ffi.BoxData | ffi.RefData) -> ()
|
) :: (ffi.BoxData | ffi.RefData) -> ()
|
||||||
|
|
||||||
-- get_offset
|
-- 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)
|
then function(result: ffi.BoxData, before: ffi.RefData, after: ffi.RefData)
|
||||||
ffi.f64:writeData(result, (ffi.f32:readData(after) - ffi.f32:readData(before)))
|
ffi.f64:writeData(result, (ffi.f32:readData(after) - ffi.f32:readData(before)))
|
||||||
end
|
end
|
||||||
else c.fn({ clock_t, clock_t }, ffi.f64):callable(lib:find("get_offset"))
|
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)
|
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)
|
return ffi.f64:readData(result)
|
||||||
end
|
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)
|
return ffi.box(clock_t.size), ffi.box(clock_t.size)
|
||||||
end
|
end
|
||||||
|
|
||||||
return proc_clock
|
return procClock
|
||||||
|
|
Loading…
Add table
Reference in a new issue