Skip to content

Commit

Permalink
Update to support new.target with Class and eval (#489)
Browse files Browse the repository at this point in the history
* Pass more tests

Signed-off-by: Boram Bae <[email protected]>
  • Loading branch information
bbrto21 authored and clover2123 committed Oct 31, 2019
1 parent 015836c commit f11752b
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/interpreter/ByteCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions src/parser/ScriptParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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();

Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions src/parser/ScriptParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ class ScriptParser : public gc {
}
};

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);
Expand Down
38 changes: 33 additions & 5 deletions src/parser/esprima_cpp/esprima.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -221,6 +222,7 @@ class Parser {
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;
Expand Down Expand Up @@ -1398,11 +1400,13 @@ class Parser {
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;
Expand All @@ -1419,6 +1423,7 @@ class Parser {
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;
Expand Down Expand Up @@ -1886,7 +1891,7 @@ class Parser {

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();
Expand Down Expand Up @@ -4157,8 +4162,11 @@ class Parser {

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);
Expand All @@ -4180,6 +4188,7 @@ class Parser {
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;
Expand All @@ -4205,8 +4214,11 @@ class Parser {

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);
Expand Down Expand Up @@ -4269,6 +4281,7 @@ class Parser {
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;
Expand Down Expand Up @@ -4354,10 +4367,12 @@ class Parser {
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);
Expand All @@ -4371,6 +4386,7 @@ class Parser {
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;
Expand Down Expand Up @@ -4398,10 +4414,12 @@ class Parser {
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);

Expand All @@ -4420,6 +4438,7 @@ class Parser {
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;
Expand Down Expand Up @@ -4447,10 +4466,12 @@ class Parser {
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);

Expand All @@ -4464,6 +4485,7 @@ class Parser {
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;
Expand Down Expand Up @@ -5198,10 +5220,15 @@ class Parser {
{
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)));
}

Expand Down Expand Up @@ -5276,7 +5303,7 @@ class Parser {
}
};

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());
Expand All @@ -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;
Expand All @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion src/parser/esprima_cpp/esprima.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/FunctionObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 8 additions & 2 deletions src/runtime/GlobalObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion test/vendortest
6 changes: 1 addition & 5 deletions tools/test/spidermonkey/excludelist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit f11752b

Please sign in to comment.