From c656a486c4b0e33ce0c23ce7395eaef178e7e1ad Mon Sep 17 00:00:00 2001 From: qwreey Date: Fri, 6 Sep 2024 07:30:45 +0000 Subject: [PATCH] Add tests for ffi (#243) --- crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs | 2 +- crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs | 10 +++--- tests/ffi/box-recursion-gc.luau | 20 ++++++++++++ tests/ffi/cast.luau | 0 tests/ffi/external.luau | 0 tests/ffi/from-boundary.luau | 0 tests/ffi/into-boundary.luau | 0 tests/ffi/isInteger.luau | 10 ++++++ tests/ffi/ptr.luau | 33 -------------------- tests/ffi/ref-hold-box.luau | 15 +++++++++ tests/ffi/struct.luau | 2 -- tests/ffi/types/arr.luau | 0 tests/ffi/types/fn.luau | 0 tests/ffi/types/ptr.luau | 32 +++++++++++++++++++ tests/ffi/types/struct.luau | 12 +++++++ 15 files changed, 94 insertions(+), 42 deletions(-) create mode 100644 tests/ffi/box-recursion-gc.luau create mode 100644 tests/ffi/cast.luau create mode 100644 tests/ffi/external.luau create mode 100644 tests/ffi/from-boundary.luau create mode 100644 tests/ffi/into-boundary.luau create mode 100644 tests/ffi/isInteger.luau delete mode 100644 tests/ffi/ptr.luau create mode 100644 tests/ffi/ref-hold-box.luau delete mode 100644 tests/ffi/struct.luau create mode 100644 tests/ffi/types/arr.luau create mode 100644 tests/ffi/types/fn.luau create mode 100644 tests/ffi/types/ptr.luau create mode 100644 tests/ffi/types/struct.luau diff --git a/crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs b/crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs index 114f67c..b6a2ca7 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs @@ -22,7 +22,7 @@ impl FfiRefFlag { pub struct FfiRefFlagList(u8); #[allow(unused)] impl FfiRefFlagList { - pub fn zero() -> Self { + pub const fn zero() -> Self { Self(0) } pub const fn new(flags: u8) -> Self { diff --git a/crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs b/crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs index 4412828..ccd5589 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs @@ -16,6 +16,9 @@ pub use self::{ flags::{FfiRefFlag, FfiRefFlagList}, }; +// Box:ref():ref() should not be able to modify, Only for external +const BOX_REF_REF_FLAGS: FfiRefFlagList = FfiRefFlagList::zero(); + // A referenced space. It is possible to read and write through types. // This operation is not safe. This may cause a memory error in Lua // if use it incorrectly. @@ -46,15 +49,10 @@ impl FfiRef { this: LuaAnyUserData<'lua>, ) -> LuaResult> { let target = this.borrow::()?; - let mut flags = target.flags.clone(); - - // FIXME: - // We cannot dereference ref which created by lua, in lua - flags.set_dereferenceable(false); let luaref = lua.create_userdata(FfiRef::new( ptr::from_ref(&target.ptr) as *mut (), - flags, + BOX_REF_REF_FLAGS, FfiRefBounds { below: 0, above: size_of::(), diff --git a/tests/ffi/box-recursion-gc.luau b/tests/ffi/box-recursion-gc.luau new file mode 100644 index 0000000..d86d045 --- /dev/null +++ b/tests/ffi/box-recursion-gc.luau @@ -0,0 +1,20 @@ +--!nocheck +--!nolint + +local ffi = require("@lune/ffi") + +local box = ffi.box(ffi.u8:ptr().size) +local ref = box:ref() +ffi.u8:ptr():into(box, ref) + +local wt = setmetatable({}, { __mode = "v" }) + +wt[1] = box +wt[2] = ref + +box = nil +ref = nil + +collectgarbage("collect") + +assert(wt[1] == nil and wt[2] == nil, "Box - ref recursion GC test failed") diff --git a/tests/ffi/cast.luau b/tests/ffi/cast.luau new file mode 100644 index 0000000..e69de29 diff --git a/tests/ffi/external.luau b/tests/ffi/external.luau new file mode 100644 index 0000000..e69de29 diff --git a/tests/ffi/from-boundary.luau b/tests/ffi/from-boundary.luau new file mode 100644 index 0000000..e69de29 diff --git a/tests/ffi/into-boundary.luau b/tests/ffi/into-boundary.luau new file mode 100644 index 0000000..e69de29 diff --git a/tests/ffi/isInteger.luau b/tests/ffi/isInteger.luau new file mode 100644 index 0000000..1084b8f --- /dev/null +++ b/tests/ffi/isInteger.luau @@ -0,0 +1,10 @@ +--!nocheck +--!nolint + +local ffi = require("@lune/ffi") + +local int = 0b1 +local float = 0.5 + +assert(ffi.isInteger(int) == true, "ffi.isInteger(int) == true failed") +assert(ffi.isInteger(float) == false, "ffi.isInteger(float) == false failed") diff --git a/tests/ffi/ptr.luau b/tests/ffi/ptr.luau deleted file mode 100644 index c62eadf..0000000 --- a/tests/ffi/ptr.luau +++ /dev/null @@ -1,33 +0,0 @@ - -local ffi = require("@lune/ffi") - --- ptr size test -assert( - 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" -) - --- inner test -local i32ptr = ffi.i32:ptr() -assert( - rawequal(ffi.i32, i32ptr.inner), - "Ptr.inner must be same with their parent\n".. - "raweq ffi.i32 == ffi.i32:ptr().inner failed" -) -assert( - rawequal(i32ptr, i32ptr:ptr().inner), - "Ptr.inner must be same with their parent\n".. - "raweq i32ptr == i32ptr:ptr().inner failed" -) -assert( - rawequal(i32ptr, i32ptr:ptr().inner:ptr().inner:ptr().inner), - "Ptr.inner must be same with their parent\n".. - "raweq i32ptr == i32ptr:ptr().inner:ptr().inner:ptr().inner failed" -) - --- deep ptr test -local ok,err = pcall(function() - i32ptr:ptr():ptr():ptr():ptr():ptr():ptr():ptr() -end) -assert(ok,`Deep ptr test failed.\n{err}`) diff --git a/tests/ffi/ref-hold-box.luau b/tests/ffi/ref-hold-box.luau new file mode 100644 index 0000000..f6f1490 --- /dev/null +++ b/tests/ffi/ref-hold-box.luau @@ -0,0 +1,15 @@ +--!nocheck +--!nolint + +local ffi = require("@lune/ffi") +local box = ffi.box(ffi.i32.size) +local ref = box:ref() + +local wt = setmetatable({}, { __mode = "v" }) + +wt[1] = box +box = nll + +collectgarbage("collect") + +assert(wt[1] ~= nil, "ref hold box failed") diff --git a/tests/ffi/struct.luau b/tests/ffi/struct.luau deleted file mode 100644 index e1c1f8d..0000000 --- a/tests/ffi/struct.luau +++ /dev/null @@ -1,2 +0,0 @@ - -local ffi = require("@lune/ffi") diff --git a/tests/ffi/types/arr.luau b/tests/ffi/types/arr.luau new file mode 100644 index 0000000..e69de29 diff --git a/tests/ffi/types/fn.luau b/tests/ffi/types/fn.luau new file mode 100644 index 0000000..e69de29 diff --git a/tests/ffi/types/ptr.luau b/tests/ffi/types/ptr.luau new file mode 100644 index 0000000..cdbc2fe --- /dev/null +++ b/tests/ffi/types/ptr.luau @@ -0,0 +1,32 @@ +--!nocheck +--!nolint + +local ffi = require("@lune/ffi") + +-- ptr size test +assert( + 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" +) + +-- inner test +local i32ptr = ffi.i32:ptr() +assert( + rawequal(ffi.i32, i32ptr.inner), + "Ptr.inner must be same with their parent\n" .. "raweq ffi.i32 == ffi.i32:ptr().inner failed" +) +assert( + rawequal(i32ptr, i32ptr:ptr().inner), + "Ptr.inner must be same with their parent\n" .. "raweq i32ptr == i32ptr:ptr().inner failed" +) +assert( + rawequal(i32ptr, i32ptr:ptr().inner:ptr().inner:ptr().inner), + "Ptr.inner must be same with their parent\n" + .. "raweq i32ptr == i32ptr:ptr().inner:ptr().inner:ptr().inner failed" +) + +-- deep ptr test +local ok, err = pcall(function() + i32ptr:ptr():ptr():ptr():ptr():ptr():ptr():ptr() +end) +assert(ok, `Deep ptr test failed.\n{err}`) diff --git a/tests/ffi/types/struct.luau b/tests/ffi/types/struct.luau new file mode 100644 index 0000000..a955e71 --- /dev/null +++ b/tests/ffi/types/struct.luau @@ -0,0 +1,12 @@ +--!nocheck +--!nolint + +local ffi = require("@lune/ffi") + +local i32ptr = ffi.i32:ptr() +local struct = ffi.struct({ i32ptr, ffi.i32 }) + +assert(rawequal(struct:field(0), i32ptr), "Struct get field failed") +assert(rawequal(struct:field(1), ffi.i32), "Struct get field failed") + +-- offset(2) should fail