mirror of
https://github.com/lune-org/lune.git
synced 2025-04-10 21:40:54 +01:00
Add and organize ffi tests (#243)
This commit is contained in:
parent
b191218993
commit
902f5f960b
13 changed files with 97 additions and 57 deletions
|
@ -110,10 +110,18 @@ create_tests! {
|
||||||
ffi_external_pointer_pointer_write: "ffi/external_pointer/pointerWrite",
|
ffi_external_pointer_pointer_write: "ffi/external_pointer/pointerWrite",
|
||||||
ffi_external_print_hello_world: "ffi/external_print/helloWorld",
|
ffi_external_print_hello_world: "ffi/external_print/helloWorld",
|
||||||
ffi_external_struct_ab: "ffi/external_struct/ab",
|
ffi_external_struct_ab: "ffi/external_struct/ab",
|
||||||
|
ffi_pretty_print_arr: "ffi/pretty_print/arr",
|
||||||
|
ffi_pretty_print_box: "ffi/pretty_print/box",
|
||||||
|
ffi_pretty_print_fn: "ffi/pretty_print/fn",
|
||||||
|
ffi_pretty_print_ptr: "ffi/pretty_print/ptr",
|
||||||
|
ffi_pretty_print_struct: "ffi/pretty_print/struct",
|
||||||
|
ffi_pretty_print_type: "ffi/pretty_print/type",
|
||||||
|
ffi_types_arr: "ffi/types/arr",
|
||||||
|
ffi_types_ptr: "ffi/types/ptr",
|
||||||
|
ffi_types_struct: "ffi/types/struct",
|
||||||
ffi_cast: "ffi/cast",
|
ffi_cast: "ffi/cast",
|
||||||
ffi_free: "ffi/free",
|
ffi_free: "ffi/free",
|
||||||
ffi_is_integer: "ffi/isInteger",
|
ffi_is_integer: "ffi/isInteger",
|
||||||
ffi_pretty_print: "ffi/prettyPrint",
|
|
||||||
ffi_read_boundary: "ffi/readBoundary",
|
ffi_read_boundary: "ffi/readBoundary",
|
||||||
ffi_write_boundary: "ffi/writeBoundary",
|
ffi_write_boundary: "ffi/writeBoundary",
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,21 +16,16 @@ gcc for library compiling (for external-\*)
|
||||||
|
|
||||||
**Luau-side**
|
**Luau-side**
|
||||||
|
|
||||||
- [x] [isInteger](./isInteger)
|
- [x] [isInteger](./isInteger.luau)
|
||||||
- [x] [cast](./cast.luau)
|
- [x] [cast](./cast.luau)
|
||||||
|
- [x] [write_boundary](./write_boundary.luau)
|
||||||
|
- [x] [read_boundary](./read_boundary.luau)
|
||||||
|
- [x] [free](./free.luau)
|
||||||
|
|
||||||
|
**Pretty Print**
|
||||||
|
|
||||||
- [ ] [pretty_print](./pretty_print)
|
- [ ] [pretty_print](./pretty_print)
|
||||||
|
|
||||||
> need box, ref test
|
|
||||||
|
|
||||||
- [ ] [write_boundary](./write_boundary.luau)
|
|
||||||
|
|
||||||
> Failed, need fix
|
|
||||||
|
|
||||||
- [ ] [read_boundary](./read_boundary.luau)
|
|
||||||
|
|
||||||
> Failed, need fix
|
|
||||||
|
|
||||||
## Benchmark Results
|
## Benchmark Results
|
||||||
|
|
||||||
> Note: LuaJit's os.clock function returns process CPU time (used) which much smaller then Luau's os.clock output. In this benchmark, luau uses 'time.h' instead of os.clock. See [utility/proc_clock](./utility/proc_clock/init.luau)
|
> Note: LuaJit's os.clock function returns process CPU time (used) which much smaller then Luau's os.clock output. In this benchmark, luau uses 'time.h' instead of os.clock. See [utility/proc_clock](./utility/proc_clock/init.luau)
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
local ffi = require("@lune/ffi")
|
|
||||||
local c = ffi.c
|
|
||||||
|
|
||||||
assert(typeof(c.int) :: string == "CTypeInfo")
|
|
||||||
assert(tostring(c.int) == "int")
|
|
||||||
|
|
||||||
assert(typeof(c.int:ptr()) :: string == "CPtrInfo")
|
|
||||||
assert(tostring(c.int:ptr()) == "int")
|
|
||||||
assert(tostring(c.int:arr(5):ptr()) == " <CArrInfo( int, length = 5 )> ")
|
|
||||||
|
|
||||||
assert(typeof(c.int:arr(5)) :: string == "CArrInfo")
|
|
||||||
assert(tostring(c.int:arr(5)) == " int, length = 5 ")
|
|
||||||
assert(tostring(c.int:ptr():arr(5)) == " <CPtrInfo(int)>, length = 5 ")
|
|
||||||
|
|
||||||
assert(typeof(c.fn({ c.int }, c.int)) :: string == "CFnInfo")
|
|
||||||
assert(tostring(c.fn({ c.int }, c.int)) == " (int) -> int ")
|
|
||||||
assert(tostring(c.fn({ c.int, ffi.f32 }, c.int)) == " (int, f32) -> int ")
|
|
||||||
assert(tostring(c.fn({ c.int:ptr() }, c.int)) == " (<CPtrInfo(int)>) -> int ")
|
|
||||||
assert(tostring(c.fn({ c.int }, c.int:ptr())) == " (int) -> <CPtrInfo(int)> ")
|
|
||||||
assert(tostring(c.fn({ c.int:ptr() }, c.int:ptr())) == " (<CPtrInfo(int)>) -> <CPtrInfo(int)> ")
|
|
||||||
assert(
|
|
||||||
tostring(c.fn({ c.int:ptr(), c.int:ptr() }, c.int:ptr()))
|
|
||||||
== " (<CPtrInfo(int)>, <CPtrInfo(int)>) -> <CPtrInfo(int)> "
|
|
||||||
)
|
|
||||||
|
|
||||||
assert(typeof(c.struct({ c.int, c.char })) :: string == "CStructInfo")
|
|
||||||
assert(
|
|
||||||
tostring(c.struct({ c.int, c.char:ptr() }))
|
|
||||||
== ` int, <CPtrInfo(char)>, size = {c.struct({ c.int, c.char:ptr() }).size} `
|
|
||||||
)
|
|
||||||
|
|
||||||
-- FIXME: add box, ref pretty-print test
|
|
6
tests/ffi/pretty_print/arr.luau
Normal file
6
tests/ffi/pretty_print/arr.luau
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
local ffi = require("@lune/ffi")
|
||||||
|
local c = ffi.c
|
||||||
|
|
||||||
|
assert(typeof(c.int:arr(5)) :: string == "CArrInfo")
|
||||||
|
assert(tostring(c.int:arr(5)) == " int, length = 5 ")
|
||||||
|
assert(tostring(c.int:ptr():arr(5)) == " <CPtrInfo(int)>, length = 5 ")
|
4
tests/ffi/pretty_print/box.luau
Normal file
4
tests/ffi/pretty_print/box.luau
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
local ffi = require("@lune/ffi")
|
||||||
|
local half_back = 0b_0000_0000_0000_0000_0000_0000_1111_1111
|
||||||
|
|
||||||
|
print(ffi.i32:box(half_back))
|
13
tests/ffi/pretty_print/fn.luau
Normal file
13
tests/ffi/pretty_print/fn.luau
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
local ffi = require("@lune/ffi")
|
||||||
|
local c = ffi.c
|
||||||
|
|
||||||
|
assert(typeof(c.fn({ c.int }, c.int)) :: string == "CFnInfo")
|
||||||
|
assert(tostring(c.fn({ c.int }, c.int)) == " (int) -> int ")
|
||||||
|
assert(tostring(c.fn({ c.int, ffi.f32 }, c.int)) == " (int, f32) -> int ")
|
||||||
|
assert(tostring(c.fn({ c.int:ptr() }, c.int)) == " (<CPtrInfo(int)>) -> int ")
|
||||||
|
assert(tostring(c.fn({ c.int }, c.int:ptr())) == " (int) -> <CPtrInfo(int)> ")
|
||||||
|
assert(tostring(c.fn({ c.int:ptr() }, c.int:ptr())) == " (<CPtrInfo(int)>) -> <CPtrInfo(int)> ")
|
||||||
|
assert(
|
||||||
|
tostring(c.fn({ c.int:ptr(), c.int:ptr() }, c.int:ptr()))
|
||||||
|
== " (<CPtrInfo(int)>, <CPtrInfo(int)>) -> <CPtrInfo(int)> "
|
||||||
|
)
|
6
tests/ffi/pretty_print/ptr.luau
Normal file
6
tests/ffi/pretty_print/ptr.luau
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
local ffi = require("@lune/ffi")
|
||||||
|
local c = ffi.c
|
||||||
|
|
||||||
|
assert(typeof(c.int:ptr()) :: string == "CPtrInfo")
|
||||||
|
assert(tostring(c.int:ptr()) == "int")
|
||||||
|
assert(tostring(c.int:arr(5):ptr()) == " <CArrInfo( int, length = 5 )> ")
|
8
tests/ffi/pretty_print/struct.luau
Normal file
8
tests/ffi/pretty_print/struct.luau
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
local ffi = require("@lune/ffi")
|
||||||
|
local c = ffi.c
|
||||||
|
|
||||||
|
assert(typeof(c.struct({ c.int, c.char })) :: string == "CStructInfo")
|
||||||
|
assert(
|
||||||
|
tostring(c.struct({ c.int, c.char:ptr() }))
|
||||||
|
== ` int, <CPtrInfo(char)>, size = {c.struct({ c.int, c.char:ptr() }).size} `
|
||||||
|
)
|
6
tests/ffi/pretty_print/type.luau
Normal file
6
tests/ffi/pretty_print/type.luau
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
local ffi = require("@lune/ffi")
|
||||||
|
local c = ffi.c
|
||||||
|
|
||||||
|
assert(typeof(c.int) :: string == "CTypeInfo")
|
||||||
|
assert(tostring(c.int) == "int")
|
||||||
|
assert(tostring(ffi.i32) == "i32")
|
|
@ -0,0 +1,19 @@
|
||||||
|
local ffi = require("@lune/ffi")
|
||||||
|
local ok
|
||||||
|
|
||||||
|
local arr = ffi.i32:arr(4)
|
||||||
|
|
||||||
|
assert(rawequal(arr.length, 4), "length assersion failed, arr.length should be 4")
|
||||||
|
assert(rawequal(arr.inner, ffi.i32), "inner assersion failed, arr.inner should be ffi.i32")
|
||||||
|
|
||||||
|
-- offset(2) success
|
||||||
|
ok = pcall(function()
|
||||||
|
arr:offset(2)
|
||||||
|
end)
|
||||||
|
assert(ok, "assersion failed, arr:offset(2) should success")
|
||||||
|
|
||||||
|
-- offset(4) success
|
||||||
|
ok = pcall(function()
|
||||||
|
arr:offset(4)
|
||||||
|
end)
|
||||||
|
assert(not ok, "assersion failed, arr:offset(4) should fail")
|
|
@ -1,32 +1,31 @@
|
||||||
--!nocheck
|
|
||||||
--!nolint
|
|
||||||
|
|
||||||
local ffi = require("@lune/ffi")
|
local ffi = require("@lune/ffi")
|
||||||
|
|
||||||
-- ptr size test
|
-- ptr size test
|
||||||
assert(
|
assert(
|
||||||
ffi.i32:ptr().size == ffi.i64:ptr().size,
|
ffi.i32:ptr().size == ffi.i64:ptr().size,
|
||||||
"All of Ptr.size must be same.\n" .. "ffi.i32:ptr().size == ffi.i64:ptr().size failed"
|
"size assersion failed, size of pointer should be same with each other (ffi.i32:ptr().size == ffi.i64:ptr().size)"
|
||||||
)
|
)
|
||||||
|
|
||||||
-- inner test
|
-- inner test
|
||||||
local i32ptr = ffi.i32:ptr()
|
local i32ptr = ffi.i32:ptr()
|
||||||
assert(
|
assert(
|
||||||
rawequal(ffi.i32, i32ptr.inner),
|
rawequal(ffi.i32, i32ptr.inner),
|
||||||
"Ptr.inner must be same with their parent\n" .. "raweq ffi.i32 == ffi.i32:ptr().inner failed"
|
"inner assersion failed, inner field must be same with their parent"
|
||||||
|
.. " (ffi.i32 == ffi.i32:ptr().inner)"
|
||||||
)
|
)
|
||||||
assert(
|
assert(
|
||||||
rawequal(i32ptr, i32ptr:ptr().inner),
|
rawequal(i32ptr, i32ptr:ptr().inner),
|
||||||
"Ptr.inner must be same with their parent\n" .. "raweq i32ptr == i32ptr:ptr().inner failed"
|
"inner assersion failed, inner field must be same with their parent"
|
||||||
|
.. " (i32ptr == i32ptr:ptr().inner)"
|
||||||
)
|
)
|
||||||
assert(
|
assert(
|
||||||
rawequal(i32ptr, i32ptr:ptr().inner:ptr().inner:ptr().inner),
|
rawequal(i32ptr, i32ptr:ptr().inner:ptr().inner:ptr().inner),
|
||||||
"Ptr.inner must be same with their parent\n"
|
"inner assersion failed, inner field must be same with their parent"
|
||||||
.. "raweq i32ptr == i32ptr:ptr().inner:ptr().inner:ptr().inner failed"
|
.. " (i32ptr == i32ptr:ptr().inner:ptr().inner:ptr().inner)"
|
||||||
)
|
)
|
||||||
|
|
||||||
-- deep ptr test
|
-- deep ptr test
|
||||||
local ok, err = pcall(function()
|
local ok, err = pcall(function()
|
||||||
i32ptr:ptr():ptr():ptr():ptr():ptr():ptr():ptr()
|
i32ptr:ptr():ptr():ptr():ptr():ptr():ptr():ptr()
|
||||||
end)
|
end)
|
||||||
assert(ok, `Deep ptr test failed.\n{err}`)
|
assert(ok, "deep ptr assersion failed\n" .. (err or ""))
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
--!nocheck
|
|
||||||
--!nolint
|
|
||||||
|
|
||||||
local ffi = require("@lune/ffi")
|
local ffi = require("@lune/ffi")
|
||||||
|
local ok
|
||||||
|
|
||||||
local i32ptr = ffi.i32:ptr()
|
local i32ptr = ffi.i32:ptr()
|
||||||
local struct = ffi.struct({ i32ptr, ffi.i32 })
|
local struct = ffi.c.struct({ i32ptr, ffi.i32 })
|
||||||
|
|
||||||
assert(rawequal(struct:field(0), i32ptr), "Struct get field failed")
|
assert(rawequal(struct:field(0), i32ptr), "Struct get field failed")
|
||||||
assert(rawequal(struct:field(1), ffi.i32), "Struct get field failed")
|
assert(rawequal(struct:field(1), ffi.i32), "Struct get field failed")
|
||||||
|
|
||||||
-- offset(2) should fail
|
-- offset(2) should fail
|
||||||
|
ok = pcall(function()
|
||||||
|
struct:offset(2)
|
||||||
|
end)
|
||||||
|
assert(not ok, "assersion failed, struct:offset(2) should fail")
|
||||||
|
|
||||||
|
-- field(2) should fail
|
||||||
|
ok = pcall(function()
|
||||||
|
struct:field(2)
|
||||||
|
end)
|
||||||
|
assert(not ok, "assersion failed, struct:field(2) should fail")
|
||||||
|
|
Loading…
Add table
Reference in a new issue