Index: src/preparser.h |
diff --git a/src/preparser.h b/src/preparser.h |
index 07e431bfc54790b0a65c081f9ea8021ab6fba84c..8f7764730257a1bc1a1ecac423fa177971a3dbc5 100644 |
--- a/src/preparser.h |
+++ b/src/preparser.h |
@@ -703,7 +703,12 @@ class ParserBase : public Traits { |
bool* ok); |
void ParseFormalParameter(FormalParametersT* parameters, |
- ExpressionClassifier* classifier, bool* ok); |
+ ExpressionClassifier* classifier, int start_pos, |
+ bool* ok); |
+ inline void ParseFormalParameter(FormalParametersT* parameters, |
adamk
2015/08/28 23:26:37
Is it really worth having two versions of this met
caitp (gmail)
2015/08/28 23:58:01
Sure, this way just seemed like less work than hun
caitp (gmail)
2015/08/29 15:51:59
Method is gone, isn't needed without the AST node
|
+ ExpressionClassifier* classifier, bool* ok) { |
+ ParseFormalParameter(parameters, classifier, peek_position(), ok); |
+ } |
void ParseFormalParameterList(FormalParametersT* parameters, |
ExpressionClassifier* classifier, bool* ok); |
void CheckArityRestrictions( |
@@ -917,7 +922,10 @@ class PreParserExpression { |
static PreParserExpression BinaryOperation(PreParserExpression left, |
Token::Value op, |
PreParserExpression right) { |
- return PreParserExpression(TypeField::encode(kBinaryOperationExpression)); |
+ return PreParserExpression( |
+ TypeField::encode(kBinaryOperationExpression) | |
+ BinaryOperationTokenField::encode(op) | |
adamk
2015/08/28 23:26:37
This seems overly general. Can you get away with j
caitp (gmail)
2015/08/28 23:58:01
Acknowledged
|
+ HasRestField::encode(right->IsSpreadExpression())); |
} |
static PreParserExpression StringLiteral() { |
@@ -972,6 +980,8 @@ class PreParserExpression { |
return TypeField::decode(code_) == kIdentifierExpression; |
} |
+ PreParserExpression AsVariableProxy() const { return *this; } |
adamk
2015/08/28 23:26:37
If you end up needing this, it seems like it shoul
caitp (gmail)
2015/08/28 23:58:01
If it only returns false for `this`, that's probab
caitp (gmail)
2015/08/29 15:51:59
It's not needed without the new AST node, so it's
|
+ |
PreParserIdentifier AsIdentifier() const { |
DCHECK(IsIdentifier()); |
return PreParserIdentifier(IdentifierTypeField::decode(code_)); |
@@ -1034,6 +1044,14 @@ class PreParserExpression { |
return TypeField::decode(code_) == kSpreadExpression; |
} |
+ bool HasRestParameter() const { |
+ // Preparser's way of determining if an arrow function has a rest parameter. |
+ return IsSpreadExpression() || |
+ (IsBinaryOperation() && |
+ BinaryOperationTokenField::decode(code_) == Token::COMMA && |
adamk
2015/08/28 23:26:37
I'm not sure that you're getting much from this to
caitp (gmail)
2015/08/28 23:58:01
It's important for making lazy parsing work with a
adamk
2015/08/29 01:01:07
I think I wasn't as clear as I could have been. I
caitp (gmail)
2015/08/29 15:51:59
Done.
|
+ HasRestField::decode(code_)); |
+ } |
+ |
PreParserExpression AsFunctionLiteral() { return *this; } |
bool IsBinaryOperation() const { |
@@ -1082,6 +1100,8 @@ class PreParserExpression { |
typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> |
IdentifierTypeField; |
+ typedef BitField<Token::Value, TypeField::kNext, 8> BinaryOperationTokenField; |
+ typedef BitField<bool, BinaryOperationTokenField::kNext, 1> HasRestField; |
uint32_t code_; |
}; |
@@ -1225,6 +1245,10 @@ class PreParserFactory { |
PreParserExpression NewVariableProxy(void* variable) { |
return PreParserExpression::Default(); |
} |
+ PreParserExpression NewRestParameter(PreParserExpression param, int index, |
+ int position) { |
+ return PreParserExpression::Default(); |
+ } |
PreParserExpression NewProperty(PreParserExpression obj, |
PreParserExpression key, |
int pos) { |
@@ -1854,6 +1878,12 @@ void PreParserTraits::ParseArrowFunctionFormalParameterList( |
Scanner::Location* duplicate_loc, bool* ok) { |
// TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter |
// lists that are too long. |
+ |
+ // Accomodate array literal for rest parameter. |
+ if (params.HasRestParameter()) { |
+ ++parameters->materialized_literals_count; |
+ pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
+ } |
} |
@@ -2862,16 +2892,19 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
scope->SetHasNonSimpleParameters(); |
parameters.is_simple = false; |
} |
- checkpoint.Restore(¶meters.materialized_literals_count); |
- scope->set_start_position(lhs_beg_pos); |
Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, |
adamk
2015/08/28 23:26:37
So this had to move up because it now affects mate
caitp (gmail)
2015/08/28 23:58:01
Yeah :( I tried to find a better way to do it, but
adamk
2015/08/29 01:01:07
No need for a comment, as long as a test will fail
|
&duplicate_loc, CHECK_OK); |
+ |
+ checkpoint.Restore(¶meters.materialized_literals_count); |
+ |
+ scope->set_start_position(lhs_beg_pos); |
if (duplicate_loc.IsValid()) { |
arrow_formals_classifier.RecordDuplicateFormalParameterError( |
duplicate_loc); |
} |
+ |
expression = this->ParseArrowFunctionLiteral( |
parameters, arrow_formals_classifier, CHECK_OK); |
return expression; |
@@ -3656,8 +3689,9 @@ ParserBase<Traits>::ParseMemberExpressionContinuation( |
template <class Traits> |
-void ParserBase<Traits>::ParseFormalParameter( |
- FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { |
+void ParserBase<Traits>::ParseFormalParameter(FormalParametersT* parameters, |
+ ExpressionClassifier* classifier, |
+ int start_pos, bool* ok) { |
// FormalParameter[Yield,GeneratorParameter] : |
// BindingElement[?Yield, ?GeneratorParameter] |
bool is_rest = parameters->has_rest; |
@@ -3679,6 +3713,13 @@ void ParserBase<Traits>::ParseFormalParameter( |
classifier->RecordNonSimpleParameter(); |
} |
+ if (is_rest) { |
+ pattern = factory()->NewRestParameter( |
+ pattern->AsVariableProxy(), |
+ function_state_->NextMaterializedLiteralIndex(), start_pos); |
+ ++parameters->materialized_literals_count; |
+ } |
+ |
ExpressionT initializer = Traits::EmptyExpression(); |
if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { |
ExpressionClassifier init_classifier; |
@@ -3713,6 +3754,7 @@ void ParserBase<Traits>::ParseFormalParameterList( |
DCHECK_EQ(0, parameters->Arity()); |
+ int parameter_start; |
if (peek() != Token::RPAREN) { |
do { |
if (parameters->Arity() > Code::kMaxArguments) { |
@@ -3720,9 +3762,11 @@ void ParserBase<Traits>::ParseFormalParameterList( |
*ok = false; |
return; |
} |
+ parameter_start = peek_position(); |
parameters->has_rest = |
allow_harmony_rest_parameters() && Check(Token::ELLIPSIS); |
- ParseFormalParameter(parameters, classifier, ok); |
+ |
+ ParseFormalParameter(parameters, classifier, parameter_start, ok); |
if (!*ok) return; |
} while (!parameters->has_rest && Check(Token::COMMA)); |
@@ -3817,6 +3861,12 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
body = this->NewStatementList(0, zone()); |
this->SkipLazyFunctionBody(&materialized_literal_count, |
&expected_property_count, CHECK_OK); |
+ |
+ if (formal_parameters.has_rest) { |
+ DCHECK(formal_parameters.materialized_literals_count > 0); |
adamk
2015/08/28 23:26:37
Would this ever be anything other than 1 in this c
caitp (gmail)
2015/08/28 23:58:01
Yes --- I believe initializers with materialized l
adamk
2015/08/29 01:01:07
Ah, I meant to say "can this ever happen without d
caitp (gmail)
2015/08/29 15:51:59
I've changed it to always add the formals material
|
+ materialized_literal_count += |
+ formal_parameters.materialized_literals_count; |
+ } |
} else { |
body = this->ParseEagerFunctionBody( |
this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |