mirror of
https://github.com/lune-org/lune.git
synced 2025-04-10 13:30:53 +01:00
commit
a2a8176241
1 changed files with 164 additions and 67 deletions
231
types/ffi.luau
231
types/ffi.luau
|
@ -1,79 +1,176 @@
|
||||||
--[=[
|
-- NOTE: T is a unique identifier for the `CType` and R is the closest Lua type.
|
||||||
@interface Box
|
export type CType<T, R> = {
|
||||||
@within FFI
|
size: number,
|
||||||
|
signedness: boolean,
|
||||||
|
|
||||||
Box is an untyped, sized memory area that Lua can manage.
|
ptr: (self: CType<T, R>) -> CPtr<R>,
|
||||||
This area is safe within Lua. Operations have their boundaries checked.
|
box: (self: CType<T, R>, val: R) -> Box,
|
||||||
|
-- FIXME: recursive types; ud should be CTypes
|
||||||
|
from: (self: CType<T, R>, ud: any, offset: number?) -> R,
|
||||||
|
into: (self: CType<T, R>, ud: any, value: R, offset: number?) -> (),
|
||||||
|
arr: (self: CType<T, R>, len: number) -> CArr<R>,
|
||||||
|
-- FIXME: recursive types; intoType should be CTypes
|
||||||
|
cast: <F, I>(self: CType<T, R>, intoType: any, from: F, into: I) -> (),
|
||||||
|
} & { ["__phantom"]: T }
|
||||||
|
|
||||||
You can passing box as raw arguments or as pointer to outside.
|
export type CPtr<T> = {
|
||||||
It also helps you handle data that Lua cannot handle. or you can reuse box to save cost from convertsion.
|
size: number,
|
||||||
Depending on the type, operations such as sum, mul, and mod may be implemented. See Types
|
inner: T?,
|
||||||
|
}
|
||||||
|
|
||||||
```lua
|
export type CArr<T> = {
|
||||||
ffi.box(size)
|
size: number,
|
||||||
```
|
length: number,
|
||||||
This is a dictionary that will contain the following values:
|
inner: { T }?,
|
||||||
|
|
||||||
* `readOnly` - If the target path is read-only or not
|
offset: (self: CArr<T>, offset: number) -> number,
|
||||||
]=]
|
ptr: (self: CArr<T>) -> CPtr<{ T }>,
|
||||||
|
box: (self: CArr<T>, table: { T }) -> Box,
|
||||||
|
-- FIXME: recursive types; ud should be CTypes
|
||||||
|
from: (self: CArr<T>, ud: any, offset: number?) -> { T },
|
||||||
|
into: (self: CArr<T>, ud: any, value: { T }, offset: number?) -> (),
|
||||||
|
}
|
||||||
|
|
||||||
|
type NumCType<T> = CType<T, number>
|
||||||
|
|
||||||
|
-- Fixed size Rust-style types --
|
||||||
|
export type u8 = NumCType<"u8">
|
||||||
|
export type u16 = NumCType<"u16">
|
||||||
|
export type u32 = NumCType<"u32">
|
||||||
|
export type u64 = NumCType<"u64">
|
||||||
|
export type u128 = NumCType<"u128">
|
||||||
|
export type i8 = NumCType<"i8">
|
||||||
|
export type i16 = NumCType<"i16">
|
||||||
|
export type i32 = NumCType<"i32">
|
||||||
|
export type i64 = NumCType<"i64">
|
||||||
|
export type i128 = NumCType<"i128">
|
||||||
|
export type f32 = NumCType<"f32">
|
||||||
|
export type f64 = NumCType<"f64">
|
||||||
|
export type usize = NumCType<"usize">
|
||||||
|
export type isize = NumCType<"isize">
|
||||||
|
|
||||||
|
-- Variable size C-style types --
|
||||||
|
export type char = NumCType<"char">
|
||||||
|
export type float = NumCType<"float">
|
||||||
|
export type double = NumCType<"double">
|
||||||
|
export type uchar = NumCType<"uchar">
|
||||||
|
export type schar = NumCType<"schar">
|
||||||
|
export type short = NumCType<"short">
|
||||||
|
export type ushort = NumCType<"ushort">
|
||||||
|
export type int = NumCType<"int">
|
||||||
|
export type uint = NumCType<"uint">
|
||||||
|
export type long = NumCType<"long">
|
||||||
|
export type ulong = NumCType<"ulong">
|
||||||
|
export type longlong = NumCType<"longlong">
|
||||||
|
export type ulonglong = NumCType<"ulonglong">
|
||||||
|
|
||||||
|
export type CFn = {
|
||||||
|
caller: (self: CFn, fnPtr: Ref) -> Callable,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CTypes =
|
||||||
|
| u8
|
||||||
|
| u16
|
||||||
|
| u32
|
||||||
|
| u64
|
||||||
|
| u128
|
||||||
|
| i8
|
||||||
|
| i16
|
||||||
|
| i32
|
||||||
|
| i64
|
||||||
|
| i128
|
||||||
|
| f32
|
||||||
|
| f64
|
||||||
|
| usize
|
||||||
|
| isize
|
||||||
|
| char
|
||||||
|
| float
|
||||||
|
| double
|
||||||
|
| uchar
|
||||||
|
| schar
|
||||||
|
| short
|
||||||
|
| ushort
|
||||||
|
| int
|
||||||
|
| uint
|
||||||
|
| long
|
||||||
|
| ulong
|
||||||
|
| longlong
|
||||||
|
| ulonglong
|
||||||
|
|
||||||
|
export type Ref = {
|
||||||
|
deref: (self: Ref) -> Ref,
|
||||||
|
offset: (self: Ref, offset: number) -> Ref,
|
||||||
|
ref: (self: Ref) -> Ref,
|
||||||
|
isNullptr: (self: Ref) -> boolean,
|
||||||
|
}
|
||||||
|
|
||||||
export type Box = {
|
export type Box = {
|
||||||
size: number,
|
size: number,
|
||||||
ref: (self: Box)->Ref,
|
|
||||||
}
|
|
||||||
export type BoxConstructor = (size: number)->Box
|
|
||||||
|
|
||||||
export type Type = {}
|
zero: (self: Box) -> Box,
|
||||||
|
leak: (self: Box, offset: number?) -> Ref,
|
||||||
---! FIXME: better typing for PointerSize
|
ref: (self: Box, offset: number?) -> Ref,
|
||||||
export type PointerSize = number -- typeof(5) | typeof(8)
|
|
||||||
|
|
||||||
export type Arr<T> = {
|
|
||||||
inner: T,
|
|
||||||
size: number,
|
|
||||||
ptr: (self: Arr<T>) -> any,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--[=[
|
export type Library = {
|
||||||
@interface Ptr
|
find: (self: Library, sym: string) -> Ref,
|
||||||
@within FFI
|
|
||||||
|
|
||||||
]=]
|
|
||||||
---! FIXME: due to recursive type limition. hardcoded 6 depth. better idea?
|
|
||||||
export type Ptr<T> = {
|
|
||||||
inner: T,
|
|
||||||
size: PointerSize,
|
|
||||||
ptr: (self: Ptr<T>)->PtrPtr<Ptr<T>>,
|
|
||||||
arr: (self: Ptr<T>, size: number) -> Arr<Ptr<T>>,
|
|
||||||
}
|
|
||||||
export type PtrPtr<T> = {
|
|
||||||
inner: T,
|
|
||||||
size: PointerSize,
|
|
||||||
ptr: (self: PtrPtr<T>)->PtrPtrPtr<PtrPtr<T>>,
|
|
||||||
arr: (self: PtrPtr<T>, size: number) -> Arr<PtrPtr<T>>,
|
|
||||||
}
|
|
||||||
export type PtrPtrPtr<T> = {
|
|
||||||
inner: T,
|
|
||||||
size: PointerSize,
|
|
||||||
ptr: (self: PtrPtrPtr<T>)->PtrPtrPtrPtr<PtrPtrPtr<T>>,
|
|
||||||
arr: (self: PtrPtrPtr<T>, size: number) -> Arr<PtrPtrPtr<T>>,
|
|
||||||
}
|
|
||||||
export type PtrPtrPtrPtr<T> = {
|
|
||||||
inner: T,
|
|
||||||
size: PointerSize,
|
|
||||||
ptr: (self: PtrPtrPtrPtr<T>)->PtrPtrPtrPtrPtr<PtrPtrPtrPtr<T>>,
|
|
||||||
arr: (self: PtrPtrPtrPtr<T>, size: number) -> Arr<PtrPtrPtrPtr<T>>,
|
|
||||||
}
|
|
||||||
export type PtrPtrPtrPtrPtr<T> = {
|
|
||||||
inner: T,
|
|
||||||
size: PointerSize,
|
|
||||||
ptr: (self: PtrPtrPtrPtrPtr<T>)->PtrPtrPtrPtrPtrPtr<PtrPtrPtrPtrPtr<T>>,
|
|
||||||
arr: (self: PtrPtrPtrPtrPtr<T>, size: number) -> Arr<PtrPtrPtrPtrPtr<T>>,
|
|
||||||
}
|
|
||||||
export type PtrPtrPtrPtrPtrPtr<T> = {
|
|
||||||
inner: T,
|
|
||||||
size: PointerSize,
|
|
||||||
ptr: (self: PtrPtrPtrPtrPtrPtr<T>)->any, -- Yes. At this point. more type is useless.
|
|
||||||
arr: (self: PtrPtrPtrPtrPtrPtr<T>, size: number) -> Arr<PtrPtrPtrPtrPtrPtr<T>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Callable = {
|
||||||
|
call: (self: Callable, retPtr: Ref, ...Box) -> (),
|
||||||
|
}
|
||||||
|
|
||||||
|
local ffi = {}
|
||||||
|
|
||||||
|
ffi.u8 = (nil :: unknown) :: u8
|
||||||
|
ffi.u16 = {} :: u16
|
||||||
|
ffi.u32 = {} :: u32
|
||||||
|
ffi.u64 = {} :: u64
|
||||||
|
ffi.u128 = {} :: u128
|
||||||
|
ffi.i8 = {} :: i8
|
||||||
|
ffi.i16 = {} :: i16
|
||||||
|
ffi.i32 = {} :: i32
|
||||||
|
ffi.i64 = {} :: i64
|
||||||
|
ffi.i128 = {} :: i128
|
||||||
|
ffi.f32 = {} :: f32
|
||||||
|
ffi.f64 = {} :: f64
|
||||||
|
ffi.usize = {} :: usize
|
||||||
|
ffi.isize = {} :: isize
|
||||||
|
|
||||||
|
ffi.char = {} :: char
|
||||||
|
ffi.float = {} :: float
|
||||||
|
ffi.double = {} :: double
|
||||||
|
ffi.uchar = {} :: uchar
|
||||||
|
ffi.schar = {} :: schar
|
||||||
|
ffi.short = {} :: short
|
||||||
|
ffi.ushort = {} :: ushort
|
||||||
|
ffi.int = {} :: int
|
||||||
|
ffi.uint = {} :: uint
|
||||||
|
ffi.long = {} :: long
|
||||||
|
ffi.ulong = {} :: ulong
|
||||||
|
ffi.longlong = {} :: longlong
|
||||||
|
ffi.ulonglong = {} :: ulonglong
|
||||||
|
|
||||||
|
ffi.nullptr = {} :: Ref
|
||||||
|
|
||||||
|
function ffi.box(size: number): Box
|
||||||
|
return nil :: any
|
||||||
|
end
|
||||||
|
|
||||||
|
function ffi.open(path: string): Library
|
||||||
|
return nil :: any
|
||||||
|
end
|
||||||
|
|
||||||
|
function ffi.ref(): Ref
|
||||||
|
return nil :: any
|
||||||
|
end
|
||||||
|
|
||||||
|
function ffi.isInteger<T>(val: T): boolean
|
||||||
|
return nil :: any
|
||||||
|
end
|
||||||
|
|
||||||
|
function ffi.fn<T>(args: { CTypes }, ret: CTypes): CFn
|
||||||
|
return nil :: any
|
||||||
|
end
|
||||||
|
|
||||||
|
return ffi
|
||||||
|
|
Loading…
Add table
Reference in a new issue