From f27bed578f4faaa19eb28ffcb29ae74a2f651519 Mon Sep 17 00:00:00 2001 From: Erica Marigold Date: Wed, 16 Oct 2024 12:34:59 +0100 Subject: [PATCH] chore(types): updated ffi types --- types/ffi.luau | 197 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 129 insertions(+), 68 deletions(-) diff --git a/types/ffi.luau b/types/ffi.luau index fb45208..c25ab4c 100644 --- a/types/ffi.luau +++ b/types/ffi.luau @@ -1,79 +1,140 @@ ---[=[ - @interface Box - @within FFI +export type CType = { + size: number, + signedness: boolean, - Box is an untyped, sized memory area that Lua can manage. - This area is safe within Lua. Operations have their boundaries checked. + ptr: (self: CType) -> CPtr, + box: (self: CType, val: K) -> Box, + from: (self: CType, ud: any, offset: number?) -> K, + into: (self: CType, ud: any, value: K, offset: number?) -> (), + arr: (self: CType, len: number) -> CArr, + -- FIXME: intoType is of type `CTypes`, but that leads to recursive types + cast: (self: CType, intoType: any, from: F, into: I) -> () +} & { ["__phantom"]: T } - You can passing box as raw arguments or as pointer to outside. - It also helps you handle data that Lua cannot handle. or you can reuse box to save cost from convertsion. - Depending on the type, operations such as sum, mul, and mod may be implemented. See Types +export type CPtr = { + size: number, + inner: T?, +} - ```lua - ffi.box(size) - ``` - This is a dictionary that will contain the following values: +export type CArr = { + size: number, + length: number, + inner: {T}?, - * `readOnly` - If the target path is read-only or not -]=] + offset: (self: CArr, offset: number) -> number, + ptr: (self: CArr) -> CPtr, + box: (self: CArr, table: { K }) -> Box, + from: (self: CArr, ud: any, offset: number?) -> { K }, + into: (self: CArr, ud: any, value: { K }, offset: number?) -> (), +} + +-- Numeric types -- +export type u8 = CType<"u8"> +export type u16 = CType<"u16"> +export type u32 = CType<"u32"> +export type u64 = CType<"u64"> +export type u128 = CType<"u128"> +export type i8 = CType<"i8"> +export type i16 = CType<"i16"> +export type i32 = CType<"i32"> +export type i64 = CType<"i64"> +export type i128 = CType<"i128"> +export type f32 = CType<"f32"> +export type f64 = CType<"f64"> +export type usize = CType<"usize"> +export type isize = CType<"isize"> + +-- C types -- +export type char = CType<"char"> +export type float = CType<"float"> +export type double = CType<"double"> +export type uchar = CType<"uchar"> +export type schar = CType<"schar"> +export type short = CType<"short"> +export type ushort = CType<"ushort"> +export type int = CType<"int"> +export type uint = CType<"uint"> +export type long = CType<"long"> +export type ulong = CType<"ulong"> +export type longlong = CType<"longlong"> +export type ulonglong = CType<"ulonglong"> +export type CFn = { + caller: () -> 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 = { - size: number, - ref: (self: Box)->Ref, -} -export type BoxConstructor = (size: number)->Box - -export type Type = {} - ----! FIXME: better typing for PointerSize -export type PointerSize = number -- typeof(5) | typeof(8) - -export type Arr = { - inner: T, size: number, - ptr: (self: Arr) -> any, + + zero: (self: Box) -> Box, + leak: (self: Box, offset: number?) -> Ref, + ref: (self: Box, offset: number?) -> Ref, } ---[=[ - @interface Ptr - @within FFI - -]=] ----! FIXME: due to recursive type limition. hardcoded 6 depth. better idea? -export type Ptr = { - inner: T, - size: PointerSize, - ptr: (self: Ptr)->PtrPtr>, - arr: (self: Ptr, size: number) -> Arr>, -} -export type PtrPtr = { - inner: T, - size: PointerSize, - ptr: (self: PtrPtr)->PtrPtrPtr>, - arr: (self: PtrPtr, size: number) -> Arr>, -} -export type PtrPtrPtr = { - inner: T, - size: PointerSize, - ptr: (self: PtrPtrPtr)->PtrPtrPtrPtr>, - arr: (self: PtrPtrPtr, size: number) -> Arr>, -} -export type PtrPtrPtrPtr = { - inner: T, - size: PointerSize, - ptr: (self: PtrPtrPtrPtr)->PtrPtrPtrPtrPtr>, - arr: (self: PtrPtrPtrPtr, size: number) -> Arr>, -} -export type PtrPtrPtrPtrPtr = { - inner: T, - size: PointerSize, - ptr: (self: PtrPtrPtrPtrPtr)->PtrPtrPtrPtrPtrPtr>, - arr: (self: PtrPtrPtrPtrPtr, size: number) -> Arr>, -} -export type PtrPtrPtrPtrPtrPtr = { - inner: T, - size: PointerSize, - ptr: (self: PtrPtrPtrPtrPtrPtr)->any, -- Yes. At this point. more type is useless. - arr: (self: PtrPtrPtrPtrPtrPtr, size: number) -> Arr>, +export type Library = { + find: (sym: string) -> Ref, } +export type Callable = { + call: (...any) -> (), +} + +local ffi = {} + +ffi.u8 = {} :: u8 +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(val: T): boolean + return nil :: any +end + +function ffi.fn(args: { any }, ret: CPtr): CFn + return nil :: any +end