OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
323 | 323 |
324 | 324 |
325 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { | 325 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { |
326 return IsEval(identifier) || IsArguments(identifier); | 326 return IsEval(identifier) || IsArguments(identifier); |
327 } | 327 } |
328 | 328 |
329 bool ParserTraits::IsUndefined(const AstRawString* identifier) const { | 329 bool ParserTraits::IsUndefined(const AstRawString* identifier) const { |
330 return identifier == parser_->ast_value_factory()->undefined_string(); | 330 return identifier == parser_->ast_value_factory()->undefined_string(); |
331 } | 331 } |
332 | 332 |
333 bool ParserTraits::IsAwait(const AstRawString* identifier) const { | |
334 return identifier == parser_->ast_value_factory()->await_string(); | |
335 } | |
336 | |
333 bool ParserTraits::IsPrototype(const AstRawString* identifier) const { | 337 bool ParserTraits::IsPrototype(const AstRawString* identifier) const { |
334 return identifier == parser_->ast_value_factory()->prototype_string(); | 338 return identifier == parser_->ast_value_factory()->prototype_string(); |
335 } | 339 } |
336 | 340 |
337 | 341 |
338 bool ParserTraits::IsConstructor(const AstRawString* identifier) const { | 342 bool ParserTraits::IsConstructor(const AstRawString* identifier) const { |
339 return identifier == parser_->ast_value_factory()->constructor_string(); | 343 return identifier == parser_->ast_value_factory()->constructor_string(); |
340 } | 344 } |
341 | 345 |
342 | 346 |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
784 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 788 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
785 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && | 789 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && |
786 info->isolate()->is_tail_call_elimination_enabled()); | 790 info->isolate()->is_tail_call_elimination_enabled()); |
787 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 791 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
788 set_allow_harmony_function_name(FLAG_harmony_function_name); | 792 set_allow_harmony_function_name(FLAG_harmony_function_name); |
789 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 793 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
790 set_allow_harmony_restrictive_declarations( | 794 set_allow_harmony_restrictive_declarations( |
791 FLAG_harmony_restrictive_declarations); | 795 FLAG_harmony_restrictive_declarations); |
792 set_allow_harmony_exponentiation_operator( | 796 set_allow_harmony_exponentiation_operator( |
793 FLAG_harmony_exponentiation_operator); | 797 FLAG_harmony_exponentiation_operator); |
798 set_allow_harmony_async_await(FLAG_harmony_async_await); | |
794 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 799 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
795 ++feature) { | 800 ++feature) { |
796 use_counts_[feature] = 0; | 801 use_counts_[feature] = 0; |
797 } | 802 } |
798 if (info->ast_value_factory() == NULL) { | 803 if (info->ast_value_factory() == NULL) { |
799 // info takes ownership of AstValueFactory. | 804 // info takes ownership of AstValueFactory. |
800 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 805 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
801 info->set_ast_value_factory_owned(); | 806 info->set_ast_value_factory_owned(); |
802 ast_value_factory_ = info->ast_value_factory(); | 807 ast_value_factory_ = info->ast_value_factory(); |
803 } | 808 } |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1058 FunctionState function_state(&function_state_, &scope_, scope, | 1063 FunctionState function_state(&function_state_, &scope_, scope, |
1059 shared_info->kind(), &function_factory); | 1064 shared_info->kind(), &function_factory); |
1060 DCHECK(is_sloppy(scope->language_mode()) || | 1065 DCHECK(is_sloppy(scope->language_mode()) || |
1061 is_strict(info->language_mode())); | 1066 is_strict(info->language_mode())); |
1062 DCHECK(info->language_mode() == shared_info->language_mode()); | 1067 DCHECK(info->language_mode() == shared_info->language_mode()); |
1063 FunctionLiteral::FunctionType function_type = | 1068 FunctionLiteral::FunctionType function_type = |
1064 ComputeFunctionType(shared_info); | 1069 ComputeFunctionType(shared_info); |
1065 bool ok = true; | 1070 bool ok = true; |
1066 | 1071 |
1067 if (shared_info->is_arrow()) { | 1072 if (shared_info->is_arrow()) { |
1073 bool is_async = allow_harmony_async_await() && | |
1074 peek() == Token::IDENTIFIER && | |
1075 PeekContextualKeyword(CStrVector("async")) && | |
1076 !scanner()->HasAnyLineTerminatorAfterNext(); | |
1077 | |
1078 if (is_async) { | |
1079 Consume(Token::IDENTIFIER); | |
1080 DCHECK(peek_any_identifier() || peek() == Token::LPAREN); | |
1081 } | |
1082 | |
1068 // TODO(adamk): We should construct this scope from the ScopeInfo. | 1083 // TODO(adamk): We should construct this scope from the ScopeInfo. |
1069 Scope* scope = | 1084 Scope* scope = |
1070 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 1085 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); |
1071 | 1086 |
1072 // These two bits only need to be explicitly set because we're | 1087 // These two bits only need to be explicitly set because we're |
1073 // not passing the ScopeInfo to the Scope constructor. | 1088 // not passing the ScopeInfo to the Scope constructor. |
1074 // TODO(adamk): Remove these calls once the above NewScope call | 1089 // TODO(adamk): Remove these calls once the above NewScope call |
1075 // passes the ScopeInfo. | 1090 // passes the ScopeInfo. |
1076 if (shared_info->scope_info()->CallsEval()) { | 1091 if (shared_info->scope_info()->CallsEval()) { |
1077 scope->RecordEvalCall(); | 1092 scope->RecordEvalCall(); |
(...skipping 20 matching lines...) Expand all Loading... | |
1098 DeclareFormalParameter(formals.scope, formals.at(0), | 1113 DeclareFormalParameter(formals.scope, formals.at(0), |
1099 &formals_classifier); | 1114 &formals_classifier); |
1100 } | 1115 } |
1101 } | 1116 } |
1102 } | 1117 } |
1103 | 1118 |
1104 if (ok) { | 1119 if (ok) { |
1105 checkpoint.Restore(&formals.materialized_literals_count); | 1120 checkpoint.Restore(&formals.materialized_literals_count); |
1106 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should | 1121 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should |
1107 // not be observable, or else the preparser would have failed. | 1122 // not be observable, or else the preparser would have failed. |
1108 Expression* expression = | 1123 Expression* expression = ParseArrowFunctionLiteral( |
1109 ParseArrowFunctionLiteral(true, formals, formals_classifier, &ok); | 1124 true, formals, is_async, formals_classifier, &ok); |
1110 if (ok) { | 1125 if (ok) { |
1111 // Scanning must end at the same position that was recorded | 1126 // Scanning must end at the same position that was recorded |
1112 // previously. If not, parsing has been interrupted due to a stack | 1127 // previously. If not, parsing has been interrupted due to a stack |
1113 // overflow, at which point the partially parsed arrow function | 1128 // overflow, at which point the partially parsed arrow function |
1114 // concise body happens to be a valid expression. This is a problem | 1129 // concise body happens to be a valid expression. This is a problem |
1115 // only for arrow functions with single expression bodies, since there | 1130 // only for arrow functions with single expression bodies, since there |
1116 // is no end token such as "}" for normal functions. | 1131 // is no end token such as "}" for normal functions. |
1117 if (scanner()->location().end_pos == shared_info->end_position()) { | 1132 if (scanner()->location().end_pos == shared_info->end_position()) { |
1118 // The pre-parser saw an arrow function here, so the full parser | 1133 // The pre-parser saw an arrow function here, so the full parser |
1119 // must produce a FunctionLiteral. | 1134 // must produce a FunctionLiteral. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1238 | 1253 |
1239 return 0; | 1254 return 0; |
1240 } | 1255 } |
1241 | 1256 |
1242 | 1257 |
1243 Statement* Parser::ParseStatementListItem(bool* ok) { | 1258 Statement* Parser::ParseStatementListItem(bool* ok) { |
1244 // (Ecma 262 6th Edition, 13.1): | 1259 // (Ecma 262 6th Edition, 13.1): |
1245 // StatementListItem: | 1260 // StatementListItem: |
1246 // Statement | 1261 // Statement |
1247 // Declaration | 1262 // Declaration |
1248 | 1263 const Token::Value peeked = peek(); |
1249 switch (peek()) { | 1264 switch (peeked) { |
1250 case Token::FUNCTION: | 1265 case Token::FUNCTION: |
1251 return ParseFunctionDeclaration(NULL, ok); | 1266 return ParseFunctionDeclaration(NULL, ok); |
1252 case Token::CLASS: | 1267 case Token::CLASS: |
1253 Consume(Token::CLASS); | 1268 Consume(Token::CLASS); |
1254 return ParseClassDeclaration(NULL, ok); | 1269 return ParseClassDeclaration(NULL, ok); |
1255 case Token::CONST: | 1270 case Token::CONST: |
1256 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1271 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1257 case Token::VAR: | 1272 case Token::VAR: |
1258 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1273 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1259 case Token::LET: | 1274 case Token::LET: |
1260 if (IsNextLetKeyword()) { | 1275 if (IsNextLetKeyword()) { |
1261 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1276 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1262 } | 1277 } |
1263 break; | 1278 break; |
1279 case Token::IDENTIFIER: | |
1280 if (allow_harmony_async_await() && | |
1281 PeekContextualKeyword(CStrVector("async")) && | |
Dan Ehrenberg
2016/04/25 21:18:16
You mentioned that this patch causes a parser slow
caitp (gmail)
2016/04/26 00:09:38
I said there was a parser slowdown in JSC. I don't
| |
1282 PeekAhead() == Token::FUNCTION && | |
1283 !scanner()->HasAnyLineTerminatorAfterNext()) { | |
1284 Consume(Token::IDENTIFIER); | |
1285 return ParseAsyncFunctionDeclaration(NULL, ok); | |
1286 } | |
1287 /* falls through */ | |
1264 default: | 1288 default: |
1265 break; | 1289 break; |
1266 } | 1290 } |
1267 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); | 1291 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); |
1268 } | 1292 } |
1269 | 1293 |
1270 | 1294 |
1271 Statement* Parser::ParseModuleItem(bool* ok) { | 1295 Statement* Parser::ParseModuleItem(bool* ok) { |
1272 // (Ecma 262 6th Edition, 15.2): | 1296 // (Ecma 262 6th Edition, 15.2): |
1273 // ModuleItem : | 1297 // ModuleItem : |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1543 // GeneratorDeclaration[+Default] :: | 1567 // GeneratorDeclaration[+Default] :: |
1544 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' | 1568 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' |
1545 default_export = ParseFunctionLiteral( | 1569 default_export = ParseFunctionLiteral( |
1546 default_string, Scanner::Location::invalid(), | 1570 default_string, Scanner::Location::invalid(), |
1547 kSkipFunctionNameCheck, | 1571 kSkipFunctionNameCheck, |
1548 is_generator ? FunctionKind::kGeneratorFunction | 1572 is_generator ? FunctionKind::kGeneratorFunction |
1549 : FunctionKind::kNormalFunction, | 1573 : FunctionKind::kNormalFunction, |
1550 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 1574 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
1551 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1575 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1552 } else { | 1576 } else { |
1553 result = ParseFunctionDeclaration(pos, is_generator, &names, CHECK_OK); | 1577 result = ParseFunctionDeclarationInternal( |
1578 pos, is_generator ? ParseFunctionFlags::kIsGenerator | |
1579 : ParseFunctionFlags::kIsNormal, | |
1580 &names, CHECK_OK); | |
1554 } | 1581 } |
1555 break; | 1582 break; |
1556 } | 1583 } |
1557 | 1584 |
1558 case Token::CLASS: | 1585 case Token::CLASS: |
1559 Consume(Token::CLASS); | 1586 Consume(Token::CLASS); |
1560 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { | 1587 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { |
1561 // ClassDeclaration[+Default] :: | 1588 // ClassDeclaration[+Default] :: |
1562 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' | 1589 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' |
1563 default_export = | 1590 default_export = |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2044 return factory()->NewExpressionStatement( | 2071 return factory()->NewExpressionStatement( |
2045 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), | 2072 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), |
2046 pos); | 2073 pos); |
2047 } | 2074 } |
2048 | 2075 |
2049 | 2076 |
2050 Statement* Parser::ParseFunctionDeclaration( | 2077 Statement* Parser::ParseFunctionDeclaration( |
2051 ZoneList<const AstRawString*>* names, bool* ok) { | 2078 ZoneList<const AstRawString*>* names, bool* ok) { |
2052 Expect(Token::FUNCTION, CHECK_OK); | 2079 Expect(Token::FUNCTION, CHECK_OK); |
2053 int pos = position(); | 2080 int pos = position(); |
2054 bool is_generator = Check(Token::MUL); | 2081 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
2055 return ParseFunctionDeclaration(pos, is_generator, names, ok); | 2082 if (Check(Token::MUL)) { |
2083 flags |= ParseFunctionFlags::kIsGenerator; | |
2084 } | |
2085 return ParseFunctionDeclarationInternal(pos, flags, names, ok); | |
2056 } | 2086 } |
2057 | 2087 |
2088 Statement* Parser::ParseAsyncFunctionDeclaration( | |
2089 ZoneList<const AstRawString*>* names, bool* ok) { | |
2090 DCHECK_EQ(scanner()->current_token(), Token::IDENTIFIER); | |
2091 DCHECK(scanner()->is_literal_contextual_keyword(CStrVector("async"))); | |
2092 int pos = position(); | |
2093 Expect(Token::FUNCTION, CHECK_OK); | |
2094 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; | |
2095 return ParseFunctionDeclarationInternal(pos, flags, names, ok); | |
2096 } | |
2058 | 2097 |
2059 Statement* Parser::ParseFunctionDeclaration( | 2098 Statement* Parser::ParseFunctionDeclarationInternal( |
2060 int pos, bool is_generator, ZoneList<const AstRawString*>* names, | 2099 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, |
2061 bool* ok) { | 2100 bool* ok) { |
2062 // FunctionDeclaration :: | 2101 // FunctionDeclaration :: |
2063 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2102 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
2064 // GeneratorDeclaration :: | 2103 // GeneratorDeclaration :: |
2065 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2104 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
2066 // | 2105 // |
2067 // 'function' and '*' (if present) have been consumed by the caller. | 2106 // 'function' and '*' (if present) have been consumed by the caller. |
2107 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; | |
2108 const bool is_async = flags & ParseFunctionFlags::kIsAsync; | |
2109 DCHECK(!is_generator || !is_async); | |
2110 | |
2068 bool is_strict_reserved = false; | 2111 bool is_strict_reserved = false; |
2069 const AstRawString* name = ParseIdentifierOrStrictReservedWord( | 2112 const AstRawString* name = ParseIdentifierOrStrictReservedWord( |
2070 &is_strict_reserved, CHECK_OK); | 2113 &is_strict_reserved, CHECK_OK); |
2071 | 2114 |
2115 if (V8_UNLIKELY(is_async_function() && is_async && this->IsAwait(name))) { | |
2116 ReportMessageAt(scanner()->location(), | |
2117 MessageTemplate::kAwaitBindingIdentifier); | |
2118 *ok = false; | |
2119 return nullptr; | |
2120 } | |
2121 | |
2072 FuncNameInferrer::State fni_state(fni_); | 2122 FuncNameInferrer::State fni_state(fni_); |
2073 if (fni_ != NULL) fni_->PushEnclosingName(name); | 2123 if (fni_ != NULL) fni_->PushEnclosingName(name); |
2074 FunctionLiteral* fun = ParseFunctionLiteral( | 2124 FunctionLiteral* fun = ParseFunctionLiteral( |
2075 name, scanner()->location(), | 2125 name, scanner()->location(), |
2076 is_strict_reserved ? kFunctionNameIsStrictReserved | 2126 is_strict_reserved ? kFunctionNameIsStrictReserved |
2077 : kFunctionNameValidityUnknown, | 2127 : kFunctionNameValidityUnknown, |
2078 is_generator ? FunctionKind::kGeneratorFunction | 2128 is_generator ? FunctionKind::kGeneratorFunction |
2079 : FunctionKind::kNormalFunction, | 2129 : is_async ? FunctionKind::kAsyncFunction |
2130 : FunctionKind::kNormalFunction, | |
2080 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 2131 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
2081 | 2132 |
2082 // Even if we're not at the top-level of the global or a function | 2133 // Even if we're not at the top-level of the global or a function |
2083 // scope, we treat it as such and introduce the function with its | 2134 // scope, we treat it as such and introduce the function with its |
2084 // initial value upon entering the corresponding scope. | 2135 // initial value upon entering the corresponding scope. |
2085 // In ES6, a function behaves as a lexical binding, except in | 2136 // In ES6, a function behaves as a lexical binding, except in |
2086 // a script scope, or the initial scope of eval or another function. | 2137 // a script scope, or the initial scope of eval or another function. |
2087 VariableMode mode = !scope_->is_declaration_scope() ? LET : VAR; | 2138 VariableMode mode = !scope_->is_declaration_scope() ? LET : VAR; |
2088 VariableProxy* proxy = NewUnresolved(name, mode); | 2139 VariableProxy* proxy = NewUnresolved(name, mode); |
2089 Declaration* declaration = | 2140 Declaration* declaration = |
(...skipping 2093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4183 expected_property_count, arity, duplicate_parameters, function_type, | 4234 expected_property_count, arity, duplicate_parameters, function_type, |
4184 eager_compile_hint, kind, pos); | 4235 eager_compile_hint, kind, pos); |
4185 function_literal->set_function_token_position(function_token_pos); | 4236 function_literal->set_function_token_position(function_token_pos); |
4186 if (should_be_used_once_hint) | 4237 if (should_be_used_once_hint) |
4187 function_literal->set_should_be_used_once_hint(); | 4238 function_literal->set_should_be_used_once_hint(); |
4188 | 4239 |
4189 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4240 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
4190 return function_literal; | 4241 return function_literal; |
4191 } | 4242 } |
4192 | 4243 |
4244 Expression* Parser::ParseAsyncFunctionExpression(bool* ok) { | |
4245 // AsyncFunctionDeclaration :: | |
4246 // async [no LineTerminator here] function ( FormalParameters[Await] ) | |
4247 // { AsyncFunctionBody } | |
4248 // | |
4249 // async [no LineTerminator here] function BindingIdentifier[Await] | |
4250 // ( FormalParameters[Await] ) { AsyncFunctionBody } | |
4251 DCHECK_EQ(scanner()->current_token(), Token::IDENTIFIER); | |
4252 DCHECK(scanner()->is_literal_contextual_keyword(CStrVector("async"))); | |
4253 int pos = position(); | |
4254 Expect(Token::FUNCTION, CHECK_OK); | |
4255 bool is_strict_reserved = false; | |
4256 const AstRawString* name = nullptr; | |
4257 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; | |
4258 | |
4259 if (peek_any_identifier()) { | |
4260 type = FunctionLiteral::kNamedExpression; | |
4261 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | |
4262 if (this->IsAwait(name)) { | |
4263 ReportMessageAt(scanner()->location(), | |
4264 MessageTemplate::kAwaitBindingIdentifier); | |
4265 *ok = false; | |
4266 return nullptr; | |
4267 } | |
4268 } | |
4269 return ParseFunctionLiteral(name, scanner()->location(), | |
4270 is_strict_reserved ? kFunctionNameIsStrictReserved | |
4271 : kFunctionNameValidityUnknown, | |
4272 FunctionKind::kAsyncFunction, pos, type, | |
4273 language_mode(), CHECK_OK); | |
4274 } | |
4193 | 4275 |
4194 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, | 4276 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
4195 int* expected_property_count, bool* ok, | 4277 int* expected_property_count, bool* ok, |
4196 Scanner::BookmarkScope* bookmark) { | 4278 Scanner::BookmarkScope* bookmark) { |
4197 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); | 4279 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); |
4198 if (produce_cached_parse_data()) CHECK(log_); | 4280 if (produce_cached_parse_data()) CHECK(log_); |
4199 | 4281 |
4200 int function_block_pos = position(); | 4282 int function_block_pos = position(); |
4201 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { | 4283 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { |
4202 // If we have cached data, we use it to skip parsing the function body. The | 4284 // If we have cached data, we use it to skip parsing the function body. The |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4587 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), | 4669 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
4588 NULL, stack_limit_); | 4670 NULL, stack_limit_); |
4589 reusable_preparser_->set_allow_lazy(true); | 4671 reusable_preparser_->set_allow_lazy(true); |
4590 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 4672 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
4591 SET_ALLOW(natives); | 4673 SET_ALLOW(natives); |
4592 SET_ALLOW(harmony_do_expressions); | 4674 SET_ALLOW(harmony_do_expressions); |
4593 SET_ALLOW(harmony_function_name); | 4675 SET_ALLOW(harmony_function_name); |
4594 SET_ALLOW(harmony_function_sent); | 4676 SET_ALLOW(harmony_function_sent); |
4595 SET_ALLOW(harmony_exponentiation_operator); | 4677 SET_ALLOW(harmony_exponentiation_operator); |
4596 SET_ALLOW(harmony_restrictive_declarations); | 4678 SET_ALLOW(harmony_restrictive_declarations); |
4679 SET_ALLOW(harmony_async_await); | |
4597 #undef SET_ALLOW | 4680 #undef SET_ALLOW |
4598 } | 4681 } |
4599 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 4682 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
4600 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), | 4683 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), |
4601 logger, bookmark); | 4684 logger, bookmark); |
4602 if (pre_parse_timer_ != NULL) { | 4685 if (pre_parse_timer_ != NULL) { |
4603 pre_parse_timer_->Stop(); | 4686 pre_parse_timer_->Stop(); |
4604 } | 4687 } |
4605 return result; | 4688 return result; |
4606 } | 4689 } |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5272 ++use_counts_[feature]; | 5355 ++use_counts_[feature]; |
5273 scope->SetLanguageMode(mode); | 5356 scope->SetLanguageMode(mode); |
5274 } | 5357 } |
5275 | 5358 |
5276 | 5359 |
5277 void Parser::RaiseLanguageMode(LanguageMode mode) { | 5360 void Parser::RaiseLanguageMode(LanguageMode mode) { |
5278 LanguageMode old = scope_->language_mode(); | 5361 LanguageMode old = scope_->language_mode(); |
5279 SetLanguageMode(scope_, old > mode ? old : mode); | 5362 SetLanguageMode(scope_, old > mode ? old : mode); |
5280 } | 5363 } |
5281 | 5364 |
5365 Expression* ParserTraits::ExpressionListToExpression( | |
5366 ZoneList<Expression*>* args) { | |
5367 AstNodeFactory* factory = parser_->factory(); | |
5368 Expression* expr = args->at(0); | |
5369 for (int i = 1; i < args->length(); ++i) { | |
5370 expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i), | |
5371 expr->position()); | |
5372 } | |
5373 return expr; | |
5374 } | |
5282 | 5375 |
5283 void ParserTraits::RewriteDestructuringAssignments() { | 5376 void ParserTraits::RewriteDestructuringAssignments() { |
5284 parser_->RewriteDestructuringAssignments(); | 5377 parser_->RewriteDestructuringAssignments(); |
5285 } | 5378 } |
5286 | 5379 |
5287 Expression* ParserTraits::RewriteExponentiation(Expression* left, | 5380 Expression* ParserTraits::RewriteExponentiation(Expression* left, |
5288 Expression* right, int pos) { | 5381 Expression* right, int pos) { |
5289 return parser_->RewriteExponentiation(left, right, pos); | 5382 return parser_->RewriteExponentiation(left, right, pos); |
5290 } | 5383 } |
5291 | 5384 |
5292 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, | 5385 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, |
5293 Expression* right, | 5386 Expression* right, |
5294 int pos) { | 5387 int pos) { |
5295 return parser_->RewriteAssignExponentiation(left, right, pos); | 5388 return parser_->RewriteAssignExponentiation(left, right, pos); |
5296 } | 5389 } |
5297 | 5390 |
5298 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, | 5391 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, |
5299 bool* ok) { | 5392 bool* ok) { |
5300 parser_->RewriteNonPattern(classifier, ok); | 5393 parser_->RewriteNonPattern(classifier, ok); |
5301 } | 5394 } |
5302 | 5395 |
5396 Expression* ParserTraits::RewriteAwaitExpression(Expression* value, int pos) { | |
5397 // TODO(caitp): Implement AsyncFunctionAwait() | |
5398 // per tc39.github.io/ecmascript-asyncawait/#abstract-ops-async-function-await | |
5399 return value; | |
5400 } | |
5303 | 5401 |
5304 Zone* ParserTraits::zone() const { | 5402 Zone* ParserTraits::zone() const { |
5305 return parser_->function_state_->scope()->zone(); | 5403 return parser_->function_state_->scope()->zone(); |
5306 } | 5404 } |
5307 | 5405 |
5308 | 5406 |
5309 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { | 5407 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { |
5310 return parser_->function_state_->non_patterns_to_rewrite(); | 5408 return parser_->function_state_->non_patterns_to_rewrite(); |
5311 } | 5409 } |
5312 | 5410 |
(...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6782 try_block, target); | 6880 try_block, target); |
6783 final_loop = target; | 6881 final_loop = target; |
6784 } | 6882 } |
6785 | 6883 |
6786 return final_loop; | 6884 return final_loop; |
6787 } | 6885 } |
6788 | 6886 |
6789 | 6887 |
6790 } // namespace internal | 6888 } // namespace internal |
6791 } // namespace v8 | 6889 } // namespace v8 |
OLD | NEW |