aboutsummaryrefslogtreecommitdiff
path: root/ltm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltm.c')
-rw-r--r--ltm.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/ltm.c b/ltm.c
index 5906a2fd..d41ab98d 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.53 2017/12/15 13:07:10 roberto Exp roberto $ 2** $Id: ltm.c,v 2.54 2017/12/19 16:40:17 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -101,12 +101,12 @@ const char *luaT_objtypename (lua_State *L, const TValue *o) {
101 101
102void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 102void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
103 const TValue *p2, const TValue *p3) { 103 const TValue *p2, const TValue *p3) {
104 StkId func = L->top; 104 StkId func = (isLuacode(L->ci)) ? L->ci->top : L->top;
105 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 105 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
106 setobj2s(L, func + 1, p1); /* 1st argument */ 106 setobj2s(L, func + 1, p1); /* 1st argument */
107 setobj2s(L, func + 2, p2); /* 2nd argument */ 107 setobj2s(L, func + 2, p2); /* 2nd argument */
108 setobj2s(L, func + 3, p3); /* 3rd argument */ 108 setobj2s(L, func + 3, p3); /* 3rd argument */
109 L->top += 4; 109 L->top = func + 4;
110 /* metamethod may yield only when called from Lua code */ 110 /* metamethod may yield only when called from Lua code */
111 if (isLuacode(L->ci)) 111 if (isLuacode(L->ci))
112 luaD_call(L, func, 0); 112 luaD_call(L, func, 0);
@@ -115,8 +115,8 @@ void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
115} 115}
116 116
117 117
118void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, 118static void reallycallTMres (lua_State *L, const TValue *f, const TValue *p1,
119 const TValue *p2, StkId res) { 119 const TValue *p2, StkId res) {
120 ptrdiff_t result = savestack(L, res); 120 ptrdiff_t result = savestack(L, res);
121 StkId func = L->top; 121 StkId func = L->top;
122 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 122 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
@@ -129,7 +129,15 @@ void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
129 else 129 else
130 luaD_callnoyield(L, func, 1); 130 luaD_callnoyield(L, func, 1);
131 res = restorestack(L, result); 131 res = restorestack(L, result);
132 setobjs2s(L, res, --L->top); /* more result to its place */ 132 setobjs2s(L, res, --L->top); /* move result to its place */
133}
134
135
136void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
137 const TValue *p2, StkId res) {
138 if (isLuacode(L->ci))
139 L->top = L->ci->top; /* prepare top */
140 reallycallTMres(L, f, p1, p2, res);
133} 141}
134 142
135 143
@@ -139,13 +147,15 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
139 if (ttisnil(tm)) 147 if (ttisnil(tm))
140 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 148 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
141 if (ttisnil(tm)) return 0; 149 if (ttisnil(tm)) return 0;
142 luaT_callTMres(L, tm, p1, p2, res); 150 reallycallTMres(L, tm, p1, p2, res);
143 return 1; 151 return 1;
144} 152}
145 153
146 154
147void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 155void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
148 StkId res, TMS event) { 156 StkId res, TMS event) {
157 if (event != TM_CONCAT && isLuacode(L->ci))
158 L->top = L->ci->top; /* prepare top */
149 if (!callbinTM(L, p1, p2, res, event)) { 159 if (!callbinTM(L, p1, p2, res, event)) {
150 switch (event) { 160 switch (event) {
151 case TM_CONCAT: 161 case TM_CONCAT:
@@ -185,6 +195,8 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, int i2,
185 195
186int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 196int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
187 TMS event) { 197 TMS event) {
198 if (isLuacode(L->ci))
199 L->top = L->ci->top; /* prepare top */
188 if (callbinTM(L, p1, p2, L->top, event)) /* try original event */ 200 if (callbinTM(L, p1, p2, L->top, event)) /* try original event */
189 return !l_isfalse(s2v(L->top)); 201 return !l_isfalse(s2v(L->top));
190 else if (event == TM_LE) { 202 else if (event == TM_LE) {