aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lvm.c3
-rw-r--r--testes/calls.lua25
2 files changed, 26 insertions, 2 deletions
diff --git a/lvm.c b/lvm.c
index 5407d144..2c96c58d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1549,9 +1549,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1549 luaF_close(L, base, NOCLOSINGMETH); 1549 luaF_close(L, base, NOCLOSINGMETH);
1550 lua_assert(base == ci->func + 1); 1550 lua_assert(base == ci->func + 1);
1551 } 1551 }
1552 if (!ttisfunction(s2v(ra))) { /* not a function? */ 1552 while (!ttisfunction(s2v(ra))) { /* not a function? */
1553 luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ 1553 luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
1554 b++; /* there is now one extra argument */ 1554 b++; /* there is now one extra argument */
1555 checkstackp(L, 1, ra);
1555 } 1556 }
1556 if (!ttisLclosure(s2v(ra))) { /* C function? */ 1557 if (!ttisLclosure(s2v(ra))) { /* C function? */
1557 luaD_call(L, ra, LUA_MULTRET); /* call it */ 1558 luaD_call(L, ra, LUA_MULTRET); /* call it */
diff --git a/testes/calls.lua b/testes/calls.lua
index 739a624f..0141ffa4 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -107,7 +107,9 @@ end
107deep(10) 107deep(10)
108deep(180) 108deep(180)
109 109
110-- testing tail calls 110
111print"testing tail calls"
112
111function deep (n) if n>0 then return deep(n-1) else return 101 end end 113function deep (n) if n>0 then return deep(n-1) else return 101 end end
112assert(deep(30000) == 101) 114assert(deep(30000) == 101)
113a = {} 115a = {}
@@ -148,6 +150,27 @@ do -- tail calls x varargs
148 assert(X == 10 and Y == 20 and #A == 1 and A[1] == 30) 150 assert(X == 10 and Y == 20 and #A == 1 and A[1] == 30)
149end 151end
150 152
153
154
155do -- tail calls x chain of __call
156 local n = 10000 -- depth
157
158 local function foo ()
159 if n == 0 then return 1023
160 else n = n - 1; return foo()
161 end
162 end
163
164 -- build a chain of __call metamethods ending in function 'foo'
165 for i = 1, 100 do
166 foo = setmetatable({}, {__call = foo})
167 end
168
169 -- call the first one as a tail call in a new coroutine
170 -- (to ensure stack is not preallocated)
171 assert(coroutine.wrap(function() return foo() end)() == 1023)
172end
173
151print('+') 174print('+')
152 175
153 176