diff options
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 73 |
1 files changed, 44 insertions, 29 deletions
@@ -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 | ||
101 | void luaD_lineHook (lua_State *L, int line) { | 101 | void 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 | ||
111 | void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, | 115 | static 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 | */ |
180 | void luaD_call (lua_State *L, StkId func, int nResults) { | 189 | void 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; |