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(); |
} |