diff options
Diffstat (limited to 'src/parsing/preparser.h')
-rw-r--r-- | src/parsing/preparser.h | 504 |
1 files changed, 332 insertions, 172 deletions
diff --git a/src/parsing/preparser.h b/src/parsing/preparser.h index f4687eb3..74981270 100644 --- a/src/parsing/preparser.h +++ b/src/parsing/preparser.h @@ -5,8 +5,11 @@ #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" +#include "src/pending-compilation-error-handler.h" namespace v8 { namespace internal { @@ -67,6 +70,9 @@ class PreParserIdentifier { static PreParserIdentifier Async() { return PreParserIdentifier(kAsyncIdentifier); } + static PreParserIdentifier Name() { + return PreParserIdentifier(kNameIdentifier); + } bool IsEmpty() const { return type_ == kEmptyIdentifier; } bool IsEval() const { return type_ == kEvalIdentifier; } bool IsArguments() const { return type_ == kArgumentsIdentifier; } @@ -79,11 +85,7 @@ class PreParserIdentifier { bool IsConstructor() const { return type_ == kConstructorIdentifier; } bool IsEnum() const { return type_ == kEnumIdentifier; } bool IsAwait() const { return type_ == kAwaitIdentifier; } - bool IsFutureStrictReserved() const { - return type_ == kFutureStrictReservedIdentifier || - type_ == kLetIdentifier || type_ == kStaticIdentifier || - type_ == kYieldIdentifier; - } + bool IsName() const { return type_ == kNameIdentifier; } // Allow identifier->name()[->length()] to work. The preparser // does not need the actual positions/lengths of the identifiers. @@ -109,7 +111,8 @@ class PreParserIdentifier { kConstructorIdentifier, kEnumIdentifier, kAwaitIdentifier, - kAsyncIdentifier + kAsyncIdentifier, + kNameIdentifier }; explicit PreParserIdentifier(Type type) : type_(type), string_(nullptr) {} @@ -125,49 +128,65 @@ 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; } static PreParserExpression BinaryOperation(PreParserExpression left, Token::Value op, - PreParserExpression right) { - return PreParserExpression(TypeField::encode(kBinaryOperationExpression)); + PreParserExpression right, + Zone* zone) { + if (op == Token::COMMA) { + // Possibly an arrow function parameter list. + if (left.variables_ == nullptr) { + return PreParserExpression(TypeField::encode(kExpression), + right.variables_); + } + if (right.variables_ != nullptr) { + for (auto variable : *right.variables_) { + left.variables_->Add(variable, zone); + } + } + return PreParserExpression(TypeField::encode(kExpression), + left.variables_); + } + return PreParserExpression(TypeField::encode(kExpression)); } - static PreParserExpression Assignment() { + static PreParserExpression Assignment(ZoneList<VariableProxy*>* variables) { return PreParserExpression(TypeField::encode(kExpression) | - ExpressionTypeField::encode(kAssignment)); + ExpressionTypeField::encode(kAssignment), + variables); } static PreParserExpression ObjectLiteral( - ZoneList<const AstRawString*>* identifiers = nullptr) { + ZoneList<VariableProxy*>* variables) { return PreParserExpression(TypeField::encode(kObjectLiteralExpression), - identifiers); + variables); } - static PreParserExpression ArrayLiteral( - ZoneList<const AstRawString*>* identifiers = nullptr) { + static PreParserExpression ArrayLiteral(ZoneList<VariableProxy*>* variables) { return PreParserExpression(TypeField::encode(kArrayLiteralExpression), - identifiers); + variables); } static PreParserExpression StringLiteral() { @@ -184,9 +203,10 @@ class PreParserExpression { IsUseAsmField::encode(true)); } - static PreParserExpression This() { + static PreParserExpression This(ZoneList<VariableProxy*>* variables) { return PreParserExpression(TypeField::encode(kExpression) | - ExpressionTypeField::encode(kThisExpression)); + ExpressionTypeField::encode(kThisExpression), + variables); } static PreParserExpression ThisProperty() { @@ -284,11 +304,6 @@ class PreParserExpression { ExpressionTypeField::decode(code_) == kCallEvalExpression); } - bool IsDirectEvalCall() const { - return TypeField::decode(code_) == kExpression && - ExpressionTypeField::decode(code_) == kCallEvalExpression; - } - bool IsSuperCallReference() const { return TypeField::decode(code_) == kExpression && ExpressionTypeField::decode(code_) == kSuperCallReference; @@ -313,10 +328,6 @@ class PreParserExpression { PreParserExpression AsFunctionLiteral() { return *this; } - bool IsBinaryOperation() const { - return TypeField::decode(code_) == kBinaryOperationExpression; - } - // Dummy implementation for making expression->somefunc() work in both Parser // and PreParser. PreParserExpression* operator->() { return this; } @@ -329,15 +340,12 @@ class PreParserExpression { int position() const { return kNoSourcePosition; } void set_function_token_position(int position) {} - void set_is_class_field_initializer(bool is_class_field_initializer) {} - private: enum Type { kEmpty, kExpression, kIdentifierExpression, kStringLiteralExpression, - kBinaryOperationExpression, kSpreadExpression, kObjectLiteralExpression, kArrayLiteralExpression @@ -354,19 +362,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. @@ -389,9 +396,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; @@ -401,23 +408,24 @@ 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); + void Add(const T& element, Zone* zone); int length() const { return length_; } static PreParserList Null() { return PreParserList(-1); } bool IsNull() const { return length_ == -1; } + void Set(int index, const T& element) {} 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; @@ -425,22 +433,22 @@ class PreParserList { template <> inline void PreParserList<PreParserExpression>::Add( - PreParserExpression expression, Zone* zone) { - if (expression.identifiers_ != nullptr) { + const PreParserExpression& expression, Zone* zone) { + 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_; } template <typename T> -void PreParserList<T>::Add(T, Zone* zone) { +void PreParserList<T>::Add(const T& element, Zone* zone) { ++length_; } @@ -532,7 +540,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; } @@ -541,7 +550,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_); + } return expression; } PreParserExpression NewNumberLiteral(double number, @@ -552,14 +568,12 @@ class PreParserFactory { return PreParserExpression::Default(); } PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, - int js_flags, int literal_index, - int pos) { + int js_flags, int pos) { return PreParserExpression::Default(); } PreParserExpression NewArrayLiteral(PreParserExpressionList values, - int first_spread_index, int literal_index, - int pos) { - return PreParserExpression::ArrayLiteral(values.identifiers_); + int first_spread_index, int pos) { + return PreParserExpression::ArrayLiteral(values.variables_); } PreParserExpression NewClassLiteralProperty(PreParserExpression key, PreParserExpression value, @@ -572,18 +586,17 @@ 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_); + int boilerplate_properties, int pos, + bool has_rest_property) { + return PreParserExpression::ObjectLiteral(properties.variables_); } PreParserExpression NewVariableProxy(void* variable) { return PreParserExpression::Default(); @@ -604,7 +617,7 @@ class PreParserFactory { PreParserExpression NewBinaryOperation(Token::Value op, PreParserExpression left, PreParserExpression right, int pos) { - return PreParserExpression::BinaryOperation(left, op, right); + return PreParserExpression::BinaryOperation(left, op, right, zone_); } PreParserExpression NewCompareOperation(Token::Value op, PreParserExpression left, @@ -618,7 +631,9 @@ class PreParserFactory { PreParserExpression left, PreParserExpression right, int pos) { - return PreParserExpression::Assignment(); + // Identifiers need to be tracked since this might be a parameter with a + // default value inside an arrow function parameter list. + return PreParserExpression::Assignment(left.variables_); } PreParserExpression NewYield(PreParserExpression generator_object, PreParserExpression expression, int pos, @@ -655,14 +670,17 @@ class PreParserFactory { int pos) { return PreParserStatement::Jump(); } + PreParserStatement NewAsyncReturnStatement(PreParserExpression expression, + int pos) { + return PreParserStatement::Jump(); + } PreParserExpression NewFunctionLiteral( PreParserIdentifier name, Scope* scope, PreParserStatementList body, - int materialized_literal_count, int expected_property_count, - int parameter_count, int function_length, + int expected_property_count, int parameter_count, int function_length, FunctionLiteral::ParameterFlag has_duplicate_parameters, FunctionLiteral::FunctionType function_type, FunctionLiteral::EagerCompileHint eager_compile_hint, int position, - bool has_braces) { + bool has_braces, int function_literal_id) { return PreParserExpression::Default(); } @@ -746,6 +764,17 @@ class PreParserFactory { return PreParserStatement::Default(); } + PreParserStatement NewForOfStatement(ZoneList<const AstRawString*>* labels, + int pos) { + return PreParserStatement::Default(); + } + + PreParserExpression NewCallRuntime(Runtime::FunctionId id, + ZoneList<PreParserExpression>* arguments, + int pos) { + return PreParserExpression::Default(); + } + // Return the object itself as AstVisitor and implement the needed // dummy method right in this class. PreParserFactory* visitor() { return this; } @@ -755,14 +784,32 @@ class PreParserFactory { } private: + AstValueFactory* ast_value_factory_; Zone* zone_; }; struct PreParserFormalParameters : FormalParametersBase { + struct Parameter : public ZoneObject { + Parameter(PreParserExpression pattern, bool is_destructuring, bool is_rest) + : pattern(pattern), + is_destructuring(is_destructuring), + is_rest(is_rest) {} + Parameter** next() { return &next_parameter; } + Parameter* const* next() const { return &next_parameter; } + + bool is_nondestructuring_rest() const { + return is_rest && !is_destructuring; + } + PreParserExpression pattern; + Parameter* next_parameter = nullptr; + bool is_destructuring : 1; + bool is_rest : 1; + }; explicit PreParserFormalParameters(DeclarationScope* scope) : FormalParametersBase(scope) {} - PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy + + ThreadedList<Parameter> params; }; @@ -838,11 +885,14 @@ class PreParser : public ParserBase<PreParser> { kPreParseSuccess }; - PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory, + PreParser(Zone* zone, Scanner* scanner, uintptr_t stack_limit, + AstValueFactory* ast_value_factory, PendingCompilationErrorHandler* pending_error_handler, - RuntimeCallStats* runtime_call_stats, uintptr_t stack_limit) + RuntimeCallStats* runtime_call_stats, + bool parsing_on_main_thread = true) : ParserBase<PreParser>(zone, scanner, stack_limit, nullptr, - ast_value_factory, runtime_call_stats), + ast_value_factory, runtime_call_stats, + parsing_on_main_thread), use_counts_(nullptr), track_unresolved_variables_(false), pending_error_handler_(pending_error_handler) {} @@ -855,17 +905,19 @@ class PreParser : public ParserBase<PreParser> { // success (even if parsing failed, the pre-parse data successfully // captured the syntax error), and false if a stack-overflow happened // during parsing. - PreParseResult PreParseProgram(int* materialized_literals = 0, - bool is_module = false) { - DCHECK_NULL(scope_state_); + PreParseResult PreParseProgram(bool is_module = false) { + DCHECK_NULL(scope_); DeclarationScope* scope = NewScriptScope(); +#ifdef DEBUG + scope->set_is_being_lazily_parsed(true); +#endif // ModuleDeclarationInstantiation for Source Text Module Records creates a // new Module Environment Record whose outer lexical environment record is // the global scope. if (is_module) scope = NewModuleScope(scope); - FunctionState top_scope(&function_state_, &scope_state_, scope); + FunctionState top_scope(&function_state_, &scope_, scope); bool ok = true; int start_position = scanner()->peek_location().beg_pos; parsing_module_ = is_module; @@ -877,11 +929,6 @@ class PreParser : public ParserBase<PreParser> { } else if (is_strict(this->scope()->language_mode())) { CheckStrictOctalLiteral(start_position, scanner()->location().end_pos, &ok); - CheckDecimalLiteralWithLeadingZero(start_position, - scanner()->location().end_pos); - } - if (materialized_literals) { - *materialized_literals = function_state_->materialized_literal_count(); } return kPreParseSuccess; } @@ -911,21 +958,16 @@ class PreParser : public ParserBase<PreParser> { // By making the 'exception handling' explicit, we are forced to check // for failure at the call sites. - V8_INLINE PreParserStatementList ParseEagerFunctionBody( - PreParserIdentifier function_name, int pos, - const PreParserFormalParameters& parameters, FunctionKind kind, - FunctionLiteral::FunctionType function_type, bool* ok); - // Indicates that we won't switch from the preparser to the preparser; we'll // just stay where we are. bool AllowsLazyParsingWithoutUnresolvedVariables() const { return false; } bool parse_lazily() const { return false; } - V8_INLINE LazyParsingResult SkipFunction( - FunctionKind kind, DeclarationScope* function_scope, int* num_parameters, - int* function_length, bool* has_duplicate_parameters, - int* materialized_literal_count, int* expected_property_count, - bool is_inner_function, bool may_abort, bool* ok) { + V8_INLINE LazyParsingResult + SkipFunction(FunctionKind kind, DeclarationScope* function_scope, + int* num_parameters, int* function_length, + bool* has_duplicate_parameters, int* expected_property_count, + bool is_inner_function, bool may_abort, bool* ok) { UNREACHABLE(); return kLazyParsingComplete; } @@ -945,7 +987,8 @@ class PreParser : public ParserBase<PreParser> { } V8_INLINE void AddTemplateExpression(TemplateLiteralState* state, PreParserExpression expression) {} - V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail) {} + V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool should_cook, + bool tail) {} V8_INLINE PreParserExpression CloseTemplateLiteral( TemplateLiteralState* state, int start, PreParserExpression tag); V8_INLINE void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} @@ -958,23 +1001,14 @@ class PreParser : public ParserBase<PreParser> { V8_INLINE void MarkCollectedTailCallExpressions() {} V8_INLINE void MarkTailPosition(PreParserExpression expression) {} - V8_INLINE PreParserExpressionList - PrepareSpreadArguments(PreParserExpressionList list) { - return list; - } - V8_INLINE PreParserExpression SpreadCall(PreParserExpression function, PreParserExpressionList args, - int pos); + int pos, + Call::PossiblyEval possibly_eval); V8_INLINE PreParserExpression SpreadCallNew(PreParserExpression function, PreParserExpressionList args, int pos); - V8_INLINE PreParserExpression - RewriteSuperCall(PreParserExpression call_expression) { - return call_expression; - } - V8_INLINE void RewriteDestructuringAssignments() {} V8_INLINE PreParserExpression RewriteExponentiation(PreParserExpression left, @@ -1015,8 +1049,7 @@ class PreParser : public ParserBase<PreParser> { bool* ok) { DCHECK(!expr.AsIdentifier().IsEnum()); DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait()); - DCHECK(is_sloppy(language_mode()) || - !IsFutureStrictReserved(expr.AsIdentifier())); + DCHECK(IsIdentifier(expr)); return labels; } @@ -1035,7 +1068,22 @@ class PreParser : public ParserBase<PreParser> { PreParserStatementList cases, Scope* scope) { return PreParserStatement::Default(); } - V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {} + + V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { + if (track_unresolved_variables_) { + if (catch_info->name.string_ != nullptr) { + // Unlike in the parser, we need to declare the catch variable as LET + // variable, so that it won't get hoisted out of the scope. + catch_info->scope->DeclareVariableName(catch_info->name.string_, LET); + } + if (catch_info->pattern.variables_ != nullptr) { + for (auto variable : *catch_info->pattern.variables_) { + scope()->DeclareVariableName(variable->raw_name(), LET); + } + } + } + } + V8_INLINE void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {} V8_INLINE PreParserStatement RewriteTryStatement( PreParserStatement try_block, PreParserStatement catch_block, @@ -1043,6 +1091,16 @@ class PreParser : public ParserBase<PreParser> { return PreParserStatement::Default(); } + V8_INLINE void ParseAndRewriteGeneratorFunctionBody( + int pos, FunctionKind kind, PreParserStatementList body, bool* ok) { + ParseStatementList(body, Token::RBRACE, ok); + } + V8_INLINE void CreateFunctionNameAssignment( + PreParserIdentifier function_name, int pos, + FunctionLiteral::FunctionType function_type, + DeclarationScope* function_scope, PreParserStatementList result, + int index) {} + V8_INLINE PreParserExpression RewriteDoExpression(PreParserStatement body, int pos, bool* ok) { return PreParserExpression::Default(); @@ -1060,9 +1118,18 @@ class PreParser : public ParserBase<PreParser> { } V8_INLINE PreParserStatement DeclareFunction( - PreParserIdentifier variable_name, PreParserExpression function, int pos, - bool is_generator, bool is_async, ZoneList<const AstRawString*>* names, - bool* ok) { + PreParserIdentifier variable_name, PreParserExpression function, + VariableMode mode, int pos, bool is_sloppy_block_function, + ZoneList<const AstRawString*>* names, bool* ok) { + DCHECK_NULL(names); + if (variable_name.string_ != nullptr) { + DCHECK(track_unresolved_variables_); + scope()->DeclareVariableName(variable_name.string_, mode); + if (is_sloppy_block_function) { + GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name.string_, + scope()); + } + } return Statement::Default(); } @@ -1070,17 +1137,29 @@ class PreParser : public ParserBase<PreParser> { DeclareClass(PreParserIdentifier variable_name, PreParserExpression value, ZoneList<const AstRawString*>* names, int class_token_pos, int end_pos, bool* ok) { + // Preparser shouldn't be used in contexts where we need to track the names. + DCHECK_NULL(names); + if (variable_name.string_ != nullptr) { + DCHECK(track_unresolved_variables_); + scope()->DeclareVariableName(variable_name.string_, LET); + } return PreParserStatement::Default(); } V8_INLINE void DeclareClassVariable(PreParserIdentifier name, - Scope* block_scope, ClassInfo* class_info, + ClassInfo* class_info, int class_token_pos, bool* ok) {} V8_INLINE void DeclareClassProperty(PreParserIdentifier class_name, PreParserExpression property, - ClassInfo* class_info, bool* ok) {} + ClassLiteralProperty::Kind kind, + bool is_static, bool is_constructor, + ClassInfo* class_info, bool* ok) { + } V8_INLINE PreParserExpression RewriteClassLiteral(PreParserIdentifier name, ClassInfo* class_info, int pos, bool* ok) { + bool has_default_constructor = !class_info->has_seen_constructor; + // Account for the default constructor. + if (has_default_constructor) GetNextFunctionLiteralId(); return PreParserExpression::Default(); } @@ -1115,10 +1194,6 @@ class PreParser : public ParserBase<PreParser> { return identifier.IsAwait(); } - V8_INLINE bool IsFutureStrictReserved(PreParserIdentifier identifier) const { - return identifier.IsFutureStrictReserved(); - } - // Returns true if the expression is of type "this.foo". V8_INLINE static bool IsThisProperty(PreParserExpression expression) { return expression.IsThisProperty(); @@ -1146,8 +1221,8 @@ class PreParser : public ParserBase<PreParser> { return identifier.IsConstructor(); } - V8_INLINE bool IsDirectEvalCall(PreParserExpression expression) const { - return expression.IsDirectEvalCall(); + V8_INLINE bool IsName(PreParserIdentifier identifier) const { + return identifier.IsName(); } V8_INLINE static bool IsBoilerplateProperty(PreParserExpression property) { @@ -1202,11 +1277,16 @@ class PreParser : public ParserBase<PreParser> { V8_INLINE static void CheckAssigningFunctionLiteralToProperty( PreParserExpression left, PreParserExpression right) {} - V8_INLINE static PreParserExpression 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. - return expression; + 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, @@ -1229,6 +1309,11 @@ class PreParser : public ParserBase<PreParser> { V8_INLINE PreParserStatement BuildInitializationBlock(DeclarationParsingResult* parsing_result, ZoneList<const AstRawString*>* names, bool* ok) { + for (auto declaration : parsing_result->declarations) { + DeclareAndInitializeVariables(PreParserStatement::Default(), + &(parsing_result->descriptor), &declaration, + names, ok); + } return PreParserStatement::Default(); } @@ -1236,17 +1321,51 @@ class PreParser : public ParserBase<PreParser> { InitializeForEachStatement(PreParserStatement stmt, PreParserExpression each, PreParserExpression subject, PreParserStatement body, int each_keyword_pos) { + MarkExpressionAsAssigned(each); + return stmt; + } + + V8_INLINE PreParserStatement InitializeForOfStatement( + PreParserStatement stmt, PreParserExpression each, + PreParserExpression iterable, PreParserStatement body, bool finalize, + IteratorType type, int next_result_pos = kNoSourcePosition) { + MarkExpressionAsAssigned(each); return stmt; } V8_INLINE PreParserStatement RewriteForVarInLegacy(const ForInfo& for_info) { return PreParserStatement::Null(); } + V8_INLINE void DesugarBindingInForEachStatement( ForInfo* for_info, PreParserStatement* body_block, - PreParserExpression* each_variable, bool* ok) {} + PreParserExpression* each_variable, bool* ok) { + if (track_unresolved_variables_) { + DCHECK(for_info->parsing_result.declarations.length() == 1); + bool is_for_var_of = + for_info->mode == ForEachStatement::ITERATE && + for_info->parsing_result.descriptor.mode == VariableMode::VAR; + bool collect_names = + IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) || + is_for_var_of; + + DeclareAndInitializeVariables( + PreParserStatement::Default(), &for_info->parsing_result.descriptor, + &for_info->parsing_result.declarations[0], + collect_names ? &for_info->bound_names : nullptr, ok); + } + } + V8_INLINE PreParserStatement CreateForEachStatementTDZ( PreParserStatement init_block, const ForInfo& for_info, bool* ok) { + if (track_unresolved_variables_) { + if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) { + for (auto name : for_info.bound_names) { + scope()->DeclareVariableName(name, LET); + } + return PreParserStatement::Default(); + } + } return init_block; } @@ -1255,9 +1374,43 @@ class PreParser : public ParserBase<PreParser> { PreParserExpression cond, PreParserStatement next, PreParserStatement body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { + // See Parser::DesugarLexicalBindingsInForStatement. + if (track_unresolved_variables_) { + for (auto name : for_info.bound_names) { + inner_scope->DeclareVariableName( + name, for_info.parsing_result.descriptor.mode); + } + } return loop; } + V8_INLINE PreParserStatement BuildParameterInitializationBlock( + const PreParserFormalParameters& parameters, bool* ok) { + if (track_unresolved_variables_) { + for (auto parameter : parameters.params) { + if (parameter->is_nondestructuring_rest()) break; + if (parameter->pattern.variables_ != nullptr) { + for (auto variable : *parameter->pattern.variables_) { + scope()->DeclareVariableName(variable->raw_name(), LET); + } + } + } + } + return PreParserStatement::Default(); + } + + V8_INLINE PreParserStatement + BuildRejectPromiseOnException(PreParserStatement init_block) { + return PreParserStatement::Default(); + } + + V8_INLINE void InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) { + scope->HoistSloppyBlockFunctions(nullptr); + } + + V8_INLINE void InsertShadowingVarBindingInitializers( + PreParserStatement block) {} + V8_INLINE PreParserExpression NewThrowReferenceError(MessageTemplate::Template message, int pos) { return PreParserExpression::Default(); @@ -1374,7 +1527,19 @@ class PreParser : public ParserBase<PreParser> { } V8_INLINE PreParserExpression ThisExpression(int pos = kNoSourcePosition) { - return PreParserExpression::This(); + ZoneList<VariableProxy*>* variables = nullptr; + if (track_unresolved_variables_) { + AstNodeFactory factory(ast_value_factory()); + // Setting the Zone is necessary because zone_ might be the temp Zone, and + // AstValueFactory doesn't know about it. + factory.set_zone(zone()); + VariableProxy* proxy = scope()->NewUnresolved( + &factory, ast_value_factory()->this_string(), pos, THIS_VARIABLE); + + variables = new (zone()) ZoneList<VariableProxy*>(1, zone()); + variables->Add(proxy, zone()); + } + return PreParserExpression::This(variables); } V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) { @@ -1449,13 +1614,31 @@ class PreParser : public ParserBase<PreParser> { PreParserExpression initializer, int initializer_end_position, bool is_rest) { + if (track_unresolved_variables_) { + DCHECK(FLAG_lazy_inner_functions); + parameters->params.Add(new (zone()) PreParserFormalParameters::Parameter( + pattern, !IsIdentifier(pattern), is_rest)); + } parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest); } - V8_INLINE void DeclareFormalParameter(DeclarationScope* scope, - PreParserIdentifier parameter) { - if (!classifier()->is_simple_parameter_list()) { - scope->SetHasNonSimpleParameters(); + V8_INLINE void DeclareFormalParameters( + DeclarationScope* scope, + const ThreadedList<PreParserFormalParameters::Parameter>& parameters) { + bool is_simple = classifier()->is_simple_parameter_list(); + if (!is_simple) scope->SetHasNonSimpleParameters(); + if (track_unresolved_variables_) { + DCHECK(FLAG_lazy_inner_functions); + for (auto parameter : parameters) { + bool use_name = is_simple || parameter->is_nondestructuring_rest(); + if (use_name) { + DCHECK_NOT_NULL(parameter->pattern.variables_); + DCHECK_EQ(parameter->pattern.variables_->length(), 1); + auto variable = (*parameter->pattern.variables_)[0]; + scope->DeclareParameterName(variable->raw_name(), parameter->is_rest, + ast_value_factory()); + } + } } } @@ -1465,10 +1648,16 @@ class PreParser : public ParserBase<PreParser> { bool* ok) { // TODO(wingo): Detect duplicated identifiers in paramlists. Detect // parameter lists that are too long. + if (track_unresolved_variables_) { + DCHECK(FLAG_lazy_inner_functions); + if (params.variables_ != nullptr) { + for (auto variable : *params.variables_) { + parameters->scope->DeclareVariableName(variable->raw_name(), VAR); + } + } + } } - V8_INLINE void ReindexLiterals(const PreParserFormalParameters& parameters) {} - V8_INLINE PreParserExpression NoTemplateTag() { return PreParserExpression::NoTemplateTag(); } @@ -1477,15 +1666,9 @@ class PreParser : public ParserBase<PreParser> { return !tag.IsNoTemplateTag(); } - V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) { - for (int i = 0; i < count; ++i) { - function_state_->NextMaterializedLiteralIndex(); - } - } - V8_INLINE PreParserExpression ExpressionListToExpression(PreParserExpressionList args) { - return PreParserExpression::Default(args.identifiers_); + return PreParserExpression::Default(args.variables_); } V8_INLINE void AddAccessorPrefixToFunctionName(bool is_get, @@ -1509,6 +1692,8 @@ class PreParser : public ParserBase<PreParser> { if (use_counts_ != nullptr) ++use_counts_[feature]; } + V8_INLINE bool ParsingDynamicFunctionDeclaration() const { return false; } + // Preparser's private field members. int* use_counts_; @@ -1518,9 +1703,9 @@ class PreParser : public ParserBase<PreParser> { }; PreParserExpression PreParser::SpreadCall(PreParserExpression function, - PreParserExpressionList args, - int pos) { - return factory()->NewCall(function, args, pos); + PreParserExpressionList args, int pos, + Call::PossiblyEval possibly_eval) { + return factory()->NewCall(function, args, pos, possibly_eval); } PreParserExpression PreParser::SpreadCallNew(PreParserExpression function, @@ -1529,34 +1714,9 @@ PreParserExpression PreParser::SpreadCallNew(PreParserExpression function, return factory()->NewCallNew(function, args, pos); } -PreParserStatementList PreParser::ParseEagerFunctionBody( - PreParserIdentifier function_name, int pos, - const PreParserFormalParameters& parameters, FunctionKind kind, - FunctionLiteral::FunctionType function_type, bool* ok) { - PreParserStatementList result; - - Scope* inner_scope = scope(); - if (!parameters.is_simple) inner_scope = NewScope(BLOCK_SCOPE); - - { - BlockState block_state(&scope_state_, inner_scope); - ParseStatementList(result, Token::RBRACE, ok); - if (!*ok) return PreParserStatementList(); - } - - Expect(Token::RBRACE, ok); - return result; -} - PreParserExpression PreParser::CloseTemplateLiteral(TemplateLiteralState* state, int start, PreParserExpression tag) { - if (IsTaggedTemplate(tag)) { - // Emulate generation of array literals for tag callsite - // 1st is array of cooked strings, second is array of raw strings - function_state_->NextMaterializedLiteralIndex(); - function_state_->NextMaterializedLiteralIndex(); - } return EmptyExpression(); } |