Skip to content

Commit 2c43758

Browse files
committed
more work and fixes around cdata types
1 parent 30013be commit 2c43758

File tree

9 files changed

+55
-46
lines changed

9 files changed

+55
-46
lines changed

nattlua/analyzer/statements/assignment.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ return {
228228

229229
if contract then
230230
val = val:CopyLiteralness(contract)
231+
self:PushCurrentExpression(exp_key)
231232
self:ErrorIfFalse(check_type_against_contract(val, contract))
233+
self:PopCurrentExpression()
232234
val:SetContract(contract)
233235
end
234236
end

nattlua/c_declarations/analyzer.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ local function cast(self, node)
105105
node.of.modifiers[1] == "const" and
106106
node.of.modifiers[2] == "char"
107107
then
108-
return Union({arr, Nil(), String()})
108+
arr.is_string = true
109109
end
110110
end
111111

nattlua/c_declarations/main.lua

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,23 @@ local function TCData(obj, ...)
119119
end
120120

121121
local function process_arg(obj)
122-
if obj.Type == "table" then
122+
if obj.Type == "number" then
123+
return Union({TCData(obj), obj})
124+
elseif obj.Type == "table" then
123125
local typ = obj:Get(Number())
126+
124127
if typ then
125-
return Union({TCData(typ:Copy()), Nil(), TCData(obj)})
128+
if typ.Type == "number" then
129+
return Union({Nil(), TCData(obj), obj.is_string and String() or nil})
130+
end
131+
132+
return Union({TCData(typ:Copy()), Nil(), TCData(obj), obj.is_string and String() or nil})
126133
end
127134
elseif obj.Type == "union" then
128135
local u = {}
129136

130137
for i, obj in ipairs(obj:GetData()) do
131-
if obj.Type == "table" then
132-
u[i] = TCData(obj)
133-
else
134-
u[i] = obj
135-
end
138+
if obj.Type == "table" then u[i] = TCData(obj) else u[i] = obj end
136139
end
137140

138141
return Union(u)
@@ -143,9 +146,8 @@ local function process_type(key, obj, is_typedef, mode)
143146
if obj.Type == "function" then
144147
for i, v in ipairs(obj:GetInputSignature():GetData()) do
145148
local newtype = process_arg(v)
146-
if newtype then
147-
obj:GetInputSignature():Set(i, newtype)
148-
end
149+
150+
if newtype then obj:GetInputSignature():Set(i, newtype) end
149151
end
150152

151153
local ret = obj:GetOutputSignature():GetFirstValue()
@@ -235,7 +237,7 @@ function cparser.reset()
235237
types = Table()
236238
local analyzer = assert(analyzer_context:GetCurrentAnalyzer(), "no analyzer in context")
237239
local env = analyzer:GetScopeHelper(analyzer.function_scope)
238-
analyzer:ErrorIfFalse(env.typesystem.ffi:Set(ConstString("C"), Table()))
240+
--analyzer:ErrorIfFalse(env.typesystem.ffi:Set(ConstString("C"), Table()))
239241
analyzer:ErrorIfFalse(env.runtime.ffi:Set(ConstString("C"), Table()))
240242
end
241243

nattlua/definitions/lua/luajit.nlua

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function TCData<|T: ConstructorArgument, ...: ...any|>
1111
-- this assumes keys are in order, which in the typesystem they SHOULD be
1212
if ... then
1313
if is_array then
14-
local tbl = ...
14+
local tbl = copy<|...|>
1515

1616
if type(tbl) == "table" then
1717
if #tbl - 1 > keysof<|T|> then error<|"too many initializers", 2|> end
@@ -24,7 +24,13 @@ function TCData<|T: ConstructorArgument, ...: ...any|>
2424
error("expected type '" .. tostring(contract) .. "' at index " .. (i - 1), 2)
2525
end
2626

27-
T[i - 1] = v & contract
27+
local obj = copy<|v|>
28+
29+
for k, v in pairs(contract) do
30+
if rawget(obj, k) == nil then obj[k] = v end
31+
end
32+
33+
T[i - 1] = obj
2834
end
2935
end
3036
elseif type(T) == "table" then
@@ -78,16 +84,16 @@ function TCData<|T: ConstructorArgument, ...: ...any|>
7884

7985
return TCData<|obj|>
8086
end,
81-
__le = function <|self: self, other: self|>
87+
__le = function <|self: self, other: self | number | any|>
8288
return boolean
8389
end,
84-
__lt = function <|self: self, other: self|>
90+
__lt = function <|self: self, other: self | number | any|>
8591
return boolean
8692
end,
87-
__add = function <|self: self, other: self | number|>
93+
__add = function <|self: self, other: self | number | any|>
8894
return TCData<|T|>
8995
end,
90-
__sub = function <|self: self, other: self | number|>
96+
__sub = function <|self: self, other: self | number | any|>
9197
return TCData<|T|>
9298
end,
9399
}
@@ -156,13 +162,12 @@ type Modules["ffi"] = {
156162
arch = "x86" | "x64" | "arm" | "ppc" | "ppcspe" | "mips",
157163
C = {},
158164
abi = function=(string)>(boolean),
159-
copy = function=(any, any, number | nil)>(nil),
165+
copy = function=(any, any, number | nil | TCData<|number|>)>(),
160166
alignof = function=(ctype)>(number),
161-
string = function=(cdata, number | nil)>(string),
162167
gc = function=(ctype, Function)>(cdata),
163168
istype = function=(ctype, any)>(boolean),
164-
fill = function=(cdata, number, any)>(nil),
165-
offsetof = function=(cdata, number)>(number),
169+
fill = function=(cdata, number | TCData<|number|>, any)>(),
170+
offsetof = function=(cdata, number | TCData<|number|>)>(number),
166171
}
167172
--type Modules["ffi"].C.@Name = "FFI_C"
168173
type Modules["jit.vmdef"] = {
@@ -326,7 +331,7 @@ function FFIType<|str: string|>
326331
return number
327332
end
328333

329-
type ffi.string = function=(TCData<|{[number] = number}|> | string, number | nil)>(string)
334+
type ffi.string = function=(TCData<|{[number] = number}|> | string, TCData<|number|> | number | nil)>(string)
330335

331336
do
332337
type ffi.C = ffi.load("")

nattlua/types/tuple.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ return {
773773

774774
if v and v.Type == "tuple" or is_inf then
775775
-- inf tuple
776-
temp[i] = v
776+
temp[i] = v or Any()
777777

778778
break
779779
end

nattlua/types/union.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,11 +453,11 @@ function META.IsSubsetOf(a--[[#: TUnion]], b--[[#: any]])
453453
for _, a_val in ipairs(a.Data) do
454454
a.suppress = true
455455
local b_val, reason
456-
456+
local ok
457457
if b.Type == "union" then
458458
b_val, reason = b:IsTypeObjectSubsetOf(a_val)
459459
else
460-
local ok, reason = a_val:IsSubsetOf(b)
460+
ok, reason = a_val:IsSubsetOf(b)
461461

462462
if ok then
463463
b_val = b

test/tests/nattlua/analyzer/complex/ffi_example.nlua

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ end
5959
local gbuf_n = 1024
6060
local gbuf = ffi.new("char [?]", gbuf_n)
6161

62-
local function buf_grow(len: number, nokeep: boolean | nil)
62+
local function buf_grow(len: ffi.typeof_arg("int"), nokeep: boolean | nil)
6363
if len > gbuf_n then
6464
gbuf_n = len
6565
local newbuf = ffi.new("char [?]", gbuf_n)
@@ -95,9 +95,9 @@ function _M.replace(automate: ac_t, str: string, replacement: string, ignore_cas
9595
-- you can change this to gbuf_p = gbuf to observe another kind of bug behaviour
9696
local gbuf_p = ffi.new("char *", gbuf)
9797

98-
if not gbuf_p then error("uh oh") end
99-
10098
while true do
99+
if _ as boolean then break end
100+
101101
local r = ac.ac_match(automate, compare_str_p, str_n)
102102

103103
if r.match_begin >= 0 then
@@ -114,7 +114,7 @@ function _M.replace(automate: ac_t, str: string, replacement: string, ignore_cas
114114
C.strncpy(gbuf_p, str_p, str_n)
115115
gbuf_p = gbuf_p + str_n
116116
-- you can also try call ffi.string(gbuf, tonumber(gbuf_p - gbuf))
117-
return ffi.string(gbuf, (gbuf_p - gbuf) as number) -- lol
117+
return ffi.string(gbuf, (gbuf_p - gbuf)) -- lol
118118
end
119119
-- here, add print of info also changes behaviour
120120
-- print(tostring(ffi.typeof(gbuf_p)))
@@ -173,6 +173,8 @@ function _M.mask(automate: ac_t, str: string, p: string, ignore_case: boolean)
173173
local gbuf_p = gbuf
174174

175175
while true do
176+
if _ as boolean then break end
177+
176178
local r = ac.ac_match(automate, compare_str_p, str_n)
177179

178180
if r.match_begin >= 0 then

test/tests/nattlua/analyzer/complex/ljsocket.nlua

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
--ANALYZE
2+
ffi.C = {}
23
local type print = any
34
local ffi = require("ffi")
45
local socket = {}
@@ -992,7 +993,7 @@ function M.get_address_info(
992993
tbl,
993994
addrinfo_to_table(res as ffi.new<|"struct addrinfo *"|>, data.host, data.service)
994995
)
995-
res = res.ai_next
996+
res = assert(res.ai_next)
996997
end
997998

998999
--ffi.C.freeaddrinfo(out[0])
@@ -1497,7 +1498,9 @@ if TEST then
14971498
local socket = M
14981499

14991500
do
1500-
for _, info in ipairs((assert(socket.get_address_info({host = "www.google.com"})))) do
1501+
local x = socket.get_address_info({host = "www.google.com"})
1502+
1503+
for _, info in ipairs((assert(x))) do
15011504
print("================================")
15021505
print("host: ", info.host)
15031506
print("service: ", info.service)

test/tests/nattlua/c_declarations/typed_ffi.lua

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ analyze[=[
5353
int foo(int, bool, lol);
5454
]])
5555
56-
attest.equal(ffi.C.foo, _ as function=(number, boolean, number)>(number))
56+
attest.equal(ffi.C.foo, _ as function=(number|TCData<|number|>, boolean, TCData<|number|> | number)>(number))
5757
]=]
5858
analyze[=[
5959
local struct
@@ -94,18 +94,18 @@ analyze[=[
9494
9595
if LINUX then
9696
ffi.cdef("void foo(int a);")
97-
attest.equal(ffi.C.foo, _ as function=(number)>(()))
97+
attest.equal(ffi.C.foo, _ as function=(number|TCData<|number|>)>())
9898
else
9999
if X64 then
100100
ffi.cdef("void foo(const char *a);")
101-
attest.equal(ffi.C.foo, _ as function=(string | nil | ffi.new<|"const char*"|>)>(()))
101+
attest.equal(ffi.C.foo, _ as function=(string | nil | ffi.new<|"const char*"|>)>())
102102
else
103103
ffi.cdef("int foo(int a);")
104-
attest.equal(ffi.C.foo, _ as function=(number)>((number)))
104+
attest.equal(ffi.C.foo, _ as function=(number|TCData<|number|>)>(number))
105105
end
106106
end
107107
108-
attest.equal(ffi.C.foo, _ as function=(number)>() | function=(number)>(number) | function=(nil | string | ffi.new<|"const char*"|>)>())
108+
attest.equal(ffi.C.foo, _ as function=(number|TCData<|number|>)>() | function=(number|TCData<|number|>)>(number) | function=(nil | string | ffi.new<|"const char*"|>)>())
109109
]=]
110110
analyze[=[
111111
ffi.cdef("void foo(void *ptr, int foo, const char *test);")
@@ -520,7 +520,7 @@ analyze[=[
520520
521521
if ffi.os == "Windows" then
522522
local x = ffi.C.strerror
523-
attest.equal(x, _ as function=(number)>())
523+
attest.equal(x, _ as function=(number | TCData<|number|>)>())
524524
end
525525
]=]
526526
analyze[=[
@@ -536,17 +536,12 @@ foo(y)
536536
]]
537537
analyze[=[
538538
ffi.cdef([[
539-
struct sockaddr {
540-
uint16_t sa_family;
541-
char sa_data[14];
542-
};
543-
544-
struct addrinfo {
539+
struct wwww {
545540
int ai_flags;
546541
int ai_family;
547542
};
548543
]])
549-
local res = ffi.new("struct addrinfo[1]", {{ai_flags = 0}})
550-
attest.equal(res[0].ai_flags, _ as number)
544+
local res = ffi.new("struct wwww[1]", {{ai_flags = 0}})
545+
attest.equal(res[0].ai_flags, _ as 0)
551546
attest.equal(res[0].ai_family, _ as number)
552547
]=]

0 commit comments

Comments
 (0)