Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 18 additions & 42 deletions the-tiny-lua-compiler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3741,6 +3741,10 @@ function VirtualMachine:getLength(...)
return select("#", ...)
end

local function pack(...)
return select("#", ...), { ... }
end

function VirtualMachine:pushClosure(closure)
closure = {
nupvalues = closure.nupvalues or 0,
Expand Down Expand Up @@ -3785,8 +3789,7 @@ function VirtualMachine:executeClosure(...)
stack[paramIdx - 1] = params[paramIdx]
end
if isVararg then
vararg = { select(numparams + 1, ...) }
varargLen = self:getLength(unpack(vararg))
varargLen, vararg = pack(select(numparams + 1, ...))
stack[numparams] = vararg -- Implicit "arg" argument.
end

Expand Down Expand Up @@ -4009,48 +4012,28 @@ function VirtualMachine:executeClosure(...)
-- Call a closure (function) with arguments and handle returns.
elseif opcode == "CALL" then
local func = stack[a]
local args = {}
local nArgs
if b ~= USE_CURRENT_TOP then
nArgs = b - 1
for index = 1, nArgs do
table.insert(args, stack[a + index])
end
else
nArgs = top - (a + 1)
for index = a + 1, top - 1 do
table.insert(args, stack[index])
end
top = a + b
end

local returns = { func(unpack(args)) }
local nReturns, returns = pack(func(unpack(stack, a + 1, top - 1)))

if c ~= USE_CURRENT_TOP then
for index = 0, c - 2 do
stack[a + index] = returns[index + 1]
end
nReturns = c - 1
else
-- Multi-return: push all results onto the stack.
local nReturns = self:getLength(unpack(returns))
top = a + nReturns
for index = 1, nReturns do
stack[a + index - 1] = returns[index]
end
end
for index = 1, nReturns do
stack[a + index - 1] = returns[index]
end

-- OP_TAILCALL [A, B, C] return R(A)(R(A+1), ... ,R(A+B-1))
-- Perform a tail call to a closure (function).
elseif opcode == "TAILCALL" then
local func = stack[a]
local args = {}
if b ~= USE_CURRENT_TOP then
for reg = a + 1, a + b - 1 do
table.insert(args, stack[reg])
end
else
for reg = a + 1, a + top do
table.insert(args, stack[reg])
end
top = a + b
end

-- Continuation of original implementation:
Expand All @@ -4067,23 +4050,16 @@ function VirtualMachine:executeClosure(...)
-- Since TAILCALL always comes before RETURN,
-- we can just return the function call results directly.

return func(unpack(args))
return func(unpack(stack, a + 1, top - 1))

-- OP_RETURN [A, B] return R(A), ... ,R(A+B-2)
-- Return values from function call.
elseif opcode == "RETURN" then
local returns = {}
if b == USE_CURRENT_TOP then
for reg = a, top do
table.insert(returns, stack[reg])
end
else
for reg = a, a + b - 2 do
table.insert(returns, stack[reg])
end
if b ~= USE_CURRENT_TOP then
top = a + b - 1
end

return unpack(returns)
return unpack(stack, a, top - 1)

-- OP_FORLOOP [A, sBx] R(A)+=R(A+2)
-- if R(A) <?= R(A+1) then { pc+=sBx R(A+3)=R(A) }
Expand Down Expand Up @@ -4250,10 +4226,10 @@ function VirtualMachine:executeClosure(...)
-- of code.
stack[a] = function(...)
self:pushClosure(tClosure)
local returns = { self:executeClosure(...) }
local nReturns, returns = pack(self:executeClosure(...))
self:pushClosure(closure)

return unpack(returns)
return unpack(returns, 1, nReturns)
end

-- OP_VARARG [A, B] R(A), R(A+1), ..., R(A+B-1) = vararg
Expand Down