1 /**
2 Boost Software License - Version 1.0 - August 17th, 2003
3 
4 Copyright (c) 2018 Clipsey
5 
6 Permission is hereby granted, free of charge, to any person or organization
7 obtaining a copy of the software and accompanying documentation covered by
8 this license (the "Software") to use, reproduce, display, distribute,
9 execute, and transmit the Software, and to prepare derivative works of the
10 Software, and to permit third-parties to whom the Software is furnished to
11 do so, all subject to the following:
12 
13 The copyright notices in the Software and this entire statement, including
14 the above license grant, this restriction and the following disclaimer,
15 must be included in all copies of the Software, in whole or in part, and
16 all derivative works of the Software, unless such copies or derivative
17 works are solely in the form of machine-executable object code generated by
18 a source language processor.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 DEALINGS IN THE SOFTWARE.
27 */
28 module lua.backend.binding;
29 import lua.backend.types;
30 import bindbc.loader;
31 import std.string;
32 
33 extern (C) nothrow {
34     /*
35     ** state manipulation
36     */
37     alias lua_newstateFunc = lua_State* function(lua_Alloc, void*) nothrow;
38     alias lua_closeFunc = void function(lua_State*) nothrow;
39     alias lua_newthreadFunc = lua_State* function(lua_State*) nothrow;
40 
41     alias lua_versionFunc = lua_Number function(lua_State*) nothrow;
42 
43     /*
44     ** basic stack manipulation
45     */
46     alias lua_absindexFunc = int function(lua_State*, int idx) nothrow;
47     alias lua_gettopFunc = int function(lua_State*) nothrow;
48     alias lua_settopFunc = void function(lua_State*, int) nothrow;
49     alias lua_pushvalueFunc = void function(lua_State*, int) nothrow;
50     alias lua_rotateFunc = void function(lua_State*, int, int) nothrow;
51     alias lua_copyFuncFunc = void function(lua_State*, int, int) nothrow;
52     alias lua_checkstackFunc = int function(lua_State*, int) nothrow;
53 
54     alias lua_xmoveFunc = void function(lua_State*, lua_State*, int) nothrow;
55 
56     /*
57     ** access functions (stack -> C)
58     */
59 
60     alias lua_isnumberFunc = int function(lua_State*, int) nothrow;
61     alias lua_isstringFunc = int function(lua_State*, int) nothrow;
62     alias lua_iscfunctionFunc = int function(lua_State*, int) nothrow;
63     alias lua_isintegerFunc = int function(lua_State*, int) nothrow;
64     alias lua_isuserdataFunc = int function(lua_State*, int) nothrow;
65     alias lua_typeFunc = int function(lua_State*, int) nothrow;
66     alias lua_typenameFunc = const(char)* function(lua_State*, int) nothrow;
67 
68     alias lua_tonumberFunc = lua_Number function(lua_State*, int) nothrow;
69     alias lua_tointegerFunc = lua_Integer function(lua_State*, int) nothrow;
70     alias lua_tobooleanFunc = int function(lua_State*, int) nothrow;
71     alias lua_tolstringFunc = const(char)* function(lua_State*, int, size_t) nothrow;
72     alias lua_rawlenFunc = size_t function(lua_State*, int) nothrow;
73     alias lua_tocfunctionFunc = lua_CFunction function(lua_State*, int) nothrow;
74     alias lua_touserdataFunc = void* function(lua_State*, int) nothrow;
75     alias lua_tothreadFunc = lua_State* function(lua_State*, int) nothrow;
76     alias lua_topointerFunc = const(void)* function(lua_State*, int) nothrow;
77 
78     /*
79     ** Comparison and arithmetic functions
80     */
81 
82     /*alias lua_arithFunc = void function(lua_State*, int);
83 
84     alias lua_rawequalFunc = int function(lua_State*, int, int);
85     alias lua_compareFunc = int function(lua_State*, int, int, int);*/
86 
87     /*
88     ** push functions (C -> stack)
89     */
90     alias lua_pushnilFunc = void function(lua_State*) nothrow;
91     alias lua_pushnumberFunc = void function(lua_State*, lua_Number) nothrow;
92     alias lua_pushintegerFunc = void function(lua_State*, lua_Integer) nothrow;
93     alias lua_pushlstringFunc = const(char)* function(lua_State*, const(char)*, size_t) nothrow;
94     alias lua_pushstringFunc = const(char)* function(lua_State*, const(char)*) nothrow;
95     alias lua_pushvfstringFunc = const(char)* function(lua_State*, const(char)*, ...) nothrow;
96     alias lua_pushfstringFunc = const(char)* function(lua_State*, const(char)* ...) nothrow;
97     alias lua_pushcclosureFunc = void function(lua_State*, lua_CFunction fn, int n) nothrow;
98     alias lua_pushbooleanFunc = void function(lua_State*, int b) nothrow;
99     alias lua_pushlightuserdataFunc = void function(lua_State*, void* p) nothrow;
100     alias lua_pushthreadFunc = int function(lua_State*) nothrow;
101 
102     /*
103     ** get functions (Lua -> stack)
104     */
105    // alias lua_getglobalFunc = int function(lua_State*, const(char)*);
106     alias lua_gettableFunc = int function(lua_State*, int) nothrow;
107     alias lua_getfieldFunc = int function(lua_State*, int, const(char)*) nothrow;
108     alias lua_getiFunc = int function(lua_State*, int, lua_Integer) nothrow;
109     alias lua_rawgetFunc = int function(lua_State*, int) nothrow;
110     alias lua_rawgetiFunc = int function(lua_State*, int, lua_Integer) nothrow;
111     alias lua_rawgetpFunc = int function(lua_State*, int, const(void)*) nothrow;
112 
113     alias lua_createtableFunc = void function(lua_State*, int, int) nothrow;
114     alias lua_newuserdataFunc = void* function(lua_State*, size_t) nothrow;
115     alias lua_getmetatableFunc = int function(lua_State*, int) nothrow;
116     alias lua_getuservalueFunc = int function(lua_State*, int) nothrow;
117 
118     /*
119     ** set functions (stack -> Lua)
120     */
121     //alias lua_setglobalFunc = void function(lua_State*, const(char)*);
122     alias lua_settableFunc = void function(lua_State*, int) nothrow;
123     alias lua_setfieldFunc = void function(lua_State*, int, const(char)*) nothrow;
124     alias lua_setiFunc = void function(lua_State*, int, lua_Integer) nothrow;
125     alias lua_rawsetFunc = void function(lua_State*, int) nothrow;
126     alias lua_rawsetiFunc = void function(lua_State*, int, lua_Integer) nothrow;
127     alias lua_rawsetpFunc = void function(lua_State*, int, const(void)*) nothrow;
128     alias lua_setmetatableFunc = int function(lua_State*, int) nothrow;
129     alias lua_setuservalueFunc = void function(lua_State*, int) nothrow;
130 
131     /*
132     ** 'load' and 'call' functions (load and run Lua code)
133     */
134     alias lua_callFunc = void function(lua_State*, int, int, lua_KContext, lua_KFunction) nothrow;
135     alias lua_pcallFunc = int function(lua_State*, int, int, int, lua_KContext, lua_KFunction) nothrow;
136     alias lua_loadFunc = int function(lua_State*, lua_Reader, void*,
137             const(char)*, const(char)*) nothrow;
138     alias lua_dumpFunc = int function(lua_State*, lua_Writer, void*, int) nothrow;
139 
140     /*
141     ** coroutine functions
142     */
143     alias lua_yieldkFunc = int function(lua_State*, int, lua_KContext, lua_KFunction) nothrow;
144     alias lua_resumeFunc = int function(lua_State*, lua_State*, int) nothrow;
145     alias lua_statusFunc = int function(lua_State*) nothrow;
146     alias lua_isyieldableFunc = int function(lua_State*) nothrow;
147 
148     /**
149         luaL
150     */
151 
152     alias luaL_getmetafieldFunc = int function(lua_State*, int, const(char)*) nothrow;
153     alias luaL_callmetaFunc = int function(lua_State*, int, const(char)*) nothrow;
154     alias luaL_tolstringFunc = const(char)* function(lua_State*, int, size_t*) nothrow;
155     alias luaL_argerrorFunc = int function(lua_State*, int, const(char)*) nothrow;
156     alias luaL_checklstringFunc = const(char)* function(lua_State*, int, size_t* l) nothrow;
157     alias luaL_optlstringFunc = const(char)* function(lua_State*, int, const(char)*, size_t*) nothrow;
158     alias luaL_checknumberFunc = lua_Number function(lua_State*, int) nothrow;
159     alias luaL_optnumberFunc = lua_Number function(lua_State*, int, lua_Number) nothrow;
160     alias luaL_checkintegerFunc = lua_Integer function(lua_State*, int) nothrow;
161     alias luaL_optintegerFunc = lua_Integer function(lua_State*, int, lua_Integer) nothrow;
162     alias luaL_checkstackFunc = void function(lua_State*, int, const char*) nothrow;
163     alias luaL_checktypeFunc = void function(lua_State*, int, int) nothrow;
164     alias luaL_checkanyFunc = void function(lua_State*, int) nothrow;
165     alias luaL_newmetatableFunc = int function(lua_State*, const(char)*) nothrow;
166     alias luaL_setmetatableFunc = void function(lua_State*, const(char)*) nothrow;
167     alias luaL_testudataFunc = void* function(lua_State*, int, const(char)*) nothrow;
168     alias luaL_checkudataFunc = void* function(lua_State*, int, const(char)*) nothrow;
169     alias luaL_whereFunc = void function(lua_State*, int) nothrow;
170     alias luaL_errorFunc = int function(lua_State*, const(char)*, ...) nothrow;
171     alias luaL_checkoptionFunc = int function(lua_State*, int, const(char)*,
172             const(const(char)*[])) nothrow;
173     alias luaL_fileresultFunc = int function(lua_State*, int, const(char)*) nothrow;
174     alias luaL_execresultFunc = int function(lua_State*, int) nothrow;
175 
176     /* predefined references */
177 
178     alias luaL_refFunc = int function(lua_State*, int) nothrow;
179     alias luaL_unrefFunc = void function(lua_State*, int, int) nothrow;
180     alias luaL_loadfileFunc = int function(lua_State*, const(char)*, const(char)*) nothrow;
181     alias luaL_loadbufferFunc = int function(lua_State*, const(char)*,
182             size_t, const(char)*, const(char)*) nothrow;
183     alias luaL_loadstringFunc = int function(lua_State*, const(char)*) nothrow;
184     alias luaL_newstateFunc = lua_State* function() nothrow;
185     alias luaL_lenFunc = lua_Integer function(lua_State*, int) nothrow;
186     alias luaL_gsubFunc = const(char)* function(lua_State*, const(char)*,
187             const(char)*, const(char)*) nothrow;
188     alias luaL_setfuncsFunc = void function(lua_State*, const luaL_Reg*, int) nothrow;
189     alias luaL_getsubtableFunc = int function(lua_State*, int, const(char)* fname) nothrow;
190     alias luaL_tracebackFunc = void function(lua_State*, lua_State*, const(char)*, int) nothrow;
191     alias luaL_requirefFunc = void function(lua_State*, const(char)*, lua_CFunction, int) nothrow;
192 
193     /* open all previous libraries */
194     alias luaopen_baseFunc = int function(lua_State*) nothrow;
195     alias luaopen_tableFunc = int function(lua_State*) nothrow;
196     alias luaopen_ioFunc = int function(lua_State*) nothrow;
197     alias luaopen_osFunc = int function(lua_State*) nothrow;
198     alias luaopen_stringFunc = int function(lua_State*) nothrow;
199     alias luaopen_mathFunc = int function(lua_State*) nothrow;
200     alias luaopen_debugFunc = int function(lua_State*) nothrow;
201     alias luaopen_packageFunc = int function(lua_State*) nothrow;
202     alias luaL_openlibsFunc = void function(lua_State*) nothrow;
203 }
204 /++
205     #define luaL_argcheck(L, cond,arg,extramsg)     \
206                     ((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
207     #define luaL_dofile(L, fn) \
208             (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
209 
210     #define luaL_dostring(L, s) \
211             (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
212 
213     #define luaL_getmetatable(L,n)  (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
214 
215     #define luaL_opt(L,f,n,d)       (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
216 
217     #define luaL_loadbuffer(L,s,sz,n)       luaL_loadbufferx(L,s,sz,n,NULL)
218 +/
219 //#define lua_call(L,n,r)         lua_callk(L, (n), (r), 0, NULL)
220 //#define lua_pcall(L,n,r,f)      lua_pcallk(L, (n), (r), (f), 0, NULL)
221 
222 /*
223 ** ===============================================================
224 ** some useful macros
225 ** ===============================================================
226 */
227 extern(C) nothrow {
228     void luaL_call(lua_State* L, int n, int r) {
229         lua_call(L, n, r, 0, null);
230     }
231 
232     int luaL_pcall(lua_State* L, int n, int r, int f) {
233         return lua_pcall(L, n, r, f, 0, null);
234     }
235 
236     int lua_loadfile(lua_State* L, const(char*) f) {
237         return luaL_loadfile(L, f, null);
238     }
239 
240     void luaL_newlibtable(T)(lua_State* L, T* l) {
241         lua_createtable(L, 0, l.sizeof / l[0].sizeof - 1);
242     }
243 
244     /*void luaL_newlib(T)(lua_State* L, T* l) {
245         luaL_checkversion(L);
246         luaL_newlibtable(L, l);
247         luaL_setfuncs(L, l, 0);
248     }*/
249 
250     const(char)* luaL_checkstring(lua_State* L, int n) {
251         return luaL_checklstring(L, n, null);
252     }
253 
254     const(char)* luaL_optstring(lua_State* L, int n, const(char)* d) {
255         return luaL_optlstring(L, n, d, null);
256     }
257 
258     const(char)* luaL_typename(lua_State* L, int i) {
259         return lua_typename(L, lua_type(L, i));
260     }
261 
262     int luaL_dostring(lua_State* L, const(char)* s) {
263         luaL_loadstring(L, s);
264         return luaL_pcall(L, 0, LUA_MULTRET, 0);
265     }
266 
267     void lua_pop(lua_State* state, int amount) {
268         lua_settop(state, -(amount)-1);
269     }
270 
271     void lua_newtable(lua_State* state) {
272         lua_createtable(state, 0, 0);
273     }
274 
275     void lua_register(lua_State* state, const(char)* n, lua_CFunction func) {
276         lua_pushcfunction(state, func);
277         lua_setglobal(state, n);
278     }
279 
280     void lua_pushcfunction(lua_State* state, lua_CFunction func) {
281         lua_pushcclosure(state, func, 0);
282     }
283 
284     /*int lua_strlen(lua_State* state, const(char)* i) {
285         return lua_objlen(state, i);
286     }*/
287 
288     void lua_pushliteral(lua_State* state, const(char)[] str) {
289         lua_pushlstring(state, str.ptr, str.sizeof-1);
290     }
291 
292 
293     string lua_tostring(lua_State* state, int index) {
294         import std.conv;
295         return lua_tolstring(state, index, 0).text;
296     }
297 }
298 
299 /*
300 #define lua_strlen(L,i)         lua_objlen(L, (i))
301 
302 #define lua_isfunction(L,n)     (lua_type(L, (n)) == LUA_TFUNCTION)
303 #define lua_istable(L,n)        (lua_type(L, (n)) == LUA_TTABLE)
304 #define lua_islightuserdata(L,n)        (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
305 #define lua_isnil(L,n)          (lua_type(L, (n)) == LUA_TNIL)
306 #define lua_isboolean(L,n)      (lua_type(L, (n)) == LUA_TBOOLEAN)
307 #define lua_isthread(L,n)       (lua_type(L, (n)) == LUA_TTHREAD)
308 #define lua_isnone(L,n)         (lua_type(L, (n)) == LUA_TNONE)
309 #define lua_isnoneornil(L, n)   (lua_type(L, (n)) <= 0)
310 
311 #define lua_pushliteral(L, s)   \
312         lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
313 
314 #define lua_setglobal(L,s)      lua_setfield(L, LUA_GLOBALSINDEX, (s))
315 #define lua_getglobal(L,s)      lua_getfield(L, LUA_GLOBALSINDEX, (s))
316 
317 #define lua_tostring(L,i)       lua_tolstring(L, (i), NULL)
318 
319 */
320 extern(C) nothrow {
321     void lua_setglobal(lua_State* state, const(char)* name) {
322         lua_setfield(state, LUA_GLOBALSINDEX, name);
323     }
324 
325     int lua_getglobal(lua_State* state, const(char)* name) {
326         return lua_getfield(state, LUA_GLOBALSINDEX, name);
327     }
328 
329     /*
330     ** compatibility macros and functions
331     */
332 
333     lua_State* lua_open() {
334         return luaL_newstate();
335     }
336 
337     void lua_getregistry(lua_State* state) {
338         lua_pushvalue(state, LUA_REGISTRYINDEX);
339     }
340 }
341 
342 //#define lua_getgccount(L)       lua_gc(L, LUA_GCCOUNT, 0)
343 
344 __gshared {
345     lua_newstateFunc lua_newstate;
346     lua_closeFunc lua_close;
347     lua_newthreadFunc lua_newthread;
348 
349     lua_versionFunc lua_version;
350 
351     lua_absindexFunc lua_absindex;
352     lua_gettopFunc lua_gettop;
353     lua_settopFunc lua_settop;
354     lua_pushvalueFunc lua_pushvalue;
355     lua_rotateFunc lua_rotate;
356     lua_copyFuncFunc lua_copyFunc;
357     lua_checkstackFunc lua_checkstack;
358     lua_xmoveFunc lua_xmove;
359 
360     lua_isnumberFunc lua_isnumber;
361     lua_isstringFunc lua_isstring;
362     lua_iscfunctionFunc lua_iscfunction;
363     lua_isintegerFunc lua_isinteger;
364     lua_isuserdataFunc lua_isuserdata;
365     lua_typeFunc lua_type;
366     lua_typenameFunc lua_typename;
367 
368     lua_tonumberFunc lua_tonumber;
369     lua_tointegerFunc lua_tointeger;
370     lua_tobooleanFunc lua_toboolean;
371     lua_tolstringFunc lua_tolstring;
372     lua_rawlenFunc lua_rawlen;
373     lua_tocfunctionFunc lua_tocfunction;
374     lua_touserdataFunc lua_touserdata;
375     lua_tothreadFunc lua_tothread;
376     lua_topointerFunc lua_topointer;
377 
378     /*lua_arithFunc lua_arith;
379 
380     lua_rawequalFunc lua_rawequal;
381     lua_compareFunc lua_compare;*/
382 
383     lua_pushnilFunc lua_pushnil;
384     lua_pushnumberFunc lua_pushnumber;
385     lua_pushintegerFunc lua_pushinteger;
386     lua_pushlstringFunc lua_pushlstring;
387     lua_pushstringFunc lua_pushstring;
388     lua_pushvfstringFunc lua_pushvfstring;
389     lua_pushfstringFunc lua_pushfstring;
390     lua_pushcclosureFunc lua_pushcclosure;
391     lua_pushbooleanFunc lua_pushboolean;
392     lua_pushlightuserdataFunc lua_pushlightuserdata;
393     lua_pushthreadFunc lua_pushthread;
394 
395     //lua_getglobalFunc lua_getglobal;
396     lua_gettableFunc lua_gettable;
397     lua_getfieldFunc lua_getfield;
398     lua_getiFunc lua_geti;
399     lua_rawgetFunc lua_rawget;
400     lua_rawgetiFunc lua_rawgeti;
401     lua_rawgetpFunc lua_rawgetp;
402 
403     lua_createtableFunc lua_createtable;
404     lua_newuserdataFunc lua_newuserdata;
405     lua_getmetatableFunc lua_getmetatable;
406     lua_getuservalueFunc lua_getuservalue;
407 
408     //lua_setglobalFunc lua_setglobal;
409     lua_settableFunc lua_settable;
410     lua_setfieldFunc lua_setfield;
411     lua_setiFunc lua_seti;
412     lua_rawsetFunc lua_rawset;
413     lua_rawsetiFunc lua_rawseti;
414     lua_rawsetpFunc lua_rawsetp;
415     lua_setmetatableFunc lua_setmetatable;
416     lua_setuservalueFunc lua_setuservalue;
417 
418     lua_callFunc lua_call;
419     lua_pcallFunc lua_pcall;
420     lua_loadFunc lua_load;
421     lua_dumpFunc lua_dump;
422 
423     lua_yieldkFunc lua_yieldk;
424     lua_resumeFunc lua_resume;
425     lua_statusFunc lua_status;
426     lua_isyieldableFunc lua_isyieldable;
427 
428     luaL_getmetafieldFunc luaL_getmetafield;
429     luaL_callmetaFunc luaL_callmeta;
430     luaL_tolstringFunc luaL_tolstring;
431     luaL_argerrorFunc luaL_argerror;
432     luaL_checklstringFunc luaL_checklstring;
433     luaL_optlstringFunc luaL_optlstring;
434     luaL_checknumberFunc luaL_checknumber;
435     luaL_optnumberFunc luaL_optnumber;
436     luaL_checkintegerFunc luaL_checkinteger;
437     luaL_optintegerFunc luaL_optinteger;
438     luaL_checkstackFunc luaL_checkstack;
439     luaL_checktypeFunc luaL_checktype;
440     luaL_checkanyFunc luaL_checkany;
441     luaL_newmetatableFunc luaL_newmetatable;
442     luaL_setmetatableFunc luaL_setmetatable;
443     luaL_testudataFunc luaL_testudata;
444     luaL_checkudataFunc luaL_checkudata;
445     luaL_whereFunc luaL_where;
446     luaL_errorFunc luaL_error;
447     luaL_checkoptionFunc luaL_checkoption;
448     luaL_fileresultFunc luaL_fileresult;
449     luaL_execresultFunc luaL_execresult;
450     luaL_refFunc luaL_ref;
451     luaL_unrefFunc luaL_unref;
452     luaL_loadfileFunc luaL_loadfile;
453     luaL_loadbufferFunc luaL_loadbuffer;
454     luaL_loadstringFunc luaL_loadstring;
455     luaL_newstateFunc luaL_newstate;
456     luaL_lenFunc luaL_len;
457     luaL_gsubFunc luaL_gsub;
458     luaL_setfuncsFunc luaL_setfuncs;
459     luaL_getsubtableFunc luaL_getsubtable;
460     luaL_tracebackFunc luaL_traceback;
461     luaL_requirefFunc luaL_requiref;
462 
463     luaopen_baseFunc luaopen_base;
464     luaopen_tableFunc luaopen_table;
465     luaopen_ioFunc luaopen_io;
466     luaopen_osFunc luaopen_os;
467     luaopen_stringFunc luaopen_string;
468     luaopen_mathFunc luaopen_math;
469     luaopen_debugFunc luaopen_debug;
470     luaopen_packageFunc luaopen_package;
471     luaL_openlibsFunc luaL_openlibs;
472 }
473 
474 private {
475     SharedLib lib;
476 }
477 
478 void unloadLua() {
479     if (lib != invalidHandle) {
480         lib.unload();
481     }
482 }
483 
484 bool loadLua() {
485 
486     version (Windows) {
487         const(char)[][] libNames = [
488             "libluajit.so", "libluajit.so.5.1", "libluajit-5.1.so",
489             "liblua.so.5.1", "liblua-5.1.so", "liblua.so"
490         ];
491     } else version (OSX) {
492         throw new Exception("Not supported");
493     } else version (Posix) {
494         const(char)[][] libNames = [
495             "libluajit.so", "libluajit.so.5.1", "libluajit-5.1.so",
496             "liblua.so.5.1", "liblua-5.1.so", "liblua.so"
497         ];
498     } else {
499         throw new Exception("Not supported");
500     }
501     foreach (lib; libNames) {
502         if (loadLua(lib.ptr))
503             return true;
504     }
505     return false;
506 }
507 
508 bool loadLua(const(char)* libName) {
509     resetErrors();
510     import std.stdio;
511     import std.conv;
512 
513     if (lib == invalidHandle) {
514         lib = load(libName);
515         if (lib == invalidHandle) {
516             return false;
517         }
518     }
519 
520     auto errCount = errorCount();
521     lib.bindSymbol(cast(void**)&lua_newstate, "lua_newstate");
522     lib.bindSymbol(cast(void**)&lua_close, "lua_close");
523     lib.bindSymbol(cast(void**)&lua_newthread, "lua_newthread");
524     lib.bindSymbol(cast(void**)&lua_gettop, "lua_gettop");
525     lib.bindSymbol(cast(void**)&lua_settop, "lua_settop");
526     lib.bindSymbol(cast(void**)&lua_pushvalue, "lua_pushvalue");
527     lib.bindSymbol(cast(void**)&lua_checkstack, "lua_checkstack");
528     lib.bindSymbol(cast(void**)&lua_xmove, "lua_xmove");
529     lib.bindSymbol(cast(void**)&lua_isnumber, "lua_isnumber");
530     lib.bindSymbol(cast(void**)&lua_isstring, "lua_isstring");
531     lib.bindSymbol(cast(void**)&lua_iscfunction, "lua_iscfunction");
532     lib.bindSymbol(cast(void**)&lua_isuserdata, "lua_isuserdata");
533     lib.bindSymbol(cast(void**)&lua_type, "lua_type");
534     lib.bindSymbol(cast(void**)&lua_typename, "lua_typename");
535     lib.bindSymbol(cast(void**)&lua_tonumber, "lua_tonumber");
536     lib.bindSymbol(cast(void**)&lua_tointeger, "lua_tointeger");
537     lib.bindSymbol(cast(void**)&lua_toboolean, "lua_toboolean");
538     lib.bindSymbol(cast(void**)&lua_tolstring, "lua_tolstring");
539     lib.bindSymbol(cast(void**)&lua_tocfunction, "lua_tocfunction");
540     lib.bindSymbol(cast(void**)&lua_touserdata, "lua_touserdata");
541     lib.bindSymbol(cast(void**)&lua_tothread, "lua_tothread");
542     lib.bindSymbol(cast(void**)&lua_topointer, "lua_topointer");
543 
544 
545     lib.bindSymbol(cast(void**)&lua_pushnil, "lua_pushnil");
546     lib.bindSymbol(cast(void**)&lua_pushnumber, "lua_pushnumber");
547     lib.bindSymbol(cast(void**)&lua_pushinteger, "lua_pushinteger");
548     lib.bindSymbol(cast(void**)&lua_pushlstring, "lua_pushlstring");
549     lib.bindSymbol(cast(void**)&lua_pushstring, "lua_pushstring");
550     lib.bindSymbol(cast(void**)&lua_pushvfstring, "lua_pushvfstring");
551     lib.bindSymbol(cast(void**)&lua_pushfstring, "lua_pushfstring");
552     lib.bindSymbol(cast(void**)&lua_pushcclosure, "lua_pushcclosure");
553     lib.bindSymbol(cast(void**)&lua_pushboolean, "lua_pushboolean");
554     lib.bindSymbol(cast(void**)&lua_pushlightuserdata, "lua_pushlightuserdata");
555     lib.bindSymbol(cast(void**)&lua_pushthread, "lua_pushthread");
556     lib.bindSymbol(cast(void**)&lua_gettable, "lua_gettable");
557     lib.bindSymbol(cast(void**)&lua_getfield, "lua_getfield");
558     lib.bindSymbol(cast(void**)&lua_rawget, "lua_rawget");
559     lib.bindSymbol(cast(void**)&lua_rawgeti, "lua_rawgeti");
560     lib.bindSymbol(cast(void**)&lua_createtable, "lua_createtable");
561     lib.bindSymbol(cast(void**)&lua_newuserdata, "lua_newuserdata");
562     lib.bindSymbol(cast(void**)&lua_getmetatable, "lua_getmetatable");
563     lib.bindSymbol(cast(void**)&lua_settable, "lua_settable");
564     lib.bindSymbol(cast(void**)&lua_setfield, "lua_setfield");
565     lib.bindSymbol(cast(void**)&lua_rawset, "lua_rawset");
566     lib.bindSymbol(cast(void**)&lua_rawseti, "lua_rawseti");
567     lib.bindSymbol(cast(void**)&lua_setmetatable, "lua_setmetatable");
568     lib.bindSymbol(cast(void**)&lua_call, "lua_call");
569     lib.bindSymbol(cast(void**)&lua_pcall, "lua_pcall");
570     lib.bindSymbol(cast(void**)&lua_load, "lua_load");
571     lib.bindSymbol(cast(void**)&lua_dump, "lua_dump");
572 
573     lib.bindSymbol(cast(void**)&lua_resume, "lua_resume");
574     lib.bindSymbol(cast(void**)&lua_status, "lua_status");
575     lib.bindSymbol(cast(void**)&lua_isyieldable, "lua_isyieldable");
576 
577     lib.bindSymbol(cast(void**)&luaL_getmetafield, "luaL_getmetafield");
578     lib.bindSymbol(cast(void**)&luaL_callmeta, "luaL_callmeta");
579     lib.bindSymbol(cast(void**)&luaL_argerror, "luaL_argerror");
580     lib.bindSymbol(cast(void**)&luaL_checklstring, "luaL_checklstring");
581     lib.bindSymbol(cast(void**)&luaL_optlstring, "luaL_optlstring");
582     lib.bindSymbol(cast(void**)&luaL_checknumber, "luaL_checknumber");
583     lib.bindSymbol(cast(void**)&luaL_optnumber, "luaL_optnumber");
584     lib.bindSymbol(cast(void**)&luaL_checkinteger, "luaL_checkinteger");
585     lib.bindSymbol(cast(void**)&luaL_optinteger, "luaL_optinteger");
586     lib.bindSymbol(cast(void**)&luaL_checkstack, "luaL_checkstack");
587     lib.bindSymbol(cast(void**)&luaL_checktype, "luaL_checktype");
588     lib.bindSymbol(cast(void**)&luaL_checkany, "luaL_checkany");
589     lib.bindSymbol(cast(void**)&luaL_newmetatable, "luaL_newmetatable");
590     lib.bindSymbol(cast(void**)&luaL_setmetatable, "luaL_setmetatable");
591     lib.bindSymbol(cast(void**)&luaL_where, "luaL_where");
592     lib.bindSymbol(cast(void**)&luaL_error, "luaL_error");
593     lib.bindSymbol(cast(void**)&luaL_checkoption, "luaL_checkoption");
594     lib.bindSymbol(cast(void**)&luaL_ref, "luaL_ref");
595     lib.bindSymbol(cast(void**)&luaL_unref, "luaL_unref");
596     lib.bindSymbol(cast(void**)&luaL_loadfile, "luaL_loadfile");
597     lib.bindSymbol(cast(void**)&luaL_loadbuffer, "luaL_loadbuffer");
598     lib.bindSymbol(cast(void**)&luaL_loadstring, "luaL_loadstring");
599     lib.bindSymbol(cast(void**)&luaL_newstate, "luaL_newstate");
600     lib.bindSymbol(cast(void**)&luaL_gsub, "luaL_gsub");
601 
602 
603     lib.bindSymbol(cast(void**)&luaopen_base, "luaopen_base");
604     lib.bindSymbol(cast(void**)&luaopen_table, "luaopen_table");
605     lib.bindSymbol(cast(void**)&luaopen_io, "luaopen_io");
606     lib.bindSymbol(cast(void**)&luaopen_os, "luaopen_os");
607     lib.bindSymbol(cast(void**)&luaopen_string, "luaopen_string");
608     lib.bindSymbol(cast(void**)&luaopen_math, "luaopen_math");
609     lib.bindSymbol(cast(void**)&luaopen_debug, "luaopen_debug");
610     lib.bindSymbol(cast(void**)&luaopen_package, "luaopen_package");
611     lib.bindSymbol(cast(void**)&luaL_openlibs, "luaL_openlibs");
612 
613 
614     //lib.bindSymbol(cast(void**)&lua_version, "lua_version");
615     //lib.bindSymbol(cast(void**)&lua_absindex, "lua_absindex");
616     //lib.bindSymbol(cast(void**)&lua_rotate, "lua_rotate");
617     //lib.bindSymbol(cast(void**)&lua_copy, "lua_copy");
618     //lib.bindSymbol(cast(void**)&lua_isinteger, "lua_isinteger");
619     //lib.bindSymbol(cast(void**)&lua_rawlen, "lua_rawlen");
620     //lib.bindSymbol(cast(void**)&lua_arith, "lua_arith");
621     //lib.bindSymbol(cast(void**)&lua_rawequal, "lua_rawequal");
622     //lib.bindSymbol(cast(void**)&lua_compare, "lua_compare");
623     //lib.bindSymbol(cast(void**)&lua_getglobal, "lua_getglobal");
624     //lib.bindSymbol(cast(void**)&lua_geti, "lua_geti");
625     //lib.bindSymbol(cast(void**)&lua_rawgetp, "lua_rawgetp");
626     //lib.bindSymbol(cast(void**)&lua_yieldk, "lua_yieldk");
627     //lib.bindSymbol(cast(void**)&luaL_tolstring, "luaL_tolstring");
628     //lib.bindSymbol(cast(void**)&luaL_testudata, "luaL_testudata");
629     //lib.bindSymbol(cast(void**)&luaL_checkudata, "luaL_checkudata");
630     //lib.bindSymbol(cast(void**)&luaL_fileresult, "luaL_fileresult");
631     //lib.bindSymbol(cast(void**)&luaL_execresult, "luaL_execresult");
632     //lib.bindSymbol(cast(void**)&luaL_len, "luaL_len");
633     //lib.bindSymbol(cast(void**)&luaL_setfuncs, "luaL_setfuncs");
634     //lib.bindSymbol(cast(void**)&luaL_getsubtable, "luaL_getsubtable");
635     //lib.bindSymbol(cast(void**)&luaL_traceback, "luaL_traceback");
636     //lib.bindSymbol(cast(void**)&luaL_requiref, "luaL_requiref");
637     //lib.bindSymbol(cast(void**)&lua_getuservalue, "lua_getuservalue");
638     //lib.bindSymbol(cast(void**)&lua_setglobal, "lua_setglobal");
639     //lib.bindSymbol(cast(void**)&lua_seti, "lua_seti");
640     //lib.bindSymbol(cast(void**)&lua_rawsetp, "lua_rawsetp");
641     //lib.bindSymbol(cast(void**)&lua_setuservalue, "lua_setuservalue");
642 
643     return errCount == errorCount();
644 }