diff options
Diffstat (limited to '')
-rw-r--r-- | llthreads2/src/l52util.c | 126 |
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 | |||
8 | int 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 | |||
16 | void 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 | |||
25 | void 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 | |||
37 | void 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 | |||
43 | void 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 | |||
50 | void 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 | |||
57 | int 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 | |||
70 | void lutil_getmetatablep (lua_State *L, const void *p) { | ||
71 | lua_rawgetp(L, LUA_REGISTRYINDEX, p); | ||
72 | } | ||
73 | |||
74 | void 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 | |||
80 | int 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 | |||
93 | void *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 | |||
108 | int 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 | |||
121 | void *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 | } | ||