annotate lua/luadyncall/src/ldyncall.c @ 43:1086ca649715

- fixed use after free issue with string handling (keeping strings as copy until after call)
author Tassilo Philipp
date Wed, 15 Apr 2020 21:58:13 +0200
parents 0cfcc391201f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 #include <stddef.h>
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2 #include "lua.h"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 #include "lauxlib.h"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 #include "dyncall.h"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 #include "dyncall_signature.h"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 DCCallVM* g_pCallVM = NULL;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
9 /**
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 * lua syntax:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11 *
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 * dodyncall( address, signature, ... )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 *
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 **/
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 int lua_dodyncall(lua_State *L)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 void* f;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 const char *callsignature, *s;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 int top = lua_gettop(L);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 if (top < 2) return luaL_error(L,"missing arguments #1 'addr' and #2 'signature'");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23 if ( lua_iscfunction(L,1) ) f = (void*) lua_tocfunction(L, 1);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24 else if (lua_islightuserdata(L,1) ) f = lua_touserdata(L, 1);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25 else if (lua_isnumber(L,1) ) f = (void*) lua_tointeger(L, 1);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26 else return luaL_argerror(L, 1, "expected a cfunction, userdata or number");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28 s = callsignature = luaL_checkstring(L,2);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30 /* parse mode */
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 // dcMode( g_pCallVM, DC_CALL_C_DEFAULT );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33 dcReset( g_pCallVM );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35 char ch;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 int p = 3;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37 int ptr = 0;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38 while ( (ch = *s++) != DC_SIGCHAR_ENDARG)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 if (p > top) return luaL_error(L,"need more arguments (call signature is '%s')", callsignature );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41 if (ptr == 0) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42 switch(ch)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44 case '*':
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 ptr++;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46 continue;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47 case DC_SIGCHAR_BOOL:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48 dcArgBool(g_pCallVM, (DCbool) luaL_checkint(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 case DC_SIGCHAR_CHAR:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 case DC_SIGCHAR_UCHAR:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 dcArgChar(g_pCallVM, (DCchar) luaL_checkint(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54 case DC_SIGCHAR_SHORT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 case DC_SIGCHAR_USHORT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 dcArgShort(g_pCallVM, (DCshort) luaL_checkint(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 case DC_SIGCHAR_INT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 case DC_SIGCHAR_UINT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 dcArgInt(g_pCallVM, (DCint) luaL_checknumber(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 case DC_SIGCHAR_LONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 case DC_SIGCHAR_ULONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 dcArgLong(g_pCallVM, (DClong) luaL_checknumber(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 case DC_SIGCHAR_LONGLONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67 case DC_SIGCHAR_ULONGLONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 dcArgLongLong(g_pCallVM, (DClonglong) luaL_checknumber(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 case DC_SIGCHAR_FLOAT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 dcArgFloat(g_pCallVM, (DCfloat) luaL_checknumber(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 case DC_SIGCHAR_DOUBLE:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 dcArgDouble(g_pCallVM, (DCdouble) luaL_checknumber(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 case DC_SIGCHAR_POINTER:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77 dcArgPointer(g_pCallVM, (DCpointer) lua_topointer(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 case DC_SIGCHAR_STRING:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 dcArgPointer(g_pCallVM, (DCpointer) lua_tostring(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82 default:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83 return luaL_error(L, "invalid typecode '%c' in call signature '%s'", s[0], callsignature);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85 } else { /* pointer types */
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86 switch(ch)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88 case '*':
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89 ptr++;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90 continue;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91 case '<':
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
92 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
93 const char* begin = s;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
94 while ( (ch = *s++) != '>' ) ;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
95 const char* end = s;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
96 switch( lua_type(L,p) ) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
97 case LUA_TNUMBER:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
98 dcArgPointer(g_pCallVM, (DCpointer) (ptrdiff_t) lua_tonumber(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
99 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
100 case LUA_TTABLE:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
101 lua_pushvalue(L, p); // 1
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
102 lua_pushliteral(L, "pointer");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
103 lua_gettable(L, -2); // 2
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
104 if ( !lua_isuserdata(L, -1) )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
105 luaL_error(L, "pointer type mismatch at argument #%d", p);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
106 dcArgPointer(g_pCallVM, (DCpointer) lua_touserdata(L, -1) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
107 lua_pop(L, 2);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
108 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
109 case LUA_TLIGHTUSERDATA:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
110 case LUA_TUSERDATA:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
111 dcArgPointer(g_pCallVM, (DCpointer) lua_topointer(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
112 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
113 default:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
114 luaL_error(L, "pointer type mismatch at argument #%d", p);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
115 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
116 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
117 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
118 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
119 case DC_SIGCHAR_BOOL:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
120 case DC_SIGCHAR_CHAR:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
121 if ( lua_isstring(L, p) ) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
122 dcArgPointer(g_pCallVM, (DCpointer) lua_tostring(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
123 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
124 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
125 case DC_SIGCHAR_UCHAR:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
126 case DC_SIGCHAR_SHORT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
127 case DC_SIGCHAR_USHORT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
128 case DC_SIGCHAR_INT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
129 case DC_SIGCHAR_UINT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
130 case DC_SIGCHAR_LONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
131 case DC_SIGCHAR_ULONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
132 case DC_SIGCHAR_LONGLONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
133 case DC_SIGCHAR_ULONGLONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
134 case DC_SIGCHAR_FLOAT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
135 case DC_SIGCHAR_DOUBLE:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
136 case DC_SIGCHAR_POINTER:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
137 case DC_SIGCHAR_STRING:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
138 case DC_SIGCHAR_VOID:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
139 if ( lua_istable(L, p) ) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
140 lua_pushvalue(L, p); // 1
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
141 lua_pushliteral(L, "pointer");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
142 lua_gettable(L, -2); // 2
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
143 if ( !lua_isuserdata(L, -1) )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
144 luaL_error(L, "pointer type mismatch at argument #%d", p);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
145 dcArgPointer(g_pCallVM, (DCpointer) lua_touserdata(L, -1) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
146 lua_pop(L, 2);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
147 } else
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
148 dcArgPointer(g_pCallVM, (DCpointer) lua_topointer(L, p) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
149 ptr = 0;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
150 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
151 default:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
152 return luaL_error(L, "invalid signature");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
153 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
154 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
155
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
156 ++p;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
157 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
158
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
159 if (top >= p)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
160 luaL_error(L,"too many arguments for given signature, expected %d but received %d" , p-3, top-2 );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
161
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
162 switch(*s++)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
163 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
164 case DC_SIGCHAR_VOID:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
165 dcCallVoid(g_pCallVM, f);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
166 return 0;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
167 case DC_SIGCHAR_BOOL:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
168 lua_pushboolean( L, (int) dcCallBool(g_pCallVM, f) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
169 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
170 case DC_SIGCHAR_CHAR:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
171 case DC_SIGCHAR_UCHAR:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
172 lua_pushnumber( L, (lua_Number) ( dcCallChar(g_pCallVM,f) ) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
173 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
174 case DC_SIGCHAR_SHORT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
175 case DC_SIGCHAR_USHORT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
176 lua_pushnumber( L, (lua_Number)( dcCallShort(g_pCallVM, f) ) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
177 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
178 case DC_SIGCHAR_INT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
179 case DC_SIGCHAR_UINT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
180 lua_pushnumber( L, (lua_Number)( dcCallInt(g_pCallVM, f) ) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
181 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
182 case DC_SIGCHAR_LONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
183 case DC_SIGCHAR_ULONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
184 lua_pushnumber( L, (lua_Number)( dcCallLong(g_pCallVM, f) ) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
185 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
186 case DC_SIGCHAR_LONGLONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
187 case DC_SIGCHAR_ULONGLONG:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
188 lua_pushnumber( L, (lua_Number)( dcCallLongLong(g_pCallVM, f) ) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
189 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
190 case DC_SIGCHAR_FLOAT:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
191 lua_pushnumber( L, (lua_Number) dcCallFloat(g_pCallVM, f) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
192 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
193 case DC_SIGCHAR_DOUBLE:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
194 lua_pushnumber( L, (lua_Number) dcCallDouble(g_pCallVM, f) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
195 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
196 case DC_SIGCHAR_STRING:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
197 lua_pushstring( L, (const char*) dcCallPointer(g_pCallVM, f) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
198 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
199 case DC_SIGCHAR_POINTER:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
200 lua_pushlightuserdata( L, dcCallPointer(g_pCallVM, f) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
201 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
202 case '*':
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
203 switch(*s++) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
204 case DC_SIGCHAR_UCHAR:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
205 case DC_SIGCHAR_CHAR:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
206 lua_pushstring( L, dcCallPointer(g_pCallVM, f) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
207 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
208 default:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
209 lua_pushlightuserdata( L, dcCallPointer(g_pCallVM, f) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
210 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
211 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
212 break;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
213 default:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
214 return luaL_error(L, "invalid signature");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
215 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
216 return 1;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
217 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
218
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
219 int topointer(lua_State* L)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
220 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
221 lua_pushlightuserdata(L, (void*) (ptrdiff_t) luaL_checkint(L, 1) );
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
222 return 1;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
223 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
224
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
225 static const struct luaL_Reg luareg_dyncall[] =
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
226 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
227 { "dodyncall", lua_dodyncall },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
228 { "topointer", topointer },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
229 { NULL, NULL }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
230 /*
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
231 { "NewCallVM", lua_dcNewCallVM },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
232 { "Mode", lua_dcMode },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
233 { "Reset", lua_dcReset },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
234 { "ArgBool", lua_dcBool },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
235 { "ArgChar", lua_dcChar },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
236 { "ArgShort", lua_dcShort },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
237 { "ArgInt", lua_dcInt },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
238 { "ArgLong", lua_dcLong },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
239 { "ArgLongLong", lua_dcLongLong },
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
240 */
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
241 };
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
242
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
243 void lua_setmetainfo(lua_State *L)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
244 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
245 lua_pushliteral(L, "_COPYRIGHT");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
246 lua_pushliteral(L, "Copyright (C) 2010 Dyncall Project");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
247 lua_settable(L, -3);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
248 lua_pushliteral(L, "_DESCRIPTION");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
249 lua_pushliteral(L, "lua bindings for dyncall libraries");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
250 lua_settable(L, -3);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
251 lua_pushliteral(L, "_VERSION");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
252 lua_pushliteral(L, "0.1");
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
253 lua_settable(L, -3);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
254 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
255
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
256 LUA_API int luaopen_ldyncall(lua_State* L)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
257 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
258 g_pCallVM = dcNewCallVM(4096);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
259 luaL_register(L, "ldyncall", luareg_dyncall);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
260 lua_setmetainfo(L);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
261 return 1;
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
262 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
263