1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "allocation.h"
33 #include "compiler.h" // For CachedDataMode
34 #include "preparse-data-format.h"
35 #include "preparse-data.h"
37 #include "preparser.h"
44 class CompilationInfo;
49 template <typename T> class ZoneListWrapper;
52 class FunctionEntry BASE_EMBEDDED {
63 explicit FunctionEntry(Vector<unsigned> backing)
64 : backing_(backing) { }
66 FunctionEntry() : backing_() { }
68 int start_pos() { return backing_[kStartPositionIndex]; }
69 int end_pos() { return backing_[kEndPositionIndex]; }
70 int literal_count() { return backing_[kLiteralCountIndex]; }
71 int property_count() { return backing_[kPropertyCountIndex]; }
72 StrictMode strict_mode() {
73 ASSERT(backing_[kStrictModeIndex] == SLOPPY ||
74 backing_[kStrictModeIndex] == STRICT);
75 return static_cast<StrictMode>(backing_[kStrictModeIndex]);
78 bool is_valid() { return !backing_.is_empty(); }
81 Vector<unsigned> backing_;
85 class ScriptDataImpl : public ScriptData {
87 explicit ScriptDataImpl(Vector<unsigned> store)
91 // Create an empty ScriptDataImpl that is guaranteed to not satisfy
93 ScriptDataImpl() : owns_store_(false) { }
95 virtual ~ScriptDataImpl();
97 virtual const char* Data();
98 virtual bool HasError();
101 void ReadNextSymbolPosition();
103 FunctionEntry GetFunctionEntry(int start);
104 int GetSymbolIdentifier();
107 Scanner::Location MessageLocation();
108 const char* BuildMessage();
109 Vector<const char*> BuildArgs();
112 return (store_.length() > PreparseDataConstants::kHeaderSize)
113 ? store_[PreparseDataConstants::kSymbolCountOffset]
116 // The following functions should only be called if SanityCheck has
118 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
119 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
120 unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
123 friend class v8::ScriptCompiler;
124 Vector<unsigned> store_;
125 unsigned char* symbol_data_;
126 unsigned char* symbol_data_end_;
130 unsigned Read(int position);
131 unsigned* ReadAddress(int position);
132 // Reads a number from the current symbols
133 int ReadNumber(byte** source);
135 ScriptDataImpl(const char* backing_store, int length)
136 : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
137 length / static_cast<int>(sizeof(unsigned))),
139 ASSERT_EQ(0, static_cast<int>(
140 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
143 // Read strings written by ParserRecorder::WriteString.
144 static const char* ReadString(unsigned* start, int* chars);
146 friend class ScriptData;
152 // Pre-parse a character stream and return full preparse data.
154 // This interface is here instead of in preparser.h because it instantiates a
155 // preparser recorder object that is suited to the parser's purposes. Also,
156 // the preparser doesn't know about ScriptDataImpl.
157 static ScriptDataImpl* PreParse(Isolate* isolate,
158 Utf16CharacterStream* source);
162 // ----------------------------------------------------------------------------
165 // A BufferedZoneList is an automatically growing list, just like (and backed
166 // by) a ZoneList, that is optimized for the case of adding and removing
167 // a single element. The last element added is stored outside the backing list,
168 // and if no more than one element is ever added, the ZoneList isn't even
170 // Elements must not be NULL pointers.
171 template <typename T, int initial_size>
172 class BufferedZoneList {
174 BufferedZoneList() : list_(NULL), last_(NULL) {}
176 // Adds element at end of list. This element is buffered and can
177 // be read using last() or removed using RemoveLast until a new Add or until
178 // RemoveLast or GetList has been called.
179 void Add(T* value, Zone* zone) {
182 list_ = new(zone) ZoneList<T*>(initial_size, zone);
184 list_->Add(last_, zone);
190 ASSERT(last_ != NULL);
195 ASSERT(last_ != NULL);
197 if ((list_ != NULL) && (list_->length() > 0))
198 last_ = list_->RemoveLast();
205 ASSERT((0 <= i) && (i < length()));
210 if (i == list_->length()) {
211 ASSERT(last_ != NULL);
225 int length = (list_ == NULL) ? 0 : list_->length();
226 return length + ((last_ == NULL) ? 0 : 1);
229 ZoneList<T*>* GetList(Zone* zone) {
231 list_ = new(zone) ZoneList<T*>(initial_size, zone);
234 list_->Add(last_, zone);
246 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
247 class RegExpBuilder: public ZoneObject {
249 explicit RegExpBuilder(Zone* zone);
250 void AddCharacter(uc16 character);
251 // "Adds" an empty expression. Does nothing except consume a
252 // following quantifier
254 void AddAtom(RegExpTree* tree);
255 void AddAssertion(RegExpTree* tree);
256 void NewAlternative(); // '|'
257 void AddQuantifierToAtom(
258 int min, int max, RegExpQuantifier::QuantifierType type);
259 RegExpTree* ToRegExp();
262 void FlushCharacters();
265 Zone* zone() const { return zone_; }
269 ZoneList<uc16>* characters_;
270 BufferedZoneList<RegExpTree, 2> terms_;
271 BufferedZoneList<RegExpTree, 2> text_;
272 BufferedZoneList<RegExpTree, 2> alternatives_;
274 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
275 #define LAST(x) last_added_ = x;
282 class RegExpParser BASE_EMBEDDED {
284 RegExpParser(FlatStringReader* in,
285 Handle<String>* error,
289 static bool ParseRegExp(FlatStringReader* input,
291 RegExpCompileData* result,
294 RegExpTree* ParsePattern();
295 RegExpTree* ParseDisjunction();
296 RegExpTree* ParseGroup();
297 RegExpTree* ParseCharacterClass();
299 // Parses a {...,...} quantifier and stores the range in the given
301 bool ParseIntervalQuantifier(int* min_out, int* max_out);
303 // Parses and returns a single escaped character. The character
304 // must not be 'b' or 'B' since they are usually handle specially.
305 uc32 ParseClassCharacterEscape();
307 // Checks whether the following is a length-digit hexadecimal number,
308 // and sets the value if it is.
309 bool ParseHexEscape(int length, uc32* value);
311 uc32 ParseOctalLiteral();
313 // Tries to parse the input as a back reference. If successful it
314 // stores the result in the output parameter and returns true. If
315 // it fails it will push back the characters read so the same characters
317 bool ParseBackReferenceIndex(int* index_out);
319 CharacterRange ParseClassAtom(uc16* char_class);
320 RegExpTree* ReportError(Vector<const char> message);
322 void Advance(int dist);
325 // Reports whether the pattern might be used as a literal search string.
326 // Only use if the result of the parse is a single atom node.
328 bool contains_anchor() { return contains_anchor_; }
329 void set_contains_anchor() { contains_anchor_ = true; }
330 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
331 int position() { return next_pos_ - 1; }
332 bool failed() { return failed_; }
334 static const int kMaxCaptures = 1 << 16;
335 static const uc32 kEndMarker = (1 << 21);
338 enum SubexpressionType {
340 CAPTURE, // All positive values represent captures.
346 class RegExpParserState : public ZoneObject {
348 RegExpParserState(RegExpParserState* previous_state,
349 SubexpressionType group_type,
350 int disjunction_capture_index,
352 : previous_state_(previous_state),
353 builder_(new(zone) RegExpBuilder(zone)),
354 group_type_(group_type),
355 disjunction_capture_index_(disjunction_capture_index) {}
356 // Parser state of containing expression, if any.
357 RegExpParserState* previous_state() { return previous_state_; }
358 bool IsSubexpression() { return previous_state_ != NULL; }
359 // RegExpBuilder building this regexp's AST.
360 RegExpBuilder* builder() { return builder_; }
361 // Type of regexp being parsed (parenthesized group or entire regexp).
362 SubexpressionType group_type() { return group_type_; }
363 // Index in captures array of first capture in this sub-expression, if any.
364 // Also the capture index of this sub-expression itself, if group_type
366 int capture_index() { return disjunction_capture_index_; }
369 // Linked list implementation of stack of states.
370 RegExpParserState* previous_state_;
371 // Builder for the stored disjunction.
372 RegExpBuilder* builder_;
373 // Stored disjunction type (capture, look-ahead or grouping), if any.
374 SubexpressionType group_type_;
375 // Stored disjunction's capture index (if any).
376 int disjunction_capture_index_;
379 Isolate* isolate() { return isolate_; }
380 Zone* zone() const { return zone_; }
382 uc32 current() { return current_; }
383 bool has_more() { return has_more_; }
384 bool has_next() { return next_pos_ < in()->length(); }
386 FlatStringReader* in() { return in_; }
387 void ScanForCaptures();
391 Handle<String>* error_;
392 ZoneList<RegExpCapture*>* captures_;
393 FlatStringReader* in_;
396 // The capture count is only valid after we have scanned for captures.
401 bool contains_anchor_;
402 bool is_scanned_for_captures_;
406 // ----------------------------------------------------------------------------
407 // JAVASCRIPT PARSING
410 class SingletonLogger;
415 // TODO(marja): To be removed. The Traits object should contain all the data
417 typedef v8::internal::Parser* Parser;
419 // Used by FunctionState and BlockState.
420 typedef v8::internal::Scope Scope;
421 typedef Variable GeneratorVariable;
422 typedef v8::internal::Zone Zone;
424 // Return types for traversing functions.
425 typedef Handle<String> Identifier;
426 typedef v8::internal::Expression* Expression;
427 typedef Yield* YieldExpression;
428 typedef v8::internal::FunctionLiteral* FunctionLiteral;
429 typedef v8::internal::Literal* Literal;
430 typedef ObjectLiteral::Property* ObjectLiteralProperty;
431 typedef ZoneList<v8::internal::Expression*>* ExpressionList;
432 typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
434 // For constructing objects returned by the traversing functions.
435 typedef AstNodeFactory<AstConstructionVisitor> Factory;
438 explicit ParserTraits(Parser* parser) : parser_(parser) {}
440 // Custom operations executed when FunctionStates are created and destructed.
441 template<typename FunctionState>
442 static void SetUpFunctionState(FunctionState* function_state, Zone* zone) {
443 Isolate* isolate = zone->isolate();
444 function_state->isolate_ = isolate;
445 function_state->saved_ast_node_id_ = isolate->ast_node_id();
446 isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
449 template<typename FunctionState>
450 static void TearDownFunctionState(FunctionState* function_state) {
451 if (function_state->outer_function_state_ != NULL) {
452 function_state->isolate_->set_ast_node_id(
453 function_state->saved_ast_node_id_);
457 // Helper functions for recursive descent.
458 bool IsEvalOrArguments(Handle<String> identifier) const;
460 // Returns true if the expression is of type "this.foo".
461 static bool IsThisProperty(Expression* expression);
463 static bool IsIdentifier(Expression* expression);
465 static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
466 return ObjectLiteral::IsBoilerplateProperty(property);
469 static bool IsArrayIndex(Handle<String> string, uint32_t* index) {
470 return !string.is_null() && string->AsArrayIndex(index);
473 // Functions for encapsulating the differences between parsing and preparsing;
474 // operations interleaved with the recursive descent.
475 static void PushLiteralName(FuncNameInferrer* fni, Handle<String> id) {
476 fni->PushLiteralName(id);
478 void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
480 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
481 Scope* scope, Expression* value, bool* has_function) {
482 if (scope->DeclarationScope()->is_global_scope() &&
483 value->AsFunctionLiteral() != NULL) {
484 *has_function = true;
485 value->AsFunctionLiteral()->set_pretenure();
489 // If we assign a function literal to a property we pretenure the
490 // literal so it can be added as a constant function property.
491 static void CheckAssigningFunctionLiteralToProperty(Expression* left,
494 // Keep track of eval() calls since they disable all local variable
495 // optimizations. This checks if expression is an eval call, and if yes,
496 // forwards the information to scope.
497 void CheckPossibleEvalCall(Expression* expression, Scope* scope);
499 // Determine if the expression is a variable proxy and mark it as being used
500 // in an assignment or with a increment/decrement operator. This is currently
501 // used on for the statically checking assignments to harmony const bindings.
502 static Expression* MarkExpressionAsLValue(Expression* expression);
504 // Checks LHS expression for assignment and prefix/postfix increment/decrement
506 void CheckStrictModeLValue(Expression* expression, bool* ok);
508 // Returns true if we have a binary expression between two numeric
509 // literals. In that case, *x will be changed to an expression which is the
511 bool ShortcutNumericLiteralBinaryExpression(
512 Expression** x, Expression* y, Token::Value op, int pos,
513 AstNodeFactory<AstConstructionVisitor>* factory);
515 // Rewrites the following types of unary expressions:
516 // not <literal> -> true / false
517 // + <numeric literal> -> <numeric literal>
518 // - <numeric literal> -> <numeric literal with value negated>
519 // ! <literal> -> true / false
520 // The following rewriting rules enable the collection of type feedback
521 // without any special stub and the multiplication is removed later in
522 // Crankshaft's canonicalization pass.
524 // - foo -> foo * (-1)
525 // ~ foo -> foo ^(~0)
526 Expression* BuildUnaryExpression(
527 Expression* expression, Token::Value op, int pos,
528 AstNodeFactory<AstConstructionVisitor>* factory);
531 void ReportMessageAt(Scanner::Location source_location,
533 Vector<const char*> args,
534 bool is_reference_error = false);
535 void ReportMessage(const char* message,
536 Vector<Handle<String> > args,
537 bool is_reference_error = false);
538 void ReportMessageAt(Scanner::Location source_location,
540 Vector<Handle<String> > args,
541 bool is_reference_error = false);
543 // "null" return type creators.
544 static Handle<String> EmptyIdentifier() {
545 return Handle<String>();
547 static Expression* EmptyExpression() {
550 static Literal* EmptyLiteral() {
553 // Used in error return values.
554 static ZoneList<Expression*>* NullExpressionList() {
558 // Odd-ball literal creators.
559 Literal* GetLiteralTheHole(int position,
560 AstNodeFactory<AstConstructionVisitor>* factory);
562 // Producing data during the recursive descent.
563 Handle<String> GetSymbol(Scanner* scanner = NULL);
564 Handle<String> NextLiteralString(Scanner* scanner,
565 PretenureFlag tenured);
566 Expression* ThisExpression(Scope* scope,
567 AstNodeFactory<AstConstructionVisitor>* factory);
568 Literal* ExpressionFromLiteral(
569 Token::Value token, int pos, Scanner* scanner,
570 AstNodeFactory<AstConstructionVisitor>* factory);
571 Expression* ExpressionFromIdentifier(
572 Handle<String> name, int pos, Scope* scope,
573 AstNodeFactory<AstConstructionVisitor>* factory);
574 Expression* ExpressionFromString(
575 int pos, Scanner* scanner,
576 AstNodeFactory<AstConstructionVisitor>* factory);
577 ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
578 return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
580 ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
581 return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
584 // Temporary glue; these functions will move to ParserBase.
585 Expression* ParseV8Intrinsic(bool* ok);
586 FunctionLiteral* ParseFunctionLiteral(
588 Scanner::Location function_name_location,
589 bool name_is_strict_reserved,
591 int function_token_position,
592 FunctionLiteral::FunctionType type,
600 class Parser : public ParserBase<ParserTraits> {
602 explicit Parser(CompilationInfo* info);
604 delete reusable_preparser_;
605 reusable_preparser_ = NULL;
608 // Parses the source code represented by the compilation info and sets its
609 // function literal. Returns false (and deallocates any allocated AST
610 // nodes) if parsing failed.
611 static bool Parse(CompilationInfo* info,
612 bool allow_lazy = false) {
614 parser.set_allow_lazy(allow_lazy);
615 return parser.Parse();
620 friend class ParserTraits;
622 // Limit the allowed number of local variables in a function. The hard limit
623 // is that offsets computed by FullCodeGenerator::StackOperand and similar
624 // functions are ints, and they should not overflow. In addition, accessing
625 // local variables creates user-controlled constants in the generated code,
626 // and we don't want too much user-controlled memory inside the code (this was
627 // the reason why this limit was introduced in the first place; see
628 // https://codereview.chromium.org/7003030/ ).
629 static const int kMaxNumFunctionLocals = 4194303; // 2^22-1
631 enum VariableDeclarationContext {
638 // If a list of variable declarations includes any initializers.
639 enum VariableDeclarationProperties {
644 // Returns NULL if parsing failed.
645 FunctionLiteral* ParseProgram();
647 FunctionLiteral* ParseLazy();
648 FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
650 Isolate* isolate() { return isolate_; }
651 CompilationInfo* info() const { return info_; }
653 // Called by ParseProgram after setting up the scanner.
654 FunctionLiteral* DoParseProgram(CompilationInfo* info,
655 Handle<String> source);
657 // Report syntax error
658 void ReportInvalidPreparseData(Handle<String> name, bool* ok);
660 void SetCachedData(ScriptDataImpl** data,
661 CachedDataMode cached_data_mode) {
662 cached_data_mode_ = cached_data_mode;
663 if (cached_data_mode == NO_CACHED_DATA) {
666 ASSERT(data != NULL);
668 symbol_cache_.Initialize(*data ? (*data)->symbol_count() : 0, zone());
672 bool inside_with() const { return scope_->inside_with(); }
673 ScriptDataImpl** cached_data() const { return cached_data_; }
674 CachedDataMode cached_data_mode() const { return cached_data_mode_; }
675 Scope* DeclarationScope(VariableMode mode) {
676 return IsLexicalVariableMode(mode)
677 ? scope_ : scope_->DeclarationScope();
680 // All ParseXXX functions take as the last argument an *ok parameter
681 // which is set to false if parsing failed; it is unchanged otherwise.
682 // By making the 'exception handling' explicit, we are forced to check
683 // for failure at the call sites.
684 void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
685 bool is_eval, bool is_global, bool* ok);
686 Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
687 Statement* ParseModuleDeclaration(ZoneStringList* names, bool* ok);
688 Module* ParseModule(bool* ok);
689 Module* ParseModuleLiteral(bool* ok);
690 Module* ParseModulePath(bool* ok);
691 Module* ParseModuleVariable(bool* ok);
692 Module* ParseModuleUrl(bool* ok);
693 Module* ParseModuleSpecifier(bool* ok);
694 Block* ParseImportDeclaration(bool* ok);
695 Statement* ParseExportDeclaration(bool* ok);
696 Statement* ParseBlockElement(ZoneStringList* labels, bool* ok);
697 Statement* ParseStatement(ZoneStringList* labels, bool* ok);
698 Statement* ParseFunctionDeclaration(ZoneStringList* names, bool* ok);
699 Statement* ParseNativeDeclaration(bool* ok);
700 Block* ParseBlock(ZoneStringList* labels, bool* ok);
701 Block* ParseVariableStatement(VariableDeclarationContext var_context,
702 ZoneStringList* names,
704 Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
705 VariableDeclarationProperties* decl_props,
706 ZoneStringList* names,
709 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
711 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
712 Statement* ParseContinueStatement(bool* ok);
713 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
714 Statement* ParseReturnStatement(bool* ok);
715 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
716 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
717 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
718 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
719 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
720 Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
721 Statement* ParseThrowStatement(bool* ok);
722 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
723 TryStatement* ParseTryStatement(bool* ok);
724 DebuggerStatement* ParseDebuggerStatement(bool* ok);
726 // Support for hamony block scoped bindings.
727 Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);
729 // Initialize the components of a for-in / for-of statement.
730 void InitializeForEachStatement(ForEachStatement* stmt,
735 FunctionLiteral* ParseFunctionLiteral(
737 Scanner::Location function_name_location,
738 bool name_is_strict_reserved,
740 int function_token_position,
741 FunctionLiteral::FunctionType type,
744 // Magical syntax support.
745 Expression* ParseV8Intrinsic(bool* ok);
747 bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
749 // Get odd-ball literals.
750 Literal* GetLiteralUndefined(int position);
752 // For harmony block scoping mode: Check if the scope has conflicting var/let
753 // declarations from different scopes. It covers for example
755 // function f() { { { var x; } let x; } }
756 // function g() { { var x; let x; } }
758 // The var declarations are hoisted to the function scope, but originate from
759 // a scope where the name has also been let bound or the var declaration is
760 // hoisted over such a scope.
761 void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
764 VariableProxy* NewUnresolved(Handle<String> name,
766 Interface* interface);
767 void Declare(Declaration* declaration, bool resolve, bool* ok);
769 bool TargetStackContainsLabel(Handle<String> label);
770 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
771 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
773 void RegisterTargetUse(Label* target, Target* stop);
777 Scope* NewScope(Scope* parent, ScopeType type);
779 Handle<String> LookupCachedSymbol(int symbol_id);
781 // Generate AST node that throw a ReferenceError with the given type.
782 Expression* NewThrowReferenceError(Handle<String> type);
784 // Generate AST node that throw a SyntaxError with the given
785 // type. The first argument may be null (in the handle sense) in
786 // which case no arguments are passed to the constructor.
787 Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
789 // Generate AST node that throw a TypeError with the given
790 // type. Both arguments must be non-null (in the handle sense).
791 Expression* NewThrowTypeError(Handle<String> type,
792 Handle<Object> first,
793 Handle<Object> second);
795 // Generic AST generator for throwing errors from compiled code.
796 Expression* NewThrowError(Handle<String> constructor,
798 Vector< Handle<Object> > arguments);
800 PreParser::PreParseResult LazyParseFunctionLiteral(
801 SingletonLogger* logger);
804 ZoneList<Handle<String> > symbol_cache_;
806 Handle<Script> script_;
808 PreParser* reusable_preparser_;
809 Scope* original_scope_; // for ES5 function declarations in sloppy eval
810 Target* target_stack_; // for break, continue statements
811 ScriptDataImpl** cached_data_;
812 CachedDataMode cached_data_mode_;
814 CompilationInfo* info_;
818 // Support for handling complex values (array and object literals) that
819 // can be fully handled at compile time.
820 class CompileTimeValue: public AllStatic {
823 OBJECT_LITERAL_FAST_ELEMENTS,
824 OBJECT_LITERAL_SLOW_ELEMENTS,
828 static bool IsCompileTimeValue(Expression* expression);
830 // Get the value as a compile time value.
831 static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
833 // Get the type of a compile time value returned by GetValue().
834 static LiteralType GetLiteralType(Handle<FixedArray> value);
836 // Get the elements array of a compile time value returned by GetValue().
837 static Handle<FixedArray> GetElements(Handle<FixedArray> value);
840 static const int kLiteralTypeSlot = 0;
841 static const int kElementsSlot = 1;
843 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
846 } } // namespace v8::internal
848 #endif // V8_PARSER_H_