mirror of
https://github.com/lune-org/lune.git
synced 2025-04-10 21:40:54 +01:00
Fix boundary check logic (#243)
This commit is contained in:
parent
902f5f960b
commit
b503cc9f5b
4 changed files with 55 additions and 61 deletions
|
@ -6,24 +6,28 @@ See [tests/ffi](../../tests/ffi/README.md)
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- Rewrite error messages
|
|
||||||
- CString
|
- CString
|
||||||
- Add buffer for owned data support
|
- Add buffer as owned data support
|
||||||
- Add math operation.
|
- Add math operation for numeric types
|
||||||
|
|
||||||
> 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`
|
||||||
> Luau cannot handle f64, i64 or i128, so we should provide math operation for it
|
> 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
|
> Luau only supports 32bit bit operations
|
||||||
|
|
||||||
- Add wchar and wstring support
|
- Add wchar and wstring support
|
||||||
|
|
||||||
> For windows API
|
> For windows API support
|
||||||
|
|
||||||
- Add varargs support
|
- Add varargs support
|
||||||
- Array argument in cfn
|
- Array argument in cfn
|
||||||
|
- More box/ref methods
|
||||||
|
- writeString
|
||||||
|
- readString
|
||||||
|
- writeBase64
|
||||||
|
- readBase64
|
||||||
|
|
||||||
## Code structure
|
## Code structure
|
||||||
|
|
||||||
|
|
|
@ -16,77 +16,62 @@ impl RefBounds {
|
||||||
Self { above, below }
|
Self { above, below }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_unsized(&self) -> bool {
|
|
||||||
self.above == usize::MAX && self.below == usize::MAX
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check boundary
|
// Check boundary
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn check_boundary(&self, offset: isize) -> bool {
|
pub fn check_boundary(&self, offset: isize) -> bool {
|
||||||
if self.is_unsized() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
let sign = offset.signum();
|
|
||||||
let offset_abs = offset.unsigned_abs();
|
let offset_abs = offset.unsigned_abs();
|
||||||
if sign == -1 {
|
match offset.signum() {
|
||||||
self.above >= offset_abs
|
-1 => self.above >= offset_abs,
|
||||||
} else if sign == 1 {
|
1 => self.below >= offset_abs,
|
||||||
self.below >= offset_abs
|
0 => true,
|
||||||
} else {
|
_ => unreachable!(),
|
||||||
// sign == 0
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check boundary with specific size
|
// 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]
|
#[inline]
|
||||||
pub fn check_sized(&self, offset: isize, size: usize) -> bool {
|
pub fn check_sized(&self, offset: isize, size: usize) -> bool {
|
||||||
if self.is_unsized() {
|
// (Case1) offset over above
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if offset < 0 && self.above < offset.unsigned_abs() {
|
if offset < 0 && self.above < offset.unsigned_abs() {
|
||||||
return true;
|
return false;
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate new boundaries from bounds and offset
|
// (Case2) end over below
|
||||||
|
let end = offset + (size as isize);
|
||||||
|
end <= 0 || self.below >= end.unsigned_abs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate new boundaries with bounds and offset
|
||||||
// No boundary checking in here
|
// No boundary checking in here
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn offset(&self, offset: isize) -> Self {
|
pub fn offset(&self, offset: isize) -> Self {
|
||||||
let sign = offset.signum();
|
let sign = offset.signum();
|
||||||
let offset_abs = offset.unsigned_abs();
|
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 {
|
Self {
|
||||||
above: high,
|
above: match sign {
|
||||||
below: low,
|
-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!(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,23 +8,28 @@ gcc for library compiling (for external-\*)
|
||||||
|
|
||||||
**External tests**
|
**External tests**
|
||||||
|
|
||||||
|
- [x] [external_closure](./external_closure/init.luau)
|
||||||
- [x] [external_math](./external_math/init.luau)
|
- [x] [external_math](./external_math/init.luau)
|
||||||
- [x] [external_pointer](./external_pointer/init.luau)
|
- [x] [external_pointer](./external_pointer/init.luau)
|
||||||
- [x] [external_print](./external_print/init.luau)
|
- [x] [external_print](./external_print/init.luau)
|
||||||
- [x] [external_struct](./external_struct/init.luau)
|
- [x] [external_struct](./external_struct/init.luau)
|
||||||
- [x] [external_closure](./external_closure/init.luau)
|
|
||||||
|
|
||||||
**Luau-side**
|
**Luau-side**
|
||||||
|
|
||||||
- [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)
|
- [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](./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
|
## Benchmark Results
|
||||||
|
|
||||||
|
|
|
@ -48,4 +48,4 @@ ok = pcall(function()
|
||||||
local box = ffi.box(ffi.u8.size * 2):ref(ffi.u16.size)
|
local box = ffi.box(ffi.u8.size * 2):ref(ffi.u16.size)
|
||||||
ffi.u16:readData(box)
|
ffi.u16:readData(box)
|
||||||
end)
|
end)
|
||||||
assert(ok, "assersion failed, Case7 should fail")
|
assert(not ok, "assersion failed, Case7 should fail")
|
||||||
|
|
Loading…
Add table
Reference in a new issue