Skip to content

Commit c26915d

Browse files
committed
Change bottom-up to top-down check
1 parent 72bba12 commit c26915d

File tree

3 files changed

+53
-56
lines changed

3 files changed

+53
-56
lines changed

src/parser/ast/ASTContext.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,21 +311,23 @@ struct ASTScopeContext {
311311
bool m_allowSuperProperty : 1;
312312
bool m_allowArguments : 1;
313313
bool m_needRareData : 1;
314+
#ifndef ESCARGOT_DEBUGGER
315+
bool m_hasStringArguments : 1;
316+
#endif
314317
unsigned int m_nodeType : 2; // it is actually NodeType but used on FunctionExpression, ArrowFunctionExpression and FunctionDeclaration only
315318
unsigned int m_functionLength : 16; // represent the number of consecutive identifier parameters from the start of parameter list (function length)
316319
unsigned int m_parameterCount : 16; // represent the number of parameter element nodes
317320
LexicalBlockIndex m_functionBodyBlockIndex : 16;
318321
LexicalBlockIndex m_lexicalBlockIndexFunctionLocatedIn : 16;
322+
#ifndef ESCARGOT_DEBUGGER
323+
uint16_t m_parameterUsed : 16;
324+
#endif
319325
ASTScopeContextNameInfoVector m_varNames;
320326
FunctionContextVarMap *m_varNamesMap;
321327
AtomicStringTightVector *m_classPrivateNames; // this is needed for direct eval in class & nested class
322328
AtomicStringTightVector m_parameters;
323329
AtomicString m_functionName;
324-
#ifndef ESCARGOT_DEBUGGER
325-
uint16_t m_parameterUsed : 16; // 0xFFFF means all parameters are used or function has more than 16 parameters
326330

327-
ASTScopeContext *m_parentScope;
328-
#endif
329331
ASTScopeContext *m_firstChild;
330332
ASTScopeContext *m_nextSibling;
331333
ASTBlockContextVector m_childBlockScopes;
@@ -700,17 +702,19 @@ struct ASTScopeContext {
700702
, m_allowSuperProperty(false)
701703
, m_allowArguments(true)
702704
, m_needRareData(false)
705+
#ifndef ESCARGOT_DEBUGGER
706+
, m_hasStringArguments(false)
707+
#endif
703708
, m_nodeType(ASTNodeType::Program)
704709
, m_functionLength(0)
705710
, m_parameterCount(0)
706711
, m_functionBodyBlockIndex(0)
707712
, m_lexicalBlockIndexFunctionLocatedIn(LEXICAL_BLOCK_INDEX_MAX)
708-
, m_varNamesMap(nullptr)
709-
, m_classPrivateNames(nullptr)
710713
#ifndef ESCARGOT_DEBUGGER
711714
, m_parameterUsed(0)
712-
, m_parentScope(nullptr)
713715
#endif
716+
, m_varNamesMap(nullptr)
717+
, m_classPrivateNames(nullptr)
714718
, m_firstChild(nullptr)
715719
, m_nextSibling(nullptr)
716720
, m_functionStartLOC(1, 1, 0) // set default start location at the start of the code

src/parser/esprima_cpp/esprima.cpp

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -317,38 +317,50 @@ class Parser {
317317
}
318318
}
319319

320-
ASTScopeContext* popScopeContext(ASTScopeContext* lastPushedScopeContext)
321-
{
322-
auto ret = this->currentScopeContext;
323-
this->lastUsingName = AtomicString();
324-
this->lastPoppedScopeContext = ret;
325-
this->currentScopeContext = lastPushedScopeContext;
326320
#ifndef ESCARGOT_DEBUGGER
327-
ASTScopeContext* scopeCtx = ret;
328-
while (scopeCtx) {
329-
if (!scopeCtx->m_parameters.size()) {
330-
scopeCtx->m_parameterUsed = 0xFFFF;
331-
}
321+
void checkUsedParameters(ASTScopeContext* scopeCtx)
322+
{
323+
AtomicStringTightVector& parameters = this->currentScopeContext->m_parameters;
332324

333-
if (scopeCtx->m_parameterUsed == 0xFFFF) {
334-
scopeCtx = scopeCtx->m_parentScope;
335-
continue;
325+
for (size_t i = 0; i < parameters.size(); i++) {
326+
AtomicString& name = parameters[i];
327+
for (size_t j = 0; j < scopeCtx->m_childBlockScopes.size(); j++) {
328+
ASTBlockContext& blockCtx = *scopeCtx->m_childBlockScopes[j];
329+
if (VectorUtil::findInVector(blockCtx.m_usingNames, name) != VectorUtil::invalidIndex) {
330+
this->currentScopeContext->m_parameterUsed |= (1 << i);
331+
break;
332+
} else if (UNLIKELY(scopeCtx->m_parameterUsed == DISABLE_PARAM_CHECK)) {
333+
this->currentScopeContext->m_parameterUsed = DISABLE_PARAM_CHECK;
334+
return;
335+
}
336336
}
337+
}
337338

338-
for (size_t i = 0; i < scopeCtx->m_parameters.size(); i++) {
339-
AtomicString paramName = scopeCtx->m_parameters[i];
340-
for (size_t j = 0; j < ret->m_childBlockScopes.size(); j++) {
341-
ASTBlockContext* block = ret->m_childBlockScopes[j];
342-
if (VectorUtil::findInVector(block->m_usingNames, paramName) != VectorUtil::invalidIndex) {
343-
scopeCtx->m_parameterUsed |= (1 << i);
344-
break;
345-
}
346-
}
339+
// check nested functions
340+
size_t childCount = scopeCtx->childCount();
341+
if (childCount > 0) {
342+
ASTScopeContext* child = scopeCtx->firstChild();
343+
for (size_t i = 0; i < childCount; i++) {
344+
checkUsedParameters(child);
345+
child = child->nextSibling();
347346
}
347+
}
348+
}
349+
#endif
348350

349-
scopeCtx = scopeCtx->m_parentScope;
351+
ASTScopeContext* popScopeContext(ASTScopeContext* lastPushedScopeContext)
352+
{
353+
#ifndef ESCARGOT_DEBUGGER
354+
if (UNLIKELY(this->currentScopeContext->m_hasEval || this->currentScopeContext->m_hasStringArguments || this->currentScopeContext->m_parameters.size() > 16)) {
355+
this->currentScopeContext->m_parameterUsed = DISABLE_PARAM_CHECK;
356+
} else {
357+
checkUsedParameters(this->currentScopeContext);
350358
}
351359
#endif
360+
auto ret = this->currentScopeContext;
361+
this->lastUsingName = AtomicString();
362+
this->lastPoppedScopeContext = ret;
363+
this->currentScopeContext = lastPushedScopeContext;
352364
return ret;
353365
}
354366

@@ -381,10 +393,6 @@ class Parser {
381393
parentContext->appendChild(this->currentScopeContext);
382394
}
383395

384-
#ifndef ESCARGOT_DEBUGGER
385-
this->currentScopeContext->m_parentScope = parentContext;
386-
#endif
387-
388396
return parentContext;
389397
}
390398

@@ -511,11 +519,6 @@ class Parser {
511519
ASSERT(this->currentScopeContext->m_functionLength == paramNames.size());
512520
ASSERT(this->currentScopeContext->m_functionLength == this->currentScopeContext->m_parameterCount);
513521
}
514-
#endif
515-
#ifndef ESCARGOT_DEBUGGER
516-
if (UNLIKELY(paramNames.size() > 16)) {
517-
this->currentScopeContext->m_parameterUsed = 0xFFFF;
518-
}
519522
#endif
520523
this->currentScopeContext->m_parameters.resizeWithUninitializedValues(paramNames.size());
521524
LexicalBlockIndex functionBodyBlockIndex = this->currentScopeContext->m_functionBodyBlockIndex;
@@ -1077,11 +1080,7 @@ class Parser {
10771080

10781081
#ifndef ESCARGOT_DEBUGGER
10791082
if (UNLIKELY(ret->asIdentifier()->name() == this->stringArguments)) {
1080-
ASTScopeContext* scopeCtx = this->currentScopeContext;
1081-
while (scopeCtx) {
1082-
scopeCtx->m_parameterUsed = 0xFFFF;
1083-
scopeCtx = scopeCtx->m_parentScope;
1084-
}
1083+
this->currentScopeContext->m_hasStringArguments = true;
10851084
}
10861085
#endif
10871086

@@ -1755,9 +1754,6 @@ class Parser {
17551754
this->currentScopeContext->m_parameterCount = 1;
17561755
this->currentScopeContext->m_parameters.resizeWithUninitializedValues(1);
17571756
this->currentScopeContext->m_parameters[0] = className;
1758-
#ifndef ESCARGOT_DEBUGGER
1759-
this->currentScopeContext->m_parameterUsed |= 1;
1760-
#endif
17611757
this->currentScopeContext->insertVarName(className, 0, true, true, true);
17621758
}
17631759

@@ -2610,9 +2606,6 @@ class Parser {
26102606
// check callee of CallExpressionNode
26112607
if (exprNode->isIdentifier() && exprNode->asIdentifier()->name() == escargotContext->staticStrings().eval) {
26122608
this->currentScopeContext->m_hasEval = true;
2613-
#ifndef ESCARGOT_DEBUGGER
2614-
this->currentScopeContext->m_parameterUsed = 0xFFFF;
2615-
#endif
26162609
}
26172610
exprNode = this->finalize(this->startNode(startToken), builder.createCallExpressionNode(exprNode, args, optional));
26182611
if (asyncArrow && this->match(Arrow)) {
@@ -3584,9 +3577,6 @@ class Parser {
35843577
this->currentScopeContext->m_parameterCount = 1;
35853578
this->currentScopeContext->m_parameters.resizeWithUninitializedValues(1);
35863579
this->currentScopeContext->m_parameters[0] = paramName;
3587-
#ifndef ESCARGOT_DEBUGGER
3588-
this->currentScopeContext->m_parameterUsed |= 1;
3589-
#endif
35903580
this->currentScopeContext->insertVarName(paramName, 0, true, true, true);
35913581
}
35923582

@@ -5088,7 +5078,7 @@ class Parser {
50885078
switch (param->type()) {
50895079
case Identifier: {
50905080
#ifndef ESCARGOT_DEBUGGER
5091-
if (this->codeBlock->parameterUsed() & (1 << paramIndex) || this->codeBlock->parameterUsed() == 0xFFFF) {
5081+
if (this->codeBlock->parameterUsed() & (1 << paramIndex) || this->codeBlock->parameterUsed() == DISABLE_PARAM_CHECK) {
50925082
#endif
50935083
Node* init = this->finalize(node, builder.createInitializeParameterExpressionNode(param, paramIndex));
50945084
Node* statement = this->finalize(node, builder.createExpressionStatementNode(init));
@@ -5108,7 +5098,7 @@ class Parser {
51085098
}
51095099
case RestElement: {
51105100
#ifndef ESCARGOT_DEBUGGER
5111-
if (this->codeBlock->parameterUsed() & (1 << paramIndex) || param->asRestElement()->argument()->type() != Identifier || this->codeBlock->parameterUsed() == 0xFFFF) {
5101+
if (this->codeBlock->parameterUsed() & (1 << paramIndex) || this->codeBlock->parameterUsed() == DISABLE_PARAM_CHECK || param->asRestElement()->argument()->type() != Identifier) {
51125102
#endif
51135103
Node* statement = this->finalize(node, builder.createExpressionStatementNode(param));
51145104
container->appendChild(statement);

src/parser/esprima_cpp/esprima.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ struct Error : public gc {
5555
};
5656

5757
#define ESPRIMA_RECURSIVE_LIMIT 1024
58+
#ifndef ESCARGOT_DEBUGGER
59+
#define DISABLE_PARAM_CHECK 0xFFFF
60+
#endif
5861

5962
ProgramNode* parseProgram(::Escargot::Context* ctx, StringView source, ASTClassInfo* outerClassInfo,
6063
bool isModule, bool strictFromOutside, bool inWith, bool allowSuperCallFromOutside,

0 commit comments

Comments
 (0)