Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: src/parser.h

Issue 1481613002: Create ast/ and parsing/ subdirectories and move appropriate files (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parameter-initializer-rewriter.cc ('k') | src/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #ifndef V8_PARSER_H_
6 #define V8_PARSER_H_
7
8 #include "src/allocation.h"
9 #include "src/ast.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"
16
17 namespace v8 {
18
19 class ScriptCompiler;
20
21 namespace internal {
22
23 class Target;
24
25 // A container for the inputs, configuration options, and outputs of parsing.
26 class ParseInfo {
27 public:
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);
33
34 ~ParseInfo() {
35 if (ast_value_factory_owned()) {
36 delete ast_value_factory_;
37 set_ast_value_factory_owned(false);
38 }
39 ast_value_factory_ = nullptr;
40 }
41
42 Zone* zone() { return zone_; }
43
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); }
49
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)
61
62 #undef FLAG_ACCESSOR
63
64 void set_parse_restriction(ParseRestriction restriction) {
65 SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION);
66 }
67
68 ParseRestriction parse_restriction() const {
69 return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL
70 : NO_PARSE_RESTRICTION;
71 }
72
73 ScriptCompiler::ExternalSourceStream* source_stream() {
74 return source_stream_;
75 }
76 void set_source_stream(ScriptCompiler::ExternalSourceStream* source_stream) {
77 source_stream_ = source_stream;
78 }
79
80 ScriptCompiler::StreamedSource::Encoding source_stream_encoding() {
81 return source_stream_encoding_;
82 }
83 void set_source_stream_encoding(
84 ScriptCompiler::StreamedSource::Encoding source_stream_encoding) {
85 source_stream_encoding_ = source_stream_encoding;
86 }
87
88 v8::Extension* extension() { return extension_; }
89 void set_extension(v8::Extension* extension) { extension_ = extension; }
90
91 ScriptData** cached_data() { return cached_data_; }
92 void set_cached_data(ScriptData** cached_data) { cached_data_ = cached_data; }
93
94 ScriptCompiler::CompileOptions compile_options() { return compile_options_; }
95 void set_compile_options(ScriptCompiler::CompileOptions compile_options) {
96 compile_options_ = compile_options;
97 }
98
99 Scope* script_scope() { return script_scope_; }
100 void set_script_scope(Scope* script_scope) { script_scope_ = script_scope; }
101
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;
105 }
106
107 FunctionLiteral* literal() { return literal_; }
108 void set_literal(FunctionLiteral* literal) { literal_ = literal; }
109
110 Scope* scope() { return scope_; }
111 void set_scope(Scope* scope) { scope_ = scope; }
112
113 UnicodeCache* unicode_cache() { return unicode_cache_; }
114 void set_unicode_cache(UnicodeCache* unicode_cache) {
115 unicode_cache_ = unicode_cache;
116 }
117
118 uintptr_t stack_limit() { return stack_limit_; }
119 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
120
121 uint32_t hash_seed() { return hash_seed_; }
122 void set_hash_seed(uint32_t hash_seed) { hash_seed_ = hash_seed; }
123
124 //--------------------------------------------------------------------------
125 // TODO(titzer): these should not be part of ParseInfo.
126 //--------------------------------------------------------------------------
127 Isolate* isolate() { return isolate_; }
128 Handle<JSFunction> closure() { return closure_; }
129 Handle<SharedFunctionInfo> shared_info() { return shared_; }
130 Handle<Script> script() { return script_; }
131 Handle<Context> context() { return context_; }
132 void clear_script() { script_ = Handle<Script>::null(); }
133 void set_isolate(Isolate* isolate) { isolate_ = isolate; }
134 void set_context(Handle<Context> context) { context_ = context; }
135 void set_script(Handle<Script> script) { script_ = script; }
136 //--------------------------------------------------------------------------
137
138 LanguageMode language_mode() {
139 return construct_language_mode(is_strict_mode(), is_strong_mode());
140 }
141 void set_language_mode(LanguageMode language_mode) {
142 STATIC_ASSERT(LANGUAGE_END == 3);
143 set_strict_mode(language_mode & STRICT_BIT);
144 set_strong_mode(language_mode & STRONG_BIT);
145 }
146
147 void ReopenHandlesInNewHandleScope() {
148 closure_ = Handle<JSFunction>(*closure_);
149 shared_ = Handle<SharedFunctionInfo>(*shared_);
150 script_ = Handle<Script>(*script_);
151 context_ = Handle<Context>(*context_);
152 }
153
154 private:
155 // Various configuration flags for parsing.
156 enum Flag {
157 // ---------- Input flags ---------------------------
158 kToplevel = 1 << 0,
159 kLazy = 1 << 1,
160 kEval = 1 << 2,
161 kGlobal = 1 << 3,
162 kStrictMode = 1 << 4,
163 kStrongMode = 1 << 5,
164 kNative = 1 << 6,
165 kParseRestriction = 1 << 7,
166 kModule = 1 << 8,
167 kAllowLazyParsing = 1 << 9,
168 // ---------- Output flags --------------------------
169 kAstValueFactoryOwned = 1 << 10
170 };
171
172 //------------- Inputs to parsing and scope analysis -----------------------
173 Zone* zone_;
174 unsigned flags_;
175 ScriptCompiler::ExternalSourceStream* source_stream_;
176 ScriptCompiler::StreamedSource::Encoding source_stream_encoding_;
177 v8::Extension* extension_;
178 ScriptCompiler::CompileOptions compile_options_;
179 Scope* script_scope_;
180 UnicodeCache* unicode_cache_;
181 uintptr_t stack_limit_;
182 uint32_t hash_seed_;
183
184 // TODO(titzer): Move handles and isolate out of ParseInfo.
185 Isolate* isolate_;
186 Handle<JSFunction> closure_;
187 Handle<SharedFunctionInfo> shared_;
188 Handle<Script> script_;
189 Handle<Context> context_;
190
191 //----------- Inputs+Outputs of parsing and scope analysis -----------------
192 ScriptData** cached_data_; // used if available, populated if requested.
193 AstValueFactory* ast_value_factory_; // used if available, otherwise new.
194
195 //----------- Outputs of parsing and scope analysis ------------------------
196 FunctionLiteral* literal_; // produced by full parser.
197 Scope* scope_; // produced by scope analysis.
198
199 void SetFlag(Flag f) { flags_ |= f; }
200 void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; }
201 bool GetFlag(Flag f) const { return (flags_ & f) != 0; }
202
203 void set_shared_info(Handle<SharedFunctionInfo> shared) { shared_ = shared; }
204 void set_closure(Handle<JSFunction> closure) { closure_ = closure; }
205 };
206
207 class FunctionEntry BASE_EMBEDDED {
208 public:
209 enum {
210 kStartPositionIndex,
211 kEndPositionIndex,
212 kLiteralCountIndex,
213 kPropertyCountIndex,
214 kLanguageModeIndex,
215 kUsesSuperPropertyIndex,
216 kCallsEvalIndex,
217 kSize
218 };
219
220 explicit FunctionEntry(Vector<unsigned> backing)
221 : backing_(backing) { }
222
223 FunctionEntry() : backing_() { }
224
225 int start_pos() { return backing_[kStartPositionIndex]; }
226 int end_pos() { return backing_[kEndPositionIndex]; }
227 int literal_count() { return backing_[kLiteralCountIndex]; }
228 int property_count() { return backing_[kPropertyCountIndex]; }
229 LanguageMode language_mode() {
230 DCHECK(is_valid_language_mode(backing_[kLanguageModeIndex]));
231 return static_cast<LanguageMode>(backing_[kLanguageModeIndex]);
232 }
233 bool uses_super_property() { return backing_[kUsesSuperPropertyIndex]; }
234 bool calls_eval() { return backing_[kCallsEvalIndex]; }
235
236 bool is_valid() { return !backing_.is_empty(); }
237
238 private:
239 Vector<unsigned> backing_;
240 };
241
242
243 // Wrapper around ScriptData to provide parser-specific functionality.
244 class ParseData {
245 public:
246 static ParseData* FromCachedData(ScriptData* cached_data) {
247 ParseData* pd = new ParseData(cached_data);
248 if (pd->IsSane()) return pd;
249 cached_data->Reject();
250 delete pd;
251 return NULL;
252 }
253
254 void Initialize();
255 FunctionEntry GetFunctionEntry(int start);
256 int FunctionCount();
257
258 bool HasError();
259
260 unsigned* Data() { // Writable data as unsigned int array.
261 return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
262 }
263
264 void Reject() { script_data_->Reject(); }
265
266 bool rejected() const { return script_data_->rejected(); }
267
268 private:
269 explicit ParseData(ScriptData* script_data) : script_data_(script_data) {}
270
271 bool IsSane();
272 unsigned Magic();
273 unsigned Version();
274 int FunctionsSize();
275 int Length() const {
276 // Script data length is already checked to be a multiple of unsigned size.
277 return script_data_->length() / sizeof(unsigned);
278 }
279
280 ScriptData* script_data_;
281 int function_index_;
282
283 DISALLOW_COPY_AND_ASSIGN(ParseData);
284 };
285
286 // ----------------------------------------------------------------------------
287 // REGEXP PARSING
288
289 // A BufferedZoneList is an automatically growing list, just like (and backed
290 // by) a ZoneList, that is optimized for the case of adding and removing
291 // a single element. The last element added is stored outside the backing list,
292 // and if no more than one element is ever added, the ZoneList isn't even
293 // allocated.
294 // Elements must not be NULL pointers.
295 template <typename T, int initial_size>
296 class BufferedZoneList {
297 public:
298 BufferedZoneList() : list_(NULL), last_(NULL) {}
299
300 // Adds element at end of list. This element is buffered and can
301 // be read using last() or removed using RemoveLast until a new Add or until
302 // RemoveLast or GetList has been called.
303 void Add(T* value, Zone* zone) {
304 if (last_ != NULL) {
305 if (list_ == NULL) {
306 list_ = new(zone) ZoneList<T*>(initial_size, zone);
307 }
308 list_->Add(last_, zone);
309 }
310 last_ = value;
311 }
312
313 T* last() {
314 DCHECK(last_ != NULL);
315 return last_;
316 }
317
318 T* RemoveLast() {
319 DCHECK(last_ != NULL);
320 T* result = last_;
321 if ((list_ != NULL) && (list_->length() > 0))
322 last_ = list_->RemoveLast();
323 else
324 last_ = NULL;
325 return result;
326 }
327
328 T* Get(int i) {
329 DCHECK((0 <= i) && (i < length()));
330 if (list_ == NULL) {
331 DCHECK_EQ(0, i);
332 return last_;
333 } else {
334 if (i == list_->length()) {
335 DCHECK(last_ != NULL);
336 return last_;
337 } else {
338 return list_->at(i);
339 }
340 }
341 }
342
343 void Clear() {
344 list_ = NULL;
345 last_ = NULL;
346 }
347
348 int length() {
349 int length = (list_ == NULL) ? 0 : list_->length();
350 return length + ((last_ == NULL) ? 0 : 1);
351 }
352
353 ZoneList<T*>* GetList(Zone* zone) {
354 if (list_ == NULL) {
355 list_ = new(zone) ZoneList<T*>(initial_size, zone);
356 }
357 if (last_ != NULL) {
358 list_->Add(last_, zone);
359 last_ = NULL;
360 }
361 return list_;
362 }
363
364 private:
365 ZoneList<T*>* list_;
366 T* last_;
367 };
368
369
370 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
371 class RegExpBuilder: public ZoneObject {
372 public:
373 explicit RegExpBuilder(Zone* zone);
374 void AddCharacter(uc16 character);
375 // "Adds" an empty expression. Does nothing except consume a
376 // following quantifier
377 void AddEmpty();
378 void AddAtom(RegExpTree* tree);
379 void AddAssertion(RegExpTree* tree);
380 void NewAlternative(); // '|'
381 void AddQuantifierToAtom(
382 int min, int max, RegExpQuantifier::QuantifierType type);
383 RegExpTree* ToRegExp();
384
385 private:
386 void FlushCharacters();
387 void FlushText();
388 void FlushTerms();
389 Zone* zone() const { return zone_; }
390
391 Zone* zone_;
392 bool pending_empty_;
393 ZoneList<uc16>* characters_;
394 BufferedZoneList<RegExpTree, 2> terms_;
395 BufferedZoneList<RegExpTree, 2> text_;
396 BufferedZoneList<RegExpTree, 2> alternatives_;
397 #ifdef DEBUG
398 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
399 #define LAST(x) last_added_ = x;
400 #else
401 #define LAST(x)
402 #endif
403 };
404
405
406 class RegExpParser BASE_EMBEDDED {
407 public:
408 RegExpParser(FlatStringReader* in, Handle<String>* error, bool multiline_mode,
409 bool unicode, Isolate* isolate, Zone* zone);
410
411 static bool ParseRegExp(Isolate* isolate, Zone* zone, FlatStringReader* input,
412 bool multiline, bool unicode,
413 RegExpCompileData* result);
414
415 RegExpTree* ParsePattern();
416 RegExpTree* ParseDisjunction();
417 RegExpTree* ParseGroup();
418 RegExpTree* ParseCharacterClass();
419
420 // Parses a {...,...} quantifier and stores the range in the given
421 // out parameters.
422 bool ParseIntervalQuantifier(int* min_out, int* max_out);
423
424 // Parses and returns a single escaped character. The character
425 // must not be 'b' or 'B' since they are usually handle specially.
426 uc32 ParseClassCharacterEscape();
427
428 // Checks whether the following is a length-digit hexadecimal number,
429 // and sets the value if it is.
430 bool ParseHexEscape(int length, uc32* value);
431 bool ParseUnicodeEscape(uc32* value);
432 bool ParseUnlimitedLengthHexNumber(int max_value, uc32* value);
433
434 uc32 ParseOctalLiteral();
435
436 // Tries to parse the input as a back reference. If successful it
437 // stores the result in the output parameter and returns true. If
438 // it fails it will push back the characters read so the same characters
439 // can be reparsed.
440 bool ParseBackReferenceIndex(int* index_out);
441
442 CharacterRange ParseClassAtom(uc16* char_class);
443 RegExpTree* ReportError(Vector<const char> message);
444 void Advance();
445 void Advance(int dist);
446 void Reset(int pos);
447
448 // Reports whether the pattern might be used as a literal search string.
449 // Only use if the result of the parse is a single atom node.
450 bool simple();
451 bool contains_anchor() { return contains_anchor_; }
452 void set_contains_anchor() { contains_anchor_ = true; }
453 int captures_started() { return captures_started_; }
454 int position() { return next_pos_ - 1; }
455 bool failed() { return failed_; }
456
457 static bool IsSyntaxCharacter(uc32 c);
458
459 static const int kMaxCaptures = 1 << 16;
460 static const uc32 kEndMarker = (1 << 21);
461
462 private:
463 enum SubexpressionType {
464 INITIAL,
465 CAPTURE, // All positive values represent captures.
466 POSITIVE_LOOKAROUND,
467 NEGATIVE_LOOKAROUND,
468 GROUPING
469 };
470
471 class RegExpParserState : public ZoneObject {
472 public:
473 RegExpParserState(RegExpParserState* previous_state,
474 SubexpressionType group_type,
475 RegExpLookaround::Type lookaround_type,
476 int disjunction_capture_index, Zone* zone)
477 : previous_state_(previous_state),
478 builder_(new (zone) RegExpBuilder(zone)),
479 group_type_(group_type),
480 lookaround_type_(lookaround_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 // Lookahead or Lookbehind.
490 RegExpLookaround::Type lookaround_type() { return lookaround_type_; }
491 // Index in captures array of first capture in this sub-expression, if any.
492 // Also the capture index of this sub-expression itself, if group_type
493 // is CAPTURE.
494 int capture_index() { return disjunction_capture_index_; }
495
496 // Check whether the parser is inside a capture group with the given index.
497 bool IsInsideCaptureGroup(int index);
498
499 private:
500 // Linked list implementation of stack of states.
501 RegExpParserState* previous_state_;
502 // Builder for the stored disjunction.
503 RegExpBuilder* builder_;
504 // Stored disjunction type (capture, look-ahead or grouping), if any.
505 SubexpressionType group_type_;
506 // Stored read direction.
507 RegExpLookaround::Type lookaround_type_;
508 // Stored disjunction's capture index (if any).
509 int disjunction_capture_index_;
510 };
511
512 // Return the 1-indexed RegExpCapture object, allocate if necessary.
513 RegExpCapture* GetCapture(int index);
514
515 Isolate* isolate() { return isolate_; }
516 Zone* zone() const { return zone_; }
517
518 uc32 current() { return current_; }
519 bool has_more() { return has_more_; }
520 bool has_next() { return next_pos_ < in()->length(); }
521 uc32 Next();
522 FlatStringReader* in() { return in_; }
523 void ScanForCaptures();
524
525 Isolate* isolate_;
526 Zone* zone_;
527 Handle<String>* error_;
528 ZoneList<RegExpCapture*>* captures_;
529 FlatStringReader* in_;
530 uc32 current_;
531 int next_pos_;
532 int captures_started_;
533 // The capture count is only valid after we have scanned for captures.
534 int capture_count_;
535 bool has_more_;
536 bool multiline_;
537 bool unicode_;
538 bool simple_;
539 bool contains_anchor_;
540 bool is_scanned_for_captures_;
541 bool failed_;
542 };
543
544 // ----------------------------------------------------------------------------
545 // JAVASCRIPT PARSING
546
547 class Parser;
548 class SingletonLogger;
549
550
551 struct ParserFormalParameters : FormalParametersBase {
552 struct Parameter {
553 Parameter(const AstRawString* name, Expression* pattern,
554 Expression* initializer, int initializer_end_position,
555 bool is_rest)
556 : name(name),
557 pattern(pattern),
558 initializer(initializer),
559 initializer_end_position(initializer_end_position),
560 is_rest(is_rest) {}
561 const AstRawString* name;
562 Expression* pattern;
563 Expression* initializer;
564 int initializer_end_position;
565 bool is_rest;
566 bool is_simple() const {
567 return pattern->IsVariableProxy() && initializer == nullptr && !is_rest;
568 }
569 };
570
571 explicit ParserFormalParameters(Scope* scope)
572 : FormalParametersBase(scope), params(4, scope->zone()) {}
573 ZoneList<Parameter> params;
574
575 int Arity() const { return params.length(); }
576 const Parameter& at(int i) const { return params[i]; }
577 };
578
579
580 class ParserTraits {
581 public:
582 struct Type {
583 // TODO(marja): To be removed. The Traits object should contain all the data
584 // it needs.
585 typedef v8::internal::Parser* Parser;
586
587 typedef Variable GeneratorVariable;
588
589 typedef v8::internal::AstProperties AstProperties;
590
591 // Return types for traversing functions.
592 typedef const AstRawString* Identifier;
593 typedef v8::internal::Expression* Expression;
594 typedef Yield* YieldExpression;
595 typedef v8::internal::FunctionLiteral* FunctionLiteral;
596 typedef v8::internal::ClassLiteral* ClassLiteral;
597 typedef v8::internal::Literal* Literal;
598 typedef ObjectLiteral::Property* ObjectLiteralProperty;
599 typedef ZoneList<v8::internal::Expression*>* ExpressionList;
600 typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
601 typedef ParserFormalParameters::Parameter FormalParameter;
602 typedef ParserFormalParameters FormalParameters;
603 typedef ZoneList<v8::internal::Statement*>* StatementList;
604
605 // For constructing objects returned by the traversing functions.
606 typedef AstNodeFactory Factory;
607 };
608
609 explicit ParserTraits(Parser* parser) : parser_(parser) {}
610
611 // Helper functions for recursive descent.
612 bool IsEval(const AstRawString* identifier) const;
613 bool IsArguments(const AstRawString* identifier) const;
614 bool IsEvalOrArguments(const AstRawString* identifier) const;
615 bool IsUndefined(const AstRawString* identifier) const;
616 V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
617
618 // Returns true if the expression is of type "this.foo".
619 static bool IsThisProperty(Expression* expression);
620
621 static bool IsIdentifier(Expression* expression);
622
623 bool IsPrototype(const AstRawString* identifier) const;
624
625 bool IsConstructor(const AstRawString* identifier) const;
626
627 static const AstRawString* AsIdentifier(Expression* expression) {
628 DCHECK(IsIdentifier(expression));
629 return expression->AsVariableProxy()->raw_name();
630 }
631
632 static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
633 return ObjectLiteral::IsBoilerplateProperty(property);
634 }
635
636 static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
637 return string->AsArrayIndex(index);
638 }
639
640 static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
641 return property->value();
642 }
643
644 // Functions for encapsulating the differences between parsing and preparsing;
645 // operations interleaved with the recursive descent.
646 static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
647 fni->PushLiteralName(id);
648 }
649
650 void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
651
652 static void InferFunctionName(FuncNameInferrer* fni,
653 FunctionLiteral* func_to_infer) {
654 fni->AddFunction(func_to_infer);
655 }
656
657 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
658 Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
659 Expression* value = property->value();
660 if (scope->DeclarationScope()->is_script_scope() &&
661 value->AsFunctionLiteral() != NULL) {
662 *has_function = true;
663 value->AsFunctionLiteral()->set_pretenure();
664 }
665 }
666
667 // If we assign a function literal to a property we pretenure the
668 // literal so it can be added as a constant function property.
669 static void CheckAssigningFunctionLiteralToProperty(Expression* left,
670 Expression* right);
671
672 // Keep track of eval() calls since they disable all local variable
673 // optimizations. This checks if expression is an eval call, and if yes,
674 // forwards the information to scope.
675 void CheckPossibleEvalCall(Expression* expression, Scope* scope);
676
677 // Determine if the expression is a variable proxy and mark it as being used
678 // in an assignment or with a increment/decrement operator.
679 static Expression* MarkExpressionAsAssigned(Expression* expression);
680
681 // Returns true if we have a binary expression between two numeric
682 // literals. In that case, *x will be changed to an expression which is the
683 // computed value.
684 bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
685 Token::Value op, int pos,
686 AstNodeFactory* factory);
687
688 // Rewrites the following types of unary expressions:
689 // not <literal> -> true / false
690 // + <numeric literal> -> <numeric literal>
691 // - <numeric literal> -> <numeric literal with value negated>
692 // ! <literal> -> true / false
693 // The following rewriting rules enable the collection of type feedback
694 // without any special stub and the multiplication is removed later in
695 // Crankshaft's canonicalization pass.
696 // + foo -> foo * 1
697 // - foo -> foo * (-1)
698 // ~ foo -> foo ^(~0)
699 Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
700 int pos, AstNodeFactory* factory);
701
702 // Generate AST node that throws a ReferenceError with the given type.
703 Expression* NewThrowReferenceError(MessageTemplate::Template message,
704 int pos);
705
706 // Generate AST node that throws a SyntaxError with the given
707 // type. The first argument may be null (in the handle sense) in
708 // which case no arguments are passed to the constructor.
709 Expression* NewThrowSyntaxError(MessageTemplate::Template message,
710 const AstRawString* arg, int pos);
711
712 // Generate AST node that throws a TypeError with the given
713 // type. Both arguments must be non-null (in the handle sense).
714 Expression* NewThrowTypeError(MessageTemplate::Template message,
715 const AstRawString* arg, int pos);
716
717 // Generic AST generator for throwing errors from compiled code.
718 Expression* NewThrowError(Runtime::FunctionId function_id,
719 MessageTemplate::Template message,
720 const AstRawString* arg, int pos);
721
722 // Reporting errors.
723 void ReportMessageAt(Scanner::Location source_location,
724 MessageTemplate::Template message,
725 const char* arg = NULL,
726 ParseErrorType error_type = kSyntaxError);
727 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
728 ParseErrorType error_type = kSyntaxError);
729 void ReportMessage(MessageTemplate::Template message, const AstRawString* arg,
730 ParseErrorType error_type = kSyntaxError);
731 void ReportMessageAt(Scanner::Location source_location,
732 MessageTemplate::Template message,
733 const AstRawString* arg,
734 ParseErrorType error_type = kSyntaxError);
735
736 // "null" return type creators.
737 static const AstRawString* EmptyIdentifier() {
738 return NULL;
739 }
740 static Expression* EmptyExpression() {
741 return NULL;
742 }
743 static Literal* EmptyLiteral() {
744 return NULL;
745 }
746 static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
747 static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
748
749 // Used in error return values.
750 static ZoneList<Expression*>* NullExpressionList() {
751 return NULL;
752 }
753 static const AstRawString* EmptyFormalParameter() { return NULL; }
754
755 // Non-NULL empty string.
756 V8_INLINE const AstRawString* EmptyIdentifierString();
757
758 // Odd-ball literal creators.
759 Literal* GetLiteralTheHole(int position, AstNodeFactory* factory);
760
761 // Producing data during the recursive descent.
762 const AstRawString* GetSymbol(Scanner* scanner);
763 const AstRawString* GetNextSymbol(Scanner* scanner);
764 const AstRawString* GetNumberAsSymbol(Scanner* scanner);
765
766 Expression* ThisExpression(Scope* scope, AstNodeFactory* factory,
767 int pos = RelocInfo::kNoPosition);
768 Expression* SuperPropertyReference(Scope* scope, AstNodeFactory* factory,
769 int pos);
770 Expression* SuperCallReference(Scope* scope, AstNodeFactory* factory,
771 int pos);
772 Expression* NewTargetExpression(Scope* scope, AstNodeFactory* factory,
773 int pos);
774 Expression* DefaultConstructor(bool call_super, Scope* scope, int pos,
775 int end_pos, LanguageMode language_mode);
776 Literal* ExpressionFromLiteral(Token::Value token, int pos, Scanner* scanner,
777 AstNodeFactory* factory);
778 Expression* ExpressionFromIdentifier(const AstRawString* name,
779 int start_position, int end_position,
780 Scope* scope, AstNodeFactory* factory);
781 Expression* ExpressionFromString(int pos, Scanner* scanner,
782 AstNodeFactory* factory);
783 Expression* GetIterator(Expression* iterable, AstNodeFactory* factory);
784 ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
785 return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
786 }
787 ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
788 return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
789 }
790 ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
791 return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
792 }
793
794 V8_INLINE void AddParameterInitializationBlock(
795 const ParserFormalParameters& parameters,
796 ZoneList<v8::internal::Statement*>* body, bool* ok);
797
798 V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type,
799 FunctionKind kind = kNormalFunction);
800
801 V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters,
802 Expression* pattern,
803 Expression* initializer,
804 int initializer_end_position, bool is_rest);
805 V8_INLINE void DeclareFormalParameter(
806 Scope* scope, const ParserFormalParameters::Parameter& parameter,
807 ExpressionClassifier* classifier);
808 void ParseArrowFunctionFormalParameters(ParserFormalParameters* parameters,
809 Expression* params,
810 const Scanner::Location& params_loc,
811 bool* ok);
812 void ParseArrowFunctionFormalParameterList(
813 ParserFormalParameters* parameters, Expression* params,
814 const Scanner::Location& params_loc,
815 Scanner::Location* duplicate_loc, bool* ok);
816
817 V8_INLINE DoExpression* ParseDoExpression(bool* ok);
818
819 void ReindexLiterals(const ParserFormalParameters& parameters);
820
821 // Temporary glue; these functions will move to ParserBase.
822 Expression* ParseV8Intrinsic(bool* ok);
823 FunctionLiteral* ParseFunctionLiteral(
824 const AstRawString* name, Scanner::Location function_name_location,
825 FunctionNameValidity function_name_validity, FunctionKind kind,
826 int function_token_position, FunctionLiteral::FunctionType type,
827 FunctionLiteral::ArityRestriction arity_restriction,
828 LanguageMode language_mode, bool* ok);
829 V8_INLINE void SkipLazyFunctionBody(
830 int* materialized_literal_count, int* expected_property_count, bool* ok,
831 Scanner::BookmarkScope* bookmark = nullptr);
832 V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
833 const AstRawString* name, int pos,
834 const ParserFormalParameters& parameters, FunctionKind kind,
835 FunctionLiteral::FunctionType function_type, bool* ok);
836
837 ClassLiteral* ParseClassLiteral(const AstRawString* name,
838 Scanner::Location class_name_location,
839 bool name_is_strict_reserved, int pos,
840 bool* ok);
841
842 V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
843 bool* ok);
844
845 class TemplateLiteral : public ZoneObject {
846 public:
847 TemplateLiteral(Zone* zone, int pos)
848 : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
849
850 const ZoneList<Expression*>* cooked() const { return &cooked_; }
851 const ZoneList<Expression*>* raw() const { return &raw_; }
852 const ZoneList<Expression*>* expressions() const { return &expressions_; }
853 int position() const { return pos_; }
854
855 void AddTemplateSpan(Literal* cooked, Literal* raw, int end, Zone* zone) {
856 DCHECK_NOT_NULL(cooked);
857 DCHECK_NOT_NULL(raw);
858 cooked_.Add(cooked, zone);
859 raw_.Add(raw, zone);
860 }
861
862 void AddExpression(Expression* expression, Zone* zone) {
863 DCHECK_NOT_NULL(expression);
864 expressions_.Add(expression, zone);
865 }
866
867 private:
868 ZoneList<Expression*> cooked_;
869 ZoneList<Expression*> raw_;
870 ZoneList<Expression*> expressions_;
871 int pos_;
872 };
873
874 typedef TemplateLiteral* TemplateLiteralState;
875
876 V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos);
877 V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail);
878 V8_INLINE void AddTemplateExpression(TemplateLiteralState* state,
879 Expression* expression);
880 V8_INLINE Expression* CloseTemplateLiteral(TemplateLiteralState* state,
881 int start, Expression* tag);
882 V8_INLINE Expression* NoTemplateTag() { return NULL; }
883 V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
884 return tag != NULL;
885 }
886
887 V8_INLINE ZoneList<v8::internal::Expression*>* PrepareSpreadArguments(
888 ZoneList<v8::internal::Expression*>* list);
889 V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {}
890 V8_INLINE Expression* SpreadCall(Expression* function,
891 ZoneList<v8::internal::Expression*>* args,
892 int pos);
893 V8_INLINE Expression* SpreadCallNew(Expression* function,
894 ZoneList<v8::internal::Expression*>* args,
895 int pos);
896
897 private:
898 Parser* parser_;
899 };
900
901
902 class Parser : public ParserBase<ParserTraits> {
903 public:
904 explicit Parser(ParseInfo* info);
905 ~Parser() {
906 delete reusable_preparser_;
907 reusable_preparser_ = NULL;
908 delete cached_parse_data_;
909 cached_parse_data_ = NULL;
910 }
911
912 // Parses the source code represented by the compilation info and sets its
913 // function literal. Returns false (and deallocates any allocated AST
914 // nodes) if parsing failed.
915 static bool ParseStatic(ParseInfo* info);
916 bool Parse(ParseInfo* info);
917 void ParseOnBackground(ParseInfo* info);
918
919 // Handle errors detected during parsing, move statistics to Isolate,
920 // internalize strings (move them to the heap).
921 void Internalize(Isolate* isolate, Handle<Script> script, bool error);
922 void HandleSourceURLComments(Isolate* isolate, Handle<Script> script);
923
924 private:
925 friend class ParserTraits;
926
927 // Limit the allowed number of local variables in a function. The hard limit
928 // is that offsets computed by FullCodeGenerator::StackOperand and similar
929 // functions are ints, and they should not overflow. In addition, accessing
930 // local variables creates user-controlled constants in the generated code,
931 // and we don't want too much user-controlled memory inside the code (this was
932 // the reason why this limit was introduced in the first place; see
933 // https://codereview.chromium.org/7003030/ ).
934 static const int kMaxNumFunctionLocals = 4194303; // 2^22-1
935
936 // Returns NULL if parsing failed.
937 FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info);
938
939 FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info);
940 FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info,
941 Utf16CharacterStream* source);
942
943 // Called by ParseProgram after setting up the scanner.
944 FunctionLiteral* DoParseProgram(ParseInfo* info);
945
946 void SetCachedData(ParseInfo* info);
947
948 ScriptCompiler::CompileOptions compile_options() const {
949 return compile_options_;
950 }
951 bool consume_cached_parse_data() const {
952 return compile_options_ == ScriptCompiler::kConsumeParserCache &&
953 cached_parse_data_ != NULL;
954 }
955 bool produce_cached_parse_data() const {
956 return compile_options_ == ScriptCompiler::kProduceParserCache;
957 }
958 Scope* DeclarationScope(VariableMode mode) {
959 return IsLexicalVariableMode(mode)
960 ? scope_ : scope_->DeclarationScope();
961 }
962
963 // All ParseXXX functions take as the last argument an *ok parameter
964 // which is set to false if parsing failed; it is unchanged otherwise.
965 // By making the 'exception handling' explicit, we are forced to check
966 // for failure at the call sites.
967 void* ParseStatementList(ZoneList<Statement*>* body, int end_token, bool* ok);
968 Statement* ParseStatementListItem(bool* ok);
969 void* ParseModuleItemList(ZoneList<Statement*>* body, bool* ok);
970 Statement* ParseModuleItem(bool* ok);
971 const AstRawString* ParseModuleSpecifier(bool* ok);
972 Statement* ParseImportDeclaration(bool* ok);
973 Statement* ParseExportDeclaration(bool* ok);
974 Statement* ParseExportDefault(bool* ok);
975 void* ParseExportClause(ZoneList<const AstRawString*>* export_names,
976 ZoneList<Scanner::Location>* export_locations,
977 ZoneList<const AstRawString*>* local_names,
978 Scanner::Location* reserved_loc, bool* ok);
979 ZoneList<ImportDeclaration*>* ParseNamedImports(int pos, bool* ok);
980 Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
981 Statement* ParseSubStatement(ZoneList<const AstRawString*>* labels, bool* ok);
982 Statement* ParseStatementAsUnlabelled(ZoneList<const AstRawString*>* labels,
983 bool* ok);
984 Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
985 bool* ok);
986 Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
987 bool* ok);
988 Statement* ParseNativeDeclaration(bool* ok);
989 Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
990 Block* ParseVariableStatement(VariableDeclarationContext var_context,
991 ZoneList<const AstRawString*>* names,
992 bool* ok);
993 DoExpression* ParseDoExpression(bool* ok);
994
995 struct DeclarationDescriptor {
996 enum Kind { NORMAL, PARAMETER };
997 Parser* parser;
998 Scope* declaration_scope;
999 Scope* scope;
1000 Scope* hoist_scope;
1001 VariableMode mode;
1002 bool is_const;
1003 bool needs_init;
1004 int declaration_pos;
1005 int initialization_pos;
1006 Kind declaration_kind;
1007 };
1008
1009 struct DeclarationParsingResult {
1010 struct Declaration {
1011 Declaration(Expression* pattern, int initializer_position,
1012 Expression* initializer)
1013 : pattern(pattern),
1014 initializer_position(initializer_position),
1015 initializer(initializer) {}
1016
1017 Expression* pattern;
1018 int initializer_position;
1019 Expression* initializer;
1020 };
1021
1022 DeclarationParsingResult()
1023 : declarations(4),
1024 first_initializer_loc(Scanner::Location::invalid()),
1025 bindings_loc(Scanner::Location::invalid()) {}
1026
1027 Block* BuildInitializationBlock(ZoneList<const AstRawString*>* names,
1028 bool* ok);
1029
1030 DeclarationDescriptor descriptor;
1031 List<Declaration> declarations;
1032 Scanner::Location first_initializer_loc;
1033 Scanner::Location bindings_loc;
1034 };
1035
1036 class PatternRewriter : private AstVisitor {
1037 public:
1038 static void DeclareAndInitializeVariables(
1039 Block* block, const DeclarationDescriptor* declaration_descriptor,
1040 const DeclarationParsingResult::Declaration* declaration,
1041 ZoneList<const AstRawString*>* names, bool* ok);
1042
1043 void set_initializer_position(int pos) { initializer_position_ = pos; }
1044
1045 private:
1046 PatternRewriter() {}
1047
1048 #define DECLARE_VISIT(type) void Visit##type(v8::internal::type* node) override;
1049 // Visiting functions for AST nodes make this an AstVisitor.
1050 AST_NODE_LIST(DECLARE_VISIT)
1051 #undef DECLARE_VISIT
1052 void Visit(AstNode* node) override;
1053
1054 void RecurseIntoSubpattern(AstNode* pattern, Expression* value) {
1055 Expression* old_value = current_value_;
1056 current_value_ = value;
1057 pattern->Accept(this);
1058 current_value_ = old_value;
1059 }
1060
1061 Variable* CreateTempVar(Expression* value = nullptr);
1062
1063 AstNodeFactory* factory() const { return descriptor_->parser->factory(); }
1064 AstValueFactory* ast_value_factory() const {
1065 return descriptor_->parser->ast_value_factory();
1066 }
1067 Zone* zone() const { return descriptor_->parser->zone(); }
1068
1069 Expression* pattern_;
1070 int initializer_position_;
1071 Block* block_;
1072 const DeclarationDescriptor* descriptor_;
1073 ZoneList<const AstRawString*>* names_;
1074 Expression* current_value_;
1075 bool* ok_;
1076 };
1077
1078
1079 void ParseVariableDeclarations(VariableDeclarationContext var_context,
1080 DeclarationParsingResult* parsing_result,
1081 bool* ok);
1082 Statement* ParseExpressionOrLabelledStatement(
1083 ZoneList<const AstRawString*>* labels, bool* ok);
1084 IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
1085 bool* ok);
1086 Statement* ParseContinueStatement(bool* ok);
1087 Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
1088 bool* ok);
1089 Statement* ParseReturnStatement(bool* ok);
1090 Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
1091 bool* ok);
1092 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
1093 Statement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
1094 bool* ok);
1095 DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
1096 bool* ok);
1097 WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
1098 bool* ok);
1099 Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
1100 Statement* ParseThrowStatement(bool* ok);
1101 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
1102 TryStatement* ParseTryStatement(bool* ok);
1103 DebuggerStatement* ParseDebuggerStatement(bool* ok);
1104
1105 // !%_IsSpecObject(result = iterator.next()) &&
1106 // %ThrowIteratorResultNotAnObject(result)
1107 Expression* BuildIteratorNextResult(Expression* iterator, Variable* result,
1108 int pos);
1109
1110
1111 // Initialize the components of a for-in / for-of statement.
1112 void InitializeForEachStatement(ForEachStatement* stmt,
1113 Expression* each,
1114 Expression* subject,
1115 Statement* body);
1116 Statement* DesugarLexicalBindingsInForStatement(
1117 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
1118 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
1119 Statement* body, bool* ok);
1120
1121 void RewriteDoExpression(Expression* expr, bool* ok);
1122
1123 FunctionLiteral* ParseFunctionLiteral(
1124 const AstRawString* name, Scanner::Location function_name_location,
1125 FunctionNameValidity function_name_validity, FunctionKind kind,
1126 int function_token_position, FunctionLiteral::FunctionType type,
1127 FunctionLiteral::ArityRestriction arity_restriction,
1128 LanguageMode language_mode, bool* ok);
1129
1130
1131 ClassLiteral* ParseClassLiteral(const AstRawString* name,
1132 Scanner::Location class_name_location,
1133 bool name_is_strict_reserved, int pos,
1134 bool* ok);
1135
1136 // Magical syntax support.
1137 Expression* ParseV8Intrinsic(bool* ok);
1138
1139 // Get odd-ball literals.
1140 Literal* GetLiteralUndefined(int position);
1141
1142 // Check if the scope has conflicting var/let declarations from different
1143 // scopes. This covers for example
1144 //
1145 // function f() { { { var x; } let x; } }
1146 // function g() { { var x; let x; } }
1147 //
1148 // The var declarations are hoisted to the function scope, but originate from
1149 // a scope where the name has also been let bound or the var declaration is
1150 // hoisted over such a scope.
1151 void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
1152
1153 // Insert initializer statements for var-bindings shadowing parameter bindings
1154 // from a non-simple parameter list.
1155 void InsertShadowingVarBindingInitializers(Block* block);
1156
1157 // Implement sloppy block-scoped functions, ES2015 Annex B 3.3
1158 void InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok);
1159
1160 // Parser support
1161 VariableProxy* NewUnresolved(const AstRawString* name, VariableMode mode);
1162 Variable* Declare(Declaration* declaration,
1163 DeclarationDescriptor::Kind declaration_kind, bool resolve,
1164 bool* ok, Scope* declaration_scope = nullptr);
1165
1166 bool TargetStackContainsLabel(const AstRawString* label);
1167 BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
1168 IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
1169
1170 Statement* BuildAssertIsCoercible(Variable* var);
1171
1172 // Factory methods.
1173 FunctionLiteral* DefaultConstructor(bool call_super, Scope* scope, int pos,
1174 int end_pos, LanguageMode language_mode);
1175
1176 // Skip over a lazy function, either using cached data if we have it, or
1177 // by parsing the function with PreParser. Consumes the ending }.
1178 //
1179 // If bookmark is set, the (pre-)parser may decide to abort skipping
1180 // in order to force the function to be eagerly parsed, after all.
1181 // In this case, it'll reset the scanner using the bookmark.
1182 void SkipLazyFunctionBody(int* materialized_literal_count,
1183 int* expected_property_count, bool* ok,
1184 Scanner::BookmarkScope* bookmark = nullptr);
1185
1186 PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
1187 SingletonLogger* logger, Scanner::BookmarkScope* bookmark = nullptr);
1188
1189 Block* BuildParameterInitializationBlock(
1190 const ParserFormalParameters& parameters, bool* ok);
1191
1192 // Consumes the ending }.
1193 ZoneList<Statement*>* ParseEagerFunctionBody(
1194 const AstRawString* function_name, int pos,
1195 const ParserFormalParameters& parameters, FunctionKind kind,
1196 FunctionLiteral::FunctionType function_type, bool* ok);
1197
1198 void ThrowPendingError(Isolate* isolate, Handle<Script> script);
1199
1200 TemplateLiteralState OpenTemplateLiteral(int pos);
1201 void AddTemplateSpan(TemplateLiteralState* state, bool tail);
1202 void AddTemplateExpression(TemplateLiteralState* state,
1203 Expression* expression);
1204 Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
1205 Expression* tag);
1206 uint32_t ComputeTemplateLiteralHash(const TemplateLiteral* lit);
1207
1208 ZoneList<v8::internal::Expression*>* PrepareSpreadArguments(
1209 ZoneList<v8::internal::Expression*>* list);
1210 Expression* SpreadCall(Expression* function,
1211 ZoneList<v8::internal::Expression*>* args, int pos);
1212 Expression* SpreadCallNew(Expression* function,
1213 ZoneList<v8::internal::Expression*>* args, int pos);
1214
1215 void SetLanguageMode(Scope* scope, LanguageMode mode);
1216 void RaiseLanguageMode(LanguageMode mode);
1217
1218 Scanner scanner_;
1219 PreParser* reusable_preparser_;
1220 Scope* original_scope_; // for ES5 function declarations in sloppy eval
1221 Target* target_stack_; // for break, continue statements
1222 ScriptCompiler::CompileOptions compile_options_;
1223 ParseData* cached_parse_data_;
1224
1225 PendingCompilationErrorHandler pending_error_handler_;
1226
1227 // Other information which will be stored in Parser and moved to Isolate after
1228 // parsing.
1229 int use_counts_[v8::Isolate::kUseCounterFeatureCount];
1230 int total_preparse_skipped_;
1231 HistogramTimer* pre_parse_timer_;
1232
1233 bool parsing_on_main_thread_;
1234 };
1235
1236
1237 bool ParserTraits::IsFutureStrictReserved(
1238 const AstRawString* identifier) const {
1239 return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
1240 }
1241
1242
1243 Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type,
1244 FunctionKind kind) {
1245 return parser_->NewScope(parent_scope, scope_type, kind);
1246 }
1247
1248
1249 const AstRawString* ParserTraits::EmptyIdentifierString() {
1250 return parser_->ast_value_factory()->empty_string();
1251 }
1252
1253
1254 void ParserTraits::SkipLazyFunctionBody(int* materialized_literal_count,
1255 int* expected_property_count, bool* ok,
1256 Scanner::BookmarkScope* bookmark) {
1257 return parser_->SkipLazyFunctionBody(materialized_literal_count,
1258 expected_property_count, ok, bookmark);
1259 }
1260
1261
1262 ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
1263 const AstRawString* name, int pos, const ParserFormalParameters& parameters,
1264 FunctionKind kind, FunctionLiteral::FunctionType function_type, bool* ok) {
1265 return parser_->ParseEagerFunctionBody(name, pos, parameters, kind,
1266 function_type, ok);
1267 }
1268
1269
1270 void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
1271 bool* ok) {
1272 parser_->CheckConflictingVarDeclarations(scope, ok);
1273 }
1274
1275
1276 // Support for handling complex values (array and object literals) that
1277 // can be fully handled at compile time.
1278 class CompileTimeValue: public AllStatic {
1279 public:
1280 enum LiteralType {
1281 OBJECT_LITERAL_FAST_ELEMENTS,
1282 OBJECT_LITERAL_SLOW_ELEMENTS,
1283 ARRAY_LITERAL
1284 };
1285
1286 static bool IsCompileTimeValue(Expression* expression);
1287
1288 // Get the value as a compile time value.
1289 static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
1290
1291 // Get the type of a compile time value returned by GetValue().
1292 static LiteralType GetLiteralType(Handle<FixedArray> value);
1293
1294 // Get the elements array of a compile time value returned by GetValue().
1295 static Handle<FixedArray> GetElements(Handle<FixedArray> value);
1296
1297 private:
1298 static const int kLiteralTypeSlot = 0;
1299 static const int kElementsSlot = 1;
1300
1301 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
1302 };
1303
1304
1305 ParserTraits::TemplateLiteralState ParserTraits::OpenTemplateLiteral(int pos) {
1306 return parser_->OpenTemplateLiteral(pos);
1307 }
1308
1309
1310 void ParserTraits::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
1311 parser_->AddTemplateSpan(state, tail);
1312 }
1313
1314
1315 void ParserTraits::AddTemplateExpression(TemplateLiteralState* state,
1316 Expression* expression) {
1317 parser_->AddTemplateExpression(state, expression);
1318 }
1319
1320
1321 Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state,
1322 int start, Expression* tag) {
1323 return parser_->CloseTemplateLiteral(state, start, tag);
1324 }
1325
1326
1327 ZoneList<v8::internal::Expression*>* ParserTraits::PrepareSpreadArguments(
1328 ZoneList<v8::internal::Expression*>* list) {
1329 return parser_->PrepareSpreadArguments(list);
1330 }
1331
1332
1333 Expression* ParserTraits::SpreadCall(Expression* function,
1334 ZoneList<v8::internal::Expression*>* args,
1335 int pos) {
1336 return parser_->SpreadCall(function, args, pos);
1337 }
1338
1339
1340 Expression* ParserTraits::SpreadCallNew(
1341 Expression* function, ZoneList<v8::internal::Expression*>* args, int pos) {
1342 return parser_->SpreadCallNew(function, args, pos);
1343 }
1344
1345
1346 void ParserTraits::AddFormalParameter(ParserFormalParameters* parameters,
1347 Expression* pattern,
1348 Expression* initializer,
1349 int initializer_end_position,
1350 bool is_rest) {
1351 bool is_simple =
1352 !is_rest && pattern->IsVariableProxy() && initializer == nullptr;
1353 DCHECK(parser_->allow_harmony_destructuring_bind() ||
1354 parser_->allow_harmony_rest_parameters() ||
1355 parser_->allow_harmony_default_parameters() || is_simple);
1356 const AstRawString* name = is_simple
1357 ? pattern->AsVariableProxy()->raw_name()
1358 : parser_->ast_value_factory()->empty_string();
1359 parameters->params.Add(
1360 ParserFormalParameters::Parameter(name, pattern, initializer,
1361 initializer_end_position, is_rest),
1362 parameters->scope->zone());
1363 }
1364
1365
1366 void ParserTraits::DeclareFormalParameter(
1367 Scope* scope, const ParserFormalParameters::Parameter& parameter,
1368 ExpressionClassifier* classifier) {
1369 bool is_duplicate = false;
1370 bool is_simple = classifier->is_simple_parameter_list();
1371 auto name = parameter.name;
1372 auto mode = is_simple ? VAR : TEMPORARY;
1373 if (!is_simple) scope->SetHasNonSimpleParameters();
1374 bool is_optional = parameter.initializer != nullptr;
1375 Variable* var = scope->DeclareParameter(
1376 name, mode, is_optional, parameter.is_rest, &is_duplicate);
1377 if (is_duplicate) {
1378 classifier->RecordDuplicateFormalParameterError(
1379 parser_->scanner()->location());
1380 }
1381 if (is_sloppy(scope->language_mode())) {
1382 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
1383 // conservative approximation necessary to account for parameters
1384 // that are assigned via the arguments array.
1385 var->set_maybe_assigned();
1386 }
1387 }
1388
1389
1390 void ParserTraits::AddParameterInitializationBlock(
1391 const ParserFormalParameters& parameters,
1392 ZoneList<v8::internal::Statement*>* body, bool* ok) {
1393 if (!parameters.is_simple) {
1394 auto* init_block =
1395 parser_->BuildParameterInitializationBlock(parameters, ok);
1396 if (!*ok) return;
1397 if (init_block != nullptr) {
1398 body->Add(init_block, parser_->zone());
1399 }
1400 }
1401 }
1402
1403
1404 DoExpression* ParserTraits::ParseDoExpression(bool* ok) {
1405 return parser_->ParseDoExpression(ok);
1406 }
1407
1408
1409 } // namespace internal
1410 } // namespace v8
1411
1412 #endif // V8_PARSER_H_
OLDNEW
« no previous file with comments | « src/parameter-initializer-rewriter.cc ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698