diff --git a/crates/lune-std-ffi/README.md b/crates/lune-std-ffi/README.md index 1140c04..352cb60 100644 --- a/crates/lune-std-ffi/README.md +++ b/crates/lune-std-ffi/README.md @@ -6,24 +6,28 @@ See [tests/ffi](../../tests/ffi/README.md) ## TODO -- Rewrite error messages - CString -- Add buffer for owned data support -- Add math operation. +- Add buffer as owned data support +- Add math operation for numeric types > Provide related methods: `CTypeInfo:add(target, from1, from2, ...)` and `:sub` `:mul` `:div` `:mod` `:pow` `:max` `:min` `:gt` `:lt` > Luau cannot handle f64, i64 or i128, so we should provide math operation for it -- Add bit operation +- Add bit operation for box/ref > Luau only supports 32bit bit operations - Add wchar and wstring support - > For windows API + > For windows API support - Add varargs support - Array argument in cfn +- More box/ref methods + - writeString + - readString + - writeBase64 + - readBase64 ## Code structure diff --git a/crates/lune-std-ffi/src/data/ref_data/bounds.rs b/crates/lune-std-ffi/src/data/ref_data/bounds.rs index be3e288..4b715f9 100644 --- a/crates/lune-std-ffi/src/data/ref_data/bounds.rs +++ b/crates/lune-std-ffi/src/data/ref_data/bounds.rs @@ -16,77 +16,62 @@ impl RefBounds { Self { above, below } } - #[inline] - pub fn is_unsized(&self) -> bool { - self.above == usize::MAX && self.below == usize::MAX - } - // Check boundary #[inline] pub fn check_boundary(&self, offset: isize) -> bool { - if self.is_unsized() { - return true; - } - let sign = offset.signum(); let offset_abs = offset.unsigned_abs(); - if sign == -1 { - self.above >= offset_abs - } else if sign == 1 { - self.below >= offset_abs - } else { - // sign == 0 - true + match offset.signum() { + -1 => self.above >= offset_abs, + 1 => self.below >= offset_abs, + 0 => true, + _ => unreachable!(), } } // Check boundary with specific size + // + // -4 ∧ ────── Above = 4 + // -3 │ (Case1) + // -2 │ ┌──── Offset = -2 : offset >= 0 || abs(offset) <= above + // -1 │ │ + // 0 │ │ Size = 4 + // 1 │ │ (Case2) + // 2 │ ∨ ─── End = 2 : end = offset + size; + // 3 │ end <= 0 || end <= below + // 4 ∨ ────── Below = 4 + // #[inline] pub fn check_sized(&self, offset: isize, size: usize) -> bool { - if self.is_unsized() { - return true; - } + // (Case1) offset over above if offset < 0 && self.above < offset.unsigned_abs() { - return true; - } - let end = offset + (size as isize) - 1; - let end_sign = end.signum(); - let end_abs = end.unsigned_abs(); - if end_sign == -1 { - self.above >= end_abs - } else if end_sign == 1 { - self.below >= end_abs - } else { - // sign == 0 - true + return false; } + + // (Case2) end over below + let end = offset + (size as isize); + end <= 0 || self.below >= end.unsigned_abs() } - // Calculate new boundaries from bounds and offset + // Calculate new boundaries with bounds and offset // No boundary checking in here #[inline] pub fn offset(&self, offset: isize) -> Self { let sign = offset.signum(); let offset_abs = offset.unsigned_abs(); - let high: usize = if sign == -1 { - self.above - offset_abs - } else if sign == 1 { - self.above + offset_abs - } else { - self.above - }; - - let low: usize = if sign == -1 { - self.below + offset_abs - } else if sign == 1 { - self.below - offset_abs - } else { - self.below - }; - Self { - above: high, - below: low, + above: match sign { + -1 => self.above - offset_abs, + 1 => self.above + offset_abs, + 0 => self.above, + _ => unreachable!(), + }, + below: match sign { + -1 => self.below + offset_abs, + 1 => self.below - offset_abs, + 0 => self.below, + _ => unreachable!(), + }, } } } diff --git a/tests/ffi/README.md b/tests/ffi/README.md index 77ed269..f42576b 100644 --- a/tests/ffi/README.md +++ b/tests/ffi/README.md @@ -8,23 +8,28 @@ gcc for library compiling (for external-\*) **External tests** +- [x] [external_closure](./external_closure/init.luau) - [x] [external_math](./external_math/init.luau) - [x] [external_pointer](./external_pointer/init.luau) - [x] [external_print](./external_print/init.luau) - [x] [external_struct](./external_struct/init.luau) -- [x] [external_closure](./external_closure/init.luau) **Luau-side** -- [x] [isInteger](./isInteger.luau) - [x] [cast](./cast.luau) -- [x] [write_boundary](./write_boundary.luau) -- [x] [read_boundary](./read_boundary.luau) - [x] [free](./free.luau) +- [x] [isInteger](./isInteger.luau) +- [x] [read_boundary](./read_boundary.luau) +- [x] [write_boundary](./write_boundary.luau) **Pretty Print** -- [ ] [pretty_print](./pretty_print) +- [x] [arr](./pretty_print/arr.luau) +- [ ] [box](./pretty_print/box.luau) +- [x] [fn](./pretty_print/fn.luau) +- [x] [ptr](./pretty_print/ptr.luau) +- [x] [struct](./pretty_print/struct.luau) +- [x] [type](./pretty_print/type.luau) ## Benchmark Results diff --git a/tests/ffi/readBoundary.luau b/tests/ffi/readBoundary.luau index dd8e3d2..94c4ff3 100644 --- a/tests/ffi/readBoundary.luau +++ b/tests/ffi/readBoundary.luau @@ -48,4 +48,4 @@ ok = pcall(function() local box = ffi.box(ffi.u8.size * 2):ref(ffi.u16.size) ffi.u16:readData(box) end) -assert(ok, "assersion failed, Case7 should fail") +assert(not ok, "assersion failed, Case7 should fail")