35 : unicode_cache_(unicode_cache),
37 harmony_scoping_(
false),
38 harmony_modules_(
false),
39 harmony_numeric_literals_(
false),
40 harmony_classes_(
false) { }
57 DCHECK(expected_length <= 4);
59 uc32 digits[4] = { 0, 0, 0, 0 };
61 for (
int i = 0;
i < expected_length;
i++) {
70 for (
int j =
i-1; j >= 0; j--) {
223 if (
static_cast<unsigned>(
c0_) <= 0x7f) {
225 if (token != Token::ILLEGAL) {
304 return Token::WHITESPACE;
314 return Token::WHITESPACE;
330 if (!
name.is_one_byte())
return;
349 if (
c0_ ==
'"' ||
c0_ ==
'\'') {
385 if (ch ==
'*' &&
c0_ ==
'/') {
387 return Token::WHITESPACE;
392 return Token::ILLEGAL;
422 token = Token::WHITESPACE;
428 token = Token::WHITESPACE;
439 token =
Select(Token::LTE);
440 }
else if (
c0_ ==
'<') {
441 token =
Select(
'=', Token::ASSIGN_SHL, Token::SHL);
442 }
else if (
c0_ ==
'!') {
453 token =
Select(Token::GTE);
454 }
else if (
c0_ ==
'>') {
458 token =
Select(Token::ASSIGN_SAR);
459 }
else if (
c0_ ==
'>') {
460 token =
Select(
'=', Token::ASSIGN_SHR, Token::SHR);
474 }
else if (
c0_ ==
'>') {
475 token =
Select(Token::ARROW);
477 token = Token::ASSIGN;
485 token =
Select(
'=', Token::NE_STRICT, Token::NE);
495 token =
Select(Token::INC);
496 }
else if (
c0_ ==
'=') {
497 token =
Select(Token::ASSIGN_ADD);
515 }
else if (
c0_ ==
'=') {
516 token =
Select(Token::ASSIGN_SUB);
529 token =
Select(
'=', Token::ASSIGN_MOD, Token::MOD);
537 if (
c0_ ==
'@' ||
c0_ ==
'#') {
544 }
else if (
c0_ ==
'*') {
546 }
else if (
c0_ ==
'=') {
547 token =
Select(Token::ASSIGN_DIV);
558 }
else if (
c0_ ==
'=') {
559 token =
Select(Token::ASSIGN_BIT_AND);
561 token = Token::BIT_AND;
570 }
else if (
c0_ ==
'=') {
571 token =
Select(Token::ASSIGN_BIT_OR);
573 token = Token::BIT_OR;
579 token =
Select(
'=', Token::ASSIGN_BIT_XOR, Token::BIT_XOR);
588 token = Token::PERIOD;
593 token =
Select(Token::COLON);
597 token =
Select(Token::SEMICOLON);
605 token =
Select(Token::LPAREN);
609 token =
Select(Token::RPAREN);
613 token =
Select(Token::LBRACK);
617 token =
Select(Token::RBRACK);
621 token =
Select(Token::LBRACE);
625 token =
Select(Token::RBRACE);
629 token =
Select(Token::CONDITIONAL);
633 token =
Select(Token::BIT_NOT);
642 token = Token::WHITESPACE;
643 }
else if (
c0_ < 0) {
646 token =
Select(Token::ILLEGAL);
653 }
while (token == Token::WHITESPACE);
667 DCHECK(pos >= current_pos);
668 if (pos != current_pos) {
698 case 'b' : c =
'\b';
break;
699 case 'f' : c =
'\f';
break;
700 case 'n' : c =
'\n';
break;
701 case 'r' : c =
'\r';
break;
702 case 't' : c =
'\t';
break;
705 if (c < 0)
return false;
708 case 'v' : c =
'\v';
break;
711 if (c < 0)
return false;
737 for (;
i < length;
i++) {
739 if (d < 0 || d > 7)
break;
741 if (nx >= 256)
break;
750 if (c !=
'0' ||
i > 0) {
762 while (
c0_ != quote &&
c0_ >= 0
772 if (
c0_ != quote)
return Token::ILLEGAL;
789 enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL;
805 if (
c0_ ==
'x' ||
c0_ ==
'X') {
811 return Token::ILLEGAL;
821 return Token::ILLEGAL;
831 return Token::ILLEGAL;
836 }
else if (
'0' <=
c0_ &&
c0_ <=
'7') {
838 kind = IMPLICIT_OCTAL;
840 if (
c0_ ==
'8' ||
c0_ ==
'9') {
844 if (
c0_ <
'0' ||
'7' <
c0_) {
855 if (kind == DECIMAL) {
865 if (
c0_ ==
'e' ||
c0_ ==
'E') {
867 if (kind != DECIMAL)
return Token::ILLEGAL;
870 if (
c0_ ==
'+' ||
c0_ ==
'-')
874 return Token::ILLEGAL;
884 return Token::ILLEGAL;
888 return Token::NUMBER;
894 if (
c0_ !=
'u')
return -1;
905 #define KEYWORDS(KEYWORD_GROUP, KEYWORD) \
907 KEYWORD("break", Token::BREAK) \
909 KEYWORD("case", Token::CASE) \
910 KEYWORD("catch", Token::CATCH) \
912 harmony_classes ? Token::CLASS : Token::FUTURE_RESERVED_WORD) \
913 KEYWORD("const", Token::CONST) \
914 KEYWORD("continue", Token::CONTINUE) \
916 KEYWORD("debugger", Token::DEBUGGER) \
917 KEYWORD("default", Token::DEFAULT) \
918 KEYWORD("delete", Token::DELETE) \
919 KEYWORD("do", Token::DO) \
921 KEYWORD("else", Token::ELSE) \
922 KEYWORD("enum", Token::FUTURE_RESERVED_WORD) \
924 harmony_modules ? Token::EXPORT : Token::FUTURE_RESERVED_WORD) \
926 harmony_classes ? Token::EXTENDS : Token::FUTURE_RESERVED_WORD) \
928 KEYWORD("false", Token::FALSE_LITERAL) \
929 KEYWORD("finally", Token::FINALLY) \
930 KEYWORD("for", Token::FOR) \
931 KEYWORD("function", Token::FUNCTION) \
933 KEYWORD("if", Token::IF) \
934 KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD) \
936 harmony_modules ? Token::IMPORT : Token::FUTURE_RESERVED_WORD) \
937 KEYWORD("in", Token::IN) \
938 KEYWORD("instanceof", Token::INSTANCEOF) \
939 KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD) \
942 harmony_scoping ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \
944 KEYWORD("new", Token::NEW) \
945 KEYWORD("null", Token::NULL_LITERAL) \
947 KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD) \
948 KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD) \
949 KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD) \
950 KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD) \
952 KEYWORD("return", Token::RETURN) \
954 KEYWORD("static", harmony_classes ? Token::STATIC \
955 : Token::FUTURE_STRICT_RESERVED_WORD) \
957 harmony_classes ? Token::SUPER : Token::FUTURE_RESERVED_WORD) \
958 KEYWORD("switch", Token::SWITCH) \
960 KEYWORD("this", Token::THIS) \
961 KEYWORD("throw", Token::THROW) \
962 KEYWORD("true", Token::TRUE_LITERAL) \
963 KEYWORD("try", Token::TRY) \
964 KEYWORD("typeof", Token::TYPEOF) \
966 KEYWORD("var", Token::VAR) \
967 KEYWORD("void", Token::VOID) \
969 KEYWORD("while", Token::WHILE) \
970 KEYWORD("with", Token::WITH) \
972 KEYWORD("yield", Token::YIELD)
977 bool harmony_scoping,
978 bool harmony_modules,
979 bool harmony_classes) {
980 DCHECK(input_length >= 1);
981 const int kMinLength = 2;
982 const int kMaxLength = 10;
983 if (input_length < kMinLength || input_length > kMaxLength) {
984 return Token::IDENTIFIER;
988 #define KEYWORD_GROUP_CASE(ch) \
991 #define KEYWORD(keyword, token) \
995 const int keyword_length = sizeof(keyword) - 1; \
996 STATIC_ASSERT(keyword_length >= kMinLength); \
997 STATIC_ASSERT(keyword_length <= kMaxLength); \
998 if (input_length == keyword_length && \
999 input[1] == keyword[1] && \
1000 (keyword_length <= 2 || input[2] == keyword[2]) && \
1001 (keyword_length <= 3 || input[3] == keyword[3]) && \
1002 (keyword_length <= 4 || input[4] == keyword[4]) && \
1003 (keyword_length <= 5 || input[5] == keyword[5]) && \
1004 (keyword_length <= 6 || input[6] == keyword[6]) && \
1005 (keyword_length <= 7 || input[7] == keyword[7]) && \
1006 (keyword_length <= 8 || input[8] == keyword[8]) && \
1007 (keyword_length <= 9 || input[9] == keyword[9])) { \
1013 return Token::IDENTIFIER;
1020 return string->is_one_byte() &&
1021 Token::FUTURE_STRICT_RESERVED_WORD ==
1038 return Token::ILLEGAL;
1046 AddLiteralChar(first_char);
1053 AddLiteralChar(next_char);
1071 return Token::IDENTIFIER;
1084 return Token::ILLEGAL;
1088 AddLiteralChar(
c0_);
1094 return Token::IDENTIFIER;
1100 bool in_character_class =
false;
1112 AddLiteralChar(
'=');
1115 while (
c0_ !=
'/' || in_character_class) {
1132 if (
c0_ ==
'[') in_character_class =
true;
1133 if (
c0_ ==
']') in_character_class =
false;
1147 uc32 chars_read[6] = {
'\\',
'u', 0, 0, 0, 0};
1155 chars_read[
i] =
c0_;
1168 for (
int i = 0;
i < 6;
i++) {
1169 AddLiteralChar(chars_read[
i]);
1247 byte* encoding =
BackupKey(key, is_one_byte);
1248 HashMap::Entry* entry =
map_.
Lookup(encoding, hash,
true);
1249 int old_value =
static_cast<int>(
reinterpret_cast<intptr_t
>(entry->value));
1251 reinterpret_cast<void*
>(
static_cast<intptr_t
>(value | old_value));
1268 if (!std::isfinite(double_value)) {
1269 string =
"Infinity";
1277 length),
true, value);
1287 int length = number.
length();
1288 if (number.
length() > 15)
return false;
1289 if (number[pos] ==
'0') {
1292 while (pos < length &&
1293 static_cast<unsigned>(number[pos] -
'0') <= (
'9' -
'0')) pos++;
1295 if (length == pos)
return true;
1296 if (number[pos] !=
'.')
return false;
1298 bool invalid_last_digit =
true;
1299 while (pos < length) {
1300 uint8_t digit = number[pos] -
'0';
1301 if (digit >
'9' -
'0')
return false;
1302 invalid_last_digit = (digit == 0);
1305 return !invalid_last_digit;
1312 int length = key.
length();
1313 uint32_t hash = (length << 1) | (is_one_byte ? 1 : 0) ;
1314 for (
int i = 0;
i < length;
i++) {
1316 hash = (hash + c) * 1025;
1317 hash ^= (hash >> 6);
1329 byte*
s1 =
reinterpret_cast<byte*
>(first);
1330 byte*
s2 =
reinterpret_cast<byte*
>(second);
1331 uint32_t length_one_byte_field = 0;
1335 if (c1 != *
s2)
return false;
1336 length_one_byte_field = (length_one_byte_field << 7) | (c1 & 0x7f);
1339 }
while ((c1 & 0x80) != 0);
1340 int length =
static_cast<int>(length_one_byte_field >> 1);
1341 return memcmp(
s1,
s2, length) == 0;
1347 uint32_t one_byte_length = (bytes.
length() << 1) | (is_one_byte ? 1 : 0);
1351 if (one_byte_length >= (1 << 7)) {
1352 if (one_byte_length >= (1 << 14)) {
1353 if (one_byte_length >= (1 << 21)) {
1354 if (one_byte_length >= (1 << 28)) {
1356 static_cast<uint8_t
>((one_byte_length >> 28) | 0x80));
1359 static_cast<uint8_t
>((one_byte_length >> 21) | 0x80u));
1362 static_cast<uint8_t
>((one_byte_length >> 14) | 0x80u));
const unsigned char * raw_data() const
virtual int length() const OVERRIDE
const AstRawString * GetTwoByteString(Vector< const uint16_t > literal)
const AstRawString * GetOneByteString(Vector< const uint8_t > literal)
Vector< T > AddBlock(int size, T initial_value)
int AddNumber(Vector< const uint8_t > key, int value)
int AddTwoByteSymbol(Vector< const uint16_t > key, int value)
int AddOneByteSymbol(Vector< const uint8_t > key, int value)
static const int kBufferSize
int AddSymbol(Vector< const uint8_t > key, bool is_one_byte, int value)
static bool Match(void *first, void *second)
static uint32_t Hash(Vector< const uint8_t > key, bool is_one_byte)
uint8_t * BackupKey(Vector< const uint8_t > key, bool is_one_byte)
UnicodeCache * unicode_constants_
static bool IsNumberCanonical(Vector< const uint8_t > key)
char number_buffer_[kBufferSize]
SequenceCollector< unsigned char > backing_store_
Vector< const uint8_t > one_byte_literal() const
Vector< const uint16_t > two_byte_literal() const
Handle< String > Internalize(Isolate *isolate) const
void SeekForward(int pos)
Scanner(UnicodeCache *scanner_contants)
int FindNumber(DuplicateFinder *finder, int value)
bool has_multiline_comment_before_next_
Utf16CharacterStream * source_
Vector< const uint16_t > next_literal_two_byte_string()
Vector< const uint8_t > literal_one_byte_string()
bool is_literal_one_byte()
void Initialize(Utf16CharacterStream *source)
UnicodeCache * unicode_cache_
Token::Value ScanString()
int FindSymbol(DuplicateFinder *finder, int value)
bool is_next_literal_one_byte()
Token::Value ScanNumber(bool seen_period)
LiteralBuffer source_mapping_url_
Token::Value SkipMultiLineComment()
bool has_line_terminator_before_next_
bool ScanRegExpPattern(bool seen_equal)
bool harmony_numeric_literals_
bool ScanLiteralUnicodeEscape()
uc32 ScanOctalEscape(uc32 c, int length)
Token::Value ScanIdentifierOrKeyword()
LiteralBuffer source_url_
Token::Value SkipSourceURLComment()
uc32 ScanHexNumber(int expected_length)
bool IdentifierIsFutureStrictReserved(const AstRawString *string) const
void AddLiteralCharAdvance()
Token::Value SkipSingleLineComment()
Vector< const uint8_t > next_literal_one_byte_string()
const AstRawString * NextSymbol(AstValueFactory *ast_value_factory)
Vector< const uint16_t > literal_two_byte_string()
uc32 ScanIdentifierUnicodeEscape()
Token::Value ScanIdentifierSuffix(LiteralScope *literal)
Token::Value ScanHtmlComment()
Token::Value Select(Token::Value tok)
void TryToParseSourceURLComment()
const AstRawString * CurrentSymbol(AstValueFactory *ast_value_factory)
Vector< T > EndSequence()
Entry * Lookup(void *key, uint32_t hash, bool insert, AllocationPolicy allocator=AllocationPolicy())
bool IsIdentifierPart(unibrow::uchar c)
bool IsLineTerminator(unibrow::uchar c)
bool IsWhiteSpace(unibrow::uchar c)
bool IsWhiteSpaceOrLineTerminator(unibrow::uchar c)
bool IsIdentifierStart(unibrow::uchar c)
unsigned SeekForward(unsigned code_unit_count)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
bool IsDecimalDigit(uc32 c)
bool IsCarriageReturn(uc32 c)
static Token::Value KeywordOrIdentifierToken(const uint8_t *input, int input_length, bool harmony_scoping, bool harmony_modules, bool harmony_classes)
bool IsOctalDigit(uc32 c)
static bool IsLittleEndianByteOrderMark(uc32 c)
bool IsBinaryDigit(uc32 c)
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const char * DoubleToCString(double v, Vector< char > buffer)
int StrLength(const char *string)
double StringToDouble(UnicodeCache *unicode_cache, const char *str, int flags, double empty_string_val)
static const byte one_char_tokens[]
Debugger support for the V8 JavaScript engine.
#define KEYWORD_GROUP_CASE(ch)
#define KEYWORD(keyword, token)
#define KEYWORDS(KEYWORD_GROUP, KEYWORD)
LiteralBuffer * literal_chars
#define STATIC_CHAR_VECTOR(x)