mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Update to support new.target with Class and eval (#489)
* Pass more tests Signed-off-by: Boram Bae <boram21.bae@samsung.com>
This commit is contained in:
parent
015836c721
commit
f11752b532
9 changed files with 53 additions and 21 deletions
|
|
@ -102,7 +102,7 @@ void ByteCodeBlock::fillLocDataIfNeeded(Context* c)
|
|||
ByteCodeBlock* block;
|
||||
// TODO give correct stack limit to parser
|
||||
if (m_codeBlock->asInterpretedCodeBlock()->isGlobalScopeCodeBlock()) {
|
||||
ProgramNode* nd = esprima::parseProgram(c, m_codeBlock->asInterpretedCodeBlock()->src(), m_codeBlock->script()->isModule(), m_codeBlock->asInterpretedCodeBlock()->isStrict(), m_codeBlock->inWith(), SIZE_MAX, false, false);
|
||||
ProgramNode* nd = esprima::parseProgram(c, m_codeBlock->asInterpretedCodeBlock()->src(), m_codeBlock->script()->isModule(), m_codeBlock->asInterpretedCodeBlock()->isStrict(), m_codeBlock->inWith(), SIZE_MAX, false, false, false);
|
||||
block = ByteCodeGenerator::generateByteCode(c, m_codeBlock->asInterpretedCodeBlock(), nd, nd->scopeContext(), m_isEvalMode, m_isOnGlobal, false, true);
|
||||
} else {
|
||||
ASTFunctionScopeContext* scopeContext = nullptr;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#include "parser/ScriptParser.h"
|
||||
#include "parser/ast/AST.h"
|
||||
#include "parser/CodeBlock.h"
|
||||
#include "runtime/Environment.h"
|
||||
#include "runtime/EnvironmentRecord.h"
|
||||
|
||||
namespace Escargot {
|
||||
|
||||
|
|
@ -202,7 +204,7 @@ void ScriptParser::generateCodeBlockTreeFromASTWalkerPostProcess(InterpretedCode
|
|||
cb->m_astContext = nullptr;
|
||||
}
|
||||
|
||||
ScriptParser::InitializeScriptResult ScriptParser::initializeScript(StringView scriptSource, String* fileName, bool isModule, InterpretedCodeBlock* parentCodeBlock, bool strictFromOutside, bool isEvalCodeInFunction, bool isEvalMode, bool inWithOperation, size_t stackSizeRemain, bool needByteCodeGeneration, bool allowSuperCall, bool allowSuperProperty)
|
||||
ScriptParser::InitializeScriptResult ScriptParser::initializeScript(StringView scriptSource, String* fileName, bool isModule, InterpretedCodeBlock* parentCodeBlock, bool strictFromOutside, bool isEvalCodeInFunction, bool isEvalMode, bool inWithOperation, size_t stackSizeRemain, bool needByteCodeGeneration, bool allowSuperCall, bool allowSuperProperty, bool allowNewTarget)
|
||||
{
|
||||
GC_disable();
|
||||
|
||||
|
|
@ -213,7 +215,7 @@ ScriptParser::InitializeScriptResult ScriptParser::initializeScript(StringView s
|
|||
// Parsing
|
||||
try {
|
||||
InterpretedCodeBlock* topCodeBlock = nullptr;
|
||||
ProgramNode* programNode = esprima::parseProgram(m_context, scriptSource, isModule, strictFromOutside, inWith, stackSizeRemain, allowSC, allowSP);
|
||||
ProgramNode* programNode = esprima::parseProgram(m_context, scriptSource, isModule, strictFromOutside, inWith, stackSizeRemain, allowSC, allowSP, allowNewTarget);
|
||||
|
||||
Script* script = new Script(fileName, new StringView(scriptSource), programNode->moduleData(), !parentCodeBlock);
|
||||
if (parentCodeBlock) {
|
||||
|
|
|
|||
|
|
@ -58,10 +58,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
InitializeScriptResult initializeScript(StringView scriptSource, String* fileName, bool isModule, InterpretedCodeBlock* parentCodeBlock, bool strictFromOutside, bool isEvalCodeInFunction, bool isEvalMode, bool inWithOperation, size_t stackSizeRemain, bool needByteCodeGeneration, bool allowSuperCall, bool allowSuperProperty);
|
||||
InitializeScriptResult initializeScript(StringView scriptSource, String* fileName, bool isModule, InterpretedCodeBlock* parentCodeBlock, bool strictFromOutside, bool isEvalCodeInFunction, bool isEvalMode, bool inWithOperation, size_t stackSizeRemain, bool needByteCodeGeneration, bool allowSuperCall, bool allowSuperProperty, bool allowNewTarget);
|
||||
InitializeScriptResult initializeScript(String* scriptSource, String* fileName, bool isModule, bool strictFromOutside = false, bool isRunningEvalOnFunction = false, bool isEvalMode = false, size_t stackSizeRemain = SIZE_MAX)
|
||||
{
|
||||
return initializeScript(StringView(scriptSource, 0, scriptSource->length()), fileName, isModule, nullptr, strictFromOutside, isRunningEvalOnFunction, isEvalMode, false, stackSizeRemain, true, false, false);
|
||||
return initializeScript(StringView(scriptSource, 0, scriptSource->length()), fileName, isModule, nullptr, strictFromOutside, isRunningEvalOnFunction, isEvalMode, false, stackSizeRemain, true, false, false, false);
|
||||
}
|
||||
|
||||
void generateFunctionByteCode(ExecutionState& state, InterpretedCodeBlock* codeBlock, size_t stackSizeRemain);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ struct Context {
|
|||
bool allowLexicalDeclaration : 1;
|
||||
bool allowSuperCall : 1;
|
||||
bool allowSuperProperty : 1;
|
||||
bool allowNewTarget : 1;
|
||||
bool isAssignmentTarget : 1;
|
||||
bool isBindingElement : 1;
|
||||
bool inFunctionBody : 1;
|
||||
|
|
@ -221,6 +222,7 @@ public:
|
|||
this->context->allowLexicalDeclaration = false;
|
||||
this->context->allowSuperCall = false;
|
||||
this->context->allowSuperProperty = false;
|
||||
this->context->allowNewTarget = false;
|
||||
this->context->isAssignmentTarget = true;
|
||||
this->context->isBindingElement = true;
|
||||
this->context->inFunctionBody = false;
|
||||
|
|
@ -1398,11 +1400,13 @@ public:
|
|||
const bool previousAllowYield = this->context->allowYield;
|
||||
const bool previousAllowSuperCall = this->context->allowSuperCall;
|
||||
const bool previousAllowSuperProperty = this->context->allowSuperProperty;
|
||||
const bool previousAllowNewTarget = this->context->allowNewTarget;
|
||||
const bool previousInArrowFunction = this->context->inArrowFunction;
|
||||
|
||||
this->context->allowYield = true;
|
||||
this->context->inArrowFunction = false;
|
||||
this->context->allowSuperProperty = true;
|
||||
this->context->allowNewTarget = true;
|
||||
|
||||
if (allowSuperCall) {
|
||||
this->context->allowSuperCall = true;
|
||||
|
|
@ -1419,6 +1423,7 @@ public:
|
|||
this->context->allowYield = previousAllowYield;
|
||||
this->context->inArrowFunction = previousInArrowFunction;
|
||||
this->context->allowSuperProperty = previousAllowSuperProperty;
|
||||
this->context->allowNewTarget = previousAllowNewTarget;
|
||||
this->context->allowSuperCall = previousAllowSuperCall;
|
||||
|
||||
this->currentScopeContext->m_paramsStartLOC.index = node.index;
|
||||
|
|
@ -1886,7 +1891,7 @@ public:
|
|||
|
||||
if (this->match(Period)) {
|
||||
this->nextToken();
|
||||
if (this->lookahead.type == Token::IdentifierToken && this->context->inFunctionBody && this->lookahead.relatedSource(this->scanner->source) == "target") {
|
||||
if (this->lookahead.type == Token::IdentifierToken && this->context->allowNewTarget && this->lookahead.relatedSource(this->scanner->source) == "target") {
|
||||
this->nextToken();
|
||||
this->currentScopeContext->m_hasSuperOrNewTarget = true;
|
||||
MetaNode node = this->createNode();
|
||||
|
|
@ -4157,8 +4162,11 @@ public:
|
|||
|
||||
bool previousAllowYield = this->context->allowYield;
|
||||
bool previousInArrowFunction = this->context->inArrowFunction;
|
||||
bool previousAllowNewTarget = this->context->allowNewTarget;
|
||||
|
||||
this->context->allowYield = !isGenerator;
|
||||
this->context->inArrowFunction = false;
|
||||
this->context->allowNewTarget = true;
|
||||
|
||||
ParseFormalParametersResult formalParameters;
|
||||
this->parseFormalParameters(newBuilder, formalParameters, &firstRestricted);
|
||||
|
|
@ -4180,6 +4188,7 @@ public:
|
|||
this->context->strict = previousStrict;
|
||||
this->context->allowYield = previousAllowYield;
|
||||
this->context->inArrowFunction = previousInArrowFunction;
|
||||
this->context->allowNewTarget = previousAllowNewTarget;
|
||||
|
||||
this->currentScopeContext->m_nodeType = ASTNodeType::FunctionDeclaration;
|
||||
this->currentScopeContext->m_isGenerator = isGenerator;
|
||||
|
|
@ -4205,8 +4214,11 @@ public:
|
|||
|
||||
bool previousAllowYield = this->context->allowYield;
|
||||
bool previousInArrowFunction = this->context->inArrowFunction;
|
||||
bool previousAllowNewTarget = this->context->allowNewTarget;
|
||||
|
||||
this->context->allowYield = !isGenerator;
|
||||
this->context->inArrowFunction = false;
|
||||
this->context->allowNewTarget = true;
|
||||
|
||||
if (!this->match(LeftParenthesis)) {
|
||||
ALLOC_TOKEN(token);
|
||||
|
|
@ -4269,6 +4281,7 @@ public:
|
|||
this->context->strict = previousStrict;
|
||||
this->context->allowYield = previousAllowYield;
|
||||
this->context->inArrowFunction = previousInArrowFunction;
|
||||
this->context->allowNewTarget = previousAllowNewTarget;
|
||||
|
||||
this->currentScopeContext->m_nodeType = ASTNodeType::FunctionExpression;
|
||||
this->currentScopeContext->m_isGenerator = isGenerator;
|
||||
|
|
@ -4354,10 +4367,12 @@ public:
|
|||
const bool previousAllowYield = this->context->allowYield;
|
||||
const bool previousInArrowFunction = this->context->inArrowFunction;
|
||||
const bool previousAllowSuperProperty = this->context->allowSuperProperty;
|
||||
const bool previousAllowNewTarget = this->context->allowNewTarget;
|
||||
|
||||
this->context->allowYield = true;
|
||||
this->context->inArrowFunction = false;
|
||||
this->context->allowSuperProperty = true;
|
||||
this->context->allowNewTarget = true;
|
||||
|
||||
this->expect(LeftParenthesis);
|
||||
this->expect(RightParenthesis);
|
||||
|
|
@ -4371,6 +4386,7 @@ public:
|
|||
this->context->allowYield = previousAllowYield;
|
||||
this->context->inArrowFunction = previousInArrowFunction;
|
||||
this->context->allowSuperProperty = previousAllowSuperProperty;
|
||||
this->context->allowNewTarget = previousAllowNewTarget;
|
||||
|
||||
this->currentScopeContext->m_paramsStartLOC.index = node.index;
|
||||
this->currentScopeContext->m_paramsStartLOC.column = node.column;
|
||||
|
|
@ -4398,10 +4414,12 @@ public:
|
|||
const bool previousAllowYield = this->context->allowYield;
|
||||
const bool previousInArrowFunction = this->context->inArrowFunction;
|
||||
const bool previousAllowSuperProperty = this->context->allowSuperProperty;
|
||||
const bool previousAllowNewTarget = this->context->allowNewTarget;
|
||||
|
||||
this->context->allowYield = true;
|
||||
this->context->allowSuperProperty = true;
|
||||
this->context->inArrowFunction = false;
|
||||
this->context->allowNewTarget = true;
|
||||
|
||||
this->expect(LeftParenthesis);
|
||||
|
||||
|
|
@ -4420,6 +4438,7 @@ public:
|
|||
this->context->allowYield = previousAllowYield;
|
||||
this->context->allowSuperProperty = previousAllowSuperProperty;
|
||||
this->context->inArrowFunction = previousInArrowFunction;
|
||||
this->context->allowNewTarget = previousAllowNewTarget;
|
||||
|
||||
this->currentScopeContext->m_paramsStartLOC.index = node.index;
|
||||
this->currentScopeContext->m_paramsStartLOC.column = node.column;
|
||||
|
|
@ -4447,10 +4466,12 @@ public:
|
|||
const bool previousAllowYield = this->context->allowYield;
|
||||
const bool previousInArrowFunction = this->context->inArrowFunction;
|
||||
const bool previousAllowSuperProperty = this->context->allowSuperProperty;
|
||||
const bool previousAllowNewTarget = this->context->allowNewTarget;
|
||||
|
||||
this->context->allowYield = false;
|
||||
this->context->allowSuperProperty = true;
|
||||
this->context->inArrowFunction = false;
|
||||
this->context->allowNewTarget = true;
|
||||
|
||||
this->expect(LeftParenthesis);
|
||||
|
||||
|
|
@ -4464,6 +4485,7 @@ public:
|
|||
this->context->allowYield = previousAllowYield;
|
||||
this->context->allowSuperProperty = previousAllowSuperProperty;
|
||||
this->context->inArrowFunction = previousInArrowFunction;
|
||||
this->context->allowNewTarget = previousAllowNewTarget;
|
||||
|
||||
this->currentScopeContext->m_paramsStartLOC.index = node.index;
|
||||
this->currentScopeContext->m_paramsStartLOC.column = node.column;
|
||||
|
|
@ -5198,10 +5220,15 @@ public:
|
|||
{
|
||||
ASSERT(this->isParsingSingleFunction);
|
||||
|
||||
const bool previousAllowNewTarget = context->allowNewTarget;
|
||||
|
||||
context->allowNewTarget = true;
|
||||
MetaNode node = this->createNode();
|
||||
StatementContainer* params = this->parseFunctionParameters(builder);
|
||||
BlockStatementNode* body = this->parseFunctionBody(builder);
|
||||
|
||||
context->allowNewTarget = previousAllowNewTarget;
|
||||
|
||||
return this->finalize(node, builder.createFunctionNode(params, body, std::move(this->numeralLiteralVector)));
|
||||
}
|
||||
|
||||
|
|
@ -5276,7 +5303,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isModule, bool strictFromOutside, bool inWith, size_t stackRemain, bool allowSuperCallOutside, bool allowSuperPropertyOutside)
|
||||
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isModule, bool strictFromOutside, bool inWith, size_t stackRemain, bool allowSuperCallFromOutside, bool allowSuperPropertyFromOutside, bool allowNewTargetFromOutside)
|
||||
{
|
||||
// GC should be disabled during the parsing process
|
||||
ASSERT(GC_is_disabled());
|
||||
|
|
@ -5287,8 +5314,9 @@ ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isMo
|
|||
|
||||
parser.context->strict = strictFromOutside;
|
||||
parser.context->inWith = inWith;
|
||||
parser.context->allowSuperCall = allowSuperCallOutside;
|
||||
parser.context->allowSuperProperty = allowSuperPropertyOutside;
|
||||
parser.context->allowSuperCall = allowSuperCallFromOutside;
|
||||
parser.context->allowSuperProperty = allowSuperPropertyFromOutside;
|
||||
parser.context->allowNewTarget = allowNewTargetFromOutside;
|
||||
|
||||
ProgramNode* nd = parser.parseProgram(builder);
|
||||
return nd;
|
||||
|
|
@ -5307,8 +5335,8 @@ FunctionNode* parseSingleFunction(::Escargot::Context* ctx, InterpretedCodeBlock
|
|||
parser.context->allowLexicalDeclaration = true;
|
||||
parser.context->allowSuperCall = true;
|
||||
parser.context->allowSuperProperty = true;
|
||||
parser.context->allowNewTarget = true;
|
||||
parser.isParsingSingleFunction = true;
|
||||
|
||||
parser.codeBlock = codeBlock;
|
||||
|
||||
scopeContext = new (ctx->astAllocator()) ASTFunctionScopeContext(ctx->astAllocator(), codeBlock->isStrict());
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ struct Error : public gc {
|
|||
|
||||
#define ESPRIMA_RECURSIVE_LIMIT 1024
|
||||
|
||||
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isModule, bool strictFromOutside, bool inWith, size_t stackRemain, bool allowSuperCallOutside, bool allowSuperPropertyOutside);
|
||||
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isModule, bool strictFromOutside, bool inWith, size_t stackRemain, bool allowSuperCallFromOutside, bool allowSuperPropertyFromOutside, bool allowNewTargetFromOutside);
|
||||
FunctionNode* parseSingleFunction(::Escargot::Context* ctx, InterpretedCodeBlock* codeBlock, ASTFunctionScopeContext*& scopeContext, size_t stackRemain);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ FunctionObject::FunctionSource FunctionObject::createFunctionSourceFromScriptSou
|
|||
try {
|
||||
srcToTest.appendString(") { }");
|
||||
String* cur = srcToTest.finalize(&state);
|
||||
esprima::parseProgram(state.context(), StringView(cur, 0, cur->length()), false, false, false, SIZE_MAX, false, false);
|
||||
esprima::parseProgram(state.context(), StringView(cur, 0, cur->length()), false, false, false, SIZE_MAX, false, false, true);
|
||||
|
||||
// reset ASTAllocator
|
||||
state.context()->astAllocator().reset();
|
||||
|
|
@ -151,7 +151,7 @@ FunctionObject::FunctionSource FunctionObject::createFunctionSourceFromScriptSou
|
|||
ScriptParser parser(state.context());
|
||||
String* scriptSource = src.finalize(&state);
|
||||
|
||||
Script* script = parser.initializeScript(StringView(scriptSource, 0, scriptSource->length()), new ASCIIString("Function Constructor input"), false, nullptr, false, false, false, false, SIZE_MAX, false, allowSuperCall, false).scriptThrowsExceptionIfParseError(state);
|
||||
Script* script = parser.initializeScript(StringView(scriptSource, 0, scriptSource->length()), new ASCIIString("Function Constructor input"), false, nullptr, false, false, false, false, SIZE_MAX, false, allowSuperCall, false, true).scriptThrowsExceptionIfParseError(state);
|
||||
InterpretedCodeBlock* cb = script->topCodeBlock()->firstChild();
|
||||
cb->updateSourceElementStart(3, 1);
|
||||
LexicalEnvironment* globalEnvironment = new LexicalEnvironment(new GlobalEnvironmentRecord(state, script->topCodeBlock(), state.context()->globalObject(), &state.context()->globalDeclarativeRecord(), &state.context()->globalDeclarativeStorage()), nullptr);
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ Value GlobalObject::eval(ExecutionState& state, const Value& arg)
|
|||
#else
|
||||
size_t stackRemainApprox = STACK_LIMIT_FROM_BASE - (currentStackBase - state.stackBase());
|
||||
#endif
|
||||
Script* script = parser.initializeScript(StringView(arg.asString(), 0, arg.asString()->length()), String::fromUTF8(s, strlen(s)), false, nullptr, strictFromOutside, false, true, false, stackRemainApprox, true, false, false).scriptThrowsExceptionIfParseError(state);
|
||||
Script* script = parser.initializeScript(StringView(arg.asString(), 0, arg.asString()->length()), String::fromUTF8(s, strlen(s)), false, nullptr, strictFromOutside, false, true, false, stackRemainApprox, true, false, false, false).scriptThrowsExceptionIfParseError(state);
|
||||
// In case of indirect call, use global execution context
|
||||
ExecutionState stateForNewGlobal(m_context);
|
||||
return script->execute(stateForNewGlobal, true, script->topCodeBlock()->isStrict());
|
||||
|
|
@ -192,6 +192,12 @@ Value GlobalObject::evalLocal(ExecutionState& state, const Value& arg, Value thi
|
|||
current = current->parent();
|
||||
}
|
||||
|
||||
bool allowNewTarget = false;
|
||||
auto thisEnvironment = state.getThisEnvironment();
|
||||
if (thisEnvironment->isDeclarativeEnvironmentRecord() && thisEnvironment->asDeclarativeEnvironmentRecord()->isFunctionEnvironmentRecord()) {
|
||||
allowNewTarget = true;
|
||||
}
|
||||
|
||||
volatile int sp;
|
||||
size_t currentStackBase = (size_t)&sp;
|
||||
#ifdef STACK_GROWS_DOWN
|
||||
|
|
@ -200,7 +206,7 @@ Value GlobalObject::evalLocal(ExecutionState& state, const Value& arg, Value thi
|
|||
size_t stackRemainApprox = STACK_LIMIT_FROM_BASE - (currentStackBase - state.stackBase());
|
||||
#endif
|
||||
|
||||
Script* script = parser.initializeScript(StringView(arg.asString(), 0, arg.asString()->length()), String::fromUTF8(s, sizeof(s) - 1), false, parentCodeBlock, strictFromOutside, isRunningEvalOnFunction, true, inWithOperation, stackRemainApprox, true, parentCodeBlock->allowSuperCall(), parentCodeBlock->allowSuperProperty()).scriptThrowsExceptionIfParseError(state);
|
||||
Script* script = parser.initializeScript(StringView(arg.asString(), 0, arg.asString()->length()), String::fromUTF8(s, sizeof(s) - 1), false, parentCodeBlock, strictFromOutside, isRunningEvalOnFunction, true, inWithOperation, stackRemainApprox, true, parentCodeBlock->allowSuperCall(), parentCodeBlock->allowSuperProperty(), allowNewTarget).scriptThrowsExceptionIfParseError(state);
|
||||
return script->executeLocal(state, thisValue, parentCodeBlock, script->topCodeBlock()->isStrict(), isRunningEvalOnFunction);
|
||||
}
|
||||
return arg;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 36bf26ba45e4f87651ab2bdce1122ad5730f07b0
|
||||
Subproject commit 35e1a26902b029c0dc60673644268f6935d15859
|
||||
|
|
@ -49,6 +49,7 @@ non262/BigInt/decimal.js
|
|||
non262/BigInt/large-bit-length.js
|
||||
non262/BigInt/mod.js
|
||||
non262/BigInt/Number-conversion-rounding.js
|
||||
non262/class/newTargetDVG.js
|
||||
|
||||
# These tests include features of ES7
|
||||
non262/Array/slice-sparse-with-large-index.js
|
||||
|
|
@ -59,11 +60,6 @@ non262/arrow-functions/arrow-not-as-end-of-statement.js
|
|||
# TODO
|
||||
non262/arrow-functions/yield-in-arrow.js
|
||||
non262/class/className.js
|
||||
non262/class/newTargetArrow.js
|
||||
non262/class/newTargetDefaults.js
|
||||
non262/class/newTargetDVG.js
|
||||
non262/class/newTargetEval.js
|
||||
non262/class/newTargetGenerators.js
|
||||
non262/class/outerBinding.js
|
||||
non262/class/strictExecution.js
|
||||
non262/class/superCallBaseInvoked.js
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue