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