1 #include "lautoc.h"
2
luaA_open(lua_State * L)3 void luaA_open(lua_State* L) {
4
5 lua_pushinteger(L, 0); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_index");
6 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids");
7 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_names");
8 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_sizes");
9
10 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push");
11 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to");
12
13 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
14 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset");
15 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums");
16 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes");
17 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values");
18 lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions");
19
20 lua_newuserdata(L, LUAA_RETURN_STACK_SIZE); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_stk");
21 lua_newuserdata(L, LUAA_ARGUMENT_STACK_SIZE); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_stk");
22 lua_pushinteger(L, 0); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr");
23 lua_pushinteger(L, 0); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_ptr");
24
25 // compiler does weird macro expansion with "bool" so no magic macro for you
26 luaA_conversion_type(L, luaA_type_add(L,"bool",sizeof(bool)), luaA_push_bool, luaA_to_bool);
27 luaA_conversion_type(L, luaA_type_add(L,"_Bool",sizeof(bool)), luaA_push_bool, luaA_to_bool);
28 luaA_conversion(L, char, luaA_push_char, luaA_to_char);
29 luaA_conversion(L, signed char, luaA_push_signed_char, luaA_to_signed_char);
30 luaA_conversion(L, unsigned char, luaA_push_unsigned_char, luaA_to_unsigned_char);
31 luaA_conversion(L, short, luaA_push_short, luaA_to_short);
32 luaA_conversion(L, unsigned short, luaA_push_unsigned_short, luaA_to_unsigned_short);
33 luaA_conversion(L, int, luaA_push_int, luaA_to_int);
34 luaA_conversion(L, unsigned int, luaA_push_unsigned_int, luaA_to_unsigned_int);
35 luaA_conversion(L, long, luaA_push_long, luaA_to_long);
36 luaA_conversion(L, unsigned long, luaA_push_unsigned_long, luaA_to_unsigned_long);
37 luaA_conversion(L, long long, luaA_push_long_long, luaA_to_long_long);
38 luaA_conversion(L, unsigned long long, luaA_push_unsigned_long_long, luaA_to_unsigned_long_long);
39 luaA_conversion(L, float, luaA_push_float, luaA_to_float);
40 luaA_conversion(L, double, luaA_push_double, luaA_to_double);
41 luaA_conversion(L, long double, luaA_push_long_double, luaA_to_long_double);
42
43 luaA_conversion_push_type(L, luaA_type_add(L,"const bool",sizeof(bool)), luaA_push_bool);
44 luaA_conversion_push_type(L, luaA_type_add(L,"const _Bool",sizeof(bool)), luaA_push_bool);
45 luaA_conversion_push(L, const char, luaA_push_char);
46 luaA_conversion_push(L, const signed char, luaA_push_signed_char);
47 luaA_conversion_push(L, const unsigned char, luaA_push_unsigned_char);
48 luaA_conversion_push(L, const short, luaA_push_short);
49 luaA_conversion_push(L, const unsigned short, luaA_push_unsigned_short);
50 luaA_conversion_push(L, const int, luaA_push_int);
51 luaA_conversion_push(L, const unsigned int, luaA_push_unsigned_int);
52 luaA_conversion_push(L, const long, luaA_push_long);
53 luaA_conversion_push(L, const unsigned long, luaA_push_unsigned_long);
54 luaA_conversion_push(L, const long long, luaA_push_long_long);
55 luaA_conversion_push(L, const unsigned long long, luaA_push_unsigned_long_long);
56 luaA_conversion_push(L, const float, luaA_push_float);
57 luaA_conversion_push(L, const double, luaA_push_double);
58 luaA_conversion_push(L, const long double, luaA_push_long_double);
59
60 luaA_conversion(L, char*, luaA_push_char_ptr, luaA_to_char_ptr);
61 luaA_conversion(L, const char*, luaA_push_const_char_ptr, luaA_to_const_char_ptr);
62 luaA_conversion(L, void*, luaA_push_void_ptr, luaA_to_void_ptr);
63
64 luaA_conversion_push(L, void, luaA_push_void);
65
66 }
67
luaA_close(lua_State * L)68 void luaA_close(lua_State* L) {
69
70 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_index");
71 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids");
72 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_names");
73 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_sizes");
74
75 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push");
76 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to");
77
78 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
79 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset");
80 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums");
81 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes");
82 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values");
83 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions");
84
85 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_stk");
86 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_stk");
87 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr");
88 lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_ptr");
89
90 }
91
92 /*
93 ** Types
94 */
95
luaA_type_add(lua_State * L,const char * type,size_t size)96 luaA_Type luaA_type_add(lua_State* L, const char* type, size_t size) {
97
98 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids");
99 lua_getfield(L, -1, type);
100
101 if (lua_isnumber(L, -1)) {
102
103 luaA_Type id = lua_tointeger(L, -1);
104 lua_pop(L, 2);
105 return id;
106
107 } else {
108
109 lua_pop(L, 2);
110
111 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_index");
112
113 luaA_Type id = lua_tointeger(L, -1);
114 lua_pop(L, 1);
115 id++;
116
117 lua_pushinteger(L, id);
118 lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_index");
119
120 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids");
121 lua_pushinteger(L, id);
122 lua_setfield(L, -2, type);
123 lua_pop(L, 1);
124
125 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_names");
126 lua_pushinteger(L, id);
127 lua_pushstring(L, type);
128 lua_settable(L, -3);
129 lua_pop(L, 1);
130
131 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_sizes");
132 lua_pushinteger(L, id);
133 lua_pushinteger(L, size);
134 lua_settable(L, -3);
135 lua_pop(L, 1);
136
137 return id;
138
139 }
140
141 }
142
luaA_type_find(lua_State * L,const char * type)143 luaA_Type luaA_type_find(lua_State* L, const char* type) {
144
145 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids");
146 lua_getfield(L, -1, type);
147
148 luaA_Type id = lua_isnil(L, -1) ? LUAA_INVALID_TYPE : lua_tointeger(L, -1);
149 lua_pop(L, 2);
150
151 return id;
152 }
153
luaA_typename(lua_State * L,luaA_Type id)154 const char* luaA_typename(lua_State* L, luaA_Type id) {
155
156 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_names");
157 lua_pushinteger(L, id);
158 lua_gettable(L, -2);
159
160 const char* type = lua_isnil(L, -1) ? "LUAA_INVALID_TYPE" : lua_tostring(L, -1);
161 lua_pop(L, 2);
162
163 return type;
164 }
165
luaA_typesize(lua_State * L,luaA_Type id)166 size_t luaA_typesize(lua_State* L, luaA_Type id) {
167
168 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_sizes");
169 lua_pushinteger(L, id);
170 lua_gettable(L, -2);
171
172 size_t size = lua_isnil(L, -1) ? -1 : lua_tointeger(L, -1);
173 lua_pop(L, 2);
174
175 return size;
176 }
177
178 /*
179 ** Stack
180 */
181
luaA_push_type(lua_State * L,luaA_Type type_id,const void * c_in)182 int luaA_push_type(lua_State* L, luaA_Type type_id, const void* c_in) {
183
184 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push");
185 lua_pushinteger(L, type_id);
186 lua_gettable(L, -2);
187
188 if (!lua_isnil(L, -1)) {
189 luaA_Pushfunc func = lua_touserdata(L, -1);
190 lua_pop(L, 2);
191 return func(L, type_id, c_in);
192 }
193
194 lua_pop(L, 2);
195
196 if (luaA_struct_registered_type(L, type_id)) {
197 return luaA_struct_push_type(L, type_id, c_in);
198 }
199
200 if (luaA_enum_registered_type(L, type_id)) {
201 return luaA_enum_push_type(L, type_id, c_in);
202 }
203
204 lua_pushfstring(L, "luaA_push: conversion to Lua object from type '%s' not registered!", luaA_typename(L, type_id));
205 lua_error(L);
206 return 0;
207 }
208
luaA_to_type(lua_State * L,luaA_Type type_id,void * c_out,int index)209 void luaA_to_type(lua_State* L, luaA_Type type_id, void* c_out, int index) {
210
211 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to");
212 lua_pushinteger(L, type_id);
213 lua_gettable(L, -2);
214
215 if (!lua_isnil(L, -1)) {
216 luaA_Tofunc func = lua_touserdata(L, -1);
217 lua_pop(L, 2);
218 func(L, type_id, c_out, index);
219 return;
220 }
221
222 lua_pop(L, 2);
223
224 if (luaA_struct_registered_type(L, type_id)) {
225 luaA_struct_to_type(L, type_id, c_out, index);
226 return;
227 }
228
229 if (luaA_enum_registered_type(L, type_id)) {
230 luaA_enum_to_type(L, type_id, c_out, index);
231 return;
232 }
233
234 lua_pushfstring(L, "luaA_to: conversion from Lua object to type '%s' not registered!", luaA_typename(L, type_id));
235 lua_error(L);
236 }
237
luaA_conversion_type(lua_State * L,luaA_Type type_id,luaA_Pushfunc push_func,luaA_Tofunc to_func)238 void luaA_conversion_type(lua_State* L, luaA_Type type_id, luaA_Pushfunc push_func, luaA_Tofunc to_func) {
239 luaA_conversion_push_type(L, type_id, push_func);
240 luaA_conversion_to_type(L, type_id, to_func);
241 }
242
luaA_conversion_push_type(lua_State * L,luaA_Type type_id,luaA_Pushfunc func)243 void luaA_conversion_push_type(lua_State* L, luaA_Type type_id, luaA_Pushfunc func) {
244 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push");
245 lua_pushinteger(L, type_id);
246 lua_pushlightuserdata(L, func);
247 lua_settable(L, -3);
248 lua_pop(L, 1);
249 }
250
luaA_conversion_to_type(lua_State * L,luaA_Type type_id,luaA_Tofunc func)251 void luaA_conversion_to_type(lua_State* L, luaA_Type type_id, luaA_Tofunc func) {
252 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to");
253 lua_pushinteger(L, type_id);
254 lua_pushlightuserdata(L, func);
255 lua_settable(L, -3);
256 lua_pop(L, 1);
257 }
258
luaA_push_bool(lua_State * L,luaA_Type type_id,const void * c_in)259 int luaA_push_bool(lua_State* L, luaA_Type type_id, const void* c_in) {
260 lua_pushboolean(L, *(bool*)c_in);
261 return 1;
262 }
263
luaA_to_bool(lua_State * L,luaA_Type type_id,void * c_out,int index)264 void luaA_to_bool(lua_State* L, luaA_Type type_id, void* c_out, int index) {
265 *(bool*)c_out = lua_toboolean(L, index);
266 }
267
luaA_push_char(lua_State * L,luaA_Type type_id,const void * c_in)268 int luaA_push_char(lua_State* L, luaA_Type type_id, const void* c_in) {
269 lua_pushinteger(L, *(char*)c_in);
270 return 1;
271 }
272
luaA_to_char(lua_State * L,luaA_Type type_id,void * c_out,int index)273 void luaA_to_char(lua_State* L, luaA_Type type_id, void* c_out, int index) {
274 *(char*)c_out = lua_tointeger(L, index);
275 }
276
luaA_push_signed_char(lua_State * L,luaA_Type type_id,const void * c_in)277 int luaA_push_signed_char(lua_State* L, luaA_Type type_id, const void* c_in) {
278 lua_pushinteger(L, *(signed char*)c_in);
279 return 1;
280 }
281
luaA_to_signed_char(lua_State * L,luaA_Type type_id,void * c_out,int index)282 void luaA_to_signed_char(lua_State* L, luaA_Type type_id, void* c_out, int index) {
283 *(signed char*)c_out = lua_tointeger(L, index);
284 }
285
luaA_push_unsigned_char(lua_State * L,luaA_Type type_id,const void * c_in)286 int luaA_push_unsigned_char(lua_State* L, luaA_Type type_id, const void* c_in) {
287 lua_pushinteger(L, *(unsigned char*)c_in);
288 return 1;
289 }
290
luaA_to_unsigned_char(lua_State * L,luaA_Type type_id,void * c_out,int index)291 void luaA_to_unsigned_char(lua_State* L, luaA_Type type_id, void* c_out, int index) {
292 *(unsigned char*)c_out = lua_tointeger(L, index);
293 }
294
luaA_push_short(lua_State * L,luaA_Type type_id,const void * c_in)295 int luaA_push_short(lua_State* L, luaA_Type type_id, const void* c_in) {
296 lua_pushinteger(L, *(short*)c_in);
297 return 1;
298 }
299
luaA_to_short(lua_State * L,luaA_Type type_id,void * c_out,int index)300 void luaA_to_short(lua_State* L, luaA_Type type_id, void* c_out, int index) {
301 *(short*)c_out = lua_tointeger(L, index);
302 }
303
luaA_push_unsigned_short(lua_State * L,luaA_Type type_id,const void * c_in)304 int luaA_push_unsigned_short(lua_State* L, luaA_Type type_id, const void* c_in) {
305 lua_pushinteger(L, *(unsigned short*)c_in);
306 return 1;
307 }
308
luaA_to_unsigned_short(lua_State * L,luaA_Type type_id,void * c_out,int index)309 void luaA_to_unsigned_short(lua_State* L, luaA_Type type_id, void* c_out, int index) {
310 *(unsigned short*)c_out = lua_tointeger(L, index);
311 }
312
luaA_push_int(lua_State * L,luaA_Type type_id,const void * c_in)313 int luaA_push_int(lua_State* L, luaA_Type type_id, const void* c_in) {
314 lua_pushinteger(L, *(int*)c_in);
315 return 1;
316 }
317
luaA_to_int(lua_State * L,luaA_Type type_id,void * c_out,int index)318 void luaA_to_int(lua_State* L, luaA_Type type_id, void* c_out, int index) {
319 *(int*)c_out = lua_tointeger(L, index);
320 }
321
luaA_push_unsigned_int(lua_State * L,luaA_Type type_id,const void * c_in)322 int luaA_push_unsigned_int(lua_State* L, luaA_Type type_id, const void* c_in) {
323 lua_pushinteger(L, *(unsigned int*)c_in);
324 return 1;
325 }
326
luaA_to_unsigned_int(lua_State * L,luaA_Type type_id,void * c_out,int index)327 void luaA_to_unsigned_int(lua_State* L, luaA_Type type_id, void* c_out, int index) {
328 *(unsigned int*)c_out = lua_tointeger(L, index);
329 }
330
luaA_push_long(lua_State * L,luaA_Type type_id,const void * c_in)331 int luaA_push_long(lua_State* L, luaA_Type type_id, const void* c_in) {
332 lua_pushinteger(L, *(long*)c_in);
333 return 1;
334 }
335
luaA_to_long(lua_State * L,luaA_Type type_id,void * c_out,int index)336 void luaA_to_long(lua_State* L, luaA_Type type_id, void* c_out, int index) {
337 *(long*)c_out = lua_tointeger(L, index);
338 }
339
luaA_push_unsigned_long(lua_State * L,luaA_Type type_id,const void * c_in)340 int luaA_push_unsigned_long(lua_State* L, luaA_Type type_id, const void* c_in) {
341 lua_pushinteger(L, *(unsigned long*)c_in);
342 return 1;
343 }
344
luaA_to_unsigned_long(lua_State * L,luaA_Type type_id,void * c_out,int index)345 void luaA_to_unsigned_long(lua_State* L, luaA_Type type_id, void* c_out, int index) {
346 *(unsigned long*)c_out = lua_tointeger(L, index);
347 }
348
luaA_push_long_long(lua_State * L,luaA_Type type_id,const void * c_in)349 int luaA_push_long_long(lua_State* L, luaA_Type type_id, const void* c_in) {
350 lua_pushinteger(L, *(long long*)c_in);
351 return 1;
352 }
353
luaA_to_long_long(lua_State * L,luaA_Type type_id,void * c_out,int index)354 void luaA_to_long_long(lua_State* L, luaA_Type type_id, void* c_out, int index) {
355 *(long long*)c_out = lua_tointeger(L, index);
356 }
357
luaA_push_unsigned_long_long(lua_State * L,luaA_Type type_id,const void * c_in)358 int luaA_push_unsigned_long_long(lua_State* L, luaA_Type type_id, const void* c_in) {
359 lua_pushinteger(L, *(unsigned long long*)c_in);
360 return 1;
361 }
362
luaA_to_unsigned_long_long(lua_State * L,luaA_Type type_id,void * c_out,int index)363 void luaA_to_unsigned_long_long(lua_State* L, luaA_Type type_id, void* c_out, int index) {
364 *(unsigned long long*)c_out = lua_tointeger(L, index);
365 }
366
luaA_push_float(lua_State * L,luaA_Type type_id,const void * c_in)367 int luaA_push_float(lua_State* L, luaA_Type type_id, const void* c_in) {
368 lua_pushnumber(L, *(float*)c_in);
369 return 1;
370 }
371
luaA_to_float(lua_State * L,luaA_Type type_id,void * c_out,int index)372 void luaA_to_float(lua_State* L, luaA_Type type_id, void* c_out, int index) {
373 *(float*)c_out = lua_tonumber(L, index);
374 }
375
luaA_push_double(lua_State * L,luaA_Type type_id,const void * c_in)376 int luaA_push_double(lua_State* L, luaA_Type type_id, const void* c_in) {
377 lua_pushnumber(L, *(double*)c_in);
378 return 1;
379 }
380
luaA_to_double(lua_State * L,luaA_Type type_id,void * c_out,int index)381 void luaA_to_double(lua_State* L, luaA_Type type_id, void* c_out, int index) {
382 *(double*)c_out = lua_tonumber(L, index);
383 }
384
luaA_push_long_double(lua_State * L,luaA_Type type_id,const void * c_in)385 int luaA_push_long_double(lua_State* L, luaA_Type type_id, const void* c_in) {
386 lua_pushnumber(L, *(long double*)c_in);
387 return 1;
388 }
389
luaA_to_long_double(lua_State * L,luaA_Type type_id,void * c_out,int index)390 void luaA_to_long_double(lua_State* L, luaA_Type type_id, void* c_out, int index) {
391 *(long double*)c_out = lua_tonumber(L, index);
392 }
393
luaA_push_char_ptr(lua_State * L,luaA_Type type_id,const void * c_in)394 int luaA_push_char_ptr(lua_State* L, luaA_Type type_id, const void* c_in) {
395 lua_pushstring(L, *(char**)c_in);
396 return 1;
397 }
398
luaA_to_char_ptr(lua_State * L,luaA_Type type_id,void * c_out,int index)399 void luaA_to_char_ptr(lua_State* L, luaA_Type type_id, void* c_out, int index) {
400 *(char**)c_out = (char*)lua_tostring(L, index);
401 }
402
luaA_push_const_char_ptr(lua_State * L,luaA_Type type_id,const void * c_in)403 int luaA_push_const_char_ptr(lua_State* L, luaA_Type type_id, const void* c_in) {
404 lua_pushstring(L, *(const char**)c_in);
405 return 1;
406 }
407
luaA_to_const_char_ptr(lua_State * L,luaA_Type type_id,void * c_out,int index)408 void luaA_to_const_char_ptr(lua_State* L, luaA_Type type_id, void* c_out, int index) {
409 *(const char**)c_out = lua_tostring(L, index);
410 }
411
luaA_push_void_ptr(lua_State * L,luaA_Type type_id,const void * c_in)412 int luaA_push_void_ptr(lua_State* L, luaA_Type type_id, const void* c_in) {
413 lua_pushlightuserdata(L, *(void**)c_in);
414 return 1;
415 }
416
luaA_to_void_ptr(lua_State * L,luaA_Type type_id,void * c_out,int index)417 void luaA_to_void_ptr(lua_State* L, luaA_Type type_id, void* c_out, int index) {
418 *(void**)c_out = (void*)lua_touserdata(L, index);
419 }
420
luaA_push_void(lua_State * L,luaA_Type type_id,const void * c_in)421 int luaA_push_void(lua_State* L, luaA_Type type_id, const void* c_in) {
422 lua_pushnil(L);
423 return 1;
424 }
425
luaA_conversion_registered_type(lua_State * L,luaA_Type type_id)426 bool luaA_conversion_registered_type(lua_State* L, luaA_Type type_id) {
427 return (luaA_conversion_push_registered_type(L, type_id)
428 && luaA_conversion_to_registered_type(L, type_id));
429 }
430
luaA_conversion_push_registered_type(lua_State * L,luaA_Type type_id)431 bool luaA_conversion_push_registered_type(lua_State* L, luaA_Type type_id) {
432
433 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push");
434 lua_pushinteger(L, type_id);
435 lua_gettable(L, -2);
436
437 bool reg = !lua_isnil(L, -1);
438 lua_pop(L, 2);
439
440 return reg;
441 }
442
luaA_conversion_to_registered_type(lua_State * L,luaA_Type type_id)443 bool luaA_conversion_to_registered_type(lua_State* L, luaA_Type type_id) {
444
445 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to");
446 lua_pushinteger(L, type_id);
447 lua_gettable(L, -2);
448
449 bool reg = !lua_isnil(L, -1);
450 lua_pop(L, 2);
451
452 return reg;
453 }
454
455 /*
456 ** Structs
457 */
458
luaA_struct_push_member_offset_type(lua_State * L,luaA_Type type,size_t offset,const void * c_in)459 int luaA_struct_push_member_offset_type(lua_State* L, luaA_Type type, size_t offset, const void* c_in) {
460
461 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset");
462 lua_pushinteger(L, type);
463 lua_gettable(L, -2);
464
465 if (!lua_isnil(L, -1)) {
466
467 lua_pushinteger(L, offset);
468 lua_gettable(L, -2);
469
470 if (!lua_isnil(L, -1)) {
471 lua_getfield(L, -1, "type");
472 luaA_Type stype = lua_tointeger(L, -1);
473 lua_pop(L, 4);
474 return luaA_push_type(L, stype, c_in + offset);
475 }
476
477 lua_pop(L, 3);
478 lua_pushfstring(L, "luaA_struct_push_member: Member offset '%d' not registered for struct '%s'!", offset, luaA_typename(L, type));
479 lua_error(L);
480
481 }
482
483 lua_pop(L, 2);
484 lua_pushfstring(L, "luaA_struct_push_member: Struct '%s' not registered!", luaA_typename(L, type));
485 lua_error(L);
486 return 0;
487
488 }
489
luaA_struct_push_member_name_type(lua_State * L,luaA_Type type,const char * member,const void * c_in)490 int luaA_struct_push_member_name_type(lua_State* L, luaA_Type type, const char* member, const void* c_in) {
491
492 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
493 lua_pushinteger(L, type);
494 lua_gettable(L, -2);
495
496 if (!lua_isnil(L, -1)) {
497
498 lua_getfield(L, -1, member);
499
500 if (!lua_isnil(L, -1)) {
501 lua_getfield(L, -1, "type");
502 luaA_Type stype = lua_tointeger(L, -1);
503 lua_pop(L, 1);
504 lua_getfield(L, -1, "offset");
505 size_t offset = lua_tointeger(L, -1);
506 lua_pop(L, 4);
507 return luaA_push_type(L, stype, c_in + offset);
508 }
509
510 lua_pop(L, 3);
511 lua_pushfstring(L, "luaA_struct_push_member: Member name '%s' not registered for struct '%s'!", member, luaA_typename(L, type));
512 lua_error(L);
513
514 }
515
516 lua_pop(L, 2);
517 lua_pushfstring(L, "luaA_struct_push_member: Struct '%s' not registered!", luaA_typename(L, type));
518 lua_error(L);
519 return 0;
520 }
521
luaA_struct_to_member_offset_type(lua_State * L,luaA_Type type,size_t offset,void * c_out,int index)522 void luaA_struct_to_member_offset_type(lua_State* L, luaA_Type type, size_t offset, void* c_out, int index) {
523
524 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset");
525 lua_pushinteger(L, type);
526 lua_gettable(L, -2);
527
528 if (!lua_isnil(L, -1)) {
529
530 lua_pushinteger(L, offset);
531 lua_gettable(L, -2);
532
533 if (!lua_isnil(L, -1)) {
534 lua_getfield(L, -1, "type");
535 luaA_Type stype = lua_tointeger(L, -1);
536 lua_pop(L, 4);
537 luaA_to_type(L, stype, c_out + offset, index);
538 return;
539 }
540
541 lua_pop(L, 3);
542 lua_pushfstring(L, "luaA_struct_to_member: Member offset '%d' not registered for struct '%s'!", offset, luaA_typename(L, type));
543 lua_error(L);
544
545 }
546
547 lua_pop(L, 2);
548 lua_pushfstring(L, "luaA_struct_to_member: Struct '%s' not registered!", luaA_typename(L, type));
549 lua_error(L);
550
551 }
552
luaA_struct_to_member_name_type(lua_State * L,luaA_Type type,const char * member,void * c_out,int index)553 void luaA_struct_to_member_name_type(lua_State* L, luaA_Type type, const char* member, void* c_out, int index) {
554
555 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
556 lua_pushinteger(L, type);
557 lua_gettable(L, -2);
558
559 if (!lua_isnil(L, -1)) {
560
561 lua_pushstring(L, member);
562 lua_gettable(L, -2);
563
564 if (!lua_isnil(L, -1)) {
565 lua_getfield(L, -1, "type");
566 luaA_Type stype = lua_tointeger(L, -1);
567 lua_pop(L, 1);
568 lua_getfield(L, -1, "offset");
569 size_t offset = lua_tointeger(L, -1);
570 lua_pop(L, 4);
571 luaA_to_type(L, stype, c_out + offset, index);
572 return;
573 }
574
575 lua_pop(L, 3);
576 lua_pushfstring(L, "luaA_struct_to_member: Member name '%s' not registered for struct '%s'!", member, luaA_typename(L, type));
577 lua_error(L);
578
579 }
580
581 lua_pop(L, 2);
582 lua_pushfstring(L, "luaA_struct_to_member: Struct '%s' not registered!", luaA_typename(L, type));
583 lua_error(L);
584
585 }
586
luaA_struct_has_member_offset_type(lua_State * L,luaA_Type type,size_t offset)587 bool luaA_struct_has_member_offset_type(lua_State* L, luaA_Type type, size_t offset) {
588
589 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset");
590 lua_pushinteger(L, type);
591 lua_gettable(L, -2);
592
593 if (!lua_isnil(L, -1)) {
594
595 lua_pushinteger(L, offset);
596 lua_gettable(L, -2);
597
598 if (!lua_isnil(L, -1)) {
599 lua_pop(L, 3);
600 return true;
601 }
602
603 lua_pop(L, 3);
604 return false;
605
606 }
607
608 lua_pop(L, 2);
609 lua_pushfstring(L, "luaA_struct_has_member: Struct '%s' not registered!", luaA_typename(L, type));
610 lua_error(L);
611 return false;
612
613 }
614
luaA_struct_has_member_name_type(lua_State * L,luaA_Type type,const char * member)615 bool luaA_struct_has_member_name_type(lua_State* L, luaA_Type type, const char* member) {
616
617 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
618 lua_pushinteger(L, type);
619 lua_gettable(L, -2);
620
621 if (!lua_isnil(L, -1)) {
622
623 lua_pushstring(L, member);
624 lua_gettable(L, -2);
625
626 if (!lua_isnil(L, -1)) {
627 lua_pop(L, 3);
628 return true;
629 }
630
631 lua_pop(L, 3);
632 return false;
633
634 }
635
636 lua_pop(L, 2);
637 lua_pushfstring(L, "luaA_struct_has_member: Struct '%s' not registered!", luaA_typename(L, type));
638 lua_error(L);
639 return false;
640
641 }
642
luaA_struct_typeof_member_offset_type(lua_State * L,luaA_Type type,size_t offset)643 luaA_Type luaA_struct_typeof_member_offset_type(lua_State* L, luaA_Type type, size_t offset) {
644
645 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset");
646 lua_pushinteger(L, type);
647 lua_gettable(L, -2);
648
649 if (!lua_isnil(L, -1)) {
650
651 lua_pushinteger(L, offset);
652 lua_gettable(L, -2);
653
654 if (!lua_isnil(L, -1)) {
655 lua_getfield(L, -1, "type");
656 luaA_Type stype = lua_tointeger(L, -1);
657 lua_pop(L, 4);
658 return stype;
659 }
660
661 lua_pop(L, 3);
662 lua_pushfstring(L, "luaA_struct_typeof_member: Member offset '%d' not registered for struct '%s'!", offset, luaA_typename(L, type));
663 lua_error(L);
664
665 }
666
667 lua_pop(L, 2);
668 lua_pushfstring(L, "luaA_struct_typeof_member: Struct '%s' not registered!", luaA_typename(L, type));
669 lua_error(L);
670 return 0;
671
672 }
673
luaA_struct_typeof_member_name_type(lua_State * L,luaA_Type type,const char * member)674 luaA_Type luaA_struct_typeof_member_name_type(lua_State* L, luaA_Type type, const char* member) {
675
676 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
677 lua_pushinteger(L, type);
678 lua_gettable(L, -2);
679
680 if (!lua_isnil(L, -1)) {
681
682 lua_pushstring(L, member);
683 lua_gettable(L, -2);
684
685 if (!lua_isnil(L, -1)) {
686 lua_getfield(L, -1, "type");
687 luaA_Type t = lua_tointeger(L, -1);
688 lua_pop(L, 4);
689 return t;
690 }
691
692 lua_pop(L, 3);
693 lua_pushfstring(L, "luaA_struct_typeof_member: Member name '%s' not registered for struct '%s'!", member, luaA_typename(L, type));
694 lua_error(L);
695
696 }
697
698 lua_pop(L, 2);
699 lua_pushfstring(L, "luaA_struct_typeof_member: Struct '%s' not registered!", luaA_typename(L, type));
700 lua_error(L);
701 return 0;
702
703 }
704
luaA_struct_type(lua_State * L,luaA_Type type)705 void luaA_struct_type(lua_State* L, luaA_Type type) {
706 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
707 lua_pushinteger(L, type);
708 lua_newtable(L);
709 lua_settable(L, -3);
710 lua_pop(L, 1);
711
712 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset");
713 lua_pushinteger(L, type);
714 lua_newtable(L);
715 lua_settable(L, -3);
716 lua_pop(L, 1);
717 }
718
luaA_struct_member_type(lua_State * L,luaA_Type type,const char * member,luaA_Type mtype,size_t offset)719 void luaA_struct_member_type(lua_State* L, luaA_Type type, const char* member, luaA_Type mtype, size_t offset) {
720
721 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
722 lua_pushinteger(L, type);
723 lua_gettable(L, -2);
724
725 if (!lua_isnil(L, -1)) {
726
727 lua_newtable(L);
728
729 lua_pushinteger(L, mtype); lua_setfield(L, -2, "type");
730 lua_pushinteger(L, offset); lua_setfield(L, -2, "offset");
731 lua_pushstring(L, member); lua_setfield(L, -2, "name");
732
733 lua_setfield(L, -2, member);
734
735 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset");
736 lua_pushinteger(L, type);
737 lua_gettable(L, -2);
738
739 lua_pushinteger(L, offset);
740 lua_getfield(L, -4, member);
741 lua_settable(L, -3);
742 lua_pop(L, 4);
743 return;
744 }
745
746 lua_pop(L, 2);
747 lua_pushfstring(L, "luaA_struct_member: Struct '%s' not registered!", luaA_typename(L, type));
748 lua_error(L);
749 }
750
luaA_struct_registered_type(lua_State * L,luaA_Type type)751 bool luaA_struct_registered_type(lua_State* L, luaA_Type type) {
752
753 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
754 lua_pushinteger(L, type);
755 lua_gettable(L, -2);
756
757 bool reg = !lua_isnil(L, -1);
758 lua_pop(L, 2);
759
760 return reg;
761 }
762
luaA_struct_push_type(lua_State * L,luaA_Type type,const void * c_in)763 int luaA_struct_push_type(lua_State* L, luaA_Type type, const void* c_in) {
764
765 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
766 lua_pushinteger(L, type);
767 lua_gettable(L, -2);
768
769 if (!lua_isnil(L, -1)) {
770 lua_remove(L, -2);
771 lua_newtable(L);
772
773 lua_pushnil(L);
774 while (lua_next(L, -3)) {
775
776 if (lua_type(L, -2) == LUA_TSTRING) {
777 lua_getfield(L, -1, "name");
778 const char* name = lua_tostring(L, -1);
779 lua_pop(L, 1);
780 int num = luaA_struct_push_member_name_type(L, type, name, c_in);
781 if (num > 1) {
782 lua_pop(L, 5);
783 lua_pushfstring(L, "luaA_struct_push: Conversion pushed %d values to stack,"
784 " don't know how to include in struct!", num);
785 lua_error(L);
786 }
787 lua_remove(L, -2);
788 lua_pushvalue(L, -2);
789 lua_insert(L, -2);
790 lua_settable(L, -4);
791 } else {
792 lua_pop(L, 1);
793 }
794
795 }
796
797 lua_remove(L, -2);
798 return 1;
799 }
800
801 lua_pop(L, 2);
802 lua_pushfstring(L, "lua_struct_push: Struct '%s' not registered!", luaA_typename(L, type));
803 lua_error(L);
804 return 0;
805 }
806
luaA_struct_to_type(lua_State * L,luaA_Type type,void * c_out,int index)807 void luaA_struct_to_type(lua_State* L, luaA_Type type, void* c_out, int index) {
808
809 lua_pushnil(L);
810 while (lua_next(L, index-1)) {
811
812 if (lua_type(L, -2) == LUA_TSTRING) {
813 luaA_struct_to_member_name_type(L, type, lua_tostring(L, -2), c_out, -1);
814 }
815
816 lua_pop(L, 1);
817 }
818
819 }
820
luaA_struct_next_member_name_type(lua_State * L,luaA_Type type,const char * member)821 const char* luaA_struct_next_member_name_type(lua_State* L, luaA_Type type, const char* member) {
822
823 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs");
824 lua_pushinteger(L, type);
825 lua_gettable(L, -2);
826
827 if(!lua_isnil(L,-1)) {
828
829 if(!member) {
830 lua_pushnil(L);
831 } else {
832 lua_pushstring(L,member);
833 }
834 if(!lua_next(L,-2)) {
835 lua_pop(L,2);
836 return LUAA_INVALID_MEMBER_NAME;
837 }
838 const char* result = lua_tostring(L,-2);
839 lua_pop(L,4);
840 return result;
841 }
842
843 lua_pop(L, 2);
844 lua_pushfstring(L, "luaA_struct_next_member: Struct '%s' not registered!", luaA_typename(L, type));
845 lua_error(L);
846 return NULL;
847 }
848
849 /*
850 ** Enums
851 */
852
luaA_enum_push_type(lua_State * L,luaA_Type type,const void * value)853 int luaA_enum_push_type(lua_State *L, luaA_Type type, const void* value) {
854
855 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values");
856 lua_pushinteger(L, type);
857 lua_gettable(L, -2);
858
859 if (!lua_isnil(L, -1)) {
860
861 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes");
862 lua_pushinteger(L, type);
863 lua_gettable(L, -2);
864 size_t size = lua_tointeger(L, -1);
865 lua_pop(L, 2);
866
867 lua_Integer lvalue =0;
868 memcpy(&lvalue, value, size);
869
870 lua_pushinteger(L, lvalue);
871 lua_gettable(L, -2);
872
873 if (!lua_isnil(L, -1)) {
874 lua_getfield(L, -1, "name");
875 lua_remove(L, -2);
876 lua_remove(L, -2);
877 lua_remove(L, -2);
878 return 1;
879 }
880
881 lua_pop(L, 3);
882 lua_pushfstring(L, "luaA_enum_push: Enum '%s' value %d not registered!", luaA_typename(L, type), lvalue);
883 lua_error(L);
884 return 0;
885 }
886
887 lua_pop(L, 2);
888 lua_pushfstring(L, "luaA_enum_push: Enum '%s' not registered!", luaA_typename(L, type));
889 lua_error(L);
890 return 0;
891
892 }
893
luaA_enum_to_type(lua_State * L,luaA_Type type,void * c_out,int index)894 void luaA_enum_to_type(lua_State* L, luaA_Type type, void* c_out, int index) {
895
896 const char* name = lua_tostring(L, index);
897
898 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums");
899 lua_pushinteger(L, type);
900 lua_gettable(L, -2);
901
902 if (!lua_isnil(L, -1)) {
903
904 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes");
905 lua_pushinteger(L, type);
906 lua_gettable(L, -2);
907 size_t size = lua_tointeger(L, -1);
908 lua_pop(L, 2);
909
910 lua_pushstring(L, name);
911 lua_gettable(L, -2);
912
913 if (!lua_isnil(L, -1)) {
914 lua_getfield(L, -1, "value");
915 lua_Integer value = lua_tointeger(L, -1);
916 lua_pop(L, 4);
917 memcpy(c_out, &value, size);
918 return;
919 }
920
921 lua_pop(L, 3);
922 lua_pushfstring(L, "luaA_enum_to: Enum '%s' field '%s' not registered!", luaA_typename(L, type), name);
923 lua_error(L);
924 return;
925 }
926
927 lua_pop(L, 3);
928 lua_pushfstring(L, "luaA_enum_to: Enum '%s' not registered!", luaA_typename(L, type));
929 lua_error(L);
930 return;
931 }
932
luaA_enum_has_value_type(lua_State * L,luaA_Type type,const void * value)933 bool luaA_enum_has_value_type(lua_State* L, luaA_Type type, const void* value) {
934
935 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values");
936 lua_pushinteger(L, type);
937 lua_gettable(L, -2);
938
939 if (!lua_isnil(L, -1)) {
940
941 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes");
942 lua_pushinteger(L, type);
943 lua_gettable(L, -2);
944 size_t size = lua_tointeger(L, -1);
945 lua_pop(L, 2);
946
947 lua_Integer lvalue = 0;
948 memcpy(&lvalue, value, size);
949
950 lua_pushinteger(L, lvalue);
951 lua_gettable(L, -2);
952
953 if (lua_isnil(L, -1)) {
954 lua_pop(L, 3);
955 return false;
956 } else {
957 lua_pop(L, 3);
958 return true;
959 }
960
961 }
962
963 lua_pop(L, 2);
964 lua_pushfstring(L, "luaA_enum_has_value: Enum '%s' not registered!", luaA_typename(L, type));
965 lua_error(L);
966 return false;
967 }
968
luaA_enum_has_name_type(lua_State * L,luaA_Type type,const char * name)969 bool luaA_enum_has_name_type(lua_State* L, luaA_Type type, const char* name) {
970 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums");
971 lua_pushinteger(L, type);
972 lua_gettable(L, -2);
973
974 if (!lua_isnil(L, -1)) {
975
976 lua_getfield(L, -1, name);
977
978 if (lua_isnil(L, -1)) {
979 lua_pop(L, 3);
980 return false;
981 } else {
982 lua_pop(L, 3);
983 return true;
984 }
985
986 }
987
988 lua_pop(L, 2);
989 lua_pushfstring(L, "luaA_enum_has_name: Enum '%s' not registered!", luaA_typename(L, type));
990 lua_error(L);
991 return false;
992 }
993
luaA_enum_type(lua_State * L,luaA_Type type,size_t size)994 void luaA_enum_type(lua_State *L, luaA_Type type, size_t size) {
995 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums");
996 lua_pushinteger(L, type);
997 lua_newtable(L);
998 lua_settable(L, -3);
999 lua_pop(L, 1);
1000
1001 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values");
1002 lua_pushinteger(L, type);
1003 lua_newtable(L);
1004 lua_settable(L, -3);
1005 lua_pop(L, 1);
1006
1007 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes");
1008 lua_pushinteger(L, type);
1009 lua_pushinteger(L, size);
1010 lua_settable(L, -3);
1011 lua_pop(L, 1);
1012 }
1013
luaA_enum_value_type(lua_State * L,luaA_Type type,const void * value,const char * name)1014 void luaA_enum_value_type(lua_State *L, luaA_Type type, const void* value, const char* name) {
1015
1016 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums");
1017 lua_pushinteger(L, type);
1018 lua_gettable(L, -2);
1019
1020 if (!lua_isnil(L, -1)) {
1021
1022 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes");
1023 lua_pushinteger(L, type);
1024 lua_gettable(L, -2);
1025 size_t size = lua_tointeger(L, -1);
1026 lua_pop(L, 2);
1027
1028 lua_newtable(L);
1029
1030 lua_Integer lvalue=0;
1031 memcpy(&lvalue, value, size);
1032
1033 lua_pushinteger(L, lvalue);
1034 lua_setfield(L, -2, "value");
1035
1036 lua_pushstring(L, name);
1037 lua_setfield(L, -2, "name");
1038
1039 lua_setfield(L, -2, name);
1040
1041 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values");
1042 lua_pushinteger(L, type);
1043 lua_gettable(L, -2);
1044 lua_pushinteger(L, lvalue);
1045 lua_getfield(L, -4, name);
1046 lua_settable(L, -3);
1047
1048 lua_pop(L, 4);
1049 return;
1050
1051 }
1052
1053 lua_pop(L, 2);
1054 lua_pushfstring(L, "luaA_enum_value: Enum '%s' not registered!", luaA_typename(L, type));
1055 lua_error(L);
1056 }
1057
luaA_enum_registered_type(lua_State * L,luaA_Type type)1058 bool luaA_enum_registered_type(lua_State *L, luaA_Type type){
1059 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums");
1060 lua_pushinteger(L, type);
1061 lua_gettable(L, -2);
1062 bool reg = !lua_isnil(L, -1);
1063 lua_pop(L, 2);
1064 return reg;
1065 }
1066
luaA_enum_next_value_name_type(lua_State * L,luaA_Type type,const char * member)1067 const char* luaA_enum_next_value_name_type(lua_State* L, luaA_Type type, const char* member) {
1068
1069 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums");
1070 lua_pushinteger(L, type);
1071 lua_gettable(L, -2);
1072
1073 if(!lua_isnil(L,-1)) {
1074
1075 if(!member) {
1076 lua_pushnil(L);
1077 } else {
1078 lua_pushstring(L,member);
1079 }
1080 if(!lua_next(L,-2)) {
1081 lua_pop(L,2);
1082 return LUAA_INVALID_MEMBER_NAME;
1083 }
1084 const char* result = lua_tostring(L,-2);
1085 lua_pop(L,4);
1086 return result;
1087 }
1088
1089 lua_pop(L, 2);
1090 lua_pushfstring(L, "luaA_enum_next_enum_name_type: Enum '%s' not registered!", luaA_typename(L, type));
1091 lua_error(L);
1092 return NULL;
1093 }
1094
1095 /*
1096 ** Functions
1097 */
1098
luaA_call_entry(lua_State * L)1099 static int luaA_call_entry(lua_State* L) {
1100
1101 /* Get return size */
1102
1103 lua_getfield(L, -1, "ret_type");
1104 luaA_Type ret_type = lua_tointeger(L, -1);
1105 lua_pop(L, 1);
1106
1107 size_t ret_size = luaA_typesize(L, ret_type);
1108
1109 /* Get total arguments sizes */
1110
1111 lua_getfield(L, -1, "arg_types");
1112
1113 size_t arg_size = 0;
1114 size_t arg_num = lua_rawlen(L, -1);
1115 for (int i = 0; i < arg_num; i++) {
1116 lua_pushinteger(L, i+1);
1117 lua_gettable(L, -2);
1118 luaA_Type arg_type = lua_tointeger(L, -1);
1119 lua_pop(L, 1);
1120 arg_size += luaA_typesize(L, arg_type);
1121 }
1122
1123 lua_pop(L, 1);
1124
1125 /* Test to see if using heap */
1126
1127 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_stk");
1128 void* ret_stack = lua_touserdata(L, -1);
1129 lua_pop(L, 1);
1130
1131 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_stk");
1132 void* arg_stack = lua_touserdata(L, -1);
1133 lua_pop(L, 1);
1134
1135 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr");
1136 lua_Integer ret_ptr = lua_tointeger(L, -1);
1137 lua_pop(L, 1);
1138
1139 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_ptr");
1140 lua_Integer arg_ptr = lua_tointeger(L, -1);
1141 lua_pop(L, 1);
1142
1143 void* ret_data = ret_stack + ret_ptr;
1144 void* arg_data = arg_stack + arg_ptr;
1145
1146 /* If fixed allocation exhausted use heap instead */
1147
1148 bool ret_heap = false;
1149 bool arg_heap = false;
1150
1151 if (ret_ptr + ret_size > LUAA_RETURN_STACK_SIZE) {
1152 ret_heap = true;
1153 ret_data = malloc(ret_size);
1154 if (ret_data == NULL) {
1155 lua_pushfstring(L, "luaA_call: Out of memory!");
1156 lua_error(L);
1157 return 0;
1158 }
1159 }
1160
1161 if (arg_ptr + arg_size > LUAA_ARGUMENT_STACK_SIZE) {
1162 arg_heap = true;
1163 arg_data = malloc(arg_size);
1164 if (arg_data == NULL) {
1165 if (ret_heap) {
1166 free(ret_data);
1167 }
1168 lua_pushfstring(L, "luaA_call: Out of memory!");
1169 lua_error(L);
1170 return 0;
1171 }
1172 }
1173
1174 /* If not using heap update stack pointers */
1175
1176 if (!ret_heap) {
1177 lua_pushinteger(L, ret_ptr + ret_size);
1178 lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr");
1179 }
1180
1181 if (!arg_heap) {
1182 lua_pushinteger(L, arg_ptr + arg_size);
1183 lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_ptr");
1184 }
1185
1186 /* Pop args and place in memory */
1187
1188 lua_getfield(L, -1, "arg_types");
1189
1190 void* arg_pos = arg_data;
1191 for (int i = 0; i < arg_num; i++) {
1192 lua_pushinteger(L, i+1);
1193 lua_gettable(L, -2);
1194 luaA_Type arg_type = lua_tointeger(L, -1);
1195 lua_pop(L, 1);
1196 luaA_to_type(L, arg_type, arg_pos, -arg_num+i-2);
1197 arg_pos += luaA_typesize(L, arg_type);
1198 }
1199
1200 lua_pop(L, 1);
1201
1202 /* Pop arguments from stack */
1203
1204 for (int i = 0; i < arg_num; i++) {
1205 lua_remove(L, -2);
1206 }
1207
1208 /* Get Function Pointer and Call */
1209
1210 lua_getfield(L, -1, "auto_func");
1211 luaA_Func auto_func = lua_touserdata(L, -1);
1212 lua_pop(L, 2);
1213
1214 auto_func(ret_data, arg_data);
1215
1216 int count = luaA_push_type(L, ret_type, ret_data);
1217
1218 /* Either free heap data or reduce stack pointers */
1219
1220 if (!ret_heap) {
1221 lua_pushinteger(L, ret_ptr);
1222 lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr");
1223 } else {
1224 free(ret_data);
1225 }
1226
1227 if (!arg_heap) {
1228 lua_pushinteger(L, arg_ptr);
1229 lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "argument_ptr");
1230 } else {
1231 free(arg_data);
1232 }
1233
1234 return count;
1235 }
1236
luaA_call(lua_State * L,void * func_ptr)1237 int luaA_call(lua_State* L, void* func_ptr) {
1238 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions");
1239 lua_pushlightuserdata(L, func_ptr);
1240 lua_gettable(L, -2);
1241 lua_remove(L, -2);
1242
1243 if (!lua_isnil(L, -1)) { return luaA_call_entry(L); }
1244
1245 lua_pop(L, 1);
1246 lua_pushfstring(L, "luaA_call: Function with address '%p' is not registered!", func_ptr);
1247 lua_error(L);
1248 return 0;
1249 }
1250
luaA_call_name(lua_State * L,const char * func_name)1251 int luaA_call_name(lua_State* L, const char* func_name) {
1252 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions");
1253 lua_pushstring(L, func_name);
1254 lua_gettable(L, -2);
1255 lua_remove(L, -2);
1256
1257 if (!lua_isnil(L, -1)) { return luaA_call_entry(L); }
1258
1259 lua_pop(L, 1);
1260 lua_pushfstring(L, "luaA_call_name: Function '%s' is not registered!", func_name);
1261 lua_error(L);
1262 return 0;
1263 }
1264
luaA_function_register_type(lua_State * L,void * src_func,luaA_Func auto_func,const char * name,luaA_Type ret_t,int num_args,...)1265 void luaA_function_register_type(lua_State* L, void* src_func, luaA_Func auto_func, const char* name, luaA_Type ret_t, int num_args, ...) {
1266
1267 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions");
1268 lua_pushstring(L, name);
1269
1270 lua_newtable(L);
1271
1272 lua_pushlightuserdata(L, src_func); lua_setfield(L, -2, "src_func");
1273 lua_pushlightuserdata(L, auto_func); lua_setfield(L, -2, "auto_func");
1274
1275 lua_pushinteger(L, ret_t);
1276 lua_setfield(L, -2, "ret_type");
1277
1278 lua_pushstring(L, "arg_types");
1279 lua_newtable(L);
1280
1281 va_list va;
1282 va_start(va, num_args);
1283 for (int i = 0; i < num_args; i++) {
1284 lua_pushinteger(L, i+1);
1285 lua_pushinteger(L, va_arg(va, luaA_Type));
1286 lua_settable(L, -3);
1287 }
1288 va_end(va);
1289
1290 lua_settable(L, -3);
1291 lua_settable(L, -3);
1292 lua_pop(L, 1);
1293
1294 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions");
1295 lua_pushlightuserdata(L, src_func);
1296
1297 lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions");
1298 lua_getfield(L, -1, name);
1299 lua_remove(L, -2);
1300
1301 lua_settable(L, -3);
1302 lua_pop(L, 1);
1303
1304 }
1305