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