escargot/src/runtime/ScriptGeneratorFunctionObject.cpp
HyukWoo Park 9f93022d78 Unlink circular dependency between runtime and parser source codes
Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
2023-03-28 16:17:00 +09:00

84 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2019-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "Escargot.h"
#include "ScriptGeneratorFunctionObject.h"
#include "runtime/Context.h"
#include "runtime/FunctionObjectInlines.h"
namespace Escargot {
Object* ScriptGeneratorFunctionObject::createFunctionPrototypeObject(ExecutionState& state)
{
Object* prototype = new PrototypeObject(state, m_codeBlock->context()->globalObject()->generatorPrototype());
return prototype;
}
class ScriptGeneratorFunctionObjectThisValueBinder {
public:
Value operator()(ExecutionState& callerState, ExecutionState& calleeState, ScriptGeneratorFunctionObject* self, const Value& thisArgument, bool isStrict)
{
Value thisValue = self->thisValue();
if (thisValue.isEmpty()) {
// OrdinaryCallBindThis ( F, calleeContext, thisArgument )
// Let thisMode be the value of Fs [[ThisMode]] internal slot.
// If thisMode is lexical, return NormalCompletion(undefined).
// --> thisMode is always not lexcial because this is class ctor.
// Let calleeRealm be the value of Fs [[Realm]] internal slot.
// Let localEnv be the LexicalEnvironment of calleeContext.
ASSERT(calleeState.context() == self->codeBlock()->context());
if (isStrict) {
// If thisMode is strict, let thisValue be thisArgument.
return thisArgument;
} else {
// Else
// if thisArgument is null or undefined, then
// Let thisValue be calleeRealm.[[globalThis]]
if (thisArgument.isUndefinedOrNull()) {
return calleeState.context()->globalObjectProxy();
} else {
// Else
// Let thisValue be ToObject(thisArgument).
// Assert: thisValue is not an abrupt completion.
// NOTE ToObject produces wrapper objects using calleeRealm.
return thisArgument.toObject(calleeState);
}
}
} else {
ASSERT(self->interpretedCodeBlock()->isArrowFunctionExpression());
return thisValue;
}
}
};
Value ScriptGeneratorFunctionObject::call(ExecutionState& state, const Value& thisValue, const size_t argc, Value* argv)
{
return FunctionObjectProcessCallGenerator::processCall<ScriptGeneratorFunctionObject, false, false, false, ScriptGeneratorFunctionObjectThisValueBinder, FunctionObjectNewTargetBinder, FunctionObjectReturnValueBinder>(state, this, thisValue, argc, argv, nullptr);
}
Value ScriptGeneratorFunctionObject::construct(ExecutionState& state, const size_t argc, Value* argv, Object* newTarget)
{
ExecutionState newState(m_codeBlock->context(), &state,
static_cast<LexicalEnvironment*>(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict());
ErrorObject::throwBuiltinError(newState, ErrorCode::TypeError, "Generator cannot be invoked with 'new'");
ASSERT_NOT_REACHED();
return Value();
}
} // namespace Escargot