WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-164808-20161116140107.patch (text/plain), 22.48 KB, created by
Caitlin Potter (:caitp)
on 2016-11-16 11:01:11 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Caitlin Potter (:caitp)
Created:
2016-11-16 11:01:11 PST
Size:
22.48 KB
patch
obsolete
>Subversion Revision: 208790 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 7816838f2bd8d071ffb905082ef85b2d37e36d04..22668bf7920efd0ff33bbaa7353822a4718fbee8 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,37 @@ >+2016-11-16 Caitlin Potter <caitp@igalia.com> >+ >+ [JSC] speed up parsing with ES2017_ASYNCFUNCTION_SYNTAX enabled >+ https://bugs.webkit.org/show_bug.cgi?id=164808 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Minor adjustments to Parser in order to mitigate slowdown with async >+ function parsing enabled: >+ >+ - Tokenize "async" as a keyword >+ - Perform less branching in various areas of the Parser >+ >+ * parser/Keywords.table: >+ * parser/Parser.cpp: >+ (JSC::Parser<LexerType>::parseStatementListItem): >+ (JSC::Parser<LexerType>::parseStatement): >+ (JSC::Parser<LexerType>::maybeParseAsyncFunctionDeclarationStatement): >+ (JSC::Parser<LexerType>::parseClass): >+ (JSC::Parser<LexerType>::parseExportDeclaration): >+ (JSC::Parser<LexerType>::parseAssignmentExpression): >+ (JSC::Parser<LexerType>::parseProperty): >+ (JSC::Parser<LexerType>::createResolveAndUseVariable): >+ (JSC::Parser<LexerType>::parsePrimaryExpression): >+ (JSC::Parser<LexerType>::parseMemberExpression): >+ (JSC::Parser<LexerType>::printUnexpectedTokenText): >+ * parser/Parser.h: >+ (JSC::isAnyContextualKeyword): >+ (JSC::isIdentifierOrAnyContextualKeyword): >+ (JSC::isSafeContextualKeyword): >+ (JSC::Parser::matchSpecIdentifier): >+ * parser/ParserTokens.h: >+ * runtime/CommonIdentifiers.h: >+ > 2016-11-15 Mark Lam <mark.lam@apple.com> > > Make JSC test functions more robust. >diff --git a/Source/JavaScriptCore/parser/Keywords.table b/Source/JavaScriptCore/parser/Keywords.table >index 2f7dfc55c0da8c031d66432136e74888bbbcf929..a0e516319cc3e0518768b023ab47dbc89cc25f6a 100644 >--- a/Source/JavaScriptCore/parser/Keywords.table >+++ b/Source/JavaScriptCore/parser/Keywords.table >@@ -7,6 +7,7 @@ true TRUETOKEN > false FALSETOKEN > > # Keywords. >+async ASYNC > await AWAIT > break BREAK > case CASE >diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp >index ce6bfa7a1f8312432689ca7c5f0376a87ba107bb..c17d5abeaf0bf9a588145cc842885103426767d3 100644 >--- a/Source/JavaScriptCore/parser/Parser.cpp >+++ b/Source/JavaScriptCore/parser/Parser.cpp >@@ -616,12 +616,12 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList > if (!strictMode()) { > SavePoint savePoint = createSavePoint(); > next(); >- // Intentionally use `match(IDENT) || match(LET) || match(YIELD)` and don't use `matchSpecIdentifier()`. >+ // Intentionally use `isIdentifierOrAnyContextualKeyword(m_token)` and don't use `matchSpecIdentifier()`. > // We would like to fall into parseVariableDeclaration path even if "yield" is not treated as an Identifier. > // For example, under a generator context, matchSpecIdentifier() for "yield" returns `false`. > // But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration > // to raise consistent errors between "var", "const" and "let". >- if (!(match(IDENT) || match(LET) || match(YIELD) || match(AWAIT)) && !match(OPENBRACE) && !match(OPENBRACKET)) >+ if (!isIdentifierOrAnyContextualKeyword(m_token) && !match(OPENBRACE) && !match(OPENBRACKET)) > shouldParseVariableDeclaration = false; > restoreSavePoint(savePoint); > } >@@ -640,9 +640,9 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList > case FUNCTION: > result = parseFunctionDeclaration(context); > break; >- case IDENT: >+ case ASYNC: > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async)) { >+ { > // Eagerly parse as AsyncFunctionDeclaration. This is the uncommon case, > // but could be mistakenly parsed as an AsyncFunctionExpression. > SavePoint savePoint = createSavePoint(); >@@ -653,8 +653,9 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList > } > restoreSavePoint(savePoint); > } >- FALLTHROUGH; > #endif >+ FALLTHROUGH; >+ case IDENT: > case AWAIT: > case YIELD: { > // This is a convenient place to notice labeled statements >@@ -1786,12 +1787,13 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre > case DEFAULT: > // These tokens imply the end of a set of source elements > return 0; >- case IDENT: >+ case ASYNC: > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async && maybeParseAsyncFunctionDeclarationStatement(context, result, parentAllowsFunctionDeclarationAsStatement))) >+ if (maybeParseAsyncFunctionDeclarationStatement(context, result, parentAllowsFunctionDeclarationAsStatement)) > break; >+#endif > FALLTHROUGH; >-#endif >+ case IDENT: > case AWAIT: > case YIELD: { > bool allowFunctionDeclarationAsStatement = false; >@@ -1874,7 +1876,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla > template <typename LexerType> > template <class TreeBuilder> bool Parser<LexerType>::maybeParseAsyncFunctionDeclarationStatement(TreeBuilder& context, TreeStatement& result, bool parentAllowsFunctionDeclarationAsStatement) > { >- ASSERT(*m_token.m_data.ident == m_vm->propertyNames->async); >+ ASSERT(match(ASYNC)); > SavePoint savePoint = createSavePoint(); > next(); > if (match(FUNCTION) && !m_lexer->prevTerminator()) { >@@ -2669,10 +2671,12 @@ template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T > bool isGetter = false; > bool isSetter = false; > bool isGenerator = false; >+ bool isAsync = false; > bool isAsyncMethod = false; > if (consume(TIMES)) > isGenerator = true; > >+UNUSED_PARAM(isAsync); > UNUSED_LABEL(parseMethod); > parseMethod: > switch (m_token.m_type) { >@@ -2682,21 +2686,25 @@ parseMethod: > ASSERT(ident); > next(); > break; >+ case ASYNC: >+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >+ isAsync = !isGenerator && !isAsyncMethod; >+ FALLTHROUGH; >+#endif > case IDENT: > case AWAIT: > ident = m_token.m_data.ident; > ASSERT(ident); > next(); > if (!isGenerator && !isAsyncMethod && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) { >- isGetter = *ident == propertyNames.get; >- isSetter = *ident == propertyNames.set; >- > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- if (UNLIKELY(*ident == propertyNames.async && !m_lexer->prevTerminator() && !isAsyncMethod)) { >+ if (UNLIKELY(isAsync) && !m_lexer->prevTerminator()) { > isAsyncMethod = true; > goto parseMethod; > } > #endif >+ isGetter = *ident == propertyNames.get; >+ isSetter = *ident == propertyNames.set; > } > break; > case DOUBLE: >@@ -3217,7 +3225,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara > } > > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- else if (UNLIKELY(isIdentifierOrKeyword(m_token) && *m_token.m_data.ident == m_vm->propertyNames->async)) { >+ else if (match(ASYNC)) { > SavePoint savePoint = createSavePoint(); > next(); > if (match(FUNCTION) && !m_lexer->prevTerminator()) { >@@ -3244,7 +3252,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara > } > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) > else { >- ASSERT(match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->async); >+ ASSERT(match(ASYNC)); > next(); > DepthManager statementDepth(&m_statementDepth); > m_statementDepth = 1; >@@ -3366,15 +3374,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara > result = parseClassDeclaration(context, ExportType::Exported); > break; > >- default: >+ case ASYNC: > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- if (UNLIKELY(isIdentifierOrKeyword(m_token) && *m_token.m_data.ident == m_vm->propertyNames->async)) { >- next(); >- semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator"); >- result = parseAsyncFunctionDeclaration(context, ExportType::Exported); >- break; >- } >+ next(); >+ semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator"); >+ result = parseAsyncFunctionDeclaration(context, ExportType::Exported); >+ break; > #endif >+ default: > failWithMessage("Expected either a declaration or a variable statement"); > break; > } >@@ -3457,11 +3464,7 @@ template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen > SavePoint savePoint = createSavePoint(); > size_t usedVariablesSize = 0; > >-#if !ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) > if (wasOpenParen) { >-#else >- if (wasOpenParen || (wasIdentifierOrKeyword && *m_token.m_data.ident == m_vm->propertyNames->async)) { >-#endif > usedVariablesSize = currentScope()->currentUsedVariablesSize(); > currentScope()->pushUsedVariableSet(); > } >@@ -3475,12 +3478,12 @@ template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen > restoreSavePoint(savePoint); > bool isAsyncArrow = false; > if (UNLIKELY(classifier.indicatesPossibleAsyncArrowFunction())) { >- ASSERT(matchContextualKeyword(m_vm->propertyNames->async)); >+ ASSERT(match(ASYNC)); > next(); > isAsyncArrow = !m_lexer->prevTerminator(); > } > if (isArrowFunctionParameters()) { >- if (wasOpenParen || isAsyncArrow) >+ if (wasOpenParen) > currentScope()->revertToPreviousUsedVariables(usedVariablesSize); > return parseArrowFunctionExpression(context, isAsyncArrow); > } >@@ -3733,16 +3736,23 @@ template <typename LexerType> > template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context, bool complete) > { > bool wasIdent = false; >+ bool isAsync = false; > bool isGenerator = false; > bool isClassProperty = false; > bool isAsyncMethod = false; > if (consume(TIMES)) > isGenerator = true; > >+UNUSED_PARAM(isAsync); > UNUSED_LABEL(parseProperty); > parseProperty: > switch (m_token.m_type) { > namedProperty: >+ case ASYNC: >+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >+ isAsync = !isGenerator && !isAsyncMethod; >+ FALLTHROUGH; >+#endif > case IDENT: > case AWAIT: > wasIdent = true; >@@ -3750,12 +3760,13 @@ parseProperty: > case STRING: { > const Identifier* ident = m_token.m_data.ident; > unsigned getterOrSetterStartOffset = tokenStart(); >- if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set))) >- nextExpectIdentifier(LexerFlagsIgnoreReservedWords); > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- else if (wasIdent && !isGenerator && *ident == m_vm->propertyNames->async) >+ if (isAsync) > nextExpectIdentifier(LexerFlagsIgnoreReservedWords); >+ else > #endif >+ if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set))) >+ nextExpectIdentifier(LexerFlagsIgnoreReservedWords); > else > nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords); > >@@ -3795,7 +3806,7 @@ parseProperty: > else if (*ident == m_vm->propertyNames->set) > type = PropertyNode::Setter; > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- else if (UNLIKELY(*ident == m_vm->propertyNames->async && !isGenerator && !isAsyncMethod)) { >+ else if (UNLIKELY(isAsync && !isAsyncMethod)) { > isAsyncMethod = true; > failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'"); > goto parseProperty; >@@ -4223,6 +4234,14 @@ template <class TreeBuilder> typename TreeBuilder::TemplateLiteral Parser<LexerT > return context.createTemplateLiteral(location, templateStringList, templateExpressionList); > } > >+template <class LexerType> >+template <class TreeBuilder> TreeExpression Parser<LexerType>::createResolveAndUseVariable(TreeBuilder& context, const Identifier* ident, bool isEval, const JSTextPosition& start, const JSTokenLocation& location) >+{ >+ currentScope()->useVariable(ident, isEval); >+ m_parserState.lastIdentifier = ident; >+ return context.createResolve(location, *ident, start, lastTokenEndPosition()); >+} >+ > template <typename LexerType> > template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpression(TreeBuilder& context) > { >@@ -4257,7 +4276,25 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) > if (m_parserState.functionParsePhase == FunctionParsePhase::Parameters) > failIfFalse(m_parserState.allowAwait, "Cannot use await expression within parameters"); >- FALLTHROUGH; >+ goto identifierExpression; >+#endif >+ case ASYNC: >+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >+ { >+ JSTextPosition start = tokenStartPosition(); >+ const Identifier* ident = m_token.m_data.ident; >+ JSTokenLocation location(tokenLocation()); >+ next(); >+ if (match(FUNCTION) && !m_lexer->prevTerminator()) >+ return parseAsyncFunctionExpression(context); >+ >+ // Avoid using variable if it is an arrow function parameter >+ if (UNLIKELY(match(ARROWFUNCTION))) >+ return 0; >+ >+ const bool isEval = false; >+ return createResolveAndUseVariable(context, ident, isEval, start, location); >+ } > #endif > case IDENT: { > identifierExpression: >@@ -4265,17 +4302,12 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre > const Identifier* ident = m_token.m_data.ident; > JSTokenLocation location(tokenLocation()); > next(); >- if (match(ARROWFUNCTION)) >- return 0; > >-#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- if (UNLIKELY(*ident == m_vm->propertyNames->async && match(FUNCTION) && !m_lexer->prevTerminator())) >- return parseAsyncFunctionExpression(context); >-#endif >+ // Avoid using variable if it is an arrow function parameter >+ if (UNLIKELY(match(ARROWFUNCTION))) >+ return 0; > >- currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident); >- m_parserState.lastIdentifier = ident; >- return context.createResolve(location, *ident, start, lastTokenEndPosition()); >+ return createResolveAndUseVariable(context, ident, *ident == m_vm->propertyNames->eval, start, location); > } > case STRING: { > const Identifier* ident = m_token.m_data.ident; >@@ -4472,14 +4504,14 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres > } > } else if (!baseIsNewTarget) { > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >- const bool isAsync = isIdentifierOrKeyword(m_token) && *m_token.m_data.ident == m_vm->propertyNames->async; >+ const bool isAsync = match(ASYNC); > #endif > > base = parsePrimaryExpression(context); > > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) > failIfFalse(base, "Cannot parse base expression"); >- if (isAsync && context.isResolve(base) && !m_lexer->prevTerminator()) { >+ if (UNLIKELY(isAsync && context.isResolve(base) && !m_lexer->prevTerminator())) { > if (matchSpecIdentifier()) { > // AsyncArrowFunction > forceClassifyExpressionError(ErrorIndicatesAsyncArrowFunction); >@@ -4521,11 +4553,15 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres > failIfFalse(arguments, "Cannot parse call arguments"); > base = context.createNewExpr(location, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition()); > } else { >+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) >+ size_t usedVariablesSize = currentScope()->currentUsedVariablesSize(); >+#endif > JSTextPosition expressionEnd = lastTokenEndPosition(); > TreeArguments arguments = parseArguments(context); > > #if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX) > if (baseIsAsyncKeyword && (!arguments || match(ARROWFUNCTION))) { >+ currentScope()->revertToPreviousUsedVariables(usedVariablesSize); > forceClassifyExpressionError(ErrorIndicatesAsyncArrowFunction); > failDueToUnexpectedToken(); > } >@@ -4828,6 +4864,7 @@ template <typename LexerType> void Parser<LexerType>::printUnexpectedTokenText(W > out.print("Invalid private name '", getToken(), "'"); > return; > >+ case ASYNC: > case AWAIT: > case IDENT: > out.print("Unexpected identifier '", getToken(), "'"); >diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h >index d600b63ba8c9158c31efb02c9703470432088038..522cc023e9ae392323f822de3e258ac6fa199966 100644 >--- a/Source/JavaScriptCore/parser/Parser.h >+++ b/Source/JavaScriptCore/parser/Parser.h >@@ -128,6 +128,22 @@ ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token) > { > return token.m_type == IDENT || token.m_type & KeywordTokenFlag; > } >+// _Any_ContextualKeyword includes keywords such as "let" or "yield", which have a specific meaning depending on the current parse mode >+// or strict mode. These helpers allow to treat all contextual keywords as identifiers as required. >+ALWAYS_INLINE static bool isAnyContextualKeyword(const JSToken& token) >+{ >+ return token.m_type >= FirstContextualKeywordToken && token.m_type <= LastContextualKeywordToken; >+} >+ALWAYS_INLINE static bool isIdentifierOrAnyContextualKeyword(const JSToken& token) >+{ >+ return token.m_type == IDENT || isAnyContextualKeyword(token); >+} >+// _Safe_ContextualKeyword includes only contextual keywords which can be treated as identifiers independently from parse mode. The exeption >+// to this rule is `await`, but matchSpecIdentifier() always treats it as an identifier regardless. >+ALWAYS_INLINE static bool isSafeContextualKeyword(const JSToken& token) >+{ >+ return token.m_type >= FirstSafeContextualKeywordToken && token.m_type <= LastSafeContextualKeywordToken; >+} > > struct Scope { > WTF_MAKE_NONCOPYABLE(Scope); >@@ -1459,12 +1475,12 @@ private: > // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors > ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator) > { >- return match(IDENT) || match(AWAIT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator); >+ return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator) || isSafeContextualKeyword(m_token); > } > > ALWAYS_INLINE bool matchSpecIdentifier() > { >- return match(IDENT) || match(AWAIT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(currentScope()->isGenerator()); >+ return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(currentScope()->isGenerator()) || isSafeContextualKeyword(m_token); > } > > template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode); >@@ -1539,6 +1555,8 @@ private: > template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings); > template <class TreeBuilder> TreeStatement parseExportDeclaration(TreeBuilder&); > >+ template <class TreeBuilder> ALWAYS_INLINE TreeExpression createResolveAndUseVariable(TreeBuilder&, const Identifier*, bool isEval, const JSTextPosition&, const JSTokenLocation&); >+ > enum class FunctionDefinitionType { Expression, Declaration, Method }; > template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionNameRequirements, SourceParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionDefinitionType); > >diff --git a/Source/JavaScriptCore/parser/ParserTokens.h b/Source/JavaScriptCore/parser/ParserTokens.h >index efc2b8f26e03633b37773838dc6be80623ec54fb..c66bb095b3505710efce17d1ebe6d9418ae40d5d 100644 >--- a/Source/JavaScriptCore/parser/ParserTokens.h >+++ b/Source/JavaScriptCore/parser/ParserTokens.h >@@ -57,7 +57,6 @@ enum JSTokenType { > FOR, > NEW, > VAR, >- LET, > CONSTTOKEN, > CONTINUE, > FUNCTION, >@@ -78,11 +77,21 @@ enum JSTokenType { > ELSE, > IMPORT, > EXPORT, >- YIELD, > CLASSTOKEN, > EXTENDS, > SUPER, >+ >+ // Conditional keywords >+ LET, >+ YIELD, > AWAIT, >+ ASYNC, >+ >+ FirstContextualKeywordToken = LET, >+ LastContextualKeywordToken = ASYNC, >+ FirstSafeContextualKeywordToken = AWAIT, >+ LastSafeContextualKeywordToken = LastContextualKeywordToken, >+ > OPENBRACE = 0, > CLOSEBRACE, > OPENPAREN, >diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.h b/Source/JavaScriptCore/runtime/CommonIdentifiers.h >index d51361ba3d052f33c2283bc3f0f7ad19e7d28366..ba4e2318246a1510a31688a71f19b12df2164452 100644 >--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h >+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.h >@@ -112,7 +112,6 @@ > macro(arguments) \ > macro(as) \ > macro(assign) \ >- macro(async) \ > macro(back) \ > macro(bind) \ > macro(blur) \ >@@ -275,6 +274,7 @@ > macro(year) > > #define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \ >+ macro(async) \ > macro(await) \ > macro(break) \ > macro(case) \
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 164808
:
294913
|
294920
|
294921
|
294922
|
294925
|
294934
|
294937
|
294939
|
294951
|
295055
|
295063
|
295064
|
295065
|
295067
|
295068
|
295072
|
295081
|
295082
|
295083
|
295084
|
295086
|
295276
|
295277