OLD | NEW |
| (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_ | |
OLD | NEW |