Skip to content

Commit f11752b

Browse files
bbrto21clover2123
authored andcommitted
Update to support new.target with Class and eval (#489)
* Pass more tests Signed-off-by: Boram Bae <boram21.bae@samsung.com>
1 parent 015836c commit f11752b

File tree

9 files changed

+53
-21
lines changed

9 files changed

+53
-21
lines changed

src/interpreter/ByteCode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void ByteCodeBlock::fillLocDataIfNeeded(Context* c)
102102
ByteCodeBlock* block;
103103
// TODO give correct stack limit to parser
104104
if (m_codeBlock->asInterpretedCodeBlock()->isGlobalScopeCodeBlock()) {
105-
ProgramNode* nd = esprima::parseProgram(c, m_codeBlock->asInterpretedCodeBlock()->src(), m_codeBlock->script()->isModule(), m_codeBlock->asInterpretedCodeBlock()->isStrict(), m_codeBlock->inWith(), SIZE_MAX, false, false);
105+
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);
106106
block = ByteCodeGenerator::generateByteCode(c, m_codeBlock->asInterpretedCodeBlock(), nd, nd->scopeContext(), m_isEvalMode, m_isOnGlobal, false, true);
107107
} else {
108108
ASTFunctionScopeContext* scopeContext = nullptr;

src/parser/ScriptParser.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "parser/ScriptParser.h"
2727
#include "parser/ast/AST.h"
2828
#include "parser/CodeBlock.h"
29+
#include "runtime/Environment.h"
30+
#include "runtime/EnvironmentRecord.h"
2931

3032
namespace Escargot {
3133

@@ -202,7 +204,7 @@ void ScriptParser::generateCodeBlockTreeFromASTWalkerPostProcess(InterpretedCode
202204
cb->m_astContext = nullptr;
203205
}
204206

205-
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)
207+
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)
206208
{
207209
GC_disable();
208210

@@ -213,7 +215,7 @@ ScriptParser::InitializeScriptResult ScriptParser::initializeScript(StringView s
213215
// Parsing
214216
try {
215217
InterpretedCodeBlock* topCodeBlock = nullptr;
216-
ProgramNode* programNode = esprima::parseProgram(m_context, scriptSource, isModule, strictFromOutside, inWith, stackSizeRemain, allowSC, allowSP);
218+
ProgramNode* programNode = esprima::parseProgram(m_context, scriptSource, isModule, strictFromOutside, inWith, stackSizeRemain, allowSC, allowSP, allowNewTarget);
217219

218220
Script* script = new Script(fileName, new StringView(scriptSource), programNode->moduleData(), !parentCodeBlock);
219221
if (parentCodeBlock) {

src/parser/ScriptParser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ class ScriptParser : public gc {
5858
}
5959
};
6060

61-
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);
61+
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);
6262
InitializeScriptResult initializeScript(String* scriptSource, String* fileName, bool isModule, bool strictFromOutside = false, bool isRunningEvalOnFunction = false, bool isEvalMode = false, size_t stackSizeRemain = SIZE_MAX)
6363
{
64-
return initializeScript(StringView(scriptSource, 0, scriptSource->length()), fileName, isModule, nullptr, strictFromOutside, isRunningEvalOnFunction, isEvalMode, false, stackSizeRemain, true, false, false);
64+
return initializeScript(StringView(scriptSource, 0, scriptSource->length()), fileName, isModule, nullptr, strictFromOutside, isRunningEvalOnFunction, isEvalMode, false, stackSizeRemain, true, false, false, false);
6565
}
6666

6767
void generateFunctionByteCode(ExecutionState& state, InterpretedCodeBlock* codeBlock, size_t stackSizeRemain);

src/parser/esprima_cpp/esprima.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct Context {
7676
bool allowLexicalDeclaration : 1;
7777
bool allowSuperCall : 1;
7878
bool allowSuperProperty : 1;
79+
bool allowNewTarget : 1;
7980
bool isAssignmentTarget : 1;
8081
bool isBindingElement : 1;
8182
bool inFunctionBody : 1;
@@ -221,6 +222,7 @@ class Parser {
221222
this->context->allowLexicalDeclaration = false;
222223
this->context->allowSuperCall = false;
223224
this->context->allowSuperProperty = false;
225+
this->context->allowNewTarget = false;
224226
this->context->isAssignmentTarget = true;
225227
this->context->isBindingElement = true;
226228
this->context->inFunctionBody = false;
@@ -1398,11 +1400,13 @@ class Parser {
13981400
const bool previousAllowYield = this->context->allowYield;
13991401
const bool previousAllowSuperCall = this->context->allowSuperCall;
14001402
const bool previousAllowSuperProperty = this->context->allowSuperProperty;
1403+
const bool previousAllowNewTarget = this->context->allowNewTarget;
14011404
const bool previousInArrowFunction = this->context->inArrowFunction;
14021405

14031406
this->context->allowYield = true;
14041407
this->context->inArrowFunction = false;
14051408
this->context->allowSuperProperty = true;
1409+
this->context->allowNewTarget = true;
14061410

14071411
if (allowSuperCall) {
14081412
this->context->allowSuperCall = true;
@@ -1419,6 +1423,7 @@ class Parser {
14191423
this->context->allowYield = previousAllowYield;
14201424
this->context->inArrowFunction = previousInArrowFunction;
14211425
this->context->allowSuperProperty = previousAllowSuperProperty;
1426+
this->context->allowNewTarget = previousAllowNewTarget;
14221427
this->context->allowSuperCall = previousAllowSuperCall;
14231428

14241429
this->currentScopeContext->m_paramsStartLOC.index = node.index;
@@ -1886,7 +1891,7 @@ class Parser {
18861891

18871892
if (this->match(Period)) {
18881893
this->nextToken();
1889-
if (this->lookahead.type == Token::IdentifierToken && this->context->inFunctionBody && this->lookahead.relatedSource(this->scanner->source) == "target") {
1894+
if (this->lookahead.type == Token::IdentifierToken && this->context->allowNewTarget && this->lookahead.relatedSource(this->scanner->source) == "target") {
18901895
this->nextToken();
18911896
this->currentScopeContext->m_hasSuperOrNewTarget = true;
18921897
MetaNode node = this->createNode();
@@ -4157,8 +4162,11 @@ class Parser {
41574162

41584163
bool previousAllowYield = this->context->allowYield;
41594164
bool previousInArrowFunction = this->context->inArrowFunction;
4165+
bool previousAllowNewTarget = this->context->allowNewTarget;
4166+
41604167
this->context->allowYield = !isGenerator;
41614168
this->context->inArrowFunction = false;
4169+
this->context->allowNewTarget = true;
41624170

41634171
ParseFormalParametersResult formalParameters;
41644172
this->parseFormalParameters(newBuilder, formalParameters, &firstRestricted);
@@ -4180,6 +4188,7 @@ class Parser {
41804188
this->context->strict = previousStrict;
41814189
this->context->allowYield = previousAllowYield;
41824190
this->context->inArrowFunction = previousInArrowFunction;
4191+
this->context->allowNewTarget = previousAllowNewTarget;
41834192

41844193
this->currentScopeContext->m_nodeType = ASTNodeType::FunctionDeclaration;
41854194
this->currentScopeContext->m_isGenerator = isGenerator;
@@ -4205,8 +4214,11 @@ class Parser {
42054214

42064215
bool previousAllowYield = this->context->allowYield;
42074216
bool previousInArrowFunction = this->context->inArrowFunction;
4217+
bool previousAllowNewTarget = this->context->allowNewTarget;
4218+
42084219
this->context->allowYield = !isGenerator;
42094220
this->context->inArrowFunction = false;
4221+
this->context->allowNewTarget = true;
42104222

42114223
if (!this->match(LeftParenthesis)) {
42124224
ALLOC_TOKEN(token);
@@ -4269,6 +4281,7 @@ class Parser {
42694281
this->context->strict = previousStrict;
42704282
this->context->allowYield = previousAllowYield;
42714283
this->context->inArrowFunction = previousInArrowFunction;
4284+
this->context->allowNewTarget = previousAllowNewTarget;
42724285

42734286
this->currentScopeContext->m_nodeType = ASTNodeType::FunctionExpression;
42744287
this->currentScopeContext->m_isGenerator = isGenerator;
@@ -4354,10 +4367,12 @@ class Parser {
43544367
const bool previousAllowYield = this->context->allowYield;
43554368
const bool previousInArrowFunction = this->context->inArrowFunction;
43564369
const bool previousAllowSuperProperty = this->context->allowSuperProperty;
4370+
const bool previousAllowNewTarget = this->context->allowNewTarget;
43574371

43584372
this->context->allowYield = true;
43594373
this->context->inArrowFunction = false;
43604374
this->context->allowSuperProperty = true;
4375+
this->context->allowNewTarget = true;
43614376

43624377
this->expect(LeftParenthesis);
43634378
this->expect(RightParenthesis);
@@ -4371,6 +4386,7 @@ class Parser {
43714386
this->context->allowYield = previousAllowYield;
43724387
this->context->inArrowFunction = previousInArrowFunction;
43734388
this->context->allowSuperProperty = previousAllowSuperProperty;
4389+
this->context->allowNewTarget = previousAllowNewTarget;
43744390

43754391
this->currentScopeContext->m_paramsStartLOC.index = node.index;
43764392
this->currentScopeContext->m_paramsStartLOC.column = node.column;
@@ -4398,10 +4414,12 @@ class Parser {
43984414
const bool previousAllowYield = this->context->allowYield;
43994415
const bool previousInArrowFunction = this->context->inArrowFunction;
44004416
const bool previousAllowSuperProperty = this->context->allowSuperProperty;
4417+
const bool previousAllowNewTarget = this->context->allowNewTarget;
44014418

44024419
this->context->allowYield = true;
44034420
this->context->allowSuperProperty = true;
44044421
this->context->inArrowFunction = false;
4422+
this->context->allowNewTarget = true;
44054423

44064424
this->expect(LeftParenthesis);
44074425

@@ -4420,6 +4438,7 @@ class Parser {
44204438
this->context->allowYield = previousAllowYield;
44214439
this->context->allowSuperProperty = previousAllowSuperProperty;
44224440
this->context->inArrowFunction = previousInArrowFunction;
4441+
this->context->allowNewTarget = previousAllowNewTarget;
44234442

44244443
this->currentScopeContext->m_paramsStartLOC.index = node.index;
44254444
this->currentScopeContext->m_paramsStartLOC.column = node.column;
@@ -4447,10 +4466,12 @@ class Parser {
44474466
const bool previousAllowYield = this->context->allowYield;
44484467
const bool previousInArrowFunction = this->context->inArrowFunction;
44494468
const bool previousAllowSuperProperty = this->context->allowSuperProperty;
4469+
const bool previousAllowNewTarget = this->context->allowNewTarget;
44504470

44514471
this->context->allowYield = false;
44524472
this->context->allowSuperProperty = true;
44534473
this->context->inArrowFunction = false;
4474+
this->context->allowNewTarget = true;
44544475

44554476
this->expect(LeftParenthesis);
44564477

@@ -4464,6 +4485,7 @@ class Parser {
44644485
this->context->allowYield = previousAllowYield;
44654486
this->context->allowSuperProperty = previousAllowSuperProperty;
44664487
this->context->inArrowFunction = previousInArrowFunction;
4488+
this->context->allowNewTarget = previousAllowNewTarget;
44674489

44684490
this->currentScopeContext->m_paramsStartLOC.index = node.index;
44694491
this->currentScopeContext->m_paramsStartLOC.column = node.column;
@@ -5198,10 +5220,15 @@ class Parser {
51985220
{
51995221
ASSERT(this->isParsingSingleFunction);
52005222

5223+
const bool previousAllowNewTarget = context->allowNewTarget;
5224+
5225+
context->allowNewTarget = true;
52015226
MetaNode node = this->createNode();
52025227
StatementContainer* params = this->parseFunctionParameters(builder);
52035228
BlockStatementNode* body = this->parseFunctionBody(builder);
52045229

5230+
context->allowNewTarget = previousAllowNewTarget;
5231+
52055232
return this->finalize(node, builder.createFunctionNode(params, body, std::move(this->numeralLiteralVector)));
52065233
}
52075234

@@ -5276,7 +5303,7 @@ class Parser {
52765303
}
52775304
};
52785305

5279-
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isModule, bool strictFromOutside, bool inWith, size_t stackRemain, bool allowSuperCallOutside, bool allowSuperPropertyOutside)
5306+
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isModule, bool strictFromOutside, bool inWith, size_t stackRemain, bool allowSuperCallFromOutside, bool allowSuperPropertyFromOutside, bool allowNewTargetFromOutside)
52805307
{
52815308
// GC should be disabled during the parsing process
52825309
ASSERT(GC_is_disabled());
@@ -5287,8 +5314,9 @@ ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isMo
52875314

52885315
parser.context->strict = strictFromOutside;
52895316
parser.context->inWith = inWith;
5290-
parser.context->allowSuperCall = allowSuperCallOutside;
5291-
parser.context->allowSuperProperty = allowSuperPropertyOutside;
5317+
parser.context->allowSuperCall = allowSuperCallFromOutside;
5318+
parser.context->allowSuperProperty = allowSuperPropertyFromOutside;
5319+
parser.context->allowNewTarget = allowNewTargetFromOutside;
52925320

52935321
ProgramNode* nd = parser.parseProgram(builder);
52945322
return nd;
@@ -5307,8 +5335,8 @@ FunctionNode* parseSingleFunction(::Escargot::Context* ctx, InterpretedCodeBlock
53075335
parser.context->allowLexicalDeclaration = true;
53085336
parser.context->allowSuperCall = true;
53095337
parser.context->allowSuperProperty = true;
5338+
parser.context->allowNewTarget = true;
53105339
parser.isParsingSingleFunction = true;
5311-
53125340
parser.codeBlock = codeBlock;
53135341

53145342
scopeContext = new (ctx->astAllocator()) ASTFunctionScopeContext(ctx->astAllocator(), codeBlock->isStrict());

src/parser/esprima_cpp/esprima.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct Error : public gc {
6161

6262
#define ESPRIMA_RECURSIVE_LIMIT 1024
6363

64-
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isModule, bool strictFromOutside, bool inWith, size_t stackRemain, bool allowSuperCallOutside, bool allowSuperPropertyOutside);
64+
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, bool isModule, bool strictFromOutside, bool inWith, size_t stackRemain, bool allowSuperCallFromOutside, bool allowSuperPropertyFromOutside, bool allowNewTargetFromOutside);
6565
FunctionNode* parseSingleFunction(::Escargot::Context* ctx, InterpretedCodeBlock* codeBlock, ASTFunctionScopeContext*& scopeContext, size_t stackRemain);
6666
}
6767
}

src/runtime/FunctionObject.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ FunctionObject::FunctionSource FunctionObject::createFunctionSourceFromScriptSou
114114
try {
115115
srcToTest.appendString(") { }");
116116
String* cur = srcToTest.finalize(&state);
117-
esprima::parseProgram(state.context(), StringView(cur, 0, cur->length()), false, false, false, SIZE_MAX, false, false);
117+
esprima::parseProgram(state.context(), StringView(cur, 0, cur->length()), false, false, false, SIZE_MAX, false, false, true);
118118

119119
// reset ASTAllocator
120120
state.context()->astAllocator().reset();
@@ -151,7 +151,7 @@ FunctionObject::FunctionSource FunctionObject::createFunctionSourceFromScriptSou
151151
ScriptParser parser(state.context());
152152
String* scriptSource = src.finalize(&state);
153153

154-
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);
154+
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);
155155
InterpretedCodeBlock* cb = script->topCodeBlock()->firstChild();
156156
cb->updateSourceElementStart(3, 1);
157157
LexicalEnvironment* globalEnvironment = new LexicalEnvironment(new GlobalEnvironmentRecord(state, script->topCodeBlock(), state.context()->globalObject(), &state.context()->globalDeclarativeRecord(), &state.context()->globalDeclarativeStorage()), nullptr);

src/runtime/GlobalObject.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ Value GlobalObject::eval(ExecutionState& state, const Value& arg)
156156
#else
157157
size_t stackRemainApprox = STACK_LIMIT_FROM_BASE - (currentStackBase - state.stackBase());
158158
#endif
159-
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);
159+
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);
160160
// In case of indirect call, use global execution context
161161
ExecutionState stateForNewGlobal(m_context);
162162
return script->execute(stateForNewGlobal, true, script->topCodeBlock()->isStrict());
@@ -192,6 +192,12 @@ Value GlobalObject::evalLocal(ExecutionState& state, const Value& arg, Value thi
192192
current = current->parent();
193193
}
194194

195+
bool allowNewTarget = false;
196+
auto thisEnvironment = state.getThisEnvironment();
197+
if (thisEnvironment->isDeclarativeEnvironmentRecord() && thisEnvironment->asDeclarativeEnvironmentRecord()->isFunctionEnvironmentRecord()) {
198+
allowNewTarget = true;
199+
}
200+
195201
volatile int sp;
196202
size_t currentStackBase = (size_t)&sp;
197203
#ifdef STACK_GROWS_DOWN
@@ -200,7 +206,7 @@ Value GlobalObject::evalLocal(ExecutionState& state, const Value& arg, Value thi
200206
size_t stackRemainApprox = STACK_LIMIT_FROM_BASE - (currentStackBase - state.stackBase());
201207
#endif
202208

203-
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);
209+
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);
204210
return script->executeLocal(state, thisValue, parentCodeBlock, script->topCodeBlock()->isStrict(), isRunningEvalOnFunction);
205211
}
206212
return arg;

tools/test/spidermonkey/excludelist.txt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ non262/BigInt/decimal.js
4949
non262/BigInt/large-bit-length.js
5050
non262/BigInt/mod.js
5151
non262/BigInt/Number-conversion-rounding.js
52+
non262/class/newTargetDVG.js
5253

5354
# These tests include features of ES7
5455
non262/Array/slice-sparse-with-large-index.js
@@ -59,11 +60,6 @@ non262/arrow-functions/arrow-not-as-end-of-statement.js
5960
# TODO
6061
non262/arrow-functions/yield-in-arrow.js
6162
non262/class/className.js
62-
non262/class/newTargetArrow.js
63-
non262/class/newTargetDefaults.js
64-
non262/class/newTargetDVG.js
65-
non262/class/newTargetEval.js
66-
non262/class/newTargetGenerators.js
6763
non262/class/outerBinding.js
6864
non262/class/strictExecution.js
6965
non262/class/superCallBaseInvoked.js

0 commit comments

Comments
 (0)