mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Check strict mode immediately
* check and convert to strict mode ahead of following tokens * identifier which has a valid keyword in strict mode is also converted to the complete keyword * fixes #513 Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
This commit is contained in:
parent
32fb8f44bd
commit
47bf20782e
3 changed files with 44 additions and 30 deletions
|
|
@ -484,7 +484,7 @@ StringView Scanner::ScannerResult::relatedSource(const StringView& source)
|
|||
|
||||
Value Scanner::ScannerResult::valueStringLiteralToValue(Scanner* scannerInstance)
|
||||
{
|
||||
if (this->type == Token::KeywordToken && !this->hasKeywordButUseString) {
|
||||
if (this->type == Token::KeywordToken) {
|
||||
return keywordToString(scannerInstance->escargotContext, this->valueKeywordKind).string();
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +500,7 @@ Value Scanner::ScannerResult::valueStringLiteralToValue(Scanner* scannerInstance
|
|||
|
||||
StringView Scanner::ScannerResult::valueStringLiteral(Scanner* scannerInstance)
|
||||
{
|
||||
if (this->type == Token::KeywordToken && !this->hasKeywordButUseString) {
|
||||
if (this->type == Token::KeywordToken) {
|
||||
AtomicString as = keywordToString(scannerInstance->escargotContext, this->valueKeywordKind);
|
||||
return StringView(as.string(), 0, as.string()->length());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,7 +245,6 @@ public:
|
|||
, octal(false)
|
||||
, hasAllocatedString(false)
|
||||
, hasNonComputedNumberLiteral(false)
|
||||
, hasKeywordButUseString(false)
|
||||
, prec(0)
|
||||
, lineNumber(0)
|
||||
, lineStart(0)
|
||||
|
|
@ -263,7 +262,6 @@ public:
|
|||
bool octal : 1;
|
||||
bool hasAllocatedString : 1;
|
||||
bool hasNonComputedNumberLiteral : 1;
|
||||
bool hasKeywordButUseString : 1;
|
||||
unsigned char prec : 8; // max prec is 11
|
||||
// we don't needs init prec.
|
||||
// prec is initialized by another function before use
|
||||
|
|
@ -304,7 +302,6 @@ public:
|
|||
this->octal = false;
|
||||
this->hasAllocatedString = false;
|
||||
this->hasNonComputedNumberLiteral = false;
|
||||
this->hasKeywordButUseString = false;
|
||||
this->lineNumber = lineNumber;
|
||||
this->lineStart = lineStart;
|
||||
this->start = start;
|
||||
|
|
@ -319,7 +316,6 @@ public:
|
|||
this->octal = false;
|
||||
this->hasAllocatedString = false;
|
||||
this->hasNonComputedNumberLiteral = false;
|
||||
this->hasKeywordButUseString = false;
|
||||
this->lineNumber = lineNumber;
|
||||
this->lineStart = lineStart;
|
||||
this->start = start;
|
||||
|
|
@ -334,7 +330,6 @@ public:
|
|||
this->octal = false;
|
||||
this->hasAllocatedString = false;
|
||||
this->hasNonComputedNumberLiteral = false;
|
||||
this->hasKeywordButUseString = false;
|
||||
this->lineNumber = lineNumber;
|
||||
this->lineStart = lineStart;
|
||||
this->start = start;
|
||||
|
|
@ -347,7 +342,6 @@ public:
|
|||
this->type = type;
|
||||
this->startWithZero = false;
|
||||
this->octal = octal;
|
||||
this->hasKeywordButUseString = true;
|
||||
this->hasNonComputedNumberLiteral = false;
|
||||
this->lineNumber = lineNumber;
|
||||
this->lineStart = lineStart;
|
||||
|
|
@ -363,7 +357,6 @@ public:
|
|||
this->type = type;
|
||||
this->startWithZero = false;
|
||||
this->octal = octal;
|
||||
this->hasKeywordButUseString = true;
|
||||
this->hasNonComputedNumberLiteral = false;
|
||||
this->lineNumber = lineNumber;
|
||||
this->lineStart = lineStart;
|
||||
|
|
@ -382,7 +375,6 @@ public:
|
|||
this->startWithZero = false;
|
||||
this->octal = false;
|
||||
this->hasAllocatedString = false;
|
||||
this->hasKeywordButUseString = true;
|
||||
this->hasNonComputedNumberLiteral = hasNonComputedNumberLiteral;
|
||||
this->lineNumber = lineNumber;
|
||||
this->lineStart = lineStart;
|
||||
|
|
@ -397,7 +389,6 @@ public:
|
|||
this->startWithZero = false;
|
||||
this->octal = false;
|
||||
this->hasAllocatedString = false;
|
||||
this->hasKeywordButUseString = true;
|
||||
this->hasNonComputedNumberLiteral = false;
|
||||
this->lineNumber = lineNumber;
|
||||
this->lineStart = lineStart;
|
||||
|
|
@ -560,6 +551,34 @@ public:
|
|||
|
||||
bool isFutureReservedWord(const StringView& id);
|
||||
|
||||
void convertToKeywordInStrictMode(ScannerResult* token)
|
||||
{
|
||||
ASSERT(token->type == Token::IdentifierToken);
|
||||
|
||||
const StringView& keyword = token->relatedSource(this->source);
|
||||
if (keyword.equals("let")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::LetKeyword);
|
||||
} else if (keyword.equals("yield")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::YieldKeyword);
|
||||
} else if (keyword.equals("static")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::StaticKeyword);
|
||||
} else if (keyword.equals("public")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::PublicKeyword);
|
||||
} else if (keyword.equals("private")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::PrivateKeyword);
|
||||
} else if (keyword.equals("package")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::PackageKeyword);
|
||||
} else if (keyword.equals("protected")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::ProtectedKeyword);
|
||||
} else if (keyword.equals("interface")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::InterfaceKeyword);
|
||||
} else if (keyword.equals("implements")) {
|
||||
token->setKeywordResult(token->lineNumber, token->lineStart, token->start, token->end, KeywordKind::ImplementsKeyword);
|
||||
} else {
|
||||
RELEASE_ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool isStrictModeReservedWord(const T& id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ public:
|
|||
this->hasLineTerminator = false;
|
||||
|
||||
if (this->context->strict && next->type == Token::IdentifierToken && this->scanner->isStrictModeReservedWord(next->relatedSource(this->scanner->source))) {
|
||||
next->type = Token::KeywordToken;
|
||||
this->scanner->convertToKeywordInStrictMode(next);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -657,7 +657,7 @@ public:
|
|||
this->hasLineTerminator = tokenLineNumber != next->lineNumber;
|
||||
|
||||
if (this->context->strict && next->type == Token::IdentifierToken && this->scanner->isStrictModeReservedWord(next->relatedSource(this->scanner->source))) {
|
||||
next->type = Token::KeywordToken;
|
||||
this->scanner->convertToKeywordInStrictMode(next);
|
||||
}
|
||||
//this->lookahead = *next;
|
||||
|
||||
|
|
@ -4548,35 +4548,31 @@ public:
|
|||
// ECMA-262 14.1.1 Directive Prologues
|
||||
|
||||
template <class ASTBuilder>
|
||||
ASTNode parseDirective(ASTBuilder& builder, bool& useStrict)
|
||||
ASTNode parseDirective(ASTBuilder& builder)
|
||||
{
|
||||
ALLOC_TOKEN(token);
|
||||
*token = this->lookahead;
|
||||
bool isLiteral = false;
|
||||
useStrict = false;
|
||||
ASSERT(token->type == StringLiteralToken);
|
||||
|
||||
// check strict mode early before lexing of following tokens
|
||||
if (!token->hasAllocatedString && token->valueStringLiteral(this->scanner).equals("use strict")) {
|
||||
this->currentScopeContext->m_isStrict = this->context->strict = true;
|
||||
}
|
||||
|
||||
MetaNode node = this->createNode();
|
||||
ASTNode expr = this->parseExpression(builder);
|
||||
if (expr->type() == Literal) {
|
||||
isLiteral = true;
|
||||
if (token->valueStringLiteral(this->scanner).equals("use strict")) {
|
||||
useStrict = true;
|
||||
}
|
||||
}
|
||||
this->consumeSemicolon();
|
||||
|
||||
if (isLiteral) {
|
||||
if (expr->type() == Literal) {
|
||||
return this->finalize(node, builder.createDirectiveNode(expr));
|
||||
} else {
|
||||
return this->finalize(node, builder.createExpressionStatementNode(expr));
|
||||
}
|
||||
return this->finalize(node, builder.createExpressionStatementNode(expr));
|
||||
}
|
||||
|
||||
template <class ASTBuilder>
|
||||
void parseDirectivePrologues(ASTBuilder& builder, ASTStatementContainer container)
|
||||
{
|
||||
ASSERT(container);
|
||||
bool useStrict = false;
|
||||
Scanner::SmallScannerResult firstRestricted;
|
||||
|
||||
ALLOC_TOKEN(token);
|
||||
|
|
@ -4586,15 +4582,14 @@ public:
|
|||
break;
|
||||
}
|
||||
|
||||
ASTNode statement = this->parseDirective(builder, useStrict);
|
||||
ASTNode statement = this->parseDirective(builder);
|
||||
container->appendChild(statement);
|
||||
|
||||
if (statement->type() != Directive) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!token->hasAllocatedString && useStrict) {
|
||||
this->currentScopeContext->m_isStrict = this->context->strict = true;
|
||||
if (this->context->strict) {
|
||||
if (firstRestricted) {
|
||||
this->throwUnexpectedToken(firstRestricted, Messages::StrictOctalLiteral);
|
||||
}
|
||||
|
|
@ -4856,7 +4851,7 @@ public:
|
|||
computed = this->match(LeftSquareBracket);
|
||||
keyNode = this->parseObjectPropertyKey(builder);
|
||||
|
||||
if (token->type == Token::KeywordToken && (this->qualifiedPropertyName(&this->lookahead) || this->match(Multiply)) && token->valueStringLiteral(this->scanner) == "static") {
|
||||
if (token->type == Token::KeywordToken && (this->qualifiedPropertyName(&this->lookahead) || this->match(Multiply)) && token->relatedSource(this->scanner->source) == "static") {
|
||||
*token = this->lookahead;
|
||||
isStatic = true;
|
||||
computed = this->match(LeftSquareBracket);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue