Chromium Code Reviews| Index: src/parsing/parser-base.h |
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h |
| index 686c53b51a40487b2fd587458118e7253a5122aa..e41d2e8fc2811b80b8f37fa206c7f18195eb421d 100644 |
| --- a/src/parsing/parser-base.h |
| +++ b/src/parsing/parser-base.h |
| @@ -209,6 +209,7 @@ class ParserBase { |
| scanner_(scanner), |
| stack_overflow_(false), |
| default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), |
| + function_literal_num_(0), |
| allow_natives_(false), |
| allow_tailcalls_(false), |
| allow_harmony_do_expressions_(false), |
| @@ -246,6 +247,12 @@ class ParserBase { |
| return default_eager_compile_hint_; |
| } |
| + int GetNextFunctionLiteralNum() { return ++function_literal_num_; } |
| + |
| + void SkipFunctionLiterals(int delta) { function_literal_num_ += delta; } |
| + |
| + void ResetFunctionLiteralNum() { function_literal_num_ = 0; } |
| + |
| Zone* zone() const { return zone_; } |
| protected: |
| @@ -1154,7 +1161,8 @@ class ParserBase { |
| ExpressionT ParseObjectLiteral(bool* ok); |
| ClassLiteralPropertyT ParseClassPropertyDefinition( |
| ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, |
| - bool* has_seen_constructor, bool* ok); |
| + bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, |
| + bool* is_static, bool* ok); |
| FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, |
| bool* ok); |
| ObjectLiteralPropertyT ParseObjectPropertyDefinition( |
| @@ -1179,7 +1187,7 @@ class ParserBase { |
| bool* is_async, bool* ok); |
| ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
| const FormalParametersT& parameters, |
| - bool* ok); |
| + int function_literal_num, bool* ok); |
| void ParseAsyncFunctionBody(Scope* scope, StatementListT body, |
| FunctionKind kind, FunctionBodyType type, |
| bool accept_IN, int pos, bool* ok); |
| @@ -1438,6 +1446,8 @@ class ParserBase { |
| FunctionLiteral::EagerCompileHint default_eager_compile_hint_; |
| + int function_literal_num_; |
| + |
| bool allow_natives_; |
| bool allow_tailcalls_; |
| bool allow_harmony_do_expressions_; |
| @@ -2114,17 +2124,17 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( |
| template <typename Impl> |
| typename ParserBase<Impl>::ClassLiteralPropertyT |
| -ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
| - bool has_extends, |
| - bool* is_computed_name, |
| - bool* has_seen_constructor, |
| - bool* ok) { |
| +ParserBase<Impl>::ParseClassPropertyDefinition( |
| + ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, |
| + bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, |
| + bool* is_static, bool* ok) { |
| DCHECK(has_seen_constructor != nullptr); |
| bool is_get = false; |
| bool is_set = false; |
| bool is_generator = false; |
| bool is_async = false; |
| - bool is_static = false; |
| + *is_static = false; |
| + *property_kind = ClassLiteralProperty::METHOD; |
| PropertyKind kind = PropertyKind::kNotSet; |
| Token::Value name_token = peek(); |
| @@ -2142,7 +2152,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
| name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
| name_expression = factory()->NewStringLiteral(name, position()); |
| } else { |
| - is_static = true; |
| + *is_static = true; |
| name_expression = ParsePropertyName( |
| &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
| is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| @@ -2169,9 +2179,10 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
| ExpressionT function_literal = ParseClassFieldForInitializer( |
| has_initializer, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| ExpectSemicolon(CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| + *property_kind = ClassLiteralProperty::FIELD; |
| return factory()->NewClassLiteralProperty( |
| - name_expression, function_literal, ClassLiteralProperty::FIELD, |
| - is_static, *is_computed_name); |
| + name_expression, function_literal, *property_kind, *is_static, |
| + *is_computed_name); |
| } else { |
| ReportUnexpectedToken(Next()); |
| *ok = false; |
| @@ -2188,7 +2199,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
| if (!*is_computed_name) { |
| checker->CheckClassMethodName( |
| name_token, PropertyKind::kMethodProperty, is_generator, is_async, |
| - is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| + *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| } |
| FunctionKind kind = is_generator |
| @@ -2196,7 +2207,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
| : is_async ? FunctionKind::kAsyncConciseMethod |
| : FunctionKind::kConciseMethod; |
| - if (!is_static && impl()->IsConstructor(name)) { |
| + if (!*is_static && impl()->IsConstructor(name)) { |
| *has_seen_constructor = true; |
| kind = has_extends ? FunctionKind::kSubclassConstructor |
| : FunctionKind::kBaseConstructor; |
| @@ -2207,9 +2218,10 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
| kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
| language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| + *property_kind = ClassLiteralProperty::METHOD; |
| return factory()->NewClassLiteralProperty(name_expression, value, |
| - ClassLiteralProperty::METHOD, |
| - is_static, *is_computed_name); |
| + *property_kind, *is_static, |
| + *is_computed_name); |
| } |
| case PropertyKind::kAccessorProperty: { |
| @@ -2218,7 +2230,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
| if (!*is_computed_name) { |
| checker->CheckClassMethodName( |
| name_token, PropertyKind::kAccessorProperty, false, false, |
| - is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| + *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| // Make sure the name expression is a string since we need a Name for |
| // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
| // this statically we can skip the extra runtime check. |
| @@ -2238,10 +2250,11 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
| impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
| } |
| - return factory()->NewClassLiteralProperty( |
| - name_expression, value, |
| - is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER, |
| - is_static, *is_computed_name); |
| + *property_kind = |
| + is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; |
| + return factory()->NewClassLiteralProperty(name_expression, value, |
| + *property_kind, *is_static, |
| + *is_computed_name); |
| } |
| } |
| UNREACHABLE(); |
| @@ -2279,7 +2292,7 @@ ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, |
| initializer_state.expected_property_count(), 0, 0, |
| FunctionLiteral::kNoDuplicateParameters, |
| FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, |
| - initializer_scope->start_position(), true); |
| + initializer_scope->start_position(), true, GetNextFunctionLiteralNum()); |
| function_literal->set_is_class_field_initializer(true); |
| return function_literal; |
| } |
| @@ -2616,6 +2629,8 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| !scanner()->HasAnyLineTerminatorAfterNext() && |
| IsValidArrowFormalParametersStart(PeekAhead()); |
| + int function_literal_num = GetNextFunctionLiteralNum(); |
| + |
| bool parenthesized_formals = peek() == Token::LPAREN; |
| if (!is_async && !parenthesized_formals) { |
| ArrowFormalParametersUnexpectedToken(); |
| @@ -2680,7 +2695,8 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| if (duplicate_loc.IsValid()) { |
| classifier()->RecordDuplicateFormalParameterError(duplicate_loc); |
| } |
| - expression = ParseArrowFunctionLiteral(accept_IN, parameters, CHECK_OK); |
| + expression = ParseArrowFunctionLiteral(accept_IN, parameters, |
| + function_literal_num, CHECK_OK); |
| impl()->Discard(); |
| classifier()->RecordPatternError(arrow_loc, |
| MessageTemplate::kUnexpectedToken, |
| @@ -2691,6 +2707,12 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| return expression; |
| } |
| + // Reset function_literal_num_ if we didn't parse an arrow function, and |
| + // the expression didn't contain other functions either. |
| + if (function_literal_num == function_literal_num_) { |
|
marja
2016/11/18 10:48:04
Looks like we could just put the function literal
jochen (gone - plz use gerrit)
2016/11/21 08:03:47
I changed the code to not allocate a function lite
|
| + --function_literal_num_; |
| + } |
| + |
| // "expression" was not itself an arrow function parameter list, but it might |
| // form part of one. Propagate speculative formal parameter error locations |
| // (including those for binding patterns, since formal parameters can |
| @@ -3889,7 +3911,8 @@ bool ParserBase<Impl>::IsTrivialExpression() { |
| template <typename Impl> |
| typename ParserBase<Impl>::ExpressionT |
| ParserBase<Impl>::ParseArrowFunctionLiteral( |
| - bool accept_IN, const FormalParametersT& formal_parameters, bool* ok) { |
| + bool accept_IN, const FormalParametersT& formal_parameters, |
| + int function_literal_num, bool* ok) { |
| const RuntimeCallStats::CounterId counters[2][2] = { |
| {&RuntimeCallStats::ParseBackgroundArrowFunctionLiteral, |
| &RuntimeCallStats::ParseArrowFunctionLiteral}, |
| @@ -4048,7 +4071,8 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( |
| formal_parameters.num_parameters(), formal_parameters.function_length, |
| FunctionLiteral::kNoDuplicateParameters, |
| FunctionLiteral::kAnonymousExpression, eager_compile_hint, |
| - formal_parameters.scope->start_position(), has_braces); |
| + formal_parameters.scope->start_position(), has_braces, |
| + function_literal_num); |
| function_literal->set_function_token_position( |
| formal_parameters.scope->start_position()); |
| @@ -4106,14 +4130,17 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral( |
| FuncNameInferrer::State fni_state(fni_); |
| bool is_computed_name = false; // Classes do not care about computed |
| // property names here. |
| + bool is_static; |
| + ClassLiteralProperty::Kind property_kind; |
| ExpressionClassifier property_classifier(this); |
| ClassLiteralPropertyT property = ParseClassPropertyDefinition( |
| &checker, has_extends, &is_computed_name, |
| - &class_info.has_seen_constructor, CHECK_OK); |
| + &class_info.has_seen_constructor, &property_kind, &is_static, CHECK_OK); |
| impl()->RewriteNonPattern(CHECK_OK); |
| impl()->AccumulateFormalParameterContainmentErrors(); |
| - impl()->DeclareClassProperty(name, property, &class_info, CHECK_OK); |
| + impl()->DeclareClassProperty(name, property, property_kind, is_static, |
| + &class_info, CHECK_OK); |
| impl()->InferFunctionName(); |
| } |