Skip to content

Commit

Permalink
more work on typed ffi
Browse files Browse the repository at this point in the history
  • Loading branch information
CapsAdmin committed May 18, 2024
1 parent beb51f5 commit feff237
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 101 deletions.
4 changes: 2 additions & 2 deletions examples/projects/luajit/src/platforms/unix/filesystem.nlua
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ do

local dot = string.byte(".")

local function is_dots(ptr: {[number] = number})
local function is_dots(ptr: FFIArray<|3, number|>)
if ptr[0] == dot then
if ptr[1] == dot and ptr[2] == 0 then return true end

Expand Down Expand Up @@ -240,4 +240,4 @@ do
end
end

return fs
return fs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ do
)
local dot = string.byte(".")

local function is_dots(ptr: {[number] = number})
local function is_dots(ptr: FFIArray<|3, number|>)
if ptr[0] == dot then
if ptr[1] == dot and ptr[2] == 0 then return true end

Expand Down
13 changes: 13 additions & 0 deletions nattlua/c_declarations/analyzer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ function META:WalkCDeclaration_(node, walk_up)

if node.modifiers then handle_modifiers(self, node) end

if node.tokens["..."] and node.type == "expression" then
self.cdecl.of = {
type = "va_list",
}
self.cdecl = assert(self.cdecl.of)
end

if not walk_up then return end

if node.parent.kind == "c_declaration" then
Expand Down Expand Up @@ -364,7 +371,13 @@ local function cast(self, node, out)
return Tuple({}):AddRemainder(Tuple({Any()}):SetRepeat(math.huge))
end

local tbl = typs:Get(LString(t)) or self.typs_write:Get(LString(t))

if tbl then return (tbl) end

return (Number())
elseif node.type == "va_list" then
return Tuple({}):AddRemainder(Tuple({Any()}):SetRepeat(math.huge))
elseif node.type == "function" then
local args = {}
local rets = {}
Expand Down
16 changes: 16 additions & 0 deletions nattlua/c_declarations/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ function META:IsInArguments()
-- void foo(void (*)(int, int))
-- I guess it still works as a hacky solution
if self:IsTokenValue(",", i) then return true end

if self:IsTokenValue("(", i) and self:IsTokenValue(")", i + 1) then
return false
end

if
self:IsTokenValue(")", i) and
(
self:IsTokenValue(";", i + 1) or
self:IsTokenType("end_of_file", i + 1)
)
and
not self:IsTokenValue(")", i - 1)
then
return true
end
end
end

Expand Down
3 changes: 1 addition & 2 deletions nattlua/definitions/index.nlua
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ import("./lua/table.nlua")
import("./lua/string.nlua")
import("./lua/math.nlua")
import("./lua/os.nlua")
import("./lua/coroutine.nlua")
import("./typed_ffi.nlua")
import("./lua/coroutine.nlua")
107 changes: 106 additions & 1 deletion nattlua/definitions/lua/luajit.nlua
Original file line number Diff line number Diff line change
@@ -1,3 +1,60 @@
function FFIPointer<|T: any|>
if T == nil then return T end

-- https://github.com/LuaJIT/LuaJIT/blob/v2.1/src/lj_carith.c#L96-L159
return {
@MetaTable = self,
[number] = T,
__tostring = function(self: ref self)
return "Pointer(" .. tostring(self[number]) .. ")"
end,
__index = function(self: ref self, key: ref string)
return self[number][key]
end,
__le = function(self: ref self, other: ref self)
return Boolean()
end,
__lt = function(self: ref self, other: ref self)
return Boolean()
end,
__add = function(self: ref self, other: ref self | number)
return FFIPointer<|T|>
end,
__sub = function(self: ref self, other: ref self | number)
return FFIPointer<|T|>
end,
}
end

function FFIArray<|size: number, T: any|>
if T == nil then return T end

return {
@MetaTable = self,
[0 .. (size - 1)] = T,
__tostring = function(self: ref self)
return "Array" .. tostring(size) .. "(" .. tostring(self[0]) .. ")"
end,
__index = function(self: ref self, key: ref string)
return self[number][key]
end,
__le = function(self: ref self, other: ref self)
return Boolean()
end,
__lt = function(self: ref self, other: ref self)
return Boolean()
end,
__add = function(self: ref self, other: ref self | number)
return FFIPointer<|T|>
end,
__sub = function(self: ref self, other: ref self | number)
return FFIPointer<|T|>
end,
}
end

type cdata = FFIPointer<|number|>
type cdata.@TypeOverride = "cdata"
type Modules["ffi"] = {
errno = function=(nil | number)>(number),
os = "Windows" | "Linux" | "OSX" | "BSD" | "POSIX" | "Other",
Expand Down Expand Up @@ -135,4 +192,52 @@ type Modules["jit.util"] = {
funcuvname = function=(func: Function, index: number)>(number, number),
-- Gets a constant at a certain index in a function.
funck = function=(func: Function, index: number)>(any),
}
}
local type ffi = require("ffi")
type _G.ffi = ffi

analyzer function ffi.sizeof(cdecl: any, len: nil | number)
return require("nattlua.c_declarations.main").sizeof(cdecl, len)
end

analyzer function ffi.cdef(cdecl: string, ...: ...any)
return require("nattlua.c_declarations.main").cdef(cdecl, ...)
end

§env.typesystem.ffi:Get(types.ConstString("cdef")):SetPreventInputArgumentExpansion(true)

analyzer function ffi.cast(cdecl: string, src: any)
return require("nattlua.c_declarations.main").cast(cdecl, src)
end

analyzer function ffi.typeof(cdecl: string, ...: ...any)
return require("nattlua.c_declarations.main").typeof(cdecl, ...)
end

§env.typesystem.ffi:Get(types.ConstString("typeof")):SetPreventInputArgumentExpansion(true)

analyzer function ffi.get_type(cdecl: string, ...: ...any)
return require("nattlua.c_declarations.main").get_type(cdecl, ...)
end

analyzer function ffi.new(cdecl: any, ...: ...any)
return require("nattlua.c_declarations.main").new(cdecl, ...)
end

analyzer function ffi.metatype(ctype: any, meta: any)
return require("nattlua.c_declarations.main").metatype(ctype, meta)
end

analyzer function ffi.load(lib: string)
return require("nattlua.c_declarations.main").load(lib)
end

analyzer function ffi.gc(ctype: any, callback: Function)
return ctype
end

function FFIType<|str: string|>
return number
end

type ffi.string = function=(FFIPointer<|number|> | string, number | nil)>(string)
88 changes: 0 additions & 88 deletions nattlua/definitions/typed_ffi.nlua

This file was deleted.

2 changes: 0 additions & 2 deletions nattlua/definitions/utility.nlua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ type integer = number
type Table = {[any] = any} | {}
type Function = function=(...any)>(...any)
type userdata = Table
type cdata = {[number] = any}
type cdata.@TypeOverride = "cdata"
type ctype = any
type thread = Table
type empty_function = function=(...)>(...any)
Expand Down
2 changes: 1 addition & 1 deletion nattlua/types/table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function META:__tostring()
local analyzer = context:GetCurrentAnalyzer()

if analyzer then
local str = func:Call(analyzer, Tuple({self})):GetFirstValue()
local str = analyzer:Assert(func:Call(analyzer, Tuple({self}))):GetFirstValue()

if str and str:IsLiteral() then
self.suppress = false
Expand Down
4 changes: 2 additions & 2 deletions test/nattlua/analyzer/complex/ffi_example.nlua
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ end
local gbuf_n = 1024
local gbuf = ffi.new("char [?]", gbuf_n)

local function buf_grow(len: any, nokeep: boolean | nil)
local function buf_grow(len: number, nokeep: boolean | nil)
if len > gbuf_n then
gbuf_n = len
local newbuf = ffi.new("char [?]", gbuf_n)
Expand Down Expand Up @@ -190,4 +190,4 @@ function _M.mask(automate: ac_t, str: string, p: string, ignore_case: boolean)
end
end

return _M
return _M
5 changes: 5 additions & 0 deletions test/nattlua/analyzer/typed_ffi.lua
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,11 @@ analyze[=[
local info = {} as AddressInfo
addrinfo_get_ip(info)
]=]

do
return
end

analyze[[
local x = tostring(_ as FFIArray<|
1,
Expand Down
2 changes: 1 addition & 1 deletion test/nattlua/c_declarations.lua
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ do -- functions
test[[ void (**NAME()) ;]]
test[[ void (** volatile NAME()) ;]]
test[[ void (* volatile * volatile NAME()) ;]]
test[[ void __ptr32**NAME() ;]]
test[[ void (__ptr32**NAME()) ;]]
test[[ void (__stdcall*NAME()) ;]]
end
Expand Down Expand Up @@ -554,7 +555,6 @@ do -- struct and union declarations

test[[ struct TYPE { char *(*(**FIELD[][8])())[]; }; ]]
test([[ %{struct|union} NAME(NAME)(]] .. [[ %{struct|union} NAME);]])

test[[ struct TYPE { int FIELD; } ]] -- without ;
end

Expand Down
9 changes: 8 additions & 1 deletion test/nattlua/c_declarations/cdef.nlua
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ do
struct MyStruct faz;
]]
attest.equal(vars.faz, typs.MyStruct)
attest.equal(assert(vars.bar)[0], _ as {a = number})
attest.equal(assert(vars.bar)[0], _ as nil | {a = number})
end

do
Expand Down Expand Up @@ -117,4 +117,11 @@ do
MyStruct = {a = number},
MyStruct2 = {},
})
end

do
local vars, typs = cdef([[
int readdir(void *dirp);
]])
attest.equal(vars.readdir, _ as function=(any)>(number))
end

0 comments on commit feff237

Please sign in to comment.