-
Notifications
You must be signed in to change notification settings - Fork 1
/
luabind.cpp
154 lines (120 loc) · 4.02 KB
/
luabind.cpp
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// Created by zhenkai on 2020/6/2.
//
#include "luabind.h"
static void dd(lua_State *L) {
printf("top %d\n", lua_gettop(L));
}
static void lbind_message (const char *msg) {
fprintf(stderr, "\n=====\nError: %s\n=====\n", msg);
}
static int lbind_report (lua_State *L, int status) {
if (status != LUA_OK) {
const char *msg = lua_tostring(L, -1);
lbind_message(msg);
lua_pop(L, 1); /* remove error message */
}
return status;
}
/*
** Message handler used to run all chunks
*/
static int l_msghandler (lua_State *L) {
const char *msg = lua_tostring(L, 1);
if (msg == NULL) { /* is error object not a string? */
if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */
return 1; /* that is the message */
else
msg = lua_pushfstring(L, "(error object is a %s value)",
luaL_typename(L, 1));
}
/* return the traceback */
luaL_traceback(L, L, msg, 1); /* append a standard traceback */
return 1;
}
int lbind_docall (lua_State *L, int narg, int nres) {
int status;
int base = lua_gettop(L) - narg; /* function index */
if (base < 0) assert(0);
lua_pushcfunction(L, &l_msghandler); /* push message handler */
lua_insert(L, base); /* put it under function and args */
status = lua_pcall(L, narg, nres, base);
lua_remove(L, base); /* remove message handler from the stack */
return lbind_report(L, status);
}
static int l_dofile(lua_State *L) {
char *name = (char *)lua_touserdata(L, 1);
int status = luaL_loadfile(L, name);
if (status == LUA_OK) status = lbind_docall(L, 0, 0);
lbind_report(L, status);
lua_pushboolean(L, status == LUA_OK);
return 1;
}
/*
** Main body of stand-alone interpreter (to be called in protected mode).
** Reads the options and handles them all.
*/
int lbind_dofile (lua_State *L, const char *filename) {
lua_pushcfunction(L, &l_dofile); /* to call 'l_dofile' in protected mode */
lua_pushlightuserdata(L, const_cast<char *> (filename));
int status = lbind_docall(L, 1, 1); /* do the call */
int ok = 0;
if (status == LUA_OK) {
ok = lua_toboolean(L, -1);
lua_pop(L , 1); /*necessary */
}
return ok;
}
static int l_proxy_func(lua_State *L) {
int n;
lbind_CFunction f = (lbind_CFunction) lua_touserdata(L, lua_upvalueindex(1));
// convert request
Request request(L);
request.gencargs();
// construct response
Response response(L);
f(request, response);
n = response.genluaargs();
// call func
return n;
}
static int l_register_proxy(lua_State *L) {
const char *funcname = (const char *)lua_touserdata(L, 1);
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA);
lua_getglobal(L, CPP);
if (lua_type(L, -1) != LUA_TTABLE) {
lua_createtable(L, 0 /* narr */, 1 /* nrec */);
lua_pushvalue(L, -1);
lua_setglobal(L, CPP);
}
lua_pushvalue(L, 2);
lua_pushcclosure(L, l_proxy_func, 1); // lua_pushcclosure also pops these values from the stack.
lua_setfield(L, -2, funcname);
lua_pop(L, -1);
return 0;
}
static int l_register(lua_State *L) {
const char *funcname = (const char *)lua_touserdata(L, 1);
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA);
lua_getglobal(L, CPP);
if (lua_type(L, -1) != LUA_TTABLE) {
lua_createtable(L, 0 /* narr */, 1 /* nrec */);
lua_pushvalue(L, -1);
lua_setglobal(L, CPP);
}
lua_pushcfunction(L, (lua_CFunction)lua_touserdata(L, 2));
lua_setfield(L, -2, funcname);
lua_pop(L, -1);
return 0;
}
int lbind_register(lua_State *L, const char *funcname, void * func, bool isoriginfunc) {
if (isoriginfunc ) {
lua_pushcfunction(L, l_register);
} else {
lua_pushcfunction(L, l_register_proxy);
}
lua_pushlightuserdata(L, const_cast<char *> (funcname));
lua_pushlightuserdata(L, func);
return lbind_docall(L, 2, 0);
}