Skip to content

Commit a2a8176

Browse files
authored
Merge pull request #1 from 0x5eal/chore/ffi-types
Update Luau types
2 parents bf33afd + 133abb5 commit a2a8176

File tree

1 file changed

+161
-64
lines changed

1 file changed

+161
-64
lines changed

types/ffi.luau

Lines changed: 161 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,176 @@
1-
--[=[
2-
@interface Box
3-
@within FFI
4-
5-
Box is an untyped, sized memory area that Lua can manage.
6-
This area is safe within Lua. Operations have their boundaries checked.
7-
8-
You can passing box as raw arguments or as pointer to outside.
9-
It also helps you handle data that Lua cannot handle. or you can reuse box to save cost from convertsion.
10-
Depending on the type, operations such as sum, mul, and mod may be implemented. See Types
1+
-- NOTE: T is a unique identifier for the `CType` and R is the closest Lua type.
2+
export type CType<T, R> = {
3+
size: number,
4+
signedness: boolean,
115

12-
```lua
13-
ffi.box(size)
14-
```
15-
This is a dictionary that will contain the following values:
6+
ptr: (self: CType<T, R>) -> CPtr<R>,
7+
box: (self: CType<T, R>, val: R) -> Box,
8+
-- FIXME: recursive types; ud should be CTypes
9+
from: (self: CType<T, R>, ud: any, offset: number?) -> R,
10+
into: (self: CType<T, R>, ud: any, value: R, offset: number?) -> (),
11+
arr: (self: CType<T, R>, len: number) -> CArr<R>,
12+
-- FIXME: recursive types; intoType should be CTypes
13+
cast: <F, I>(self: CType<T, R>, intoType: any, from: F, into: I) -> (),
14+
} & { ["__phantom"]: T }
1615

17-
* `readOnly` - If the target path is read-only or not
18-
]=]
16+
export type CPtr<T> = {
17+
size: number,
18+
inner: T?,
19+
}
1920

20-
export type Box = {
21+
export type CArr<T> = {
2122
size: number,
22-
ref: (self: Box)->Ref,
23+
length: number,
24+
inner: { T }?,
25+
26+
offset: (self: CArr<T>, offset: number) -> number,
27+
ptr: (self: CArr<T>) -> CPtr<{ T }>,
28+
box: (self: CArr<T>, table: { T }) -> Box,
29+
-- FIXME: recursive types; ud should be CTypes
30+
from: (self: CArr<T>, ud: any, offset: number?) -> { T },
31+
into: (self: CArr<T>, ud: any, value: { T }, offset: number?) -> (),
2332
}
24-
export type BoxConstructor = (size: number)->Box
2533

26-
export type Type = {}
34+
type NumCType<T> = CType<T, number>
2735

28-
---! FIXME: better typing for PointerSize
29-
export type PointerSize = number -- typeof(5) | typeof(8)
36+
-- Fixed size Rust-style types --
37+
export type u8 = NumCType<"u8">
38+
export type u16 = NumCType<"u16">
39+
export type u32 = NumCType<"u32">
40+
export type u64 = NumCType<"u64">
41+
export type u128 = NumCType<"u128">
42+
export type i8 = NumCType<"i8">
43+
export type i16 = NumCType<"i16">
44+
export type i32 = NumCType<"i32">
45+
export type i64 = NumCType<"i64">
46+
export type i128 = NumCType<"i128">
47+
export type f32 = NumCType<"f32">
48+
export type f64 = NumCType<"f64">
49+
export type usize = NumCType<"usize">
50+
export type isize = NumCType<"isize">
3051

31-
export type Arr<T> = {
32-
inner: T,
33-
size: number,
34-
ptr: (self: Arr<T>) -> any,
35-
}
52+
-- Variable size C-style types --
53+
export type char = NumCType<"char">
54+
export type float = NumCType<"float">
55+
export type double = NumCType<"double">
56+
export type uchar = NumCType<"uchar">
57+
export type schar = NumCType<"schar">
58+
export type short = NumCType<"short">
59+
export type ushort = NumCType<"ushort">
60+
export type int = NumCType<"int">
61+
export type uint = NumCType<"uint">
62+
export type long = NumCType<"long">
63+
export type ulong = NumCType<"ulong">
64+
export type longlong = NumCType<"longlong">
65+
export type ulonglong = NumCType<"ulonglong">
3666

37-
--[=[
38-
@interface Ptr
39-
@within FFI
40-
41-
]=]
42-
---! FIXME: due to recursive type limition. hardcoded 6 depth. better idea?
43-
export type Ptr<T> = {
44-
inner: T,
45-
size: PointerSize,
46-
ptr: (self: Ptr<T>)->PtrPtr<Ptr<T>>,
47-
arr: (self: Ptr<T>, size: number) -> Arr<Ptr<T>>,
48-
}
49-
export type PtrPtr<T> = {
50-
inner: T,
51-
size: PointerSize,
52-
ptr: (self: PtrPtr<T>)->PtrPtrPtr<PtrPtr<T>>,
53-
arr: (self: PtrPtr<T>, size: number) -> Arr<PtrPtr<T>>,
67+
export type CFn = {
68+
caller: (self: CFn, fnPtr: Ref) -> Callable,
5469
}
55-
export type PtrPtrPtr<T> = {
56-
inner: T,
57-
size: PointerSize,
58-
ptr: (self: PtrPtrPtr<T>)->PtrPtrPtrPtr<PtrPtrPtr<T>>,
59-
arr: (self: PtrPtrPtr<T>, size: number) -> Arr<PtrPtrPtr<T>>,
70+
71+
export type CTypes =
72+
| u8
73+
| u16
74+
| u32
75+
| u64
76+
| u128
77+
| i8
78+
| i16
79+
| i32
80+
| i64
81+
| i128
82+
| f32
83+
| f64
84+
| usize
85+
| isize
86+
| char
87+
| float
88+
| double
89+
| uchar
90+
| schar
91+
| short
92+
| ushort
93+
| int
94+
| uint
95+
| long
96+
| ulong
97+
| longlong
98+
| ulonglong
99+
100+
export type Ref = {
101+
deref: (self: Ref) -> Ref,
102+
offset: (self: Ref, offset: number) -> Ref,
103+
ref: (self: Ref) -> Ref,
104+
isNullptr: (self: Ref) -> boolean,
60105
}
61-
export type PtrPtrPtrPtr<T> = {
62-
inner: T,
63-
size: PointerSize,
64-
ptr: (self: PtrPtrPtrPtr<T>)->PtrPtrPtrPtrPtr<PtrPtrPtrPtr<T>>,
65-
arr: (self: PtrPtrPtrPtr<T>, size: number) -> Arr<PtrPtrPtrPtr<T>>,
106+
107+
export type Box = {
108+
size: number,
109+
110+
zero: (self: Box) -> Box,
111+
leak: (self: Box, offset: number?) -> Ref,
112+
ref: (self: Box, offset: number?) -> Ref,
66113
}
67-
export type PtrPtrPtrPtrPtr<T> = {
68-
inner: T,
69-
size: PointerSize,
70-
ptr: (self: PtrPtrPtrPtrPtr<T>)->PtrPtrPtrPtrPtrPtr<PtrPtrPtrPtrPtr<T>>,
71-
arr: (self: PtrPtrPtrPtrPtr<T>, size: number) -> Arr<PtrPtrPtrPtrPtr<T>>,
114+
115+
export type Library = {
116+
find: (self: Library, sym: string) -> Ref,
72117
}
73-
export type PtrPtrPtrPtrPtrPtr<T> = {
74-
inner: T,
75-
size: PointerSize,
76-
ptr: (self: PtrPtrPtrPtrPtrPtr<T>)->any, -- Yes. At this point. more type is useless.
77-
arr: (self: PtrPtrPtrPtrPtrPtr<T>, size: number) -> Arr<PtrPtrPtrPtrPtrPtr<T>>,
118+
119+
export type Callable = {
120+
call: (self: Callable, retPtr: Ref, ...Box) -> (),
78121
}
79122

123+
local ffi = {}
124+
125+
ffi.u8 = (nil :: unknown) :: u8
126+
ffi.u16 = {} :: u16
127+
ffi.u32 = {} :: u32
128+
ffi.u64 = {} :: u64
129+
ffi.u128 = {} :: u128
130+
ffi.i8 = {} :: i8
131+
ffi.i16 = {} :: i16
132+
ffi.i32 = {} :: i32
133+
ffi.i64 = {} :: i64
134+
ffi.i128 = {} :: i128
135+
ffi.f32 = {} :: f32
136+
ffi.f64 = {} :: f64
137+
ffi.usize = {} :: usize
138+
ffi.isize = {} :: isize
139+
140+
ffi.char = {} :: char
141+
ffi.float = {} :: float
142+
ffi.double = {} :: double
143+
ffi.uchar = {} :: uchar
144+
ffi.schar = {} :: schar
145+
ffi.short = {} :: short
146+
ffi.ushort = {} :: ushort
147+
ffi.int = {} :: int
148+
ffi.uint = {} :: uint
149+
ffi.long = {} :: long
150+
ffi.ulong = {} :: ulong
151+
ffi.longlong = {} :: longlong
152+
ffi.ulonglong = {} :: ulonglong
153+
154+
ffi.nullptr = {} :: Ref
155+
156+
function ffi.box(size: number): Box
157+
return nil :: any
158+
end
159+
160+
function ffi.open(path: string): Library
161+
return nil :: any
162+
end
163+
164+
function ffi.ref(): Ref
165+
return nil :: any
166+
end
167+
168+
function ffi.isInteger<T>(val: T): boolean
169+
return nil :: any
170+
end
171+
172+
function ffi.fn<T>(args: { CTypes }, ret: CTypes): CFn
173+
return nil :: any
174+
end
175+
176+
return ffi

0 commit comments

Comments
 (0)