Skip to content

Commit

Permalink
Add tests for ffi (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
qwreey committed Oct 13, 2024
1 parent e23aaef commit c656a48
Show file tree
Hide file tree
Showing 15 changed files with 94 additions and 42 deletions.
2 changes: 1 addition & 1 deletion crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 4 additions & 6 deletions crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -46,15 +49,10 @@ impl FfiRef {
this: LuaAnyUserData<'lua>,
) -> LuaResult<LuaAnyUserData<'lua>> {
let target = this.borrow::<FfiRef>()?;
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::<usize>(),
Expand Down
20 changes: 20 additions & 0 deletions tests/ffi/box-recursion-gc.luau
Original file line number Diff line number Diff line change
@@ -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")
Empty file added tests/ffi/cast.luau
Empty file.
Empty file added tests/ffi/external.luau
Empty file.
Empty file added tests/ffi/from-boundary.luau
Empty file.
Empty file added tests/ffi/into-boundary.luau
Empty file.
10 changes: 10 additions & 0 deletions tests/ffi/isInteger.luau
Original file line number Diff line number Diff line change
@@ -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")
33 changes: 0 additions & 33 deletions tests/ffi/ptr.luau

This file was deleted.

15 changes: 15 additions & 0 deletions tests/ffi/ref-hold-box.luau
Original file line number Diff line number Diff line change
@@ -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")
2 changes: 0 additions & 2 deletions tests/ffi/struct.luau

This file was deleted.

Empty file added tests/ffi/types/arr.luau
Empty file.
Empty file added tests/ffi/types/fn.luau
Empty file.
32 changes: 32 additions & 0 deletions tests/ffi/types/ptr.luau
Original file line number Diff line number Diff line change
@@ -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}`)
12 changes: 12 additions & 0 deletions tests/ffi/types/struct.luau
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit c656a48

Please sign in to comment.