| 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 |