0
|
1 #include "lua.h"
|
|
2 #include "lauxlib.h"
|
|
3 #include "dyncall.h"
|
|
4 #include "dyncall_signature.h"
|
|
5 #include <stddef.h>
|
|
6
|
|
7 static int lua_newstruct(lua_State *L)
|
|
8 {
|
|
9 size_t size;
|
|
10 void *addr;
|
|
11 size = (size_t) luaL_checkinteger(L, 1);
|
|
12 addr = lua_newuserdata(L, size);
|
|
13 return 1;
|
|
14 }
|
|
15
|
|
16 static int lua_aslightuserdata(lua_State *L)
|
|
17 {
|
|
18 lua_pushlightuserdata(L, (void*) (ptrdiff_t) luaL_checkinteger(L, 1) );
|
|
19 return 1;
|
|
20 }
|
|
21
|
|
22 /*
|
|
23 static int lua_newdynstruct(lua_State *L)
|
|
24 {
|
|
25 size_t size;
|
|
26 void *addr;
|
|
27 size = (size_t) luaL_checkinteger(L, 1);
|
|
28 luaL_checktype(L, 2, LUA_TTABLE);
|
|
29 addr = lua_newuserdata(L, size);
|
|
30 lua_pushvalue(L, 2);
|
|
31 lua_setmetatable(L, 3);
|
|
32 return 1;
|
|
33 }
|
|
34 */
|
|
35
|
|
36 int lua_dynpoke(lua_State *L)
|
|
37 {
|
|
38 const char *ptr = (const char *) lua_touserdata(L, 1);
|
|
39 size_t offset = (ptrdiff_t) lua_tointeger(L, 2);
|
|
40 const char *typesig = (const char*) lua_tostring(L, 3);
|
|
41 const char *sig = typesig;
|
|
42 char ch;
|
|
43 ptr += offset;
|
|
44 while ((ch=*sig++) != '\0') {
|
|
45 switch(ch) {
|
|
46 case DC_SIGCHAR_BOOL: *((int*)ptr) = lua_toboolean(L, 4); break;
|
|
47 case DC_SIGCHAR_CHAR: *((char*)ptr) = (char) lua_tointeger(L, 4); break;
|
|
48 case DC_SIGCHAR_UCHAR: *((unsigned char*)ptr) = (unsigned char) lua_tointeger(L, 4); break;
|
|
49 case DC_SIGCHAR_SHORT: *((short*)ptr) = (short) lua_tointeger(L, 4); break;
|
|
50 case DC_SIGCHAR_USHORT: *((unsigned short*)ptr) = (unsigned short) lua_tointeger(L, 4); break;
|
|
51 case DC_SIGCHAR_INT: *((int*)ptr) = lua_tointeger(L, 4); break;
|
|
52 case DC_SIGCHAR_UINT: *((unsigned int*)ptr) = (unsigned int) lua_tonumber(L, 4); break;
|
|
53 case DC_SIGCHAR_LONG: *((long*)ptr) = (long) lua_tonumber(L, 4); break;
|
|
54 case DC_SIGCHAR_ULONG: *((unsigned long*)ptr) = (unsigned long) lua_tonumber(L, 4); break;
|
|
55 case DC_SIGCHAR_LONGLONG: *((DClonglong*)ptr) = (long long) lua_tonumber(L, 4); break;
|
|
56 case DC_SIGCHAR_ULONGLONG: *((DCulonglong*)ptr) = (unsigned long long) lua_tonumber(L, 4); break;
|
|
57 case DC_SIGCHAR_FLOAT: *((float*)ptr) = (float) lua_tonumber(L, 4); break;
|
|
58 case DC_SIGCHAR_DOUBLE: *((double*)ptr) = (double) lua_tonumber(L, 4); break;
|
|
59 case DC_SIGCHAR_POINTER: *((const void**)ptr) = lua_topointer(L, 4); break;
|
|
60 case DC_SIGCHAR_STRING: *((const char**)ptr) = lua_topointer(L, 4); break;
|
|
61 default: luaL_error(L, "invalid type signature %s", typesig); return 0;
|
|
62 }
|
|
63 }
|
|
64 return 0;
|
|
65 }
|
|
66
|
|
67 int lua_dynpeek(lua_State *L)
|
|
68 {
|
|
69 const char *ptr = (const char *) lua_touserdata(L, 1);
|
|
70 size_t offset = (ptrdiff_t) lua_tointeger(L, 2);
|
|
71 const char *typesig = (const char*) lua_tostring(L, 3);
|
|
72 const char* sig = typesig;
|
|
73 char ch;
|
|
74 ptr += offset;
|
|
75 while ((ch = *sig++) != '\0') {
|
|
76 switch(ch) {
|
|
77 case DC_SIGCHAR_BOOL: lua_pushboolean(L, *((int*)ptr)); break;
|
|
78 case DC_SIGCHAR_CHAR: lua_pushinteger(L, (int) *((char*)ptr)); break;
|
|
79 case DC_SIGCHAR_UCHAR: lua_pushinteger(L, (int) *((unsigned char*)ptr)); break;
|
|
80 case DC_SIGCHAR_SHORT: lua_pushinteger(L, (int) *((short*)ptr)); break;
|
|
81 case DC_SIGCHAR_USHORT: lua_pushinteger(L, (int) *((unsigned short*)ptr)); break;
|
|
82 case DC_SIGCHAR_INT: lua_pushinteger(L, *((int*)ptr)); break;
|
|
83 case DC_SIGCHAR_UINT: lua_pushnumber(L, (lua_Number) *((unsigned int*)ptr)); break;
|
|
84 case DC_SIGCHAR_LONG: lua_pushnumber(L, (lua_Number) *((long*)ptr)); break;
|
|
85 case DC_SIGCHAR_ULONG: lua_pushnumber(L, (lua_Number) *((unsigned long*)ptr)); break;
|
|
86 case DC_SIGCHAR_LONGLONG: lua_pushnumber(L, (lua_Number) *((DClonglong*)ptr)); break;
|
|
87 case DC_SIGCHAR_ULONGLONG: lua_pushnumber(L, (lua_Number) *((DCulonglong*)ptr)); break;
|
|
88 case DC_SIGCHAR_FLOAT: lua_pushnumber(L, (lua_Number) *((float*)ptr)); break;
|
|
89 case DC_SIGCHAR_DOUBLE: lua_pushnumber(L, (lua_Number) *((double*)ptr)); break;
|
|
90 case DC_SIGCHAR_POINTER: lua_pushlightuserdata(L, *((void**)ptr) ); break;
|
|
91 case DC_SIGCHAR_STRING: lua_pushstring(L, (const char*)ptr); break;
|
|
92 default: luaL_error(L, "invalid type signature %s", typesig); return 0;
|
|
93 }
|
|
94 }
|
|
95 return 1;
|
|
96 }
|
|
97
|
|
98 static const struct luaL_Reg luareg_dynstruct[] =
|
|
99 {
|
|
100 { "newstruct", lua_newstruct },
|
|
101 { "aslightuserdata", lua_aslightuserdata },
|
|
102 { "dynpoke", lua_dynpoke },
|
|
103 { "dynpeek", lua_dynpeek },
|
|
104 { NULL, NULL }
|
|
105 };
|
|
106
|
|
107 LUA_API int luaopen_ldynstruct(lua_State *L)
|
|
108 {
|
|
109 luaL_register(L, "ldynstruct", luareg_dynstruct);
|
|
110 return 1;
|
|
111 }
|