aboutsummaryrefslogtreecommitdiff
path: root/llthreads2/src/l52util.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--llthreads2/src/l52util.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/llthreads2/src/l52util.c b/llthreads2/src/l52util.c
new file mode 100644
index 0000000..9d44a40
--- /dev/null
+++ b/llthreads2/src/l52util.c
@@ -0,0 +1,126 @@
1#include "l52util.h"
2
3#include <memory.h>
4#include <assert.h>
5
6#if LUA_VERSION_NUM >= 502
7
8int luaL_typerror (lua_State *L, int narg, const char *tname) {
9 const char *msg = lua_pushfstring(L, "%s expected, got %s", tname,
10 luaL_typename(L, narg));
11 return luaL_argerror(L, narg, msg);
12}
13
14#ifndef luaL_register
15
16void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l){
17 if(libname) lua_newtable(L);
18 luaL_setfuncs(L, l, 0);
19}
20
21#endif
22
23#else
24
25void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup){
26 luaL_checkstack(L, nup, "too many upvalues");
27 for (; l->name != NULL; l++) { /* fill the table with given functions */
28 int i;
29 for (i = 0; i < nup; i++) /* copy upvalues to the top */
30 lua_pushvalue(L, -nup);
31 lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
32 lua_setfield(L, -(nup + 2), l->name);
33 }
34 lua_pop(L, nup); /* remove upvalues */
35}
36
37void lua_rawgetp(lua_State *L, int index, const void *p){
38 index = lua_absindex(L, index);
39 lua_pushlightuserdata(L, (void *)p);
40 lua_rawget(L, index);
41}
42
43void lua_rawsetp (lua_State *L, int index, const void *p){
44 index = lua_absindex(L, index);
45 lua_pushlightuserdata(L, (void *)p);
46 lua_insert(L, -2);
47 lua_rawset(L, index);
48}
49
50void lutil_require(lua_State *L, const char* name, lua_CFunction fn, int glb) {
51 // @fixme generate error if we can not load module
52 lua_cpcall(L, fn, NULL);
53}
54
55#endif
56
57int lutil_newmetatablep (lua_State *L, const void *p) {
58 lua_rawgetp(L, LUA_REGISTRYINDEX, p);
59 if (!lua_isnil(L, -1)) /* name already in use? */
60 return 0; /* leave previous value on top, but return 0 */
61 lua_pop(L, 1);
62
63 lua_newtable(L); /* create metatable */
64 lua_pushvalue(L, -1); /* duplicate metatable to set*/
65 lua_rawsetp(L, LUA_REGISTRYINDEX, p);
66
67 return 1;
68}
69
70void lutil_getmetatablep (lua_State *L, const void *p) {
71 lua_rawgetp(L, LUA_REGISTRYINDEX, p);
72}
73
74void lutil_setmetatablep (lua_State *L, const void *p) {
75 lutil_getmetatablep(L, p);
76 assert(lua_istable(L,-1));
77 lua_setmetatable (L, -2);
78}
79
80int lutil_isudatap (lua_State *L, int ud, const void *p) {
81 if (lua_isuserdata(L, ud)){
82 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
83 int res;
84 lutil_getmetatablep(L,p); /* get correct metatable */
85 res = lua_rawequal(L, -1, -2); /* does it have the correct mt? */
86 lua_pop(L, 2); /* remove both metatables */
87 return res;
88 }
89 }
90 return 0;
91}
92
93void *lutil_checkudatap (lua_State *L, int ud, const void *p) {
94 void *up = lua_touserdata(L, ud);
95 if (up != NULL) { /* value is a userdata? */
96 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
97 lutil_getmetatablep(L,p); /* get correct metatable */
98 if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
99 lua_pop(L, 2); /* remove both metatables */
100 return up;
101 }
102 }
103 }
104 luaL_typerror(L, ud, p); /* else error */
105 return NULL; /* to avoid warnings */
106}
107
108int lutil_createmetap (lua_State *L, const void *p, const luaL_Reg *methods, int nup) {
109 if (!lutil_newmetatablep(L, p))
110 return 0;
111
112 lua_insert(L, -1 - nup); /* move mt prior upvalues */
113 luaL_setfuncs (L, methods, nup); /* define methods */
114 lua_pushliteral (L, "__index"); /* define metamethods */
115 lua_pushvalue (L, -2);
116 lua_settable (L, -3);
117
118 return 1;
119}
120
121void *lutil_newudatap_impl(lua_State *L, size_t size, const void *p){
122 void *obj = lua_newuserdata (L, size);
123 memset(obj, 0, size);
124 lutil_setmetatablep(L, p);
125 return obj;
126}