escargot/src/runtime/ExecutionState.cpp
Zoltan Herczeg ebcd331fd8 Move m_generatorTarget into ExecutionStateRareData. (#293)
Also do some cleanup in ExecutionState.

Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
2019-07-01 16:42:46 +09:00

117 lines
3.8 KiB
C++

/*
* Copyright (c) 2016-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 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 "ExecutionState.h"
#include "Context.h"
#include "Environment.h"
#include "EnvironmentRecord.h"
#include "FunctionObject.h"
namespace Escargot {
void ExecutionState::throwException(const Value& e)
{
context()->throwException(*this, e);
}
ExecutionStateRareData* ExecutionState::ensureRareData()
{
if (m_parent & 1) {
ExecutionState* p = parent();
m_rareData = new ExecutionStateRareData();
m_rareData->m_parent = p;
}
return rareData();
}
FunctionObject* ExecutionState::resolveCallee()
{
LexicalEnvironment* env = m_lexicalEnvironment;
while (env != nullptr) {
if (env->record()->isDeclarativeEnvironmentRecord() && env->record()->asDeclarativeEnvironmentRecord()->isFunctionEnvironmentRecord()) {
return env->record()->asDeclarativeEnvironmentRecord()->asFunctionEnvironmentRecord()->functionObject();
}
env = env->outerEnvironment();
}
return nullptr;
}
Value ExecutionState::getNewTarget()
{
EnvironmentRecord* envRec = getThisEnvironment();
ASSERT(envRec->isDeclarativeEnvironmentRecord() && envRec->asDeclarativeEnvironmentRecord()->isFunctionEnvironmentRecord());
FunctionEnvironmentRecord* funcEnvRec = envRec->asDeclarativeEnvironmentRecord()->asFunctionEnvironmentRecord();
return funcEnvRec->newTarget() ? funcEnvRec->newTarget() : Value();
}
EnvironmentRecord* ExecutionState::getThisEnvironment()
{
LexicalEnvironment* lex = m_lexicalEnvironment;
LexicalEnvironment* prevLex = nullptr;
while (true) {
EnvironmentRecord* envRec = lex->record();
if (envRec->hasThisBinding()) {
return envRec;
}
lex = lex->outerEnvironment();
}
}
Value ExecutionState::makeSuperPropertyReference(ExecutionState& state)
{
EnvironmentRecord* envRec = getThisEnvironment();
if (!envRec->hasSuperBinding()) {
ErrorObject::throwBuiltinError(state, ErrorObject::Code::ReferenceError, errorMessage_No_Super_Binding);
}
ASSERT(envRec->isDeclarativeEnvironmentRecord() && envRec->asDeclarativeEnvironmentRecord()->isFunctionEnvironmentRecord());
FunctionEnvironmentRecord* funcEnvRec = envRec->asDeclarativeEnvironmentRecord()->asFunctionEnvironmentRecord();
Value bv = funcEnvRec->getSuperBase(state).toObject(state);
return bv;
}
Value ExecutionState::getSuperConstructor(ExecutionState& state)
{
EnvironmentRecord* envRec = getThisEnvironment();
ASSERT(envRec->isDeclarativeEnvironmentRecord() && envRec->asDeclarativeEnvironmentRecord()->isFunctionEnvironmentRecord());
FunctionEnvironmentRecord* funcEnvRec = envRec->asDeclarativeEnvironmentRecord()->asFunctionEnvironmentRecord();
Value activeFunction = funcEnvRec->functionObject() ? funcEnvRec->functionObject() : Value();
Value superConstructor = activeFunction.asObject()->getPrototype(state);
if (superConstructor.isConstructor() == false) {
ErrorObject::throwBuiltinError(state, ErrorObject::Code::TypeError, errorMessage_No_Super_Binding);
}
return superConstructor;
}
}