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" // For CachedDataMode
11 #include "src/preparse-data.h"
12 #include "src/preparse-data-format.h"
13 #include "src/preparser.h"
14 #include "src/scopes.h"
21 class CompilationInfo;
26 template <typename T> class ZoneListWrapper;
29 class FunctionEntry BASE_EMBEDDED {
40 explicit FunctionEntry(Vector<unsigned> backing)
41 : backing_(backing) { }
43 FunctionEntry() : backing_() { }
45 int start_pos() { return backing_[kStartPositionIndex]; }
46 int end_pos() { return backing_[kEndPositionIndex]; }
47 int literal_count() { return backing_[kLiteralCountIndex]; }
48 int property_count() { return backing_[kPropertyCountIndex]; }
49 StrictMode strict_mode() {
50 DCHECK(backing_[kStrictModeIndex] == SLOPPY ||
51 backing_[kStrictModeIndex] == STRICT);
52 return static_cast<StrictMode>(backing_[kStrictModeIndex]);
55 bool is_valid() { return !backing_.is_empty(); }
58 Vector<unsigned> backing_;
62 // Wrapper around ScriptData to provide parser-specific functionality.
65 explicit ParseData(ScriptData* script_data) : script_data_(script_data) {
66 CHECK(IsAligned(script_data->length(), sizeof(unsigned)));
70 FunctionEntry GetFunctionEntry(int start);
75 unsigned* Data() { // Writable data as unsigned int array.
76 return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
85 // Script data length is already checked to be a multiple of unsigned size.
86 return script_data_->length() / sizeof(unsigned);
89 ScriptData* script_data_;
92 DISALLOW_COPY_AND_ASSIGN(ParseData);
95 // ----------------------------------------------------------------------------
98 // A BufferedZoneList is an automatically growing list, just like (and backed
99 // by) a ZoneList, that is optimized for the case of adding and removing
100 // a single element. The last element added is stored outside the backing list,
101 // and if no more than one element is ever added, the ZoneList isn't even
103 // Elements must not be NULL pointers.
104 template <typename T, int initial_size>
105 class BufferedZoneList {
107 BufferedZoneList() : list_(NULL), last_(NULL) {}
109 // Adds element at end of list. This element is buffered and can
110 // be read using last() or removed using RemoveLast until a new Add or until
111 // RemoveLast or GetList has been called.
112 void Add(T* value, Zone* zone) {
115 list_ = new(zone) ZoneList<T*>(initial_size, zone);
117 list_->Add(last_, zone);
123 DCHECK(last_ != NULL);
128 DCHECK(last_ != NULL);
130 if ((list_ != NULL) && (list_->length() > 0))
131 last_ = list_->RemoveLast();
138 DCHECK((0 <= i) && (i < length()));
143 if (i == list_->length()) {
144 DCHECK(last_ != NULL);
158 int length = (list_ == NULL) ? 0 : list_->length();
159 return length + ((last_ == NULL) ? 0 : 1);
162 ZoneList<T*>* GetList(Zone* zone) {
164 list_ = new(zone) ZoneList<T*>(initial_size, zone);
167 list_->Add(last_, zone);
179 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
180 class RegExpBuilder: public ZoneObject {
182 explicit RegExpBuilder(Zone* zone);
183 void AddCharacter(uc16 character);
184 // "Adds" an empty expression. Does nothing except consume a
185 // following quantifier
187 void AddAtom(RegExpTree* tree);
188 void AddAssertion(RegExpTree* tree);
189 void NewAlternative(); // '|'
190 void AddQuantifierToAtom(
191 int min, int max, RegExpQuantifier::QuantifierType type);
192 RegExpTree* ToRegExp();
195 void FlushCharacters();
198 Zone* zone() const { return zone_; }
202 ZoneList<uc16>* characters_;
203 BufferedZoneList<RegExpTree, 2> terms_;
204 BufferedZoneList<RegExpTree, 2> text_;
205 BufferedZoneList<RegExpTree, 2> alternatives_;
207 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
208 #define LAST(x) last_added_ = x;
215 class RegExpParser BASE_EMBEDDED {
217 RegExpParser(FlatStringReader* in,
218 Handle<String>* error,
222 static bool ParseRegExp(FlatStringReader* input,
224 RegExpCompileData* result,
227 RegExpTree* ParsePattern();
228 RegExpTree* ParseDisjunction();
229 RegExpTree* ParseGroup();
230 RegExpTree* ParseCharacterClass();
232 // Parses a {...,...} quantifier and stores the range in the given
234 bool ParseIntervalQuantifier(int* min_out, int* max_out);
236 // Parses and returns a single escaped character. The character
237 // must not be 'b' or 'B' since they are usually handle specially.
238 uc32 ParseClassCharacterEscape();
240 // Checks whether the following is a length-digit hexadecimal number,
241 // and sets the value if it is.
242 bool ParseHexEscape(int length, uc32* value);
244 uc32 ParseOctalLiteral();
246 // Tries to parse the input as a back reference. If successful it
247 // stores the result in the output parameter and returns true. If
248 // it fails it will push back the characters read so the same characters
250 bool ParseBackReferenceIndex(int* index_out);
252 CharacterRange ParseClassAtom(uc16* char_class);
253 RegExpTree* ReportError(Vector<const char> message);
255 void Advance(int dist);
258 // Reports whether the pattern might be used as a literal search string.
259 // Only use if the result of the parse is a single atom node.
261 bool contains_anchor() { return contains_anchor_; }
262 void set_contains_anchor() { contains_anchor_ = true; }
263 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
264 int position() { return next_pos_ - 1; }
265 bool failed() { return failed_; }
267 static const int kMaxCaptures = 1 << 16;
268 static const uc32 kEndMarker = (1 << 21);
271 enum SubexpressionType {
273 CAPTURE, // All positive values represent captures.
279 class RegExpParserState : public ZoneObject {
281 RegExpParserState(RegExpParserState* previous_state,
282 SubexpressionType group_type,
283 int disjunction_capture_index,
285 : previous_state_(previous_state),
286 builder_(new(zone) RegExpBuilder(zone)),
287 group_type_(group_type),
288 disjunction_capture_index_(disjunction_capture_index) {}
289 // Parser state of containing expression, if any.
290 RegExpParserState* previous_state() { return previous_state_; }
291 bool IsSubexpression() { return previous_state_ != NULL; }
292 // RegExpBuilder building this regexp's AST.
293 RegExpBuilder* builder() { return builder_; }
294 // Type of regexp being parsed (parenthesized group or entire regexp).
295 SubexpressionType group_type() { return group_type_; }
296 // Index in captures array of first capture in this sub-expression, if any.
297 // Also the capture index of this sub-expression itself, if group_type
299 int capture_index() { return disjunction_capture_index_; }
302 // Linked list implementation of stack of states.
303 RegExpParserState* previous_state_;
304 // Builder for the stored disjunction.
305 RegExpBuilder* builder_;
306 // Stored disjunction type (capture, look-ahead or grouping), if any.
307 SubexpressionType group_type_;
308 // Stored disjunction's capture index (if any).
309 int disjunction_capture_index_;
312 Isolate* isolate() { return isolate_; }
313 Zone* zone() const { return zone_; }
315 uc32 current() { return current_; }
316 bool has_more() { return has_more_; }
317 bool has_next() { return next_pos_ < in()->length(); }
319 FlatStringReader* in() { return in_; }
320 void ScanForCaptures();
324 Handle<String>* error_;
325 ZoneList<RegExpCapture*>* captures_;
326 FlatStringReader* in_;
329 // The capture count is only valid after we have scanned for captures.
334 bool contains_anchor_;
335 bool is_scanned_for_captures_;
339 // ----------------------------------------------------------------------------
340 // JAVASCRIPT PARSING
343 class SingletonLogger;
348 // TODO(marja): To be removed. The Traits object should contain all the data
350 typedef v8::internal::Parser* Parser;
352 // Used by FunctionState and BlockState.
353 typedef v8::internal::Scope Scope;
354 typedef v8::internal::Scope* ScopePtr;
355 inline static Scope* ptr_to_scope(ScopePtr scope) { return scope; }
357 typedef Variable GeneratorVariable;
358 typedef v8::internal::Zone Zone;
360 typedef v8::internal::AstProperties AstProperties;
361 typedef Vector<VariableProxy*> ParameterIdentifierVector;
363 // Return types for traversing functions.
364 typedef const AstRawString* Identifier;
365 typedef v8::internal::Expression* Expression;
366 typedef Yield* YieldExpression;
367 typedef v8::internal::FunctionLiteral* FunctionLiteral;
368 typedef v8::internal::ClassLiteral* ClassLiteral;
369 typedef v8::internal::Literal* Literal;
370 typedef ObjectLiteral::Property* ObjectLiteralProperty;
371 typedef ZoneList<v8::internal::Expression*>* ExpressionList;
372 typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
373 typedef ZoneList<v8::internal::Statement*>* StatementList;
375 // For constructing objects returned by the traversing functions.
376 typedef AstNodeFactory<AstConstructionVisitor> Factory;
379 explicit ParserTraits(Parser* parser) : parser_(parser) {}
381 // Helper functions for recursive descent.
382 bool IsEvalOrArguments(const AstRawString* identifier) const;
383 V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
385 // Returns true if the expression is of type "this.foo".
386 static bool IsThisProperty(Expression* expression);
388 static bool IsIdentifier(Expression* expression);
390 bool IsPrototype(const AstRawString* identifier) const;
392 bool IsConstructor(const AstRawString* identifier) const;
394 static const AstRawString* AsIdentifier(Expression* expression) {
395 DCHECK(IsIdentifier(expression));
396 return expression->AsVariableProxy()->raw_name();
399 static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
400 return ObjectLiteral::IsBoilerplateProperty(property);
403 static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
404 return string->AsArrayIndex(index);
407 bool IsConstructorProperty(ObjectLiteral::Property* property) {
408 return property->key()->raw_value()->EqualsString(
409 ast_value_factory()->constructor_string());
412 static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
413 return property->value();
416 // Functions for encapsulating the differences between parsing and preparsing;
417 // operations interleaved with the recursive descent.
418 static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
419 fni->PushLiteralName(id);
421 void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
422 static void InferFunctionName(FuncNameInferrer* fni,
423 FunctionLiteral* func_to_infer) {
424 fni->AddFunction(func_to_infer);
427 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
428 Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
429 Expression* value = property->value();
430 if (scope->DeclarationScope()->is_global_scope() &&
431 value->AsFunctionLiteral() != NULL) {
432 *has_function = true;
433 value->AsFunctionLiteral()->set_pretenure();
437 // If we assign a function literal to a property we pretenure the
438 // literal so it can be added as a constant function property.
439 static void CheckAssigningFunctionLiteralToProperty(Expression* left,
442 // Keep track of eval() calls since they disable all local variable
443 // optimizations. This checks if expression is an eval call, and if yes,
444 // forwards the information to scope.
445 void CheckPossibleEvalCall(Expression* expression, Scope* scope);
447 // Determine if the expression is a variable proxy and mark it as being used
448 // in an assignment or with a increment/decrement operator.
449 static Expression* MarkExpressionAsAssigned(Expression* expression);
451 // Returns true if we have a binary expression between two numeric
452 // literals. In that case, *x will be changed to an expression which is the
454 bool ShortcutNumericLiteralBinaryExpression(
455 Expression** x, Expression* y, Token::Value op, int pos,
456 AstNodeFactory<AstConstructionVisitor>* factory);
458 // If we find a SIMD load or store call with array types
459 // and offset as arguments, we will return an expression
460 // calling array types load or store with offset as argument.
461 // Otherwise, returns NULL.
462 bool BuildSIMD128LoadStoreExpression(
463 Expression** expression, ZoneList<Expression*>* arguments, int pos,
464 AstNodeFactory<AstConstructionVisitor>* factory);
466 // Rewrites the following types of unary expressions:
467 // not <literal> -> true / false
468 // + <numeric literal> -> <numeric literal>
469 // - <numeric literal> -> <numeric literal with value negated>
470 // ! <literal> -> true / false
471 // The following rewriting rules enable the collection of type feedback
472 // without any special stub and the multiplication is removed later in
473 // Crankshaft's canonicalization pass.
475 // - foo -> foo * (-1)
476 // ~ foo -> foo ^(~0)
477 Expression* BuildUnaryExpression(
478 Expression* expression, Token::Value op, int pos,
479 AstNodeFactory<AstConstructionVisitor>* factory);
481 // Generate AST node that throws a ReferenceError with the given type.
482 Expression* NewThrowReferenceError(const char* type, int pos);
484 // Generate AST node that throws a SyntaxError with the given
485 // type. The first argument may be null (in the handle sense) in
486 // which case no arguments are passed to the constructor.
487 Expression* NewThrowSyntaxError(
488 const char* type, const AstRawString* arg, int pos);
490 // Generate AST node that throws a TypeError with the given
491 // type. Both arguments must be non-null (in the handle sense).
492 Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
495 // Generic AST generator for throwing errors from compiled code.
496 Expression* NewThrowError(
497 const AstRawString* constructor, const char* type,
498 const AstRawString* arg, int pos);
501 void ReportMessageAt(Scanner::Location source_location,
503 const char* arg = NULL,
504 bool is_reference_error = false);
505 void ReportMessage(const char* message,
506 const char* arg = NULL,
507 bool is_reference_error = false);
508 void ReportMessage(const char* message,
509 const AstRawString* arg,
510 bool is_reference_error = false);
511 void ReportMessageAt(Scanner::Location source_location,
513 const AstRawString* arg,
514 bool is_reference_error = false);
516 // "null" return type creators.
517 static const AstRawString* EmptyIdentifier() {
520 static Expression* EmptyExpression() {
523 static Expression* EmptyArrowParamList() { return NULL; }
524 static Literal* EmptyLiteral() {
527 static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
528 static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
530 // Used in error return values.
531 static ZoneList<Expression*>* NullExpressionList() {
535 // Non-NULL empty string.
536 V8_INLINE const AstRawString* EmptyIdentifierString();
538 // Odd-ball literal creators.
539 Literal* GetLiteralTheHole(int position,
540 AstNodeFactory<AstConstructionVisitor>* factory);
542 // Producing data during the recursive descent.
543 const AstRawString* GetSymbol(Scanner* scanner);
544 const AstRawString* GetNextSymbol(Scanner* scanner);
545 const AstRawString* GetNumberAsSymbol(Scanner* scanner);
547 Expression* ThisExpression(Scope* scope,
548 AstNodeFactory<AstConstructionVisitor>* factory,
549 int pos = RelocInfo::kNoPosition);
550 Expression* SuperReference(Scope* scope,
551 AstNodeFactory<AstConstructionVisitor>* factory,
552 int pos = RelocInfo::kNoPosition);
553 Expression* ClassExpression(const AstRawString* name, Expression* extends,
554 Expression* constructor,
555 ZoneList<ObjectLiteral::Property*>* properties,
556 int start_position, int end_position,
557 AstNodeFactory<AstConstructionVisitor>* factory);
559 Literal* ExpressionFromLiteral(
560 Token::Value token, int pos, Scanner* scanner,
561 AstNodeFactory<AstConstructionVisitor>* factory);
562 Expression* ExpressionFromIdentifier(
563 const AstRawString* name, int pos, Scope* scope,
564 AstNodeFactory<AstConstructionVisitor>* factory);
565 Expression* ExpressionFromString(
566 int pos, Scanner* scanner,
567 AstNodeFactory<AstConstructionVisitor>* factory);
568 Expression* GetIterator(Expression* iterable,
569 AstNodeFactory<AstConstructionVisitor>* factory);
570 ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
571 return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
573 ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
574 return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
576 ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
577 return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
579 V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type);
582 int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
583 Scanner::Location* dupe_loc,
585 V8_INLINE AstValueFactory* ast_value_factory();
587 // Temporary glue; these functions will move to ParserBase.
588 Expression* ParseV8Intrinsic(bool* ok);
589 FunctionLiteral* ParseFunctionLiteral(
590 const AstRawString* name, Scanner::Location function_name_location,
591 bool name_is_strict_reserved, FunctionKind kind,
592 int function_token_position, FunctionLiteral::FunctionType type,
593 FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
594 V8_INLINE void SkipLazyFunctionBody(const AstRawString* name,
595 int* materialized_literal_count,
596 int* expected_property_count, bool* ok);
597 V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
598 const AstRawString* name, int pos, Variable* fvar,
599 Token::Value fvar_init_op, bool is_generator, bool* ok);
600 V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
608 class Parser : public ParserBase<ParserTraits> {
610 // Note that the hash seed in ParseInfo must be the hash seed from the
611 // Isolate's heap, otherwise the heap will be in an inconsistent state once
612 // the strings created by the Parser are internalized.
614 uintptr_t stack_limit;
616 UnicodeCache* unicode_cache;
619 Parser(CompilationInfo* info, ParseInfo* parse_info);
621 delete reusable_preparser_;
622 reusable_preparser_ = NULL;
623 delete cached_parse_data_;
624 cached_parse_data_ = NULL;
627 // Parses the source code represented by the compilation info and sets its
628 // function literal. Returns false (and deallocates any allocated AST
629 // nodes) if parsing failed.
630 static bool Parse(CompilationInfo* info,
631 bool allow_lazy = false) {
632 ParseInfo parse_info = {info->isolate()->stack_guard()->real_climit(),
633 info->isolate()->heap()->HashSeed(),
634 info->isolate()->unicode_cache()};
635 Parser parser(info, &parse_info);
636 parser.set_allow_lazy(allow_lazy);
637 if (parser.Parse()) {
638 info->SetStrictMode(info->function()->strict_mode());
644 void ParseOnBackground();
646 // Handle errors detected during parsing, move statistics to Isolate,
647 // internalize strings (move them to the heap).
651 friend class ParserTraits;
653 // Limit the allowed number of local variables in a function. The hard limit
654 // is that offsets computed by FullCodeGenerator::StackOperand and similar
655 // functions are ints, and they should not overflow. In addition, accessing
656 // local variables creates user-controlled constants in the generated code,
657 // and we don't want too much user-controlled memory inside the code (this was
658 // the reason why this limit was introduced in the first place; see
659 // https://codereview.chromium.org/7003030/ ).
660 static const int kMaxNumFunctionLocals = 4194303; // 2^22-1
662 enum VariableDeclarationContext {
669 // If a list of variable declarations includes any initializers.
670 enum VariableDeclarationProperties {
675 // Returns NULL if parsing failed.
676 FunctionLiteral* ParseProgram();
678 FunctionLiteral* ParseLazy();
679 FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
681 Isolate* isolate() { return info_->isolate(); }
682 CompilationInfo* info() const { return info_; }
683 Handle<Script> script() const { return info_->script(); }
684 AstValueFactory* ast_value_factory() const {
685 return info_->ast_value_factory();
688 // Called by ParseProgram after setting up the scanner.
689 FunctionLiteral* DoParseProgram(CompilationInfo* info, Scope** scope,
690 Scope** ad_hoc_eval_scope);
692 void SetCachedData();
694 bool inside_with() const { return scope_->inside_with(); }
695 ScriptCompiler::CompileOptions compile_options() const {
696 return info_->compile_options();
698 Scope* DeclarationScope(VariableMode mode) {
699 return IsLexicalVariableMode(mode)
700 ? scope_ : scope_->DeclarationScope();
703 // All ParseXXX functions take as the last argument an *ok parameter
704 // which is set to false if parsing failed; it is unchanged otherwise.
705 // By making the 'exception handling' explicit, we are forced to check
706 // for failure at the call sites.
707 void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
708 bool is_eval, bool is_global,
709 Scope** ad_hoc_eval_scope, bool* ok);
710 Statement* ParseModuleElement(ZoneList<const AstRawString*>* labels,
712 Statement* ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
714 Module* ParseModule(bool* ok);
715 Module* ParseModuleLiteral(bool* ok);
716 Module* ParseModulePath(bool* ok);
717 Module* ParseModuleVariable(bool* ok);
718 Module* ParseModuleUrl(bool* ok);
719 Module* ParseModuleSpecifier(bool* ok);
720 Block* ParseImportDeclaration(bool* ok);
721 Statement* ParseExportDeclaration(bool* ok);
722 Statement* ParseBlockElement(ZoneList<const AstRawString*>* labels, bool* ok);
723 Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
724 Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
726 Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
728 Statement* ParseNativeDeclaration(bool* ok);
729 Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
730 Block* ParseVariableStatement(VariableDeclarationContext var_context,
731 ZoneList<const AstRawString*>* names,
733 Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
734 VariableDeclarationProperties* decl_props,
735 ZoneList<const AstRawString*>* names,
736 const AstRawString** out,
738 Statement* ParseExpressionOrLabelledStatement(
739 ZoneList<const AstRawString*>* labels, bool* ok);
740 IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
742 Statement* ParseContinueStatement(bool* ok);
743 Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
745 Statement* ParseReturnStatement(bool* ok);
746 Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
748 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
749 SwitchStatement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
751 DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
753 WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
755 Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
756 Statement* ParseThrowStatement(bool* ok);
757 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
758 TryStatement* ParseTryStatement(bool* ok);
759 DebuggerStatement* ParseDebuggerStatement(bool* ok);
761 // Support for hamony block scoped bindings.
762 Block* ParseScopedBlock(ZoneList<const AstRawString*>* labels, bool* ok);
764 // Initialize the components of a for-in / for-of statement.
765 void InitializeForEachStatement(ForEachStatement* stmt,
769 Statement* DesugarLetBindingsInForStatement(
770 Scope* inner_scope, ZoneList<const AstRawString*>* names,
771 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
772 Statement* body, bool* ok);
774 FunctionLiteral* ParseFunctionLiteral(
775 const AstRawString* name, Scanner::Location function_name_location,
776 bool name_is_strict_reserved, FunctionKind kind,
777 int function_token_position, FunctionLiteral::FunctionType type,
778 FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
780 // Magical syntax support.
781 Expression* ParseV8Intrinsic(bool* ok);
783 bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
785 // Get odd-ball literals.
786 Literal* GetLiteralUndefined(int position);
788 // For harmony block scoping mode: Check if the scope has conflicting var/let
789 // declarations from different scopes. It covers for example
791 // function f() { { { var x; } let x; } }
792 // function g() { { var x; let x; } }
794 // The var declarations are hoisted to the function scope, but originate from
795 // a scope where the name has also been let bound or the var declaration is
796 // hoisted over such a scope.
797 void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
800 VariableProxy* NewUnresolved(const AstRawString* name,
802 Interface* interface);
803 void Declare(Declaration* declaration, bool resolve, bool* ok);
805 bool TargetStackContainsLabel(const AstRawString* label);
806 BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
807 IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
809 void RegisterTargetUse(Label* target, Target* stop);
813 Scope* NewScope(Scope* parent, ScopeType type);
815 // Skip over a lazy function, either using cached data if we have it, or
816 // by parsing the function with PreParser. Consumes the ending }.
817 void SkipLazyFunctionBody(const AstRawString* function_name,
818 int* materialized_literal_count,
819 int* expected_property_count,
822 PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
823 SingletonLogger* logger);
825 // Consumes the ending }.
826 ZoneList<Statement*>* ParseEagerFunctionBody(
827 const AstRawString* function_name, int pos, Variable* fvar,
828 Token::Value fvar_init_op, bool is_generator, bool* ok);
830 void HandleSourceURLComments();
832 void ThrowPendingError();
835 PreParser* reusable_preparser_;
836 Scope* original_scope_; // for ES5 function declarations in sloppy eval
837 Target* target_stack_; // for break, continue statements
838 ParseData* cached_parse_data_;
840 CompilationInfo* info_;
843 bool has_pending_error_;
844 Scanner::Location pending_error_location_;
845 const char* pending_error_message_;
846 const AstRawString* pending_error_arg_;
847 const char* pending_error_char_arg_;
848 bool pending_error_is_reference_error_;
850 // Other information which will be stored in Parser and moved to Isolate after
852 int use_counts_[v8::Isolate::kUseCounterFeatureCount];
853 int total_preparse_skipped_;
854 HistogramTimer* pre_parse_timer_;
856 // Temporary; for debugging. See Parser::SkipLazyFunctionBody. TODO(marja):
857 // remove this once done.
858 ScriptCompiler::CompileOptions debug_saved_compile_options_;
862 bool ParserTraits::IsFutureStrictReserved(
863 const AstRawString* identifier) const {
864 return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
868 Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type) {
869 return parser_->NewScope(parent_scope, scope_type);
873 const AstRawString* ParserTraits::EmptyIdentifierString() {
874 return parser_->ast_value_factory()->empty_string();
878 void ParserTraits::SkipLazyFunctionBody(const AstRawString* function_name,
879 int* materialized_literal_count,
880 int* expected_property_count,
882 return parser_->SkipLazyFunctionBody(
883 function_name, materialized_literal_count, expected_property_count, ok);
887 ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
888 const AstRawString* name, int pos, Variable* fvar,
889 Token::Value fvar_init_op, bool is_generator, bool* ok) {
890 return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op,
894 void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
896 parser_->CheckConflictingVarDeclarations(scope, ok);
900 AstValueFactory* ParserTraits::ast_value_factory() {
901 return parser_->ast_value_factory();
905 // Support for handling complex values (array and object literals) that
906 // can be fully handled at compile time.
907 class CompileTimeValue: public AllStatic {
910 OBJECT_LITERAL_FAST_ELEMENTS,
911 OBJECT_LITERAL_SLOW_ELEMENTS,
915 static bool IsCompileTimeValue(Expression* expression);
917 // Get the value as a compile time value.
918 static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
920 // Get the type of a compile time value returned by GetValue().
921 static LiteralType GetLiteralType(Handle<FixedArray> value);
923 // Get the elements array of a compile time value returned by GetValue().
924 static Handle<FixedArray> GetElements(Handle<FixedArray> value);
927 static const int kLiteralTypeSlot = 0;
928 static const int kElementsSlot = 1;
930 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
933 } } // namespace v8::internal
935 #endif // V8_PARSER_H_