18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Features shared by parsing and pre-parsing scanners. 6589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_PARSING_SCANNER_H_ 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_PARSING_SCANNER_H_ 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h" 1121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "src/base/hashmap.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/logging.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/char-predicates.h" 141b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#include "src/collector.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/globals.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/list.h" 171b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#include "src/messages.h" 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/token.h" 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/unicode-decoder.h" 2021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "src/unicode.h" 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass AstRawString; 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass AstValueFactory; 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ParserRecorder; 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass UnicodeCache; 30589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 31589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 32589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// --------------------------------------------------------------------- 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Buffered stream of UTF-16 code units, using an internal UTF-16 buffer. 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A code unit is a 16 bit value representing either a 16 bit code point 353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// or one part of a surrogate pair that make a single 21 bit code point. 36589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Utf16CharacterStream { 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Utf16CharacterStream() : pos_(0) { } 403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual ~Utf16CharacterStream() { } 41589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns and advances past the next UTF-16 code unit in the input 433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // stream. If there are no more code units, it returns a negative 44589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // value. 45589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch inline uc32 Advance() { 46589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (buffer_cursor_ < buffer_end_ || ReadBlock()) { 47589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch pos_++; 48589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return static_cast<uc32>(*(buffer_cursor_++)); 49589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 50589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Note: currently the following increment is necessary to avoid a 51589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // parser problem! The scanner treats the final kEndOfInput as 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a code unit with a position, and does math relative to that 53589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // position. 54589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch pos_++; 55589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 56589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return kEndOfInput; 57589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 58b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Return the current position in the code unit stream. 60589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Starts at zero. 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline size_t pos() const { return pos_; } 62589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skips forward past the next code_unit_count UTF-16 code units 64589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // in the input, or until the end of input if that comes sooner. 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns the number of code units actually skipped. If less 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // than code_unit_count, 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline size_t SeekForward(size_t code_unit_count) { 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t buffered_chars = buffer_end_ - buffer_cursor_; 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (code_unit_count <= buffered_chars) { 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer_cursor_ += code_unit_count; 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pos_ += code_unit_count; 723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code_unit_count; 73589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return SlowSeekForward(code_unit_count); 75589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 76589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pushes back the most recently read UTF-16 code unit (or negative 78589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // value if at end of input), i.e., the value returned by the most recent 79589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // call to Advance. 80589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Must not be used right after calling SeekForward. 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void PushBack(int32_t code_unit) = 0; 82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual bool SetBookmark(); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual void ResetToBookmark(); 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 87589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch static const uc32 kEndOfInput = -1; 88589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Ensures that the buffer_cursor_ points to the code_unit at 90589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // position pos_ of the input, if possible. If the position 91589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // is at or after the end of the input, return false. If there 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // are more code_units available, return true. 93589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch virtual bool ReadBlock() = 0; 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual size_t SlowSeekForward(size_t code_unit_count) = 0; 95589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const uint16_t* buffer_cursor_; 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const uint16_t* buffer_end_; 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t pos_; 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --------------------------------------------------------------------- 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DuplicateFinder discovers duplicate symbols. 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DuplicateFinder { 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit DuplicateFinder(UnicodeCache* constants) 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : unicode_constants_(constants), 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backing_store_(16), 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_(&Match) { } 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int AddOneByteSymbol(Vector<const uint8_t> key, int value); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int AddTwoByteSymbol(Vector<const uint16_t> key, int value); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add a a number literal by converting it (if necessary) 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the string that ToString(ToNumber(literal)) would generate. 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and then adding that string with AddOneByteSymbol. 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This string is the actual value used as key in an object literal, 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and the one that must be different from the other keys. 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int AddNumber(Vector<const uint8_t> key, int value); 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int AddSymbol(Vector<const uint8_t> key, bool is_one_byte, int value); 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Backs up the key and its length in the backing store. 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The backup is stored with a base 127 encoding of the 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // length (plus a bit saying whether the string is one byte), 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // followed by the bytes of the key. 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t* BackupKey(Vector<const uint8_t> key, bool is_one_byte); 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compare two encoded keys (both pointing into the backing store) 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for having the same base-127 encoded lengths and representation. 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and then having the same 'length' bytes following. 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool Match(void* first, void* second); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Creates a hash from a sequence of bytes. 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t Hash(Vector<const uint8_t> key, bool is_one_byte); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks whether a string containing a JS number is its canonical 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // form. 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsNumberCanonical(Vector<const uint8_t> key); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of buffer. Sufficient for using it to call DoubleToCString in 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // from conversions.h. 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kBufferSize = 100; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnicodeCache* unicode_constants_; 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Backing store used to store strings used as hashmap keys. 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SequenceCollector<unsigned char> backing_store_; 14621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch base::HashMap map_; 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Buffer used for string->number->canonical string conversions. 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char number_buffer_[kBufferSize]; 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 151589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// ---------------------------------------------------------------------------- 152589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// LiteralBuffer - Collector of chars of literals. 153589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 15421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochconst int kMaxAscii = 127; 15521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 156589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochclass LiteralBuffer { 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LiteralBuffer() : is_one_byte_(true), position_(0), backing_store_() { } 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~LiteralBuffer() { backing_store_.Dispose(); } 161589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 16221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch INLINE(void AddChar(char code_unit)) { 16321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (position_ >= backing_store_.length()) ExpandBuffer(); 16421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(is_one_byte_); 16521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(0 <= code_unit && code_unit <= kMaxAscii); 16621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch backing_store_[position_] = static_cast<byte>(code_unit); 16721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch position_ += kOneByteSize; 16821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return; 16921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 17021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 17121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch INLINE(void AddChar(uc32 code_unit)) { 172589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (position_ >= backing_store_.length()) ExpandBuffer(); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_one_byte_) { 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_unit <= unibrow::Latin1::kMaxChar) { 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch backing_store_[position_] = static_cast<byte>(code_unit); 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch position_ += kOneByteSize; 177589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return; 178589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConvertToTwoByte(); 180589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (code_unit <= unibrow::Utf16::kMaxNonSurrogateCharCode) { 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = code_unit; 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position_ += kUC16Size; 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unibrow::Utf16::LeadSurrogate(code_unit); 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position_ += kUC16Size; 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (position_ >= backing_store_.length()) ExpandBuffer(); 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unibrow::Utf16::TrailSurrogate(code_unit); 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position_ += kUC16Size; 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 193589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 194589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_one_byte() const { return is_one_byte_; } 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_contextual_keyword(Vector<const char> keyword) const { 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return is_one_byte() && keyword.length() == position_ && 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (memcmp(keyword.start(), backing_store_.start(), position_) == 0); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 201589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint16_t> two_byte_literal() const { 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!is_one_byte_); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((position_ & 0x1) == 0); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Vector<const uint16_t>( 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const uint16_t*>(backing_store_.start()), 207589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch position_ >> 1); 208589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 209589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint8_t> one_byte_literal() const { 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_one_byte_); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Vector<const uint8_t>( 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const uint8_t*>(backing_store_.start()), 214589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch position_); 215589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length() const { 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return is_one_byte_ ? position_ : (position_ >> 1); 219589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 220589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ReduceLength(int delta) { 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position_ -= delta * (is_one_byte_ ? kOneByteSize : kUC16Size); 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 225589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void Reset() { 226589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch position_ = 0; 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_one_byte_ = true; 228589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 229589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> Internalize(Isolate* isolate) const; 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CopyFrom(const LiteralBuffer* other) { 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (other == nullptr) { 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Reset(); 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_one_byte_ = other->is_one_byte_; 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch position_ = other->position_; 238537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (position_ < backing_store_.length()) { 239537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch std::copy(other->backing_store_.begin(), 240537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch other->backing_store_.begin() + position_, 241537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch backing_store_.begin()); 242537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } else { 243537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch backing_store_.Dispose(); 244537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch backing_store_ = other->backing_store_.Clone(); 245537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 249589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch private: 250589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch static const int kInitialCapacity = 16; 251589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch static const int kGrowthFactory = 4; 252589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch static const int kMinConversionSlack = 256; 253589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch static const int kMaxGrowth = 1 * MB; 254589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch inline int NewCapacity(int min_capacity) { 255589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int capacity = Max(min_capacity, backing_store_.length()); 256589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int new_capacity = Min(capacity * kGrowthFactory, capacity + kMaxGrowth); 257589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return new_capacity; 258589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 259589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 260589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void ExpandBuffer() { 261589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Vector<byte> new_store = Vector<byte>::New(NewCapacity(kInitialCapacity)); 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemCopy(new_store.start(), backing_store_.start(), position_); 263589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch backing_store_.Dispose(); 264589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch backing_store_ = new_store; 265589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 266589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ConvertToTwoByte() { 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_one_byte_); 269589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Vector<byte> new_store; 270589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int new_content_size = position_ * kUC16Size; 271589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (new_content_size >= backing_store_.length()) { 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Ensure room for all currently read code units as UC16 as well 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // as the code unit about to be stored. 274589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch new_store = Vector<byte>::New(NewCapacity(new_content_size)); 275589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 276589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch new_store = backing_store_; 277589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t* src = backing_store_.start(); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint16_t* dst = reinterpret_cast<uint16_t*>(new_store.start()); 280589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch for (int i = position_ - 1; i >= 0; i--) { 281589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch dst[i] = src[i]; 282589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 283589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (new_store.start() != backing_store_.start()) { 284589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch backing_store_.Dispose(); 285589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch backing_store_ = new_store; 286589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 287589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch position_ = new_content_size; 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_one_byte_ = false; 289589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 290589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_one_byte_; 292589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int position_; 293589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Vector<byte> backing_store_; 294589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 295589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch DISALLOW_COPY_AND_ASSIGN(LiteralBuffer); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// ---------------------------------------------------------------------------- 3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// JavaScript Scanner. 301589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 302589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochclass Scanner { 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Scoped helper for literal recording. Automatically drops the literal 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // if aborting the scanning before it's complete. 306589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch class LiteralScope { 307589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch public: 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit LiteralScope(Scanner* self) : scanner_(self), complete_(false) { 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scanner_->StartLiteral(); 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ~LiteralScope() { 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!complete_) scanner_->DropLiteral(); 3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Complete() { 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch complete_ = true; 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 317589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 318589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch private: 319589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Scanner* scanner_; 320589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool complete_; 321589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch }; 322589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Scoped helper for a re-settable bookmark. 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class BookmarkScope { 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit BookmarkScope(Scanner* scanner) : scanner_(scanner) { 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NOT_NULL(scanner_); 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~BookmarkScope() { scanner_->DropBookmark(); } 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool Set() { return scanner_->SetBookmark(); } 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Reset() { scanner_->ResetToBookmark(); } 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool HasBeenSet() { return scanner_->BookmarkHasBeenSet(); } 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool HasBeenReset() { return scanner_->BookmarkHasBeenReset(); } 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Scanner* scanner_; 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DISALLOW_COPY_AND_ASSIGN(BookmarkScope); 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Representation of an interval of source positions. 343589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch struct Location { 344589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Location(int b, int e) : beg_pos(b), end_pos(e) { } 345589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Location() : beg_pos(0), end_pos(0) { } 346589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 347589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool IsValid() const { 348589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return beg_pos >= 0 && end_pos >= beg_pos; 349589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 350589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 351589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch static Location invalid() { return Location(-1, -1); } 352589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 353589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int beg_pos; 354589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int end_pos; 355589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch }; 356589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // -1 is outside of the range of any real source code. 3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kNoOctalLocation = -1; 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit Scanner(UnicodeCache* scanner_contants); 3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Initialize(Utf16CharacterStream* source); 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns the next token and advances input. 3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::Value Next(); 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Returns the token following peek() 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Token::Value PeekAhead(); 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns the current token again. 3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::Value current_token() { return current_.token; } 370589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Returns the location information for the current token 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // (the token last returned by Next()). 372589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Location location() const { return current_.location; } 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3741b268ca467c924004286c97bac133db489cf43d0Ben Murdoch bool has_error() const { return scanner_error_ != MessageTemplate::kNone; } 3751b268ca467c924004286c97bac133db489cf43d0Ben Murdoch MessageTemplate::Template error() const { return scanner_error_; } 3761b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Location error_location() const { return scanner_error_location_; } 3771b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Similar functions for the upcoming token. 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // One token look-ahead (past the token returned by Next()). 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value peek() const { return next_.token; } 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Location peek_location() const { return next_.location; } 384589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 385589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool literal_contains_escapes() const { 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LiteralContainsEscapes(current_); 387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool next_literal_contains_escapes() const { 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LiteralContainsEscapes(next_); 390589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_literal_contextual_keyword(Vector<const char> keyword) { 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(current_.literal_chars); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return current_.literal_chars->is_contextual_keyword(keyword); 394592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_next_contextual_keyword(Vector<const char> keyword) { 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(next_.literal_chars); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next_.literal_chars->is_contextual_keyword(keyword); 398589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 399589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const AstRawString* CurrentSymbol(AstValueFactory* ast_value_factory); 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const AstRawString* NextSymbol(AstValueFactory* ast_value_factory); 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const AstRawString* CurrentRawSymbol(AstValueFactory* ast_value_factory); 403589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double DoubleValue(); 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool ContainsDot(); 406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool LiteralMatches(const char* data, int length, bool allow_escapes = true) { 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_literal_one_byte() && 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literal_length() == length && 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (allow_escapes || !literal_contains_escapes())) { 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* token = 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const char*>(literal_one_byte_string().start()); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !strncmp(token, data, length); 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline bool UnescapedLiteralMatches(const char* data, int length) { 417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return LiteralMatches(data, length, false); 418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IsGetOrSet(bool* is_get, bool* is_set) { 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_literal_one_byte() && 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literal_length() == 3 && 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !literal_contains_escapes()) { 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* token = 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const char*>(literal_one_byte_string().start()); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *is_get = strncmp(token, "get", 3) == 0; 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *is_set = !*is_get && strncmp(token, "set", 3) == 0; 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int FindSymbol(DuplicateFinder* finder, int value); 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnicodeCache* unicode_cache() { return unicode_cache_; } 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns the location of the last seen octal literal. 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Location octal_position() const { return octal_pos_; } 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void clear_octal_position() { octal_pos_ = Location::invalid(); } 438537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // Returns the location of the last seen decimal literal with a leading zero. 439537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Location decimal_with_leading_zero_position() const { 440537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch return decimal_with_leading_zero_pos_; 441537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 442537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch void clear_decimal_with_leading_zero_position() { 443537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch decimal_with_leading_zero_pos_ = Location::invalid(); 444537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Returns the value of the last smi that was scanned. 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int smi_value() const { return current_.smi_value_; } 448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Seek forward to the given position. This operation does not 4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // work in general, for instance when there are pushed back 4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // characters, but works for seeking forward until simple delimiter 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // tokens, which is what it is used for. 4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SeekForward(int pos); 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns true if there was a line terminator before the peek'ed token, 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // possibly inside a multi-line comment. 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool HasAnyLineTerminatorBeforeNext() const { 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return has_line_terminator_before_next_ || 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_multiline_comment_before_next_; 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 462537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch bool HasAnyLineTerminatorAfterNext() { 463537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Token::Value ensure_next_next = PeekAhead(); 464537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch USE(ensure_next_next); 465537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch return has_line_terminator_after_next_; 466537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 467537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Scans the input as a regular expression pattern, previous 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // character(s) must be /(=). Returns true if a pattern is scanned. 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool ScanRegExpPattern(bool seen_equal); 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Scans the input as regular expression flags. Returns the flags on success. 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Maybe<RegExp::Flags> ScanRegExpFlags(); 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Scans the input as a template literal 475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Token::Value ScanTemplateStart(); 476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Token::Value ScanTemplateContinuation(); 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const LiteralBuffer* source_url() const { return &source_url_; } 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const LiteralBuffer* source_mapping_url() const { 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return &source_mapping_url_; 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IdentifierIsFutureStrictReserved(const AstRawString* string) const; 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 485342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch bool FoundHtmlComment() const { return found_html_comment_; } 486342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 4871b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#define DECLARE_ACCESSORS(name) \ 4881b268ca467c924004286c97bac133db489cf43d0Ben Murdoch inline bool allow_##name() const { return allow_##name##_; } \ 4891b268ca467c924004286c97bac133db489cf43d0Ben Murdoch inline void set_allow_##name(bool allow) { allow_##name##_ = allow; } 4901b268ca467c924004286c97bac133db489cf43d0Ben Murdoch DECLARE_ACCESSORS(harmony_exponentiation_operator) 4911b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#undef ACCESSOR 4921b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 494589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // The current and look-ahead token. 495589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch struct TokenDesc { 496589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Token::Value token; 497589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Location location; 498589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LiteralBuffer* literal_chars; 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiteralBuffer* raw_literal_chars; 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int smi_value_; 501589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch }; 502589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCharacterLookaheadBufferSize = 1; 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scans octal escape sequence. Also accepts "\0" decimal escape sequence. 506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <bool capture_raw> 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uc32 ScanOctalEscape(uc32 c, int length); 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 509589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Call this after setting source_ to the input. 510589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void Init() { 511589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set c0_ (one character ahead) 512589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch STATIC_ASSERT(kCharacterLookaheadBufferSize == 1); 513589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Advance(); 514589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Initialize current_ to not refer to a literal. 515589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch current_.literal_chars = NULL; 516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current_.raw_literal_chars = NULL; 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next_next_.token = Token::UNINITIALIZED; 518342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch found_html_comment_ = false; 5191b268ca467c924004286c97bac133db489cf43d0Ben Murdoch scanner_error_ = MessageTemplate::kNone; 520589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 521589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Support BookmarkScope functionality. 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool SetBookmark(); 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ResetToBookmark(); 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BookmarkHasBeenSet(); 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BookmarkHasBeenReset(); 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DropBookmark(); 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void CopyTokenDesc(TokenDesc* to, TokenDesc* from); 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5301b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void ReportScannerError(const Location& location, 5311b268ca467c924004286c97bac133db489cf43d0Ben Murdoch MessageTemplate::Template error) { 5321b268ca467c924004286c97bac133db489cf43d0Ben Murdoch if (has_error()) return; 5331b268ca467c924004286c97bac133db489cf43d0Ben Murdoch scanner_error_ = error; 5341b268ca467c924004286c97bac133db489cf43d0Ben Murdoch scanner_error_location_ = location; 5351b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 5361b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 5371b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void ReportScannerError(int pos, MessageTemplate::Template error) { 5381b268ca467c924004286c97bac133db489cf43d0Ben Murdoch if (has_error()) return; 5391b268ca467c924004286c97bac133db489cf43d0Ben Murdoch scanner_error_ = error; 5401b268ca467c924004286c97bac133db489cf43d0Ben Murdoch scanner_error_location_ = Location(pos, pos + 1); 5411b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 5421b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 543589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Literal buffer support 544589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch inline void StartLiteral() { 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer* free_buffer = 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (current_.literal_chars == &literal_buffer0_) 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? &literal_buffer1_ 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : (current_.literal_chars == &literal_buffer1_) ? &literal_buffer2_ 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : &literal_buffer0_; 550589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch free_buffer->Reset(); 551589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch next_.literal_chars = free_buffer; 552589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 553589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void StartRawLiteral() { 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer* free_buffer = 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (current_.raw_literal_chars == &raw_literal_buffer0_) 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? &raw_literal_buffer1_ 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : (current_.raw_literal_chars == &raw_literal_buffer1_) 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? &raw_literal_buffer2_ 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : &raw_literal_buffer0_; 561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch free_buffer->Reset(); 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next_.raw_literal_chars = free_buffer; 563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INLINE(void AddLiteralChar(uc32 c)) { 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(next_.literal_chars); 567589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch next_.literal_chars->AddChar(c); 568589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 569589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 57021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch INLINE(void AddLiteralChar(char c)) { 57121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK_NOT_NULL(next_.literal_chars); 57221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch next_.literal_chars->AddChar(c); 57321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 57421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void AddRawLiteralChar(uc32 c)) { 576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_NOT_NULL(next_.raw_literal_chars); 577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_.raw_literal_chars->AddChar(c); 578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void ReduceRawLiteralLength(int delta)) { 581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_NOT_NULL(next_.raw_literal_chars); 582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_.raw_literal_chars->ReduceLength(delta); 583589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 584589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 585589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Stops scanning of a literal and drop the collected characters, 586589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // e.g., due to an encountered error. 587589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch inline void DropLiteral() { 588589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch next_.literal_chars = NULL; 589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_.raw_literal_chars = NULL; 590589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 591589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 592589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch inline void AddLiteralCharAdvance() { 593589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch AddLiteralChar(c0_); 594589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Advance(); 595589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 596589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 597589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Low-level scanning support. 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <bool capture_raw = false, bool check_surrogate = true> 599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Advance() { 600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (capture_raw) { 601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddRawLiteralChar(c0_); 602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier c0_ = source_->Advance(); 604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (check_surrogate) HandleLeadSurrogate(); 605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void HandleLeadSurrogate() { 608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (unibrow::Utf16::IsLeadSurrogate(c0_)) { 609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uc32 c1 = source_->Advance(); 610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!unibrow::Utf16::IsTrailSurrogate(c1)) { 611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier source_->PushBack(c1); 612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier c0_ = unibrow::Utf16::CombineSurrogatePair(c0_, c1); 614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 618589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void PushBack(uc32 ch) { 619537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (c0_ > static_cast<uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) { 620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier source_->PushBack(unibrow::Utf16::TrailSurrogate(c0_)); 621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier source_->PushBack(unibrow::Utf16::LeadSurrogate(c0_)); 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier source_->PushBack(c0_); 624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 625589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch c0_ = ch; 626589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 627589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 628589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch inline Token::Value Select(Token::Value tok) { 629589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Advance(); 630589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return tok; 631589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 632589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 633589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch inline Token::Value Select(uc32 next, Token::Value then, Token::Value else_) { 634589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Advance(); 635589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (c0_ == next) { 636589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Advance(); 637589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return then; 638589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 639589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return else_; 640589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 641589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 642589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns the literal string, if any, for the current token (the 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // token last returned by Next()). The string is 0-terminated. 645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Literal strings are collected for identifiers, strings, numbers as well 646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // as for template literals. For template literals we also collect the raw 647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // form. 648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // These functions only give the correct result if the literal was scanned 649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // when a LiteralScope object is alive. 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint8_t> literal_one_byte_string() { 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(current_.literal_chars); 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return current_.literal_chars->one_byte_literal(); 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint16_t> literal_two_byte_string() { 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(current_.literal_chars); 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return current_.literal_chars->two_byte_literal(); 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_literal_one_byte() { 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(current_.literal_chars); 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return current_.literal_chars->is_one_byte(); 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int literal_length() const { 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(current_.literal_chars); 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return current_.literal_chars->length(); 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns the literal string for the next token (the token that 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // would be returned if Next() were called). 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint8_t> next_literal_one_byte_string() { 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(next_.literal_chars); 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next_.literal_chars->one_byte_literal(); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint16_t> next_literal_two_byte_string() { 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(next_.literal_chars); 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next_.literal_chars->two_byte_literal(); 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_next_literal_one_byte() { 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(next_.literal_chars); 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next_.literal_chars->is_one_byte(); 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Vector<const uint8_t> raw_literal_one_byte_string() { 681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_NOT_NULL(current_.raw_literal_chars); 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return current_.raw_literal_chars->one_byte_literal(); 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Vector<const uint16_t> raw_literal_two_byte_string() { 685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_NOT_NULL(current_.raw_literal_chars); 686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return current_.raw_literal_chars->two_byte_literal(); 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_raw_literal_one_byte() { 689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_NOT_NULL(current_.raw_literal_chars); 690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return current_.raw_literal_chars->is_one_byte(); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6931b268ca467c924004286c97bac133db489cf43d0Ben Murdoch template <bool capture_raw, bool unicode = false> 694589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uc32 ScanHexNumber(int expected_length); 695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Scan a number of any length but not bigger than max_value. For example, the 696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // number can be 000000001, so it's very long in characters but its value is 697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // small. 698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <bool capture_raw> 6991b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uc32 ScanUnlimitedLengthHexNumber(int max_value, int beg_pos); 700589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Scans a single JavaScript token. 7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Scan(); 70385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 704589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool SkipWhiteSpace(); 705589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Token::Value SkipSingleLineComment(); 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value SkipSourceURLComment(); 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TryToParseSourceURLComment(); 708589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Token::Value SkipMultiLineComment(); 7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Scans a possible HTML comment -- begins with '<!'. 7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::Value ScanHtmlComment(); 711589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 712589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void ScanDecimalDigits(); 713589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Token::Value ScanNumber(bool seen_period); 714589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Token::Value ScanIdentifierOrKeyword(); 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Token::Value ScanIdentifierSuffix(LiteralScope* literal, bool escaped); 716589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 717589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Token::Value ScanString(); 718589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scans an escape-sequence which is part of a string and adds the 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // decoded character to the current literal. Returns true if a pattern 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is scanned. 722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <bool capture_raw, bool in_template_literal> 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ScanEscape(); 724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Decodes a Unicode escape-sequence which is part of an identifier. 726589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // If the escape sequence cannot be decoded the result is kBadChar. 727589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uc32 ScanIdentifierUnicodeEscape(); 728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Helper for the above functions. 729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <bool capture_raw> 730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uc32 ScanUnicodeEscape(); 731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Token::Value ScanTemplateSpan(); 733589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 7343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Return the current source position. 7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int source_pos() { 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<int>(source_->pos()) - kCharacterLookaheadBufferSize; 737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool LiteralContainsEscapes(const TokenDesc& token) { 740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Location location = token.location; 741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int source_length = (location.end_pos - location.beg_pos); 742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (token.token == Token::STRING) { 743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Subtract delimiters. 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch source_length -= 2; 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return token.literal_chars->length() != source_length; 7473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UnicodeCache* unicode_cache_; 7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Buffers collecting literal strings, numbers, etc. 752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer literal_buffer0_; 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiteralBuffer literal_buffer1_; 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiteralBuffer literal_buffer2_; 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Values parsed from magic comments. 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LiteralBuffer source_url_; 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LiteralBuffer source_mapping_url_; 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Buffer to store raw string values 761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer raw_literal_buffer0_; 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer raw_literal_buffer1_; 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer raw_literal_buffer2_; 764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TokenDesc current_; // desc for current token (as returned by Next()) 766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TokenDesc next_; // desc for next token (one token look-ahead) 767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TokenDesc next_next_; // desc for the token after next (after PeakAhead()) 768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Variables for Scanner::BookmarkScope and the *Bookmark implementation. 770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // These variables contain the scanner state when a bookmark is set. 771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We will use bookmark_c0_ as a 'control' variable, where: 773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - bookmark_c0_ >= 0: A bookmark has been set and this contains c0_. 774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - bookmark_c0_ == -1: No bookmark has been set. 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - bookmark_c0_ == -2: The bookmark has been applied (ResetToBookmark). 776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Which state is being bookmarked? The parser state is distributed over 778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // several variables, roughly like this: 779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // ... 1234 + 5678 ..... [character stream] 780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // [current_] [next_] c0_ | [scanner state] 781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // So when the scanner is logically at the beginning of an expression 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // like "1234 + 4567", then: 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - current_ contains "1234" 784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - next_ contains "+" 785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - c0_ contains ' ' (the space between "+" and "5678", 786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - the source_ character stream points to the beginning of "5678". 787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // To be able to restore this state, we will keep copies of current_, next_, 788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and c0_; we'll ask the stream to bookmark itself, and we'll copy the 789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // contents of current_'s and next_'s literal buffers to bookmark_*_literal_. 790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const uc32 kNoBookmark = -1; 791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const uc32 kBookmarkWasApplied = -2; 792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uc32 bookmark_c0_; 793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TokenDesc bookmark_current_; 794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TokenDesc bookmark_next_; 795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer bookmark_current_literal_; 796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer bookmark_current_raw_literal_; 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer bookmark_next_literal_; 798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LiteralBuffer bookmark_next_raw_literal_; 7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Input stream. Must be initialized to an Utf16CharacterStream. 8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Utf16CharacterStream* source_; 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 803537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // Last-seen positions of potentially problematic tokens. 804589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Location octal_pos_; 805537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Location decimal_with_leading_zero_pos_; 806589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // One Unicode character look-ahead; c0_ < 0 at the end of the input. 8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uc32 c0_; 8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 810589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Whether there is a line terminator whitespace character after 811589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // the current token, and before the next. Does not count newlines 812589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // inside multiline comments. 813589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool has_line_terminator_before_next_; 814589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Whether there is a multi-line comment that contains a 815589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // line-terminator after the current token, and before the next. 816589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool has_multiline_comment_before_next_; 817537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch bool has_line_terminator_after_next_; 818342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 819342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Whether this scanner encountered an HTML comment. 820342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch bool found_html_comment_; 8211b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 8221b268ca467c924004286c97bac133db489cf43d0Ben Murdoch bool allow_harmony_exponentiation_operator_; 8231b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 8241b268ca467c924004286c97bac133db489cf43d0Ben Murdoch MessageTemplate::Template scanner_error_; 8251b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Location scanner_error_location_; 826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_PARSING_SCANNER_H_ 832