annotate lua/luadyncall/src/dyntype.lua @ 62:4a9f6c7c09c1 default tip

- fix inccorect overflow errors for int (and long on LLP64 systems)
author Tassilo Philipp
date Sat, 18 May 2024 15:33:54 +0200
parents 0cfcc391201f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 require "ldyntype"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 -- utilities
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 local function align(x, align)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 return math.floor( ( x + (align-1) ) / align ) * align
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
9 -- typeinfo table constructors
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11 function typeinfo_base(signature, size, align)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 return { name = signature, signature = signature, class = "base", size = size, align = align }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15 function typeinfo_ptr(signature, basetypeinfo, ptrlevels)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 return { name = signature, signature = signature, class = "ptr", basetypeinfo = basetypeinfo, ptrlevels = ptrlevels, size = _TI.p.size, align = _TI.p.align }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 function typeinfo_struct(name, signature, size, align, fields)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 return { name = name, signature = signature, class = "struct" , size = size, align = align , fields = fields }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23 local function istypeinfo(typespec)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24 return type(typespec) == "table"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27 function typeinfo_tostring(typename)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28 local ti = gettypeinfo(typename)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29 local s = ti.name .. "\tsize=" .. ti.size .. "\talign=" .. ti.align
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30 if ti.basetypeinfo then
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31 local baseti = gettypeinfo(ti.basetypeinfo)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 if baseti.name then
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33 s = s .. "\tbase=" .. baseti.name
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34 else
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35 s = s .. "\tbase=" .. baseti
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38 if ti.fields then
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39 for k, v in pairs(ti.fields) do
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 s = s .. "\n- "..k .. ":\toffset=" .. v.offset
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 return s
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47 -- typeinfo registry
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49 _TI = { }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 function settypeinfo(name,info)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 _TI[name] = info
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 function gettypeinfo(typespec)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 if istypeinfo(typespec) then return typespec end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 local typeinfo = _TI[typespec]
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 if not typeinfo then -- pointer type ?
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 local ptrs, basename = typespec:match("(%**)<(%a+)>")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 if ptrs and basename then -- pointer type signature:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 typeinfo = typeinfo_ptr( typespec, gettypeinfo(basename), #ptrs)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 settypeinfo(typespec, typeinfo)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 end -- else, typespec remains a string (unknown type)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 return typeinfo
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 function dumptypeinfos()
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 for k,v in pairs(_TI) do
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 print(typeinfo_tostring(v))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 function dumptypeinfo(x)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 print(typeinfo_tostring(x))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 --
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 local function regbasetypes()
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 local sigs = "BcCsSiIjJlLpZ"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82 for typechar in sigs:gmatch(".") do
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83 settypeinfo(typechar, typeinfo_base( typechar, ldyntype.dtSize(typechar), ldyntype.dtAlign(typechar) ) )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 function regstructinfo(structsignature)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88 local name, typeclass, signature, fieldnames = structsignature:match("(%a+)([{|])(.+)%}(.+)")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90 if name and type and signature then
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91 local offset = 0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
92 local maxalign = 0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
93 local maxsize = 0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
94 local fields = { }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
95
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
96 local fieldname = signature:gmatch("(%S+)")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
97
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
98 for typespec, fieldname in signature:gmatch("(%S)") do
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
99
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
100 local typeinfo = gettypeinfo(typespec)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
101
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
102 offset = align(offset, typeinfo.align)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
103 maxalign = math.max(typeinfo.align,maxalign)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
104 maxsize = math.max(typeinfo.size, maxsize)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
105
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
106 fields[fieldname] = { offset = offset, typeinfo = typeinfo }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
107
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
108 if typeclass == "{" then -- structure
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
109 offset = offset + typeinfo.size
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
110 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
111
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
112 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
113
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
114 local structsize
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
115
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
116 if typeclass == "|" then
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
117 structsize = maxsize
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
118 else
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
119 structsize = offset
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
120 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
121
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
122 settypeinfo(name, typeinfo_struct(name, signature, structsize, maxalign, fields) )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
123 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
124
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
125 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
126
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
127 function regstructinfo_backup(structsignature)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
128 local name, typeclass, signature = structsignature:match("(%a+)([{|])(.+)%}")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
129
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
130 if name and type and signature then
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
131 local offset = 0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
132 local maxalign = 0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
133 local maxsize = 0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
134 local fields = { }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
135 for typespec, fieldname in signature:gmatch("(%S+)%s+(%S+)") do
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
136
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
137 local typeinfo = gettypeinfo(typespec)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
138
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
139 offset = align(offset, typeinfo.align)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
140 maxalign = math.max(typeinfo.align,maxalign)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
141 maxsize = math.max(typeinfo.size, maxsize)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
142
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
143 fields[fieldname] = { offset = offset, typeinfo = typeinfo }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
144
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
145 if typeclass == "{" then -- structure
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
146 offset = offset + typeinfo.size
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
147 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
148
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
149 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
150
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
151 local structsize
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
152
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
153 if typeclass == "|" then
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
154 structsize = maxsize
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
155 else
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
156 structsize = offset
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
157 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
158
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
159 settypeinfo(name, typeinfo_struct(name, signature, structsize, maxalign, fields) )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
160 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
161
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
162 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
163
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
164 function parsebasetypes(basetypesignature)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
165 for type,size,align in basetypesignature:gmatch("(%a+)%s+(%d)%s+(%d)%s*") do
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
166 settypeinfo(type, {signature=type,base=type,class="storage",size=size,align=align})
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
167 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
168 end
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
169
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
170 -- initialize typeinfo registry
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
171
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
172 regbasetypes()
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
173