annotate lua/luadyncall/src/ldynstruct.c @ 37:8c8f848131c6

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