1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "src/allocation.h"
10 #include "src/compiler.h" // TODO(titzer): remove this include dependency
11 #include "src/pending-compilation-error-handler.h"
12 #include "src/preparse-data.h"
13 #include "src/preparse-data-format.h"
14 #include "src/preparser.h"
15 #include "src/scopes.h"
25 // A container for the inputs, configuration options, and outputs of parsing.
28 explicit ParseInfo(Zone* zone);
29 ParseInfo(Zone* zone, Handle<JSFunction> function);
30 ParseInfo(Zone* zone, Handle<Script> script);
31 // TODO(all) Only used via Debug::FindSharedFunctionInfoInScript, remove?
32 ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared);
35 if (ast_value_factory_owned()) {
36 delete ast_value_factory_;
37 set_ast_value_factory_owned(false);
39 ast_value_factory_ = nullptr;
42 Zone* zone() { return zone_; }
44 // Convenience accessor methods for flags.
45 #define FLAG_ACCESSOR(flag, getter, setter) \
46 bool getter() const { return GetFlag(flag); } \
47 void setter() { SetFlag(flag); } \
48 void setter(bool val) { SetFlag(flag, val); }
50 FLAG_ACCESSOR(kToplevel, is_toplevel, set_toplevel)
51 FLAG_ACCESSOR(kLazy, is_lazy, set_lazy)
52 FLAG_ACCESSOR(kEval, is_eval, set_eval)
53 FLAG_ACCESSOR(kGlobal, is_global, set_global)
54 FLAG_ACCESSOR(kStrictMode, is_strict_mode, set_strict_mode)
55 FLAG_ACCESSOR(kStrongMode, is_strong_mode, set_strong_mode)
56 FLAG_ACCESSOR(kNative, is_native, set_native)
57 FLAG_ACCESSOR(kModule, is_module, set_module)
58 FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing)
59 FLAG_ACCESSOR(kAstValueFactoryOwned, ast_value_factory_owned,
60 set_ast_value_factory_owned)
64 void set_parse_restriction(ParseRestriction restriction) {
65 SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION);
68 ParseRestriction parse_restriction() const {
69 return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL
70 : NO_PARSE_RESTRICTION;
73 ScriptCompiler::ExternalSourceStream* source_stream() {
74 return source_stream_;
76 void set_source_stream(ScriptCompiler::ExternalSourceStream* source_stream) {
77 source_stream_ = source_stream;
80 ScriptCompiler::StreamedSource::Encoding source_stream_encoding() {
81 return source_stream_encoding_;
83 void set_source_stream_encoding(
84 ScriptCompiler::StreamedSource::Encoding source_stream_encoding) {
85 source_stream_encoding_ = source_stream_encoding;
88 v8::Extension* extension() { return extension_; }
89 void set_extension(v8::Extension* extension) { extension_ = extension; }
91 ScriptData** cached_data() { return cached_data_; }
92 void set_cached_data(ScriptData** cached_data) { cached_data_ = cached_data; }
94 ScriptCompiler::CompileOptions compile_options() { return compile_options_; }
95 void set_compile_options(ScriptCompiler::CompileOptions compile_options) {
96 compile_options_ = compile_options;
99 Scope* script_scope() { return script_scope_; }
100 void set_script_scope(Scope* script_scope) { script_scope_ = script_scope; }
102 AstValueFactory* ast_value_factory() { return ast_value_factory_; }
103 void set_ast_value_factory(AstValueFactory* ast_value_factory) {
104 ast_value_factory_ = ast_value_factory;
107 FunctionLiteral* function() { // TODO(titzer): temporary name adapter
110 FunctionLiteral* literal() { return literal_; }
111 void set_literal(FunctionLiteral* literal) { literal_ = literal; }
113 Scope* scope() { return scope_; }
114 void set_scope(Scope* scope) { scope_ = scope; }
116 UnicodeCache* unicode_cache() { return unicode_cache_; }
117 void set_unicode_cache(UnicodeCache* unicode_cache) {
118 unicode_cache_ = unicode_cache;
121 uintptr_t stack_limit() { return stack_limit_; }
122 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
124 uint32_t hash_seed() { return hash_seed_; }
125 void set_hash_seed(uint32_t hash_seed) { hash_seed_ = hash_seed; }
127 //--------------------------------------------------------------------------
128 // TODO(titzer): these should not be part of ParseInfo.
129 //--------------------------------------------------------------------------
130 Isolate* isolate() { return isolate_; }
131 Handle<JSFunction> closure() { return closure_; }
132 Handle<SharedFunctionInfo> shared_info() { return shared_; }
133 Handle<Script> script() { return script_; }
134 Handle<Context> context() { return context_; }
135 void clear_script() { script_ = Handle<Script>::null(); }
136 void set_isolate(Isolate* isolate) { isolate_ = isolate; }
137 void set_context(Handle<Context> context) { context_ = context; }
138 void set_script(Handle<Script> script) { script_ = script; }
139 //--------------------------------------------------------------------------
141 LanguageMode language_mode() {
142 return construct_language_mode(is_strict_mode(), is_strong_mode());
144 void set_language_mode(LanguageMode language_mode) {
145 STATIC_ASSERT(LANGUAGE_END == 3);
146 set_strict_mode(language_mode & STRICT_BIT);
147 set_strong_mode(language_mode & STRONG_BIT);
150 void ReopenHandlesInNewHandleScope() {
151 closure_ = Handle<JSFunction>(*closure_);
152 shared_ = Handle<SharedFunctionInfo>(*shared_);
153 script_ = Handle<Script>(*script_);
154 context_ = Handle<Context>(*context_);
158 // Various configuration flags for parsing.
160 // ---------- Input flags ---------------------------
165 kStrictMode = 1 << 4,
166 kStrongMode = 1 << 5,
168 kParseRestriction = 1 << 7,
170 kAllowLazyParsing = 1 << 9,
171 // ---------- Output flags --------------------------
172 kAstValueFactoryOwned = 1 << 10
175 //------------- Inputs to parsing and scope analysis -----------------------
178 ScriptCompiler::ExternalSourceStream* source_stream_;
179 ScriptCompiler::StreamedSource::Encoding source_stream_encoding_;
180 v8::Extension* extension_;
181 ScriptCompiler::CompileOptions compile_options_;
182 Scope* script_scope_;
183 UnicodeCache* unicode_cache_;
184 uintptr_t stack_limit_;
187 // TODO(titzer): Move handles and isolate out of ParseInfo.
189 Handle<JSFunction> closure_;
190 Handle<SharedFunctionInfo> shared_;
191 Handle<Script> script_;
192 Handle<Context> context_;
194 //----------- Inputs+Outputs of parsing and scope analysis -----------------
195 ScriptData** cached_data_; // used if available, populated if requested.
196 AstValueFactory* ast_value_factory_; // used if available, otherwise new.
198 //----------- Outputs of parsing and scope analysis ------------------------
199 FunctionLiteral* literal_; // produced by full parser.
200 Scope* scope_; // produced by scope analysis.
202 void SetFlag(Flag f) { flags_ |= f; }
203 void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; }
204 bool GetFlag(Flag f) const { return (flags_ & f) != 0; }
206 void set_shared_info(Handle<SharedFunctionInfo> shared) { shared_ = shared; }
207 void set_closure(Handle<JSFunction> closure) { closure_ = closure; }
210 class FunctionEntry BASE_EMBEDDED {
218 kUsesSuperPropertyIndex,
222 explicit FunctionEntry(Vector<unsigned> backing)
223 : backing_(backing) { }
225 FunctionEntry() : backing_() { }
227 int start_pos() { return backing_[kStartPositionIndex]; }
228 int end_pos() { return backing_[kEndPositionIndex]; }
229 int literal_count() { return backing_[kLiteralCountIndex]; }
230 int property_count() { return backing_[kPropertyCountIndex]; }
231 LanguageMode language_mode() {
232 DCHECK(is_valid_language_mode(backing_[kLanguageModeIndex]));
233 return static_cast<LanguageMode>(backing_[kLanguageModeIndex]);
235 bool uses_super_property() { return backing_[kUsesSuperPropertyIndex]; }
237 bool is_valid() { return !backing_.is_empty(); }
240 Vector<unsigned> backing_;
244 // Wrapper around ScriptData to provide parser-specific functionality.
247 static ParseData* FromCachedData(ScriptData* cached_data) {
248 ParseData* pd = new ParseData(cached_data);
249 if (pd->IsSane()) return pd;
250 cached_data->Reject();
256 FunctionEntry GetFunctionEntry(int start);
261 unsigned* Data() { // Writable data as unsigned int array.
262 return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
265 void Reject() { script_data_->Reject(); }
267 bool rejected() const { return script_data_->rejected(); }
270 explicit ParseData(ScriptData* script_data) : script_data_(script_data) {}
277 // Script data length is already checked to be a multiple of unsigned size.
278 return script_data_->length() / sizeof(unsigned);
281 ScriptData* script_data_;
284 DISALLOW_COPY_AND_ASSIGN(ParseData);
287 // ----------------------------------------------------------------------------
290 // A BufferedZoneList is an automatically growing list, just like (and backed
291 // by) a ZoneList, that is optimized for the case of adding and removing
292 // a single element. The last element added is stored outside the backing list,
293 // and if no more than one element is ever added, the ZoneList isn't even
295 // Elements must not be NULL pointers.
296 template <typename T, int initial_size>
297 class BufferedZoneList {
299 BufferedZoneList() : list_(NULL), last_(NULL) {}
301 // Adds element at end of list. This element is buffered and can
302 // be read using last() or removed using RemoveLast until a new Add or until
303 // RemoveLast or GetList has been called.
304 void Add(T* value, Zone* zone) {
307 list_ = new(zone) ZoneList<T*>(initial_size, zone);
309 list_->Add(last_, zone);
315 DCHECK(last_ != NULL);
320 DCHECK(last_ != NULL);
322 if ((list_ != NULL) && (list_->length() > 0))
323 last_ = list_->RemoveLast();
330 DCHECK((0 <= i) && (i < length()));
335 if (i == list_->length()) {
336 DCHECK(last_ != NULL);
350 int length = (list_ == NULL) ? 0 : list_->length();
351 return length + ((last_ == NULL) ? 0 : 1);
354 ZoneList<T*>* GetList(Zone* zone) {
356 list_ = new(zone) ZoneList<T*>(initial_size, zone);
359 list_->Add(last_, zone);
371 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
372 class RegExpBuilder: public ZoneObject {
374 explicit RegExpBuilder(Zone* zone);
375 void AddCharacter(uc16 character);
376 // "Adds" an empty expression. Does nothing except consume a
377 // following quantifier
379 void AddAtom(RegExpTree* tree);
380 void AddAssertion(RegExpTree* tree);
381 void NewAlternative(); // '|'
382 void AddQuantifierToAtom(
383 int min, int max, RegExpQuantifier::QuantifierType type);
384 RegExpTree* ToRegExp();
387 void FlushCharacters();
390 Zone* zone() const { return zone_; }
394 ZoneList<uc16>* characters_;
395 BufferedZoneList<RegExpTree, 2> terms_;
396 BufferedZoneList<RegExpTree, 2> text_;
397 BufferedZoneList<RegExpTree, 2> alternatives_;
399 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
400 #define LAST(x) last_added_ = x;
407 class RegExpParser BASE_EMBEDDED {
409 RegExpParser(FlatStringReader* in, Handle<String>* error, bool multiline_mode,
410 bool unicode, Isolate* isolate, Zone* zone);
412 static bool ParseRegExp(Isolate* isolate, Zone* zone, FlatStringReader* input,
413 bool multiline, bool unicode,
414 RegExpCompileData* result);
416 RegExpTree* ParsePattern();
417 RegExpTree* ParseDisjunction();
418 RegExpTree* ParseGroup();
419 RegExpTree* ParseCharacterClass();
421 // Parses a {...,...} quantifier and stores the range in the given
423 bool ParseIntervalQuantifier(int* min_out, int* max_out);
425 // Parses and returns a single escaped character. The character
426 // must not be 'b' or 'B' since they are usually handle specially.
427 uc32 ParseClassCharacterEscape();
429 // Checks whether the following is a length-digit hexadecimal number,
430 // and sets the value if it is.
431 bool ParseHexEscape(int length, uc32* value);
432 bool ParseUnicodeEscape(uc32* value);
433 bool ParseUnlimitedLengthHexNumber(int max_value, uc32* value);
435 uc32 ParseOctalLiteral();
437 // Tries to parse the input as a back reference. If successful it
438 // stores the result in the output parameter and returns true. If
439 // it fails it will push back the characters read so the same characters
441 bool ParseBackReferenceIndex(int* index_out);
443 CharacterRange ParseClassAtom(uc16* char_class);
444 RegExpTree* ReportError(Vector<const char> message);
446 void Advance(int dist);
449 // Reports whether the pattern might be used as a literal search string.
450 // Only use if the result of the parse is a single atom node.
452 bool contains_anchor() { return contains_anchor_; }
453 void set_contains_anchor() { contains_anchor_ = true; }
454 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
455 int position() { return next_pos_ - 1; }
456 bool failed() { return failed_; }
458 static bool IsSyntaxCharacter(uc32 c);
460 static const int kMaxCaptures = 1 << 16;
461 static const uc32 kEndMarker = (1 << 21);
464 enum SubexpressionType {
466 CAPTURE, // All positive values represent captures.
472 class RegExpParserState : public ZoneObject {
474 RegExpParserState(RegExpParserState* previous_state,
475 SubexpressionType group_type,
476 int disjunction_capture_index,
478 : previous_state_(previous_state),
479 builder_(new(zone) RegExpBuilder(zone)),
480 group_type_(group_type),
481 disjunction_capture_index_(disjunction_capture_index) {}
482 // Parser state of containing expression, if any.
483 RegExpParserState* previous_state() { return previous_state_; }
484 bool IsSubexpression() { return previous_state_ != NULL; }
485 // RegExpBuilder building this regexp's AST.
486 RegExpBuilder* builder() { return builder_; }
487 // Type of regexp being parsed (parenthesized group or entire regexp).
488 SubexpressionType group_type() { return group_type_; }
489 // Index in captures array of first capture in this sub-expression, if any.
490 // Also the capture index of this sub-expression itself, if group_type
492 int capture_index() { return disjunction_capture_index_; }
495 // Linked list implementation of stack of states.
496 RegExpParserState* previous_state_;
497 // Builder for the stored disjunction.
498 RegExpBuilder* builder_;
499 // Stored disjunction type (capture, look-ahead or grouping), if any.
500 SubexpressionType group_type_;
501 // Stored disjunction's capture index (if any).
502 int disjunction_capture_index_;
505 Isolate* isolate() { return isolate_; }
506 Zone* zone() const { return zone_; }
508 uc32 current() { return current_; }
509 bool has_more() { return has_more_; }
510 bool has_next() { return next_pos_ < in()->length(); }
512 FlatStringReader* in() { return in_; }
513 void ScanForCaptures();
517 Handle<String>* error_;
518 ZoneList<RegExpCapture*>* captures_;
519 FlatStringReader* in_;
522 // The capture count is only valid after we have scanned for captures.
528 bool contains_anchor_;
529 bool is_scanned_for_captures_;
533 // ----------------------------------------------------------------------------
534 // JAVASCRIPT PARSING
537 class SingletonLogger;
542 // TODO(marja): To be removed. The Traits object should contain all the data
544 typedef v8::internal::Parser* Parser;
546 typedef Variable GeneratorVariable;
548 typedef v8::internal::AstProperties AstProperties;
550 // Return types for traversing functions.
551 typedef const AstRawString* Identifier;
552 typedef v8::internal::Expression* Expression;
553 typedef Yield* YieldExpression;
554 typedef v8::internal::FunctionLiteral* FunctionLiteral;
555 typedef v8::internal::ClassLiteral* ClassLiteral;
556 typedef v8::internal::Literal* Literal;
557 typedef ObjectLiteral::Property* ObjectLiteralProperty;
558 typedef ZoneList<v8::internal::Expression*>* ExpressionList;
559 typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
560 typedef ZoneList<v8::internal::Statement*>* StatementList;
562 // For constructing objects returned by the traversing functions.
563 typedef AstNodeFactory Factory;
566 explicit ParserTraits(Parser* parser) : parser_(parser) {}
568 // Helper functions for recursive descent.
569 bool IsEval(const AstRawString* identifier) const;
570 bool IsArguments(const AstRawString* identifier) const;
571 bool IsEvalOrArguments(const AstRawString* identifier) const;
572 V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
574 // Returns true if the expression is of type "this.foo".
575 static bool IsThisProperty(Expression* expression);
577 static bool IsIdentifier(Expression* expression);
579 bool IsPrototype(const AstRawString* identifier) const;
581 bool IsConstructor(const AstRawString* identifier) const;
583 static const AstRawString* AsIdentifier(Expression* expression) {
584 DCHECK(IsIdentifier(expression));
585 return expression->AsVariableProxy()->raw_name();
588 static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
589 return ObjectLiteral::IsBoilerplateProperty(property);
592 static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
593 return string->AsArrayIndex(index);
596 static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
597 return property->value();
600 // Functions for encapsulating the differences between parsing and preparsing;
601 // operations interleaved with the recursive descent.
602 static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
603 fni->PushLiteralName(id);
606 void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
608 static void InferFunctionName(FuncNameInferrer* fni,
609 FunctionLiteral* func_to_infer) {
610 fni->AddFunction(func_to_infer);
613 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
614 Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
615 Expression* value = property->value();
616 if (scope->DeclarationScope()->is_script_scope() &&
617 value->AsFunctionLiteral() != NULL) {
618 *has_function = true;
619 value->AsFunctionLiteral()->set_pretenure();
623 // If we assign a function literal to a property we pretenure the
624 // literal so it can be added as a constant function property.
625 static void CheckAssigningFunctionLiteralToProperty(Expression* left,
628 // Keep track of eval() calls since they disable all local variable
629 // optimizations. This checks if expression is an eval call, and if yes,
630 // forwards the information to scope.
631 void CheckPossibleEvalCall(Expression* expression, Scope* scope);
633 // Determine if the expression is a variable proxy and mark it as being used
634 // in an assignment or with a increment/decrement operator.
635 static Expression* MarkExpressionAsAssigned(Expression* expression);
637 // Returns true if we have a binary expression between two numeric
638 // literals. In that case, *x will be changed to an expression which is the
640 bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
641 Token::Value op, int pos,
642 AstNodeFactory* factory);
644 // Rewrites the following types of unary expressions:
645 // not <literal> -> true / false
646 // + <numeric literal> -> <numeric literal>
647 // - <numeric literal> -> <numeric literal with value negated>
648 // ! <literal> -> true / false
649 // The following rewriting rules enable the collection of type feedback
650 // without any special stub and the multiplication is removed later in
651 // Crankshaft's canonicalization pass.
653 // - foo -> foo * (-1)
654 // ~ foo -> foo ^(~0)
655 Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
656 int pos, AstNodeFactory* factory);
658 // Generate AST node that throws a ReferenceError with the given type.
659 Expression* NewThrowReferenceError(const char* type, int pos);
661 // Generate AST node that throws a SyntaxError with the given
662 // type. The first argument may be null (in the handle sense) in
663 // which case no arguments are passed to the constructor.
664 Expression* NewThrowSyntaxError(
665 const char* type, const AstRawString* arg, int pos);
667 // Generate AST node that throws a TypeError with the given
668 // type. Both arguments must be non-null (in the handle sense).
669 Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
672 // Generic AST generator for throwing errors from compiled code.
673 Expression* NewThrowError(
674 const AstRawString* constructor, const char* type,
675 const AstRawString* arg, int pos);
678 void ReportMessageAt(Scanner::Location source_location, const char* message,
679 const char* arg = NULL,
680 ParseErrorType error_type = kSyntaxError);
681 void ReportMessage(const char* message, const char* arg = NULL,
682 ParseErrorType error_type = kSyntaxError);
683 void ReportMessage(const char* message, const AstRawString* arg,
684 ParseErrorType error_type = kSyntaxError);
685 void ReportMessageAt(Scanner::Location source_location, const char* message,
686 const AstRawString* arg,
687 ParseErrorType error_type = kSyntaxError);
689 // "null" return type creators.
690 static const AstRawString* EmptyIdentifier() {
693 static Expression* EmptyExpression() {
696 static Expression* EmptyArrowParamList() { return NULL; }
697 static Literal* EmptyLiteral() {
700 static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
701 static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
703 // Used in error return values.
704 static ZoneList<Expression*>* NullExpressionList() {
708 // Non-NULL empty string.
709 V8_INLINE const AstRawString* EmptyIdentifierString();
711 // Odd-ball literal creators.
712 Literal* GetLiteralTheHole(int position, AstNodeFactory* factory);
714 // Producing data during the recursive descent.
715 const AstRawString* GetSymbol(Scanner* scanner);
716 const AstRawString* GetNextSymbol(Scanner* scanner);
717 const AstRawString* GetNumberAsSymbol(Scanner* scanner);
719 Expression* ThisExpression(Scope* scope, AstNodeFactory* factory,
720 int pos = RelocInfo::kNoPosition);
721 Expression* SuperReference(Scope* scope, AstNodeFactory* factory,
722 int pos = RelocInfo::kNoPosition);
723 Expression* DefaultConstructor(bool call_super, Scope* scope, int pos,
725 Literal* ExpressionFromLiteral(Token::Value token, int pos, Scanner* scanner,
726 AstNodeFactory* factory);
727 Expression* ExpressionFromIdentifier(const AstRawString* name,
728 int start_position, int end_position,
729 Scope* scope, AstNodeFactory* factory);
730 Expression* ExpressionFromString(int pos, Scanner* scanner,
731 AstNodeFactory* factory);
732 Expression* GetIterator(Expression* iterable, AstNodeFactory* factory);
733 ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
734 return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
736 ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
737 return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
739 ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
740 return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
742 V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type,
743 FunctionKind kind = kNormalFunction);
746 int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
747 Scanner::Location* dupe_loc,
750 // Temporary glue; these functions will move to ParserBase.
751 Expression* ParseV8Intrinsic(bool* ok);
752 FunctionLiteral* ParseFunctionLiteral(
753 const AstRawString* name, Scanner::Location function_name_location,
754 bool name_is_strict_reserved, FunctionKind kind,
755 int function_token_position, FunctionLiteral::FunctionType type,
756 FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
757 V8_INLINE void SkipLazyFunctionBody(const AstRawString* name,
758 int* materialized_literal_count,
759 int* expected_property_count, bool* ok);
760 V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
761 const AstRawString* name, int pos, Variable* fvar,
762 Token::Value fvar_init_op, FunctionKind kind, bool* ok);
764 ClassLiteral* ParseClassLiteral(const AstRawString* name,
765 Scanner::Location class_name_location,
766 bool name_is_strict_reserved, int pos,
769 V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
772 class TemplateLiteral : public ZoneObject {
774 TemplateLiteral(Zone* zone, int pos)
775 : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
777 const ZoneList<Expression*>* cooked() const { return &cooked_; }
778 const ZoneList<Expression*>* raw() const { return &raw_; }
779 const ZoneList<Expression*>* expressions() const { return &expressions_; }
780 int position() const { return pos_; }
782 void AddTemplateSpan(Literal* cooked, Literal* raw, int end, Zone* zone) {
783 DCHECK_NOT_NULL(cooked);
784 DCHECK_NOT_NULL(raw);
785 cooked_.Add(cooked, zone);
789 void AddExpression(Expression* expression, Zone* zone) {
790 DCHECK_NOT_NULL(expression);
791 expressions_.Add(expression, zone);
795 ZoneList<Expression*> cooked_;
796 ZoneList<Expression*> raw_;
797 ZoneList<Expression*> expressions_;
801 typedef TemplateLiteral* TemplateLiteralState;
803 V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos);
804 V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail);
805 V8_INLINE void AddTemplateExpression(TemplateLiteralState* state,
806 Expression* expression);
807 V8_INLINE Expression* CloseTemplateLiteral(TemplateLiteralState* state,
808 int start, Expression* tag);
809 V8_INLINE Expression* NoTemplateTag() { return NULL; }
810 V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
819 class Parser : public ParserBase<ParserTraits> {
821 explicit Parser(ParseInfo* info);
823 delete reusable_preparser_;
824 reusable_preparser_ = NULL;
825 delete cached_parse_data_;
826 cached_parse_data_ = NULL;
829 // Parses the source code represented by the compilation info and sets its
830 // function literal. Returns false (and deallocates any allocated AST
831 // nodes) if parsing failed.
832 static bool ParseStatic(ParseInfo* info);
833 bool Parse(ParseInfo* info);
834 void ParseOnBackground(ParseInfo* info);
836 // Handle errors detected during parsing, move statistics to Isolate,
837 // internalize strings (move them to the heap).
838 void Internalize(Isolate* isolate, Handle<Script> script, bool error);
839 void HandleSourceURLComments(Isolate* isolate, Handle<Script> script);
842 friend class ParserTraits;
844 // Limit the allowed number of local variables in a function. The hard limit
845 // is that offsets computed by FullCodeGenerator::StackOperand and similar
846 // functions are ints, and they should not overflow. In addition, accessing
847 // local variables creates user-controlled constants in the generated code,
848 // and we don't want too much user-controlled memory inside the code (this was
849 // the reason why this limit was introduced in the first place; see
850 // https://codereview.chromium.org/7003030/ ).
851 static const int kMaxNumFunctionLocals = 4194303; // 2^22-1
853 // Returns NULL if parsing failed.
854 FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info);
856 FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info);
857 FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info,
858 Utf16CharacterStream* source);
860 // Called by ParseProgram after setting up the scanner.
861 FunctionLiteral* DoParseProgram(ParseInfo* info, Scope** scope,
862 Scope** ad_hoc_eval_scope);
864 void SetCachedData(ParseInfo* info);
866 bool inside_with() const { return scope_->inside_with(); }
867 ScriptCompiler::CompileOptions compile_options() const {
868 return compile_options_;
870 bool consume_cached_parse_data() const {
871 return compile_options_ == ScriptCompiler::kConsumeParserCache &&
872 cached_parse_data_ != NULL;
874 bool produce_cached_parse_data() const {
875 return compile_options_ == ScriptCompiler::kProduceParserCache;
877 Scope* DeclarationScope(VariableMode mode) {
878 return IsLexicalVariableMode(mode)
879 ? scope_ : scope_->DeclarationScope();
882 // All ParseXXX functions take as the last argument an *ok parameter
883 // which is set to false if parsing failed; it is unchanged otherwise.
884 // By making the 'exception handling' explicit, we are forced to check
885 // for failure at the call sites.
886 void* ParseStatementList(ZoneList<Statement*>* body, int end_token,
887 bool is_eval, Scope** ad_hoc_eval_scope, bool* ok);
888 Statement* ParseStatementListItem(bool* ok);
889 void* ParseModuleItemList(ZoneList<Statement*>* body, bool* ok);
890 Statement* ParseModuleItem(bool* ok);
891 const AstRawString* ParseModuleSpecifier(bool* ok);
892 Statement* ParseImportDeclaration(bool* ok);
893 Statement* ParseExportDeclaration(bool* ok);
894 Statement* ParseExportDefault(bool* ok);
895 void* ParseExportClause(ZoneList<const AstRawString*>* export_names,
896 ZoneList<Scanner::Location>* export_locations,
897 ZoneList<const AstRawString*>* local_names,
898 Scanner::Location* reserved_loc, bool* ok);
899 ZoneList<ImportDeclaration*>* ParseNamedImports(int pos, bool* ok);
900 Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
901 Statement* ParseSubStatement(ZoneList<const AstRawString*>* labels, bool* ok);
902 Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
904 Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
906 Statement* ParseNativeDeclaration(bool* ok);
907 Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
908 Block* ParseVariableStatement(VariableDeclarationContext var_context,
909 ZoneList<const AstRawString*>* names,
911 Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
912 VariableDeclarationProperties* decl_props,
913 ZoneList<const AstRawString*>* names,
914 const AstRawString** out,
916 Statement* ParseExpressionOrLabelledStatement(
917 ZoneList<const AstRawString*>* labels, bool* ok);
918 IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
920 Statement* ParseContinueStatement(bool* ok);
921 Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
923 Statement* ParseReturnStatement(bool* ok);
924 Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
926 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
927 SwitchStatement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
929 DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
931 WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
933 Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
934 Statement* ParseThrowStatement(bool* ok);
935 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
936 TryStatement* ParseTryStatement(bool* ok);
937 DebuggerStatement* ParseDebuggerStatement(bool* ok);
939 // Support for hamony block scoped bindings.
940 Block* ParseScopedBlock(ZoneList<const AstRawString*>* labels, bool* ok);
942 // Initialize the components of a for-in / for-of statement.
943 void InitializeForEachStatement(ForEachStatement* stmt,
947 Statement* DesugarLexicalBindingsInForStatement(
948 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
949 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
950 Statement* body, bool* ok);
952 FunctionLiteral* ParseFunctionLiteral(
953 const AstRawString* name, Scanner::Location function_name_location,
954 bool name_is_strict_reserved, FunctionKind kind,
955 int function_token_position, FunctionLiteral::FunctionType type,
956 FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
959 ClassLiteral* ParseClassLiteral(const AstRawString* name,
960 Scanner::Location class_name_location,
961 bool name_is_strict_reserved, int pos,
964 // Magical syntax support.
965 Expression* ParseV8Intrinsic(bool* ok);
967 // Get odd-ball literals.
968 Literal* GetLiteralUndefined(int position);
970 // For harmony block scoping mode: Check if the scope has conflicting var/let
971 // declarations from different scopes. It covers for example
973 // function f() { { { var x; } let x; } }
974 // function g() { { var x; let x; } }
976 // The var declarations are hoisted to the function scope, but originate from
977 // a scope where the name has also been let bound or the var declaration is
978 // hoisted over such a scope.
979 void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
982 VariableProxy* NewUnresolved(const AstRawString* name, VariableMode mode);
983 Variable* Declare(Declaration* declaration, bool resolve, bool* ok);
985 bool TargetStackContainsLabel(const AstRawString* label);
986 BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
987 IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
989 void AddAssertIsConstruct(ZoneList<Statement*>* body, int pos);
992 FunctionLiteral* DefaultConstructor(bool call_super, Scope* scope, int pos,
995 // Skip over a lazy function, either using cached data if we have it, or
996 // by parsing the function with PreParser. Consumes the ending }.
997 void SkipLazyFunctionBody(const AstRawString* function_name,
998 int* materialized_literal_count,
999 int* expected_property_count,
1002 PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
1003 SingletonLogger* logger);
1005 // Consumes the ending }.
1006 ZoneList<Statement*>* ParseEagerFunctionBody(
1007 const AstRawString* function_name, int pos, Variable* fvar,
1008 Token::Value fvar_init_op, FunctionKind kind, bool* ok);
1010 void ThrowPendingError(Isolate* isolate, Handle<Script> script);
1012 TemplateLiteralState OpenTemplateLiteral(int pos);
1013 void AddTemplateSpan(TemplateLiteralState* state, bool tail);
1014 void AddTemplateExpression(TemplateLiteralState* state,
1015 Expression* expression);
1016 Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
1018 uint32_t ComputeTemplateLiteralHash(const TemplateLiteral* lit);
1021 PreParser* reusable_preparser_;
1022 Scope* original_scope_; // for ES5 function declarations in sloppy eval
1023 Target* target_stack_; // for break, continue statements
1024 ScriptCompiler::CompileOptions compile_options_;
1025 ParseData* cached_parse_data_;
1027 bool parsing_lazy_arrow_parameters_; // for lazily parsed arrow functions.
1029 PendingCompilationErrorHandler pending_error_handler_;
1031 // Other information which will be stored in Parser and moved to Isolate after
1033 int use_counts_[v8::Isolate::kUseCounterFeatureCount];
1034 int total_preparse_skipped_;
1035 HistogramTimer* pre_parse_timer_;
1037 bool parsing_on_main_thread_;
1041 bool ParserTraits::IsFutureStrictReserved(
1042 const AstRawString* identifier) const {
1043 return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
1047 Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type,
1048 FunctionKind kind) {
1049 return parser_->NewScope(parent_scope, scope_type, kind);
1053 const AstRawString* ParserTraits::EmptyIdentifierString() {
1054 return parser_->ast_value_factory()->empty_string();
1058 void ParserTraits::SkipLazyFunctionBody(const AstRawString* function_name,
1059 int* materialized_literal_count,
1060 int* expected_property_count,
1062 return parser_->SkipLazyFunctionBody(
1063 function_name, materialized_literal_count, expected_property_count, ok);
1067 ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
1068 const AstRawString* name, int pos, Variable* fvar,
1069 Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
1070 return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op, kind,
1074 void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
1076 parser_->CheckConflictingVarDeclarations(scope, ok);
1080 // Support for handling complex values (array and object literals) that
1081 // can be fully handled at compile time.
1082 class CompileTimeValue: public AllStatic {
1085 OBJECT_LITERAL_FAST_ELEMENTS,
1086 OBJECT_LITERAL_SLOW_ELEMENTS,
1090 static bool IsCompileTimeValue(Expression* expression);
1092 // Get the value as a compile time value.
1093 static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
1095 // Get the type of a compile time value returned by GetValue().
1096 static LiteralType GetLiteralType(Handle<FixedArray> value);
1098 // Get the elements array of a compile time value returned by GetValue().
1099 static Handle<FixedArray> GetElements(Handle<FixedArray> value);
1102 static const int kLiteralTypeSlot = 0;
1103 static const int kElementsSlot = 1;
1105 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
1109 ParserTraits::TemplateLiteralState ParserTraits::OpenTemplateLiteral(int pos) {
1110 return parser_->OpenTemplateLiteral(pos);
1114 void ParserTraits::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
1115 parser_->AddTemplateSpan(state, tail);
1119 void ParserTraits::AddTemplateExpression(TemplateLiteralState* state,
1120 Expression* expression) {
1121 parser_->AddTemplateExpression(state, expression);
1125 Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state,
1126 int start, Expression* tag) {
1127 return parser_->CloseTemplateLiteral(state, start, tag);
1129 } } // namespace v8::internal
1131 #endif // V8_PARSER_H_