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

Side by Side Diff: src/parser.cc

Issue 6577036: [Isolates] Merge from bleeding_edge to isolates, revisions 6100-6300. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/platform.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 parent_(*variable) { 317 parent_(*variable) {
318 *variable = this; 318 *variable = this;
319 } 319 }
320 320
321 321
322 TemporaryScope::~TemporaryScope() { 322 TemporaryScope::~TemporaryScope() {
323 *variable_ = parent_; 323 *variable_ = parent_;
324 } 324 }
325 325
326 326
327 Handle<String> Parser::LookupSymbol(int symbol_id, 327 Handle<String> Parser::LookupSymbol(int symbol_id) {
328 Vector<const char> string) {
329 // Length of symbol cache is the number of identified symbols. 328 // Length of symbol cache is the number of identified symbols.
330 // If we are larger than that, or negative, it's not a cached symbol. 329 // If we are larger than that, or negative, it's not a cached symbol.
331 // This might also happen if there is no preparser symbol data, even 330 // This might also happen if there is no preparser symbol data, even
332 // if there is some preparser data. 331 // if there is some preparser data.
333 if (static_cast<unsigned>(symbol_id) 332 if (static_cast<unsigned>(symbol_id)
334 >= static_cast<unsigned>(symbol_cache_.length())) { 333 >= static_cast<unsigned>(symbol_cache_.length())) {
335 return isolate()->factory()->LookupSymbol(string); 334 if (scanner().is_literal_ascii()) {
335 return isolate()->factory()->LookupAsciiSymbol(
336 scanner().literal_ascii_string());
337 } else {
338 return isolate()->factory()->LookupTwoByteSymbol(
339 scanner().literal_uc16_string());
340 }
336 } 341 }
337 return LookupCachedSymbol(symbol_id, string); 342 return LookupCachedSymbol(symbol_id);
338 } 343 }
339 344
340 345
341 Handle<String> Parser::LookupCachedSymbol(int symbol_id, 346 Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
342 Vector<const char> string) {
343 // Make sure the cache is large enough to hold the symbol identifier. 347 // Make sure the cache is large enough to hold the symbol identifier.
344 if (symbol_cache_.length() <= symbol_id) { 348 if (symbol_cache_.length() <= symbol_id) {
345 // Increase length to index + 1. 349 // Increase length to index + 1.
346 symbol_cache_.AddBlock(Handle<String>::null(), 350 symbol_cache_.AddBlock(Handle<String>::null(),
347 symbol_id + 1 - symbol_cache_.length()); 351 symbol_id + 1 - symbol_cache_.length());
348 } 352 }
349 Handle<String> result = symbol_cache_.at(symbol_id); 353 Handle<String> result = symbol_cache_.at(symbol_id);
350 if (result.is_null()) { 354 if (result.is_null()) {
351 result = isolate()->factory()->LookupSymbol(string); 355 if (scanner().is_literal_ascii()) {
356 result = isolate()->factory()->LookupAsciiSymbol(
357 scanner().literal_ascii_string());
358 } else {
359 result = isolate()->factory()->LookupTwoByteSymbol(
360 scanner().literal_uc16_string());
361 }
352 symbol_cache_.at(symbol_id) = result; 362 symbol_cache_.at(symbol_id) = result;
353 return result; 363 return result;
354 } 364 }
355 COUNTERS->total_preparse_symbols_skipped()->Increment(); 365 COUNTERS->total_preparse_symbols_skipped()->Increment();
356 return result; 366 return result;
357 } 367 }
358 368
359 369
360 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { 370 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
361 // The current pre-data entry must be a FunctionEntry with the given 371 // The current pre-data entry must be a FunctionEntry with the given
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 fni_ = new FuncNameInferrer(); 620 fni_ = new FuncNameInferrer();
611 621
612 // Initialize parser state. 622 // Initialize parser state.
613 source->TryFlatten(); 623 source->TryFlatten();
614 if (source->IsExternalTwoByteString()) { 624 if (source->IsExternalTwoByteString()) {
615 // Notice that the stream is destroyed at the end of the branch block. 625 // Notice that the stream is destroyed at the end of the branch block.
616 // The last line of the blocks can't be moved outside, even though they're 626 // The last line of the blocks can't be moved outside, even though they're
617 // identical calls. 627 // identical calls.
618 ExternalTwoByteStringUC16CharacterStream stream( 628 ExternalTwoByteStringUC16CharacterStream stream(
619 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 629 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
620 scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals); 630 scanner_.Initialize(&stream);
621 return DoParseProgram(source, in_global_context, &zone_scope); 631 return DoParseProgram(source, in_global_context, &zone_scope);
622 } else { 632 } else {
623 GenericStringUC16CharacterStream stream(source, 0, source->length()); 633 GenericStringUC16CharacterStream stream(source, 0, source->length());
624 scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals); 634 scanner_.Initialize(&stream);
625 return DoParseProgram(source, in_global_context, &zone_scope); 635 return DoParseProgram(source, in_global_context, &zone_scope);
626 } 636 }
627 } 637 }
628 638
629 639
630 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, 640 FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
631 bool in_global_context, 641 bool in_global_context,
632 ZoneScope* zone_scope) { 642 ZoneScope* zone_scope) {
633 ASSERT(target_stack_ == NULL); 643 ASSERT(target_stack_ == NULL);
634 if (pre_data_ != NULL) pre_data_->Initialize(); 644 if (pre_data_ != NULL) pre_data_->Initialize();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 info->end_position()); 710 info->end_position());
701 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); 711 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
702 return result; 712 return result;
703 } 713 }
704 } 714 }
705 715
706 716
707 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info, 717 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info,
708 UC16CharacterStream* source, 718 UC16CharacterStream* source,
709 ZoneScope* zone_scope) { 719 ZoneScope* zone_scope) {
710 scanner_.Initialize(source, JavaScriptScanner::kAllLiterals); 720 scanner_.Initialize(source);
711 ASSERT(target_stack_ == NULL); 721 ASSERT(target_stack_ == NULL);
712 722
713 Handle<String> name(String::cast(info->name())); 723 Handle<String> name(String::cast(info->name()));
714 fni_ = new FuncNameInferrer(); 724 fni_ = new FuncNameInferrer();
715 fni_->PushEnclosingName(name); 725 fni_->PushEnclosingName(name);
716 726
717 mode_ = PARSE_EAGERLY; 727 mode_ = PARSE_EAGERLY;
718 728
719 // Place holder for the result. 729 // Place holder for the result.
720 FunctionLiteral* result = NULL; 730 FunctionLiteral* result = NULL;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 } 762 }
753 return result; 763 return result;
754 } 764 }
755 765
756 766
757 Handle<String> Parser::GetSymbol(bool* ok) { 767 Handle<String> Parser::GetSymbol(bool* ok) {
758 int symbol_id = -1; 768 int symbol_id = -1;
759 if (pre_data() != NULL) { 769 if (pre_data() != NULL) {
760 symbol_id = pre_data()->GetSymbolIdentifier(); 770 symbol_id = pre_data()->GetSymbolIdentifier();
761 } 771 }
762 return LookupSymbol(symbol_id, scanner().literal()); 772 return LookupSymbol(symbol_id);
763 } 773 }
764 774
765 775
766 void Parser::ReportMessage(const char* type, Vector<const char*> args) { 776 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
767 Scanner::Location source_location = scanner().location(); 777 Scanner::Location source_location = scanner().location();
768 ReportMessageAt(source_location, type, args); 778 ReportMessageAt(source_location, type, args);
769 } 779 }
770 780
771 781
772 void Parser::ReportMessageAt(Scanner::Location source_location, 782 void Parser::ReportMessageAt(Scanner::Location source_location,
(...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 2330 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
2321 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 2331 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
2322 x = NewNumberLiteral(value); 2332 x = NewNumberLiteral(value);
2323 continue; 2333 continue;
2324 } 2334 }
2325 default: 2335 default:
2326 break; 2336 break;
2327 } 2337 }
2328 } 2338 }
2329 2339
2330 // Convert constant divisions to multiplications for speed.
2331 if (op == Token::DIV &&
2332 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
2333 double y_val = y->AsLiteral()->handle()->Number();
2334 int64_t y_int = static_cast<int64_t>(y_val);
2335 // There are rounding issues with this optimization, but they don't
2336 // apply if the number to be divided with has a reciprocal that can be
2337 // precisely represented as a floating point number. This is the case
2338 // if the number is an integer power of 2. Negative integer powers of
2339 // 2 work too, but for -2, -1, 1 and 2 we don't do the strength
2340 // reduction because the inlined optimistic idiv has a reasonable
2341 // chance of succeeding by producing a Smi answer with no remainder.
2342 if (static_cast<double>(y_int) == y_val &&
2343 (IsPowerOf2(y_int) || IsPowerOf2(-y_int)) &&
2344 (y_int > 2 || y_int < -2)) {
2345 y = NewNumberLiteral(1 / y_val);
2346 op = Token::MUL;
2347 }
2348 }
2349
2350 // For now we distinguish between comparisons and other binary 2340 // For now we distinguish between comparisons and other binary
2351 // operations. (We could combine the two and get rid of this 2341 // operations. (We could combine the two and get rid of this
2352 // code and AST node eventually.) 2342 // code and AST node eventually.)
2353 if (Token::IsCompareOp(op)) { 2343 if (Token::IsCompareOp(op)) {
2354 // We have a comparison. 2344 // We have a comparison.
2355 Token::Value cmp = op; 2345 Token::Value cmp = op;
2356 switch (op) { 2346 switch (op) {
2357 case Token::NE: cmp = Token::EQ; break; 2347 case Token::NE: cmp = Token::EQ; break;
2358 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 2348 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2359 default: break; 2349 default: break;
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
2721 2711
2722 case Token::IDENTIFIER: { 2712 case Token::IDENTIFIER: {
2723 Handle<String> name = ParseIdentifier(CHECK_OK); 2713 Handle<String> name = ParseIdentifier(CHECK_OK);
2724 if (fni_ != NULL) fni_->PushVariableName(name); 2714 if (fni_ != NULL) fni_->PushVariableName(name);
2725 result = top_scope_->NewUnresolved(name, inside_with()); 2715 result = top_scope_->NewUnresolved(name, inside_with());
2726 break; 2716 break;
2727 } 2717 }
2728 2718
2729 case Token::NUMBER: { 2719 case Token::NUMBER: {
2730 Consume(Token::NUMBER); 2720 Consume(Token::NUMBER);
2731 double value = 2721 ASSERT(scanner().is_literal_ascii());
2732 StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS); 2722 double value = StringToDouble(scanner().literal_ascii_string(),
2723 ALLOW_HEX | ALLOW_OCTALS);
2733 result = NewNumberLiteral(value); 2724 result = NewNumberLiteral(value);
2734 break; 2725 break;
2735 } 2726 }
2736 2727
2737 case Token::STRING: { 2728 case Token::STRING: {
2738 Consume(Token::STRING); 2729 Consume(Token::STRING);
2739 Handle<String> symbol = GetSymbol(CHECK_OK); 2730 Handle<String> symbol = GetSymbol(CHECK_OK);
2740 result = new Literal(symbol); 2731 result = new Literal(symbol);
2741 if (fni_ != NULL) fni_->PushLiteralName(symbol); 2732 if (fni_ != NULL) fni_->PushLiteralName(symbol);
2742 break; 2733 break;
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2994 *depth = depth_acc; 2985 *depth = depth_acc;
2995 } 2986 }
2996 2987
2997 2988
2998 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, 2989 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
2999 bool* ok) { 2990 bool* ok) {
3000 // Special handling of getter and setter syntax: 2991 // Special handling of getter and setter syntax:
3001 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 2992 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
3002 // We have already read the "get" or "set" keyword. 2993 // We have already read the "get" or "set" keyword.
3003 Token::Value next = Next(); 2994 Token::Value next = Next();
3004 // TODO(820): Allow NUMBER and STRING as well (and handle array indices). 2995 bool is_keyword = Token::IsKeyword(next);
3005 if (next == Token::IDENTIFIER || Token::IsKeyword(next)) { 2996 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
3006 Handle<String> name = GetSymbol(CHECK_OK); 2997 next == Token::STRING || is_keyword) {
2998 Handle<String> name;
2999 if (is_keyword) {
3000 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
3001 } else {
3002 name = GetSymbol(CHECK_OK);
3003 }
3007 FunctionLiteral* value = 3004 FunctionLiteral* value =
3008 ParseFunctionLiteral(name, 3005 ParseFunctionLiteral(name,
3009 RelocInfo::kNoPosition, 3006 RelocInfo::kNoPosition,
3010 DECLARATION, 3007 DECLARATION,
3011 CHECK_OK); 3008 CHECK_OK);
3009 // Allow any number of parameters for compatiabilty with JSC.
3010 // Specification only allows zero parameters for get and one for set.
3012 ObjectLiteral::Property* property = 3011 ObjectLiteral::Property* property =
3013 new ObjectLiteral::Property(is_getter, value); 3012 new ObjectLiteral::Property(is_getter, value);
3014 return property; 3013 return property;
3015 } else { 3014 } else {
3016 ReportUnexpectedToken(next); 3015 ReportUnexpectedToken(next);
3017 *ok = false; 3016 *ok = false;
3018 return NULL; 3017 return NULL;
3019 } 3018 }
3020 } 3019 }
3021 3020
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3072 uint32_t index; 3071 uint32_t index;
3073 if (!string.is_null() && string->AsArrayIndex(&index)) { 3072 if (!string.is_null() && string->AsArrayIndex(&index)) {
3074 key = NewNumberLiteral(index); 3073 key = NewNumberLiteral(index);
3075 break; 3074 break;
3076 } 3075 }
3077 key = new Literal(string); 3076 key = new Literal(string);
3078 break; 3077 break;
3079 } 3078 }
3080 case Token::NUMBER: { 3079 case Token::NUMBER: {
3081 Consume(Token::NUMBER); 3080 Consume(Token::NUMBER);
3082 double value = 3081 ASSERT(scanner().is_literal_ascii());
3083 StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS); 3082 double value = StringToDouble(scanner().literal_ascii_string(),
3083 ALLOW_HEX | ALLOW_OCTALS);
3084 key = NewNumberLiteral(value); 3084 key = NewNumberLiteral(value);
3085 break; 3085 break;
3086 } 3086 }
3087 default: 3087 default:
3088 if (Token::IsKeyword(next)) { 3088 if (Token::IsKeyword(next)) {
3089 Consume(next); 3089 Consume(next);
3090 Handle<String> string = GetSymbol(CHECK_OK); 3090 Handle<String> string = GetSymbol(CHECK_OK);
3091 key = new Literal(string); 3091 key = new Literal(string);
3092 } else { 3092 } else {
3093 // Unexpected token. 3093 // Unexpected token.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3143 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { 3143 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
3144 if (!scanner().ScanRegExpPattern(seen_equal)) { 3144 if (!scanner().ScanRegExpPattern(seen_equal)) {
3145 Next(); 3145 Next();
3146 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 3146 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
3147 *ok = false; 3147 *ok = false;
3148 return NULL; 3148 return NULL;
3149 } 3149 }
3150 3150
3151 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 3151 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
3152 3152
3153 Handle<String> js_pattern = 3153 Handle<String> js_pattern = NextLiteralString(TENURED);
3154 isolate_->factory()->NewStringFromUtf8(scanner().next_literal(), TENURED);
3155 scanner().ScanRegExpFlags(); 3154 scanner().ScanRegExpFlags();
3156 Handle<String> js_flags = 3155 Handle<String> js_flags = NextLiteralString(TENURED);
3157 isolate_->factory()->NewStringFromUtf8(scanner().next_literal(), TENURED);
3158 Next(); 3156 Next();
3159 3157
3160 return new RegExpLiteral(js_pattern, js_flags, literal_index); 3158 return new RegExpLiteral(js_pattern, js_flags, literal_index);
3161 } 3159 }
3162 3160
3163 3161
3164 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { 3162 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
3165 // Arguments :: 3163 // Arguments ::
3166 // '(' (AssignmentExpression)*[','] ')' 3164 // '(' (AssignmentExpression)*[','] ')'
3167 3165
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3431 3429
3432 // This function reads an identifier and determines whether or not it 3430 // This function reads an identifier and determines whether or not it
3433 // is 'get' or 'set'. The reason for not using ParseIdentifier and 3431 // is 'get' or 'set'. The reason for not using ParseIdentifier and
3434 // checking on the output is that this involves heap allocation which 3432 // checking on the output is that this involves heap allocation which
3435 // we can't do during preparsing. 3433 // we can't do during preparsing.
3436 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, 3434 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
3437 bool* is_set, 3435 bool* is_set,
3438 bool* ok) { 3436 bool* ok) {
3439 Expect(Token::IDENTIFIER, ok); 3437 Expect(Token::IDENTIFIER, ok);
3440 if (!*ok) return Handle<String>(); 3438 if (!*ok) return Handle<String>();
3441 if (scanner().literal_length() == 3) { 3439 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
3442 const char* token = scanner().literal_string(); 3440 const char* token = scanner().literal_ascii_string().start();
3443 *is_get = strcmp(token, "get") == 0; 3441 *is_get = strncmp(token, "get", 3) == 0;
3444 *is_set = !*is_get && strcmp(token, "set") == 0; 3442 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
3445 } 3443 }
3446 return GetSymbol(ok); 3444 return GetSymbol(ok);
3447 } 3445 }
3448 3446
3449 3447
3450 // ---------------------------------------------------------------------------- 3448 // ----------------------------------------------------------------------------
3451 // Parser support 3449 // Parser support
3452 3450
3453 3451
3454 bool Parser::TargetStackContainsLabel(Handle<String> label) { 3452 bool Parser::TargetStackContainsLabel(Handle<String> label) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3616 } 3614 }
3617 return result; 3615 return result;
3618 } 3616 }
3619 3617
3620 3618
3621 Handle<String> JsonParser::GetString() { 3619 Handle<String> JsonParser::GetString() {
3622 int literal_length = scanner_.literal_length(); 3620 int literal_length = scanner_.literal_length();
3623 if (literal_length == 0) { 3621 if (literal_length == 0) {
3624 return isolate()->factory()->empty_string(); 3622 return isolate()->factory()->empty_string();
3625 } 3623 }
3626 const char* literal_string = scanner_.literal_string(); 3624 if (scanner_.is_literal_ascii()) {
3627 Vector<const char> literal(literal_string, literal_length); 3625 return isolate()->factory()->NewStringFromAscii(
3628 return isolate()->factory()->NewStringFromUtf8(literal); 3626 scanner_.literal_ascii_string());
3627 } else {
3628 return isolate()->factory()->NewStringFromTwoByte(
3629 scanner_.literal_uc16_string());
3630 }
3629 } 3631 }
3630 3632
3631 3633
3632 // Parse any JSON value. 3634 // Parse any JSON value.
3633 Handle<Object> JsonParser::ParseJsonValue() { 3635 Handle<Object> JsonParser::ParseJsonValue() {
3634 Token::Value token = scanner_.Next(); 3636 Token::Value token = scanner_.Next();
3635 switch (token) { 3637 switch (token) {
3636 case Token::STRING: { 3638 case Token::STRING: {
3637 return GetString(); 3639 return GetString();
3638 } 3640 }
3639 case Token::NUMBER: { 3641 case Token::NUMBER: {
3640 double value = StringToDouble(scanner_.literal(), 3642 ASSERT(scanner_.is_literal_ascii());
3643 double value = StringToDouble(scanner_.literal_ascii_string(),
3641 NO_FLAGS, // Hex, octal or trailing junk. 3644 NO_FLAGS, // Hex, octal or trailing junk.
3642 OS::nan_value()); 3645 OS::nan_value());
3643 return isolate()->factory()->NewNumber(value); 3646 return isolate()->factory()->NewNumber(value);
3644 } 3647 }
3645 case Token::FALSE_LITERAL: 3648 case Token::FALSE_LITERAL:
3646 return isolate()->factory()->false_value(); 3649 return isolate()->factory()->false_value();
3647 case Token::TRUE_LITERAL: 3650 case Token::TRUE_LITERAL:
3648 return isolate()->factory()->true_value(); 3651 return isolate()->factory()->true_value();
3649 case Token::NULL_LITERAL: 3652 case Token::NULL_LITERAL:
3650 return isolate()->factory()->null_value(); 3653 return isolate()->factory()->null_value();
(...skipping 25 matching lines...) Expand all
3676 return ReportUnexpectedToken(); 3679 return ReportUnexpectedToken();
3677 } 3680 }
3678 Handle<String> key = GetString(); 3681 Handle<String> key = GetString();
3679 if (scanner_.Next() != Token::COLON) { 3682 if (scanner_.Next() != Token::COLON) {
3680 return ReportUnexpectedToken(); 3683 return ReportUnexpectedToken();
3681 } 3684 }
3682 Handle<Object> value = ParseJsonValue(); 3685 Handle<Object> value = ParseJsonValue();
3683 if (value.is_null()) return Handle<Object>::null(); 3686 if (value.is_null()) return Handle<Object>::null();
3684 uint32_t index; 3687 uint32_t index;
3685 if (key->AsArrayIndex(&index)) { 3688 if (key->AsArrayIndex(&index)) {
3686 SetElement(json_object, index, value); 3689 SetOwnElement(json_object, index, value);
3687 } else { 3690 } else {
3688 SetProperty(json_object, key, value, NONE); 3691 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
3689 } 3692 }
3690 } while (scanner_.Next() == Token::COMMA); 3693 } while (scanner_.Next() == Token::COMMA);
3691 if (scanner_.current_token() != Token::RBRACE) { 3694 if (scanner_.current_token() != Token::RBRACE) {
3692 return ReportUnexpectedToken(); 3695 return ReportUnexpectedToken();
3693 } 3696 }
3694 } 3697 }
3695 return json_object; 3698 return json_object;
3696 } 3699 }
3697 3700
3698 3701
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
4039 break; 4042 break;
4040 case 't': 4043 case 't':
4041 Advance(2); 4044 Advance(2);
4042 builder->AddCharacter('\t'); 4045 builder->AddCharacter('\t');
4043 break; 4046 break;
4044 case 'v': 4047 case 'v':
4045 Advance(2); 4048 Advance(2);
4046 builder->AddCharacter('\v'); 4049 builder->AddCharacter('\v');
4047 break; 4050 break;
4048 case 'c': { 4051 case 'c': {
4049 Advance(2); 4052 Advance();
4050 uc32 control = ParseControlLetterEscape(); 4053 uc32 controlLetter = Next();
4051 builder->AddCharacter(control); 4054 // Special case if it is an ASCII letter.
4055 // Convert lower case letters to uppercase.
4056 uc32 letter = controlLetter & ~('a' ^ 'A');
4057 if (letter < 'A' || 'Z' < letter) {
4058 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4059 // This is outside the specification. We match JSC in
4060 // reading the backslash as a literal character instead
4061 // of as starting an escape.
4062 builder->AddCharacter('\\');
4063 } else {
4064 Advance(2);
4065 builder->AddCharacter(controlLetter & 0x1f);
4066 }
4052 break; 4067 break;
4053 } 4068 }
4054 case 'x': { 4069 case 'x': {
4055 Advance(2); 4070 Advance(2);
4056 uc32 value; 4071 uc32 value;
4057 if (ParseHexEscape(2, &value)) { 4072 if (ParseHexEscape(2, &value)) {
4058 builder->AddCharacter(value); 4073 builder->AddCharacter(value);
4059 } else { 4074 } else {
4060 builder->AddCharacter('x'); 4075 builder->AddCharacter('x');
4061 } 4076 }
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
4292 } else { 4307 } else {
4293 Reset(start); 4308 Reset(start);
4294 return false; 4309 return false;
4295 } 4310 }
4296 *min_out = min; 4311 *min_out = min;
4297 *max_out = max; 4312 *max_out = max;
4298 return true; 4313 return true;
4299 } 4314 }
4300 4315
4301 4316
4302 // Upper and lower case letters differ by one bit.
4303 STATIC_CHECK(('a' ^ 'A') == 0x20);
4304
4305 uc32 RegExpParser::ParseControlLetterEscape() {
4306 if (!has_more())
4307 return 'c';
4308 uc32 letter = current() & ~(0x20); // Collapse upper and lower case letters.
4309 if (letter < 'A' || 'Z' < letter) {
4310 // Non-spec error-correction: "\c" followed by non-control letter is
4311 // interpreted as an IdentityEscape of 'c'.
4312 return 'c';
4313 }
4314 Advance();
4315 return letter & 0x1f; // Remainder modulo 32, per specification.
4316 }
4317
4318
4319 uc32 RegExpParser::ParseOctalLiteral() { 4317 uc32 RegExpParser::ParseOctalLiteral() {
4320 ASSERT('0' <= current() && current() <= '7'); 4318 ASSERT('0' <= current() && current() <= '7');
4321 // For compatibility with some other browsers (not all), we parse 4319 // For compatibility with some other browsers (not all), we parse
4322 // up to three octal digits with a value below 256. 4320 // up to three octal digits with a value below 256.
4323 uc32 value = current() - '0'; 4321 uc32 value = current() - '0';
4324 Advance(); 4322 Advance();
4325 if ('0' <= current() && current() <= '7') { 4323 if ('0' <= current() && current() <= '7') {
4326 value = value * 8 + current() - '0'; 4324 value = value * 8 + current() - '0';
4327 Advance(); 4325 Advance();
4328 if (value < 32 && '0' <= current() && current() <= '7') { 4326 if (value < 32 && '0' <= current() && current() <= '7') {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4374 return '\n'; 4372 return '\n';
4375 case 'r': 4373 case 'r':
4376 Advance(); 4374 Advance();
4377 return '\r'; 4375 return '\r';
4378 case 't': 4376 case 't':
4379 Advance(); 4377 Advance();
4380 return '\t'; 4378 return '\t';
4381 case 'v': 4379 case 'v':
4382 Advance(); 4380 Advance();
4383 return '\v'; 4381 return '\v';
4384 case 'c': 4382 case 'c': {
4385 Advance(); 4383 uc32 controlLetter = Next();
4386 return ParseControlLetterEscape(); 4384 uc32 letter = controlLetter & ~('A' ^ 'a');
4385 // For compatibility with JSC, inside a character class
4386 // we also accept digits and underscore as control characters.
4387 if ((controlLetter >= '0' && controlLetter <= '9') ||
4388 controlLetter == '_' ||
4389 (letter >= 'A' && letter <= 'Z')) {
4390 Advance(2);
4391 // Control letters mapped to ASCII control characters in the range
4392 // 0x00-0x1f.
4393 return controlLetter & 0x1f;
4394 }
4395 // We match JSC in reading the backslash as a literal
4396 // character instead of as starting an escape.
4397 return '\\';
4398 }
4387 case '0': case '1': case '2': case '3': case '4': case '5': 4399 case '0': case '1': case '2': case '3': case '4': case '5':
4388 case '6': case '7': 4400 case '6': case '7':
4389 // For compatibility, we interpret a decimal escape that isn't 4401 // For compatibility, we interpret a decimal escape that isn't
4390 // a back reference (and therefore either \0 or not valid according 4402 // a back reference (and therefore either \0 or not valid according
4391 // to the specification) as a 1..3 digit octal character code. 4403 // to the specification) as a 1..3 digit octal character code.
4392 return ParseOctalLiteral(); 4404 return ParseOctalLiteral();
4393 case 'x': { 4405 case 'x': {
4394 Advance(); 4406 Advance();
4395 uc32 value; 4407 uc32 value;
4396 if (ParseHexEscape(2, &value)) { 4408 if (ParseHexEscape(2, &value)) {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
4587 data++; 4599 data++;
4588 } 4600 }
4589 *source = data; 4601 *source = data;
4590 return result; 4602 return result;
4591 } 4603 }
4592 4604
4593 4605
4594 // Create a Scanner for the preparser to use as input, and preparse the source. 4606 // Create a Scanner for the preparser to use as input, and preparse the source.
4595 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, 4607 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
4596 bool allow_lazy, 4608 bool allow_lazy,
4597 ParserRecorder* recorder, 4609 ParserRecorder* recorder) {
4598 int literal_flags) {
4599 Isolate* isolate = Isolate::Current(); 4610 Isolate* isolate = Isolate::Current();
4600 V8JavaScriptScanner scanner(isolate); 4611 V8JavaScriptScanner scanner(isolate);
4601 scanner.Initialize(source, literal_flags); 4612 scanner.Initialize(source);
4602 intptr_t stack_limit = isolate->stack_guard()->real_climit(); 4613 intptr_t stack_limit = isolate->stack_guard()->real_climit();
4603 if (!preparser::PreParser::PreParseProgram(&scanner, 4614 if (!preparser::PreParser::PreParseProgram(&scanner,
4604 recorder, 4615 recorder,
4605 allow_lazy, 4616 allow_lazy,
4606 stack_limit)) { 4617 stack_limit)) {
4607 isolate->StackOverflow(); 4618 isolate->StackOverflow();
4608 return NULL; 4619 return NULL;
4609 } 4620 }
4610 4621
4611 // Extract the accumulated data from the recorder as a single 4622 // Extract the accumulated data from the recorder as a single
4612 // contiguous vector that we are responsible for disposing. 4623 // contiguous vector that we are responsible for disposing.
4613 Vector<unsigned> store = recorder->ExtractData(); 4624 Vector<unsigned> store = recorder->ExtractData();
4614 return new ScriptDataImpl(store); 4625 return new ScriptDataImpl(store);
4615 } 4626 }
4616 4627
4617 4628
4618 // Preparse, but only collect data that is immediately useful, 4629 // Preparse, but only collect data that is immediately useful,
4619 // even if the preparser data is only used once. 4630 // even if the preparser data is only used once.
4620 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, 4631 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source,
4621 v8::Extension* extension) { 4632 v8::Extension* extension) {
4622 bool allow_lazy = FLAG_lazy && (extension == NULL); 4633 bool allow_lazy = FLAG_lazy && (extension == NULL);
4623 if (!allow_lazy) { 4634 if (!allow_lazy) {
4624 // Partial preparsing is only about lazily compiled functions. 4635 // Partial preparsing is only about lazily compiled functions.
4625 // If we don't allow lazy compilation, the log data will be empty. 4636 // If we don't allow lazy compilation, the log data will be empty.
4626 return NULL; 4637 return NULL;
4627 } 4638 }
4628 PartialParserRecorder recorder; 4639 PartialParserRecorder recorder;
4629 return DoPreParse(source, allow_lazy, &recorder, 4640 return DoPreParse(source, allow_lazy, &recorder);
4630 JavaScriptScanner::kNoLiterals);
4631 } 4641 }
4632 4642
4633 4643
4634 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, 4644 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source,
4635 v8::Extension* extension) { 4645 v8::Extension* extension) {
4636 Handle<Script> no_script; 4646 Handle<Script> no_script;
4637 bool allow_lazy = FLAG_lazy && (extension == NULL); 4647 bool allow_lazy = FLAG_lazy && (extension == NULL);
4638 CompleteParserRecorder recorder; 4648 CompleteParserRecorder recorder;
4639 int kPreParseLiteralsFlags = 4649 return DoPreParse(source, allow_lazy, &recorder);
4640 JavaScriptScanner::kLiteralString | JavaScriptScanner::kLiteralIdentifier;
4641 return DoPreParse(source, allow_lazy, &recorder, kPreParseLiteralsFlags);
4642 } 4650 }
4643 4651
4644 4652
4645 bool RegExpParser::ParseRegExp(FlatStringReader* input, 4653 bool RegExpParser::ParseRegExp(FlatStringReader* input,
4646 bool multiline, 4654 bool multiline,
4647 RegExpCompileData* result) { 4655 RegExpCompileData* result) {
4648 ASSERT(result != NULL); 4656 ASSERT(result != NULL);
4649 RegExpParser parser(input, &result->error, multiline); 4657 RegExpParser parser(input, &result->error, multiline);
4650 RegExpTree* tree = parser.ParsePattern(); 4658 RegExpTree* tree = parser.ParsePattern();
4651 if (parser.failed()) { 4659 if (parser.failed()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4692 Handle<String> source = Handle<String>(String::cast(script->source())); 4700 Handle<String> source = Handle<String>(String::cast(script->source()));
4693 result = parser.ParseProgram(source, info->is_global()); 4701 result = parser.ParseProgram(source, info->is_global());
4694 } 4702 }
4695 } 4703 }
4696 4704
4697 info->SetFunction(result); 4705 info->SetFunction(result);
4698 return (result != NULL); 4706 return (result != NULL);
4699 } 4707 }
4700 4708
4701 } } // namespace v8::internal 4709 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/platform.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698