aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c73
1 files changed, 44 insertions, 29 deletions
diff --git a/ldo.c b/ldo.c
index 384bd244..60b9b354 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.57 1999/12/06 11:43:58 roberto Exp roberto $ 2** $Id: ldo.c,v 1.58 1999/12/06 12:03:45 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -99,30 +99,43 @@ void luaD_openstack (lua_State *L, StkId pos) {
99 99
100 100
101void luaD_lineHook (lua_State *L, int line) { 101void luaD_lineHook (lua_State *L, int line) {
102 struct C_Lua_Stack oldCLS = L->Cstack; 102 if (L->allowhooks) {
103 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; 103 struct C_Lua_Stack oldCLS = L->Cstack;
104 L->Cstack.num = 0; 104 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
105 (*L->linehook)(L, line); 105 L->Cstack.num = 0;
106 L->top = old_top; 106 L->allowhooks = 0; /* cannot call hooks inside a hook */
107 L->Cstack = oldCLS; 107 (*L->linehook)(L, line);
108 L->allowhooks = 1;
109 L->top = old_top;
110 L->Cstack = oldCLS;
111 }
108} 112}
109 113
110 114
111void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, 115static void luaD_callHook (lua_State *L, StkId func, lua_CHFunction callhook,
112 int isreturn) { 116 int isreturn) {
113 struct C_Lua_Stack oldCLS = L->Cstack; 117 if (L->allowhooks) {
114 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; 118 struct C_Lua_Stack oldCLS = L->Cstack;
115 L->Cstack.num = 0; 119 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
116 if (isreturn) 120 L->Cstack.num = 0;
117 (*L->callhook)(L, LUA_NOOBJECT, "(return)", 0); 121 L->allowhooks = 0; /* cannot call hooks inside a hook */
118 else { 122 if (isreturn)
119 TObject *f = base-1; 123 callhook(L, LUA_NOOBJECT, "(return)", 0);
120 if (tf) 124 else {
121 v 1.3 1997/10/16, f, tf->source->str, tf->lineDefined); 125 if (ttype(func) == LUA_T_PROTO)
122 else (*L->callhook)(L, f, "(C)", -1); 126 callhook(L, func, tfvalue(func)->source->str,
127 tfvalue(func)->lineDefined);
128 else if (ttype(func) == LUA_T_CLOSURE &&
129 ttype(clvalue(func)->consts) == LUA_T_PROTO)
130 callhook(L, func, tfvalue(protovalue(func))->source->str,
131 tfvalue(protovalue(func))->lineDefined);
132 else
133 callhook(L, func, "(C)", -1);
134 }
135 L->allowhooks = 1;
136 L->top = old_top;
137 L->Cstack = oldCLS;
123 } 138 }
124 L->top = old_top;
125 L->Cstack = oldCLS;
126} 139}
127 140
128 141
@@ -138,11 +151,7 @@ static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
138 L->Cstack.num = numarg; 151 L->Cstack.num = numarg;
139 L->Cstack.lua2C = base; 152 L->Cstack.lua2C = base;
140 L->Cstack.base = L->top; 153 L->Cstack.base = L->top;
141 if (L->callhook)
142 luaD_callHook(L, base, NULL, 0);
143 (*f)(L); /* do the actual call */ 154 (*f)(L); /* do the actual call */
144 if (L->callhook) /* test again: `func' may change callhook */
145 luaD_callHook(L, base, NULL, 1);
146 firstResult = L->Cstack.base; 155 firstResult = L->Cstack.base;
147 L->Cstack = oldCLS; 156 L->Cstack = oldCLS;
148 return firstResult; 157 return firstResult;
@@ -179,6 +188,10 @@ void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
179*/ 188*/
180void luaD_call (lua_State *L, StkId func, int nResults) { 189void luaD_call (lua_State *L, StkId func, int nResults) {
181 StkId firstResult; 190 StkId firstResult;
191 lua_CHFunction callhook = L->callhook;
192 if (callhook)
193 luaD_callHook(L, func, callhook, 0);
194 retry: /* for `function' tag method */
182 switch (ttype(func)) { 195 switch (ttype(func)) {
183 case LUA_T_CPROTO: 196 case LUA_T_CPROTO:
184 ttype(func) = LUA_T_CMARK; 197 ttype(func) = LUA_T_CMARK;
@@ -197,15 +210,17 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
197 luaV_execute(L, c, tfvalue(proto), func+1); 210 luaV_execute(L, c, tfvalue(proto), func+1);
198 break; 211 break;
199 } 212 }
200 default: { /* `func' is not a function */ 213 default: { /* `func' is not a function; check the `function' tag method */
201 /* Check the tag method for invalid functions */
202 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION); 214 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
203 if (ttype(im) == LUA_T_NIL) 215 if (ttype(im) == LUA_T_NIL)
204 lua_error(L, "call expression not a function"); 216 lua_error(L, "call expression not a function");
205 luaD_callTM(L, im, L->top-func, nResults); 217 luaD_openstack(L, func);
206 return; 218 *func = *im; /* tag method is the new function to be called */
219 goto retry; /* retry the call (without calling callhook again) */
207 } 220 }
208 } 221 }
222 if (callhook) /* same hook that was used at entry */
223 luaD_callHook(L, NULL, callhook, 1); /* `return' hook */
209 /* adjust the number of results */ 224 /* adjust the number of results */
210 if (nResults == MULT_RET) 225 if (nResults == MULT_RET)
211 nResults = L->top - firstResult; 226 nResults = L->top - firstResult;