Mercurial > pub > dyncall > bindings
comparison lua/luadc/luadc.c @ 0:0cfcc391201f
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:26:28 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0cfcc391201f |
---|---|
1 #include <lua.h> | |
2 #include <lauxlib.h> | |
3 #include <dyncall.h> | |
4 #include <dyncall_signature.h> | |
5 #include <dynload.h> | |
6 | |
7 #define LUA_DCLIBNAME "dc" | |
8 | |
9 DCCallVM* g_pCallVM; | |
10 | |
11 int luaDC_load(lua_State* L) | |
12 { | |
13 void* handle; | |
14 if (lua_gettop(L) != 1) return luaL_error(L,"wrong number of arguments"); | |
15 handle = dlLoadLibrary( lua_tostring(L,1) ); | |
16 if (!handle) return luaL_error(L,"library not found"); | |
17 lua_pushlightuserdata(L, handle); | |
18 return 1; | |
19 } | |
20 | |
21 int luaDC_find(lua_State* L) | |
22 { | |
23 void* h; | |
24 const char* s; | |
25 void* f; | |
26 if (lua_gettop(L) != 2) return luaL_error(L,"wrong number of arguments"); | |
27 h = lua_touserdata(L, 1); | |
28 s = lua_tostring(L, 2); | |
29 f = dlFindSymbol(h, s); | |
30 if (!f) return luaL_error(L,"symbol not found"); | |
31 lua_pushlightuserdata(L, f); | |
32 return 1; | |
33 } | |
34 | |
35 int luaDC_mode(lua_State* L) | |
36 { | |
37 if (lua_gettop(L) < 1) return luaL_error(L,"missing arguments"); | |
38 dcMode(g_pCallVM, (DCint) lua_tonumber(L, 1) ); | |
39 return 0; | |
40 } | |
41 | |
42 int luaDC_call(lua_State* L) | |
43 { | |
44 void* f; | |
45 const char* s; | |
46 if (lua_gettop(L) < 2) return luaL_error(L,"missing arguments"); | |
47 | |
48 if ( lua_iscfunction(L,1) ) | |
49 f = (void*) lua_tocfunction(L,1); | |
50 else if (lua_islightuserdata(L,1) ) | |
51 f = lua_touserdata(L, 1); | |
52 else | |
53 return luaL_error(L,"argument #1 mismatch: expected userdata"); | |
54 | |
55 s = lua_tostring(L,2); | |
56 | |
57 // dcMode( g_pCallVM, DC_CALL_C_DEFAULT ); | |
58 dcReset( g_pCallVM ); | |
59 | |
60 char ch; | |
61 int p = 3; | |
62 while ( (ch = *s++) != DC_SIGCHAR_ENDARG) | |
63 { | |
64 switch(ch) | |
65 { | |
66 case DC_SIGCHAR_BOOL: | |
67 dcArgBool(g_pCallVM, (DCbool) lua_toboolean(L, p) ); | |
68 break; | |
69 case DC_SIGCHAR_CHAR: | |
70 dcArgChar(g_pCallVM, (DCchar) lua_tonumber(L, p) ); | |
71 break; | |
72 case DC_SIGCHAR_SHORT: | |
73 dcArgShort(g_pCallVM, (DCshort) lua_tonumber(L, p) ); | |
74 break; | |
75 case DC_SIGCHAR_INT: | |
76 dcArgInt(g_pCallVM, (DCint) lua_tonumber(L, p) ); | |
77 break; | |
78 case DC_SIGCHAR_LONG: | |
79 dcArgLong(g_pCallVM, (DClong) lua_tonumber(L, p) ); | |
80 break; | |
81 case DC_SIGCHAR_LONGLONG: | |
82 dcArgLongLong(g_pCallVM, (DClonglong) lua_tonumber(L, p) ); | |
83 break; | |
84 case DC_SIGCHAR_FLOAT: | |
85 dcArgFloat(g_pCallVM, (DCfloat) lua_tonumber(L, p) ); | |
86 break; | |
87 case DC_SIGCHAR_DOUBLE: | |
88 dcArgDouble(g_pCallVM, (DCdouble) lua_tonumber(L, p) ); | |
89 break; | |
90 case DC_SIGCHAR_POINTER: | |
91 dcArgPointer(g_pCallVM, (DCpointer) lua_topointer(L, p) ); | |
92 break; | |
93 case DC_SIGCHAR_STRING: | |
94 dcArgPointer(g_pCallVM, (DCpointer) lua_tostring(L, p) ); | |
95 break; | |
96 } | |
97 ++p; | |
98 } | |
99 | |
100 switch(*s) | |
101 { | |
102 case DC_SIGCHAR_VOID: | |
103 dcCallVoid(g_pCallVM, f); | |
104 return 0; | |
105 case DC_SIGCHAR_BOOL: | |
106 lua_pushboolean( L, (int) dcCallBool(g_pCallVM, f) ); | |
107 break; | |
108 case DC_SIGCHAR_CHAR: | |
109 lua_pushnumber( L, (lua_Number) ( dcCallChar(g_pCallVM,f) ) ); | |
110 break; | |
111 case DC_SIGCHAR_SHORT: | |
112 lua_pushnumber( L, (lua_Number)( dcCallShort(g_pCallVM, f) ) ); | |
113 break; | |
114 case DC_SIGCHAR_INT: | |
115 lua_pushnumber( L, (lua_Number)( dcCallInt(g_pCallVM, f) ) ); | |
116 break; | |
117 case DC_SIGCHAR_LONG: | |
118 lua_pushnumber( L, (lua_Number)( dcCallLong(g_pCallVM, f) ) ); | |
119 break; | |
120 case DC_SIGCHAR_LONGLONG: | |
121 lua_pushnumber( L, (lua_Number)( dcCallLongLong(g_pCallVM, f) ) ); | |
122 break; | |
123 case DC_SIGCHAR_FLOAT: | |
124 lua_pushnumber( L, (lua_Number) dcCallFloat(g_pCallVM, f) ); | |
125 break; | |
126 case DC_SIGCHAR_DOUBLE: | |
127 lua_pushnumber( L, (lua_Number) dcCallDouble(g_pCallVM, f) ); | |
128 break; | |
129 case DC_SIGCHAR_STRING: | |
130 lua_pushstring( L, (const char*) dcCallPointer(g_pCallVM, f) ); | |
131 break; | |
132 case DC_SIGCHAR_POINTER: | |
133 lua_pushlightuserdata( L, dcCallPointer(g_pCallVM, f) ); | |
134 break; | |
135 } | |
136 return 1; | |
137 } | |
138 | |
139 static const luaL_Reg dclib[] = | |
140 { | |
141 {"load", luaDC_load}, | |
142 {"find", luaDC_find}, | |
143 {"mode", luaDC_mode}, | |
144 {"call", luaDC_call}, | |
145 {NULL,NULL} | |
146 }; | |
147 | |
148 typedef struct | |
149 { | |
150 const char* name; | |
151 int value; | |
152 } ModeEnum; | |
153 | |
154 ModeEnum gModeEnums[] = | |
155 { | |
156 "C_DEFAULT", DC_CALL_C_DEFAULT, | |
157 "C_X86_CDECL", DC_CALL_C_X86_CDECL, | |
158 "C_X86_WIN32_STD", DC_CALL_C_X86_WIN32_STD, | |
159 "C_X86_FAST_MS", DC_CALL_C_X86_WIN32_FAST_MS, | |
160 "C_X86_WIN32_THIS_MS", DC_CALL_C_X86_WIN32_THIS_MS, | |
161 "C_X86_WIN32_THIS_GNU", DC_CALL_C_X86_WIN32_THIS_GNU, | |
162 "C_X86_WIN32_FAST_GNU", DC_CALL_C_X86_WIN32_FAST_GNU, | |
163 "C_X64_WIN64", DC_CALL_C_X64_WIN64, | |
164 "C_PPC32_DARWIN", DC_CALL_C_PPC32_DARWIN, | |
165 "C_ARM", DC_CALL_C_ARM, | |
166 "C_MIPS_EABI", DC_CALL_C_MIPS32_EABI, | |
167 "C_MIPS_PSPSDK", DC_CALL_C_MIPS32_PSPSDK | |
168 }; | |
169 | |
170 LUA_API int luadc_open (lua_State* L) | |
171 { | |
172 int i = 0, n = sizeof(gModeEnums)/sizeof(ModeEnum); | |
173 g_pCallVM = dcNewCallVM(256); | |
174 luaL_register(L, LUA_DCLIBNAME, dclib); | |
175 | |
176 for (i = 0; i < n ; ++i ) | |
177 { | |
178 lua_pushnumber(L, gModeEnums[i].value); | |
179 lua_setfield(L, -2, gModeEnums[i].name); | |
180 | |
181 } | |
182 return 1; | |
183 } | |
184 |