mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Update TCO to handle tail recursion with non-identical argument counts
Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
This commit is contained in:
parent
e9cec1d0b4
commit
11d9427bb8
2 changed files with 15 additions and 5 deletions
|
|
@ -1540,7 +1540,7 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
TailRecursion* code = (TailRecursion*)programCounter;
|
||||
const Value& callee = registerFile[code->m_calleeIndex];
|
||||
|
||||
if (UNLIKELY((callee != Value(state->resolveCallee())) || (state->m_argc != code->m_argumentCount))) {
|
||||
if (UNLIKELY((callee != Value(state->resolveCallee())) || (state->initTCO() && (state->m_argc != code->m_argumentCount)))) {
|
||||
// goto slow path
|
||||
return InterpreterSlowPath::tailRecursionSlowCase(*state, code, callee, registerFile);
|
||||
}
|
||||
|
|
@ -1548,12 +1548,13 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
// fast tail recursion
|
||||
ASSERT(callee.isPointerValue() && callee.asPointerValue()->isScriptFunctionObject());
|
||||
ASSERT(callee.asPointerValue()->asScriptFunctionObject()->codeBlock() == byteCodeBlock->codeBlock());
|
||||
ASSERT(state->m_argc == code->m_argumentCount);
|
||||
ASSERT(!state->initTCO() || (state->m_argc == code->m_argumentCount));
|
||||
|
||||
if (code->m_argumentCount) {
|
||||
// At the start of tail call, we need to allocate a buffer for arguments
|
||||
// because recursive tail call reuses this buffer
|
||||
if (UNLIKELY(!state->initTCO())) {
|
||||
state->m_argc = code->m_argumentCount;
|
||||
Value* newArgs = ALLOCA(sizeof(Value) * code->m_argumentCount, Value);
|
||||
state->setTCOArguments(newArgs);
|
||||
}
|
||||
|
|
@ -1564,6 +1565,8 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
}
|
||||
}
|
||||
|
||||
state->setInitTCO();
|
||||
|
||||
// set this value
|
||||
registerFile[byteCodeBlock->m_requiredOperandRegisterNumber] = state->inStrictMode() ? Value() : state->context()->globalObjectProxy();
|
||||
|
||||
|
|
@ -1582,7 +1585,7 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
const Value& callee = registerFile[code->m_calleeIndex];
|
||||
const Value& receiver = registerFile[code->m_receiverIndex];
|
||||
|
||||
if (UNLIKELY((callee != Value(state->resolveCallee())) || (state->m_argc != code->m_argumentCount))) {
|
||||
if (UNLIKELY((callee != Value(state->resolveCallee())) || (state->initTCO() && (state->m_argc != code->m_argumentCount)))) {
|
||||
// goto slow path
|
||||
return InterpreterSlowPath::tailRecursionWithReceiverSlowCase(*state, code, callee, receiver, registerFile);
|
||||
}
|
||||
|
|
@ -1590,12 +1593,13 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
// fast tail recursion with receiver
|
||||
ASSERT(callee.isPointerValue() && callee.asPointerValue()->isScriptFunctionObject());
|
||||
ASSERT(callee.asPointerValue()->asScriptFunctionObject()->codeBlock() == byteCodeBlock->codeBlock());
|
||||
ASSERT(state->m_argc == code->m_argumentCount);
|
||||
ASSERT(!state->initTCO() || (state->m_argc == code->m_argumentCount));
|
||||
|
||||
if (code->m_argumentCount) {
|
||||
// At the start of tail call, we need to allocate a buffer for arguments
|
||||
// because recursive tail call reuses this buffer
|
||||
if (UNLIKELY(!state->initTCO())) {
|
||||
state->m_argc = code->m_argumentCount;
|
||||
Value* newArgs = ALLOCA(sizeof(Value) * code->m_argumentCount, Value);
|
||||
state->setTCOArguments(newArgs);
|
||||
}
|
||||
|
|
@ -1606,6 +1610,8 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
}
|
||||
}
|
||||
|
||||
state->setInitTCO();
|
||||
|
||||
// set this value (receiver) // FIXME
|
||||
if (state->inStrictMode()) {
|
||||
registerFile[byteCodeBlock->m_requiredOperandRegisterNumber] = receiver;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue