diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-26 14:59:39 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-26 14:59:39 -0300 |
| commit | b80077b8f3e27a94c6afa895b41a9f8b52c42e61 (patch) | |
| tree | 8a7c21ee0acfed553ef1d92bdfd7b1f728f35a91 /ltm.c | |
| parent | e70f275f32a5339a86be6f8b9d08c20cb874b205 (diff) | |
| download | lua-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.c | 12 |
1 files changed, 9 insertions, 3 deletions
| @@ -147,11 +147,9 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
| 147 | 147 | ||
| 148 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | 148 | void 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 | ||
| 168 | void 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 | |||
| 170 | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, | 175 | void 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 | ||
| 187 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, | 192 | int 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) |
