aboutsummaryrefslogtreecommitdiff
path: root/ltm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-26 14:59:39 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-26 14:59:39 -0300
commitb80077b8f3e27a94c6afa895b41a9f8b52c42e61 (patch)
tree8a7c21ee0acfed553ef1d92bdfd7b1f728f35a91 /ltm.c
parente70f275f32a5339a86be6f8b9d08c20cb874b205 (diff)
downloadlua-b80077b8f3e27a94c6afa895b41a9f8b52c42e61.tar.gz
lua-b80077b8f3e27a94c6afa895b41a9f8b52c42e61.tar.bz2
lua-b80077b8f3e27a94c6afa895b41a9f8b52c42e61.zip
Change in the handling of 'L->top' when calling metamethods
Instead of updating 'L->top' in every place that may call a metamethod, the metamethod functions themselves (luaT_trybinTM and luaT_callorderTM) correct the top. (When calling metamethods from the C API, however, the callers must preserve 'L->top'.)
Diffstat (limited to 'ltm.c')
-rw-r--r--ltm.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/ltm.c b/ltm.c
index 24739444..19233a87 100644
--- a/ltm.c
+++ b/ltm.c
@@ -147,11 +147,9 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
147 147
148void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 148void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
149 StkId res, TMS event) { 149 StkId res, TMS event) {
150 L->top = L->ci->top;
150 if (!callbinTM(L, p1, p2, res, event)) { 151 if (!callbinTM(L, p1, p2, res, event)) {
151 switch (event) { 152 switch (event) {
152 case TM_CONCAT:
153 luaG_concaterror(L, p1, p2);
154 /* call never returns, but to avoid warnings: *//* FALLTHROUGH */
155 case TM_BAND: case TM_BOR: case TM_BXOR: 153 case TM_BAND: case TM_BOR: case TM_BXOR:
156 case TM_SHL: case TM_SHR: case TM_BNOT: { 154 case TM_SHL: case TM_SHR: case TM_BNOT: {
157 if (ttisnumber(p1) && ttisnumber(p2)) 155 if (ttisnumber(p1) && ttisnumber(p2))
@@ -167,6 +165,13 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
167} 165}
168 166
169 167
168void luaT_tryconcatTM (lua_State *L) {
169 StkId top = L->top;
170 if (!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, TM_CONCAT))
171 luaG_concaterror(L, s2v(top - 2), s2v(top - 1));
172}
173
174
170void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, 175void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2,
171 StkId res, int flip, TMS event) { 176 StkId res, int flip, TMS event) {
172 if (flip) 177 if (flip)
@@ -186,6 +191,7 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2,
186 191
187int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 192int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
188 TMS event) { 193 TMS event) {
194 L->top = L->ci->top;
189 if (callbinTM(L, p1, p2, L->top, event)) /* try original event */ 195 if (callbinTM(L, p1, p2, L->top, event)) /* try original event */
190 return !l_isfalse(s2v(L->top)); 196 return !l_isfalse(s2v(L->top));
191#if defined(LUA_COMPAT_LT_LE) 197#if defined(LUA_COMPAT_LT_LE)