mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Also do some cleanup in ExecutionState. Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
117 lines
3.8 KiB
C++
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;
|
|
}
|
|
}
|