Chromium Code Reviews| Index: src/parsing/preparser.h |
| diff --git a/src/parsing/preparser.h b/src/parsing/preparser.h |
| index 58a0137e2664545ae6b45169efbd3c67b06294cf..28074a65af64993a1cb65612458e697f783bc0ce 100644 |
| --- a/src/parsing/preparser.h |
| +++ b/src/parsing/preparser.h |
| @@ -5,6 +5,7 @@ |
| #ifndef V8_PARSING_PREPARSER_H |
| #define V8_PARSING_PREPARSER_H |
| +#include "src/ast/ast.h" |
| #include "src/ast/scopes.h" |
| #include "src/parsing/parser-base.h" |
| #include "src/parsing/preparse-data.h" |
| @@ -126,25 +127,26 @@ class PreParserIdentifier { |
| class PreParserExpression { |
| public: |
| PreParserExpression() |
| - : code_(TypeField::encode(kEmpty)), identifiers_(nullptr) {} |
| + : code_(TypeField::encode(kEmpty)), variables_(nullptr) {} |
| static PreParserExpression Empty() { return PreParserExpression(); } |
| static PreParserExpression Default( |
| - ZoneList<const AstRawString*>* identifiers = nullptr) { |
| - return PreParserExpression(TypeField::encode(kExpression), identifiers); |
| + ZoneList<VariableProxy*>* variables = nullptr) { |
| + return PreParserExpression(TypeField::encode(kExpression), variables); |
| } |
| static PreParserExpression Spread(PreParserExpression expression) { |
| return PreParserExpression(TypeField::encode(kSpreadExpression), |
| - expression.identifiers_); |
| + expression.variables_); |
| } |
| static PreParserExpression FromIdentifier(PreParserIdentifier id, |
| + VariableProxy* variable, |
| Zone* zone) { |
| PreParserExpression expression(TypeField::encode(kIdentifierExpression) | |
| IdentifierTypeField::encode(id.type_)); |
| - expression.AddIdentifier(id.string_, zone); |
| + expression.AddVariable(variable, zone); |
| return expression; |
| } |
| @@ -155,22 +157,22 @@ class PreParserExpression { |
| } |
| static PreParserExpression Assignment( |
| - ZoneList<const AstRawString*>* identifiers = nullptr) { |
| + ZoneList<VariableProxy*>* variables = nullptr) { |
|
neis
2016/12/12 13:01:36
Can we remove the default value here and below? I
marja
2016/12/12 13:36:46
Done.
|
| return PreParserExpression(TypeField::encode(kExpression) | |
| ExpressionTypeField::encode(kAssignment), |
| - identifiers); |
| + variables); |
| } |
| static PreParserExpression ObjectLiteral( |
| - ZoneList<const AstRawString*>* identifiers = nullptr) { |
| + ZoneList<VariableProxy*>* variables = nullptr) { |
| return PreParserExpression(TypeField::encode(kObjectLiteralExpression), |
| - identifiers); |
| + variables); |
| } |
| static PreParserExpression ArrayLiteral( |
| - ZoneList<const AstRawString*>* identifiers = nullptr) { |
| + ZoneList<VariableProxy*>* variables = nullptr) { |
| return PreParserExpression(TypeField::encode(kArrayLiteralExpression), |
| - identifiers); |
| + variables); |
| } |
| static PreParserExpression StringLiteral() { |
| @@ -347,19 +349,18 @@ class PreParserExpression { |
| kAssignment |
| }; |
| - explicit PreParserExpression( |
| - uint32_t expression_code, |
| - ZoneList<const AstRawString*>* identifiers = nullptr) |
| - : code_(expression_code), identifiers_(identifiers) {} |
| + explicit PreParserExpression(uint32_t expression_code, |
| + ZoneList<VariableProxy*>* variables = nullptr) |
| + : code_(expression_code), variables_(variables) {} |
| - void AddIdentifier(const AstRawString* identifier, Zone* zone) { |
| - if (identifier == nullptr) { |
| + void AddVariable(VariableProxy* variable, Zone* zone) { |
| + if (variable == nullptr) { |
| return; |
| } |
| - if (identifiers_ == nullptr) { |
| - identifiers_ = new (zone) ZoneList<const AstRawString*>(1, zone); |
| + if (variables_ == nullptr) { |
| + variables_ = new (zone) ZoneList<VariableProxy*>(1, zone); |
| } |
| - identifiers_->Add(identifier, zone); |
| + variables_->Add(variable, zone); |
| } |
| // The first three bits are for the Type. |
| @@ -382,9 +383,9 @@ class PreParserExpression { |
| typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField; |
| uint32_t code_; |
| - // If the PreParser is used in the identifier tracking mode, |
| - // PreParserExpression accumulates identifiers in that expression. |
| - ZoneList<const AstRawString*>* identifiers_; |
| + // If the PreParser is used in the variable tracking mode, PreParserExpression |
| + // accumulates variables in that expression. |
| + ZoneList<VariableProxy*>* variables_; |
| friend class PreParser; |
| friend class PreParserFactory; |
| @@ -394,13 +395,13 @@ class PreParserExpression { |
| // The pre-parser doesn't need to build lists of expressions, identifiers, or |
| -// the like. If the PreParser is used in identifier tracking mode, it needs to |
| -// build lists of identifiers though. |
| +// the like. If the PreParser is used in variable tracking mode, it needs to |
| +// build lists of variables though. |
| template <typename T> |
| class PreParserList { |
| public: |
| // These functions make list->Add(some_expression) work (and do nothing). |
| - PreParserList() : length_(0), identifiers_(nullptr) {} |
| + PreParserList() : length_(0), variables_(nullptr) {} |
| PreParserList* operator->() { return this; } |
| void Add(T, Zone* zone); |
| int length() const { return length_; } |
| @@ -408,9 +409,9 @@ class PreParserList { |
| bool IsNull() const { return length_ == -1; } |
| private: |
| - explicit PreParserList(int n) : length_(n), identifiers_(nullptr) {} |
| + explicit PreParserList(int n) : length_(n), variables_(nullptr) {} |
| int length_; |
| - ZoneList<const AstRawString*>* identifiers_; |
| + ZoneList<VariableProxy*>* variables_; |
| friend class PreParser; |
| friend class PreParserFactory; |
| @@ -419,14 +420,14 @@ class PreParserList { |
| template <> |
| inline void PreParserList<PreParserExpression>::Add( |
| PreParserExpression expression, Zone* zone) { |
| - if (expression.identifiers_ != nullptr) { |
| + if (expression.variables_ != nullptr) { |
| DCHECK(FLAG_lazy_inner_functions); |
| DCHECK(zone != nullptr); |
| - if (identifiers_ == nullptr) { |
| - identifiers_ = new (zone) ZoneList<const AstRawString*>(1, zone); |
| + if (variables_ == nullptr) { |
| + variables_ = new (zone) ZoneList<VariableProxy*>(1, zone); |
| } |
| - for (auto identifier : (*expression.identifiers_)) { |
| - identifiers_->Add(identifier, zone); |
| + for (auto identifier : (*expression.variables_)) { |
| + variables_->Add(identifier, zone); |
| } |
| } |
| ++length_; |
| @@ -525,7 +526,8 @@ class PreParserStatement { |
| class PreParserFactory { |
| public: |
| explicit PreParserFactory(AstValueFactory* ast_value_factory) |
| - : zone_(ast_value_factory->zone()) {} |
| + : ast_value_factory_(ast_value_factory), |
| + zone_(ast_value_factory->zone()) {} |
| void set_zone(Zone* zone) { zone_ = zone; } |
| @@ -534,7 +536,14 @@ class PreParserFactory { |
| // This is needed for object literal property names. Property names are |
| // normalized to string literals during object literal parsing. |
| PreParserExpression expression = PreParserExpression::Default(); |
| - expression.AddIdentifier(identifier.string_, zone_); |
| + if (identifier.string_ != nullptr) { |
| + DCHECK(FLAG_lazy_inner_functions); |
| + AstNodeFactory factory(ast_value_factory_); |
| + factory.set_zone(zone_); |
| + VariableProxy* variable = |
| + factory.NewVariableProxy(identifier.string_, NORMAL_VARIABLE); |
| + expression.AddVariable(variable, zone_); |
| + } |
|
neis
2016/12/12 13:01:36
Why do we create a variable proxy for a string lit
marja
2016/12/12 13:36:46
Discussed offline: for object literal properties w
|
| return expression; |
| } |
| PreParserExpression NewNumberLiteral(double number, |
| @@ -552,7 +561,7 @@ class PreParserFactory { |
| PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
| int first_spread_index, int literal_index, |
| int pos) { |
| - return PreParserExpression::ArrayLiteral(values.identifiers_); |
| + return PreParserExpression::ArrayLiteral(values.variables_); |
| } |
| PreParserExpression NewClassLiteralProperty(PreParserExpression key, |
| PreParserExpression value, |
| @@ -565,18 +574,18 @@ class PreParserFactory { |
| PreParserExpression value, |
| ObjectLiteralProperty::Kind kind, |
| bool is_computed_name) { |
| - return PreParserExpression::Default(value.identifiers_); |
| + return PreParserExpression::Default(value.variables_); |
| } |
| PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
| PreParserExpression value, |
| bool is_computed_name) { |
| - return PreParserExpression::Default(value.identifiers_); |
| + return PreParserExpression::Default(value.variables_); |
| } |
| PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
| int literal_index, |
| int boilerplate_properties, |
| int pos) { |
| - return PreParserExpression::ObjectLiteral(properties.identifiers_); |
| + return PreParserExpression::ObjectLiteral(properties.variables_); |
| } |
| PreParserExpression NewVariableProxy(void* variable) { |
| return PreParserExpression::Default(); |
| @@ -611,8 +620,8 @@ class PreParserFactory { |
| PreParserExpression left, |
| PreParserExpression right, |
| int pos) { |
| - // For tracking identifiers for parameters with a default value. |
| - return PreParserExpression::Assignment(left.identifiers_); |
| + // For tracking variables for parameters with a default value. |
| + return PreParserExpression::Assignment(left.variables_); |
| } |
| PreParserExpression NewYield(PreParserExpression generator_object, |
| PreParserExpression expression, int pos, |
| @@ -749,6 +758,7 @@ class PreParserFactory { |
| } |
| private: |
| + AstValueFactory* ast_value_factory_; |
| Zone* zone_; |
| }; |
| @@ -1211,10 +1221,16 @@ class PreParser : public ParserBase<PreParser> { |
| V8_INLINE static void CheckAssigningFunctionLiteralToProperty( |
| PreParserExpression left, PreParserExpression right) {} |
| - V8_INLINE static void MarkExpressionAsAssigned( |
| - PreParserExpression expression) { |
| + V8_INLINE void MarkExpressionAsAssigned(PreParserExpression expression) { |
| // TODO(marja): To be able to produce the same errors, the preparser needs |
| // to start tracking which expressions are variables and which are assigned. |
|
neis
2016/12/12 13:01:36
Is this TODO now resolved?
marja
2016/12/12 13:36:46
Sadly, no. It's orthogonal-ish. We still only trac
|
| + if (expression.variables_ != nullptr) { |
| + DCHECK(FLAG_lazy_inner_functions); |
| + DCHECK(track_unresolved_variables_); |
| + for (auto variable : *expression.variables_) { |
| + variable->set_is_assigned(); |
| + } |
| + } |
| } |
| V8_INLINE bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, |
| @@ -1244,6 +1260,7 @@ class PreParser : public ParserBase<PreParser> { |
| InitializeForEachStatement(PreParserStatement stmt, PreParserExpression each, |
| PreParserExpression subject, |
| PreParserStatement body, int each_keyword_pos) { |
| + MarkExpressionAsAssigned(each); |
|
neis
2016/12/12 13:01:36
Maybe reflect this change in the CL description.
marja
2016/12/12 13:36:46
Offline discussion: this falls under the descripti
|
| return stmt; |
| } |
| @@ -1474,9 +1491,9 @@ class PreParser : public ParserBase<PreParser> { |
| if (track_unresolved_variables_) { |
| DCHECK(FLAG_lazy_inner_functions); |
| for (auto parameter : parameters) { |
| - if (parameter->pattern.identifiers_ != nullptr) { |
| - for (auto i : *parameter->pattern.identifiers_) { |
| - scope->DeclareVariableName(i, VAR); |
| + if (parameter->pattern.variables_ != nullptr) { |
| + for (auto variable : *parameter->pattern.variables_) { |
| + scope->DeclareVariableName(variable->raw_name(), VAR); |
| } |
| } |
| } |
| @@ -1511,7 +1528,7 @@ class PreParser : public ParserBase<PreParser> { |
| V8_INLINE PreParserExpression |
| ExpressionListToExpression(PreParserExpressionList args) { |
| - return PreParserExpression::Default(args.identifiers_); |
| + return PreParserExpression::Default(args.variables_); |
| } |
| V8_INLINE void AddAccessorPrefixToFunctionName(bool is_get, |