| OLD | NEW |
| 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 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 parent_(*variable) { | 316 parent_(*variable) { |
| 317 *variable = this; | 317 *variable = this; |
| 318 } | 318 } |
| 319 | 319 |
| 320 | 320 |
| 321 TemporaryScope::~TemporaryScope() { | 321 TemporaryScope::~TemporaryScope() { |
| 322 *variable_ = parent_; | 322 *variable_ = parent_; |
| 323 } | 323 } |
| 324 | 324 |
| 325 | 325 |
| 326 Handle<String> Parser::LookupSymbol(int symbol_id, | 326 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| 327 Vector<const char> string) { | |
| 328 // Length of symbol cache is the number of identified symbols. | 327 // Length of symbol cache is the number of identified symbols. |
| 329 // If we are larger than that, or negative, it's not a cached symbol. | 328 // If we are larger than that, or negative, it's not a cached symbol. |
| 330 // This might also happen if there is no preparser symbol data, even | 329 // This might also happen if there is no preparser symbol data, even |
| 331 // if there is some preparser data. | 330 // if there is some preparser data. |
| 332 if (static_cast<unsigned>(symbol_id) | 331 if (static_cast<unsigned>(symbol_id) |
| 333 >= static_cast<unsigned>(symbol_cache_.length())) { | 332 >= static_cast<unsigned>(symbol_cache_.length())) { |
| 334 return Factory::LookupSymbol(string); | 333 if (scanner().is_literal_ascii()) { |
| 334 return Factory::LookupAsciiSymbol(scanner().literal_ascii_string()); |
| 335 } else { |
| 336 return Factory::LookupTwoByteSymbol(scanner().literal_uc16_string()); |
| 337 } |
| 335 } | 338 } |
| 336 return LookupCachedSymbol(symbol_id, string); | 339 return LookupCachedSymbol(symbol_id); |
| 337 } | 340 } |
| 338 | 341 |
| 339 | 342 |
| 340 Handle<String> Parser::LookupCachedSymbol(int symbol_id, | 343 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { |
| 341 Vector<const char> string) { | |
| 342 // Make sure the cache is large enough to hold the symbol identifier. | 344 // Make sure the cache is large enough to hold the symbol identifier. |
| 343 if (symbol_cache_.length() <= symbol_id) { | 345 if (symbol_cache_.length() <= symbol_id) { |
| 344 // Increase length to index + 1. | 346 // Increase length to index + 1. |
| 345 symbol_cache_.AddBlock(Handle<String>::null(), | 347 symbol_cache_.AddBlock(Handle<String>::null(), |
| 346 symbol_id + 1 - symbol_cache_.length()); | 348 symbol_id + 1 - symbol_cache_.length()); |
| 347 } | 349 } |
| 348 Handle<String> result = symbol_cache_.at(symbol_id); | 350 Handle<String> result = symbol_cache_.at(symbol_id); |
| 349 if (result.is_null()) { | 351 if (result.is_null()) { |
| 350 result = Factory::LookupSymbol(string); | 352 if (scanner().is_literal_ascii()) { |
| 353 result = Factory::LookupAsciiSymbol(scanner().literal_ascii_string()); |
| 354 } else { |
| 355 result = Factory::LookupTwoByteSymbol(scanner().literal_uc16_string()); |
| 356 } |
| 351 symbol_cache_.at(symbol_id) = result; | 357 symbol_cache_.at(symbol_id) = result; |
| 352 return result; | 358 return result; |
| 353 } | 359 } |
| 354 Counters::total_preparse_symbols_skipped.Increment(); | 360 Counters::total_preparse_symbols_skipped.Increment(); |
| 355 return result; | 361 return result; |
| 356 } | 362 } |
| 357 | 363 |
| 358 | 364 |
| 359 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { | 365 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
| 360 // The current pre-data entry must be a FunctionEntry with the given | 366 // The current pre-data entry must be a FunctionEntry with the given |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 fni_ = new FuncNameInferrer(); | 614 fni_ = new FuncNameInferrer(); |
| 609 | 615 |
| 610 // Initialize parser state. | 616 // Initialize parser state. |
| 611 source->TryFlatten(); | 617 source->TryFlatten(); |
| 612 if (source->IsExternalTwoByteString()) { | 618 if (source->IsExternalTwoByteString()) { |
| 613 // Notice that the stream is destroyed at the end of the branch block. | 619 // Notice that the stream is destroyed at the end of the branch block. |
| 614 // The last line of the blocks can't be moved outside, even though they're | 620 // The last line of the blocks can't be moved outside, even though they're |
| 615 // identical calls. | 621 // identical calls. |
| 616 ExternalTwoByteStringUC16CharacterStream stream( | 622 ExternalTwoByteStringUC16CharacterStream stream( |
| 617 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 623 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
| 618 scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals); | 624 scanner_.Initialize(&stream); |
| 619 return DoParseProgram(source, in_global_context, &zone_scope); | 625 return DoParseProgram(source, in_global_context, &zone_scope); |
| 620 } else { | 626 } else { |
| 621 GenericStringUC16CharacterStream stream(source, 0, source->length()); | 627 GenericStringUC16CharacterStream stream(source, 0, source->length()); |
| 622 scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals); | 628 scanner_.Initialize(&stream); |
| 623 return DoParseProgram(source, in_global_context, &zone_scope); | 629 return DoParseProgram(source, in_global_context, &zone_scope); |
| 624 } | 630 } |
| 625 } | 631 } |
| 626 | 632 |
| 627 | 633 |
| 628 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, | 634 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, |
| 629 bool in_global_context, | 635 bool in_global_context, |
| 630 ZoneScope* zone_scope) { | 636 ZoneScope* zone_scope) { |
| 631 ASSERT(target_stack_ == NULL); | 637 ASSERT(target_stack_ == NULL); |
| 632 if (pre_data_ != NULL) pre_data_->Initialize(); | 638 if (pre_data_ != NULL) pre_data_->Initialize(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 info->end_position()); | 704 info->end_position()); |
| 699 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); | 705 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); |
| 700 return result; | 706 return result; |
| 701 } | 707 } |
| 702 } | 708 } |
| 703 | 709 |
| 704 | 710 |
| 705 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info, | 711 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info, |
| 706 UC16CharacterStream* source, | 712 UC16CharacterStream* source, |
| 707 ZoneScope* zone_scope) { | 713 ZoneScope* zone_scope) { |
| 708 scanner_.Initialize(source, JavaScriptScanner::kAllLiterals); | 714 scanner_.Initialize(source); |
| 709 ASSERT(target_stack_ == NULL); | 715 ASSERT(target_stack_ == NULL); |
| 710 | 716 |
| 711 Handle<String> name(String::cast(info->name())); | 717 Handle<String> name(String::cast(info->name())); |
| 712 fni_ = new FuncNameInferrer(); | 718 fni_ = new FuncNameInferrer(); |
| 713 fni_->PushEnclosingName(name); | 719 fni_->PushEnclosingName(name); |
| 714 | 720 |
| 715 mode_ = PARSE_EAGERLY; | 721 mode_ = PARSE_EAGERLY; |
| 716 | 722 |
| 717 // Place holder for the result. | 723 // Place holder for the result. |
| 718 FunctionLiteral* result = NULL; | 724 FunctionLiteral* result = NULL; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 } | 756 } |
| 751 return result; | 757 return result; |
| 752 } | 758 } |
| 753 | 759 |
| 754 | 760 |
| 755 Handle<String> Parser::GetSymbol(bool* ok) { | 761 Handle<String> Parser::GetSymbol(bool* ok) { |
| 756 int symbol_id = -1; | 762 int symbol_id = -1; |
| 757 if (pre_data() != NULL) { | 763 if (pre_data() != NULL) { |
| 758 symbol_id = pre_data()->GetSymbolIdentifier(); | 764 symbol_id = pre_data()->GetSymbolIdentifier(); |
| 759 } | 765 } |
| 760 return LookupSymbol(symbol_id, scanner().literal()); | 766 return LookupSymbol(symbol_id); |
| 761 } | 767 } |
| 762 | 768 |
| 763 | 769 |
| 764 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 770 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
| 765 Scanner::Location source_location = scanner().location(); | 771 Scanner::Location source_location = scanner().location(); |
| 766 ReportMessageAt(source_location, type, args); | 772 ReportMessageAt(source_location, type, args); |
| 767 } | 773 } |
| 768 | 774 |
| 769 | 775 |
| 770 void Parser::ReportMessageAt(Scanner::Location source_location, | 776 void Parser::ReportMessageAt(Scanner::Location source_location, |
| (...skipping 1937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2708 | 2714 |
| 2709 case Token::IDENTIFIER: { | 2715 case Token::IDENTIFIER: { |
| 2710 Handle<String> name = ParseIdentifier(CHECK_OK); | 2716 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2711 if (fni_ != NULL) fni_->PushVariableName(name); | 2717 if (fni_ != NULL) fni_->PushVariableName(name); |
| 2712 result = top_scope_->NewUnresolved(name, inside_with()); | 2718 result = top_scope_->NewUnresolved(name, inside_with()); |
| 2713 break; | 2719 break; |
| 2714 } | 2720 } |
| 2715 | 2721 |
| 2716 case Token::NUMBER: { | 2722 case Token::NUMBER: { |
| 2717 Consume(Token::NUMBER); | 2723 Consume(Token::NUMBER); |
| 2718 double value = | 2724 ASSERT(scanner().is_literal_ascii()); |
| 2719 StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS); | 2725 double value = StringToDouble(scanner().literal_ascii_string(), |
| 2726 ALLOW_HEX | ALLOW_OCTALS); |
| 2720 result = NewNumberLiteral(value); | 2727 result = NewNumberLiteral(value); |
| 2721 break; | 2728 break; |
| 2722 } | 2729 } |
| 2723 | 2730 |
| 2724 case Token::STRING: { | 2731 case Token::STRING: { |
| 2725 Consume(Token::STRING); | 2732 Consume(Token::STRING); |
| 2726 Handle<String> symbol = GetSymbol(CHECK_OK); | 2733 Handle<String> symbol = GetSymbol(CHECK_OK); |
| 2727 result = new Literal(symbol); | 2734 result = new Literal(symbol); |
| 2728 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 2735 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
| 2729 break; | 2736 break; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2981 *depth = depth_acc; | 2988 *depth = depth_acc; |
| 2982 } | 2989 } |
| 2983 | 2990 |
| 2984 | 2991 |
| 2985 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, | 2992 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, |
| 2986 bool* ok) { | 2993 bool* ok) { |
| 2987 // Special handling of getter and setter syntax: | 2994 // Special handling of getter and setter syntax: |
| 2988 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } | 2995 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } |
| 2989 // We have already read the "get" or "set" keyword. | 2996 // We have already read the "get" or "set" keyword. |
| 2990 Token::Value next = Next(); | 2997 Token::Value next = Next(); |
| 2991 // TODO(820): Allow NUMBER and STRING as well (and handle array indices). | 2998 bool is_keyword = Token::IsKeyword(next); |
| 2992 if (next == Token::IDENTIFIER || Token::IsKeyword(next)) { | 2999 if (next == Token::IDENTIFIER || next == Token::NUMBER || |
| 2993 Handle<String> name = GetSymbol(CHECK_OK); | 3000 next == Token::STRING || is_keyword) { |
| 3001 Handle<String> name; |
| 3002 if (is_keyword) { |
| 3003 name = Factory::LookupAsciiSymbol(Token::String(next)); |
| 3004 } else { |
| 3005 name = GetSymbol(CHECK_OK); |
| 3006 } |
| 2994 FunctionLiteral* value = | 3007 FunctionLiteral* value = |
| 2995 ParseFunctionLiteral(name, | 3008 ParseFunctionLiteral(name, |
| 2996 RelocInfo::kNoPosition, | 3009 RelocInfo::kNoPosition, |
| 2997 DECLARATION, | 3010 DECLARATION, |
| 2998 CHECK_OK); | 3011 CHECK_OK); |
| 3012 // Allow any number of parameters for compatiabilty with JSC. |
| 3013 // Specification only allows zero parameters for get and one for set. |
| 2999 ObjectLiteral::Property* property = | 3014 ObjectLiteral::Property* property = |
| 3000 new ObjectLiteral::Property(is_getter, value); | 3015 new ObjectLiteral::Property(is_getter, value); |
| 3001 return property; | 3016 return property; |
| 3002 } else { | 3017 } else { |
| 3003 ReportUnexpectedToken(next); | 3018 ReportUnexpectedToken(next); |
| 3004 *ok = false; | 3019 *ok = false; |
| 3005 return NULL; | 3020 return NULL; |
| 3006 } | 3021 } |
| 3007 } | 3022 } |
| 3008 | 3023 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3059 uint32_t index; | 3074 uint32_t index; |
| 3060 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3075 if (!string.is_null() && string->AsArrayIndex(&index)) { |
| 3061 key = NewNumberLiteral(index); | 3076 key = NewNumberLiteral(index); |
| 3062 break; | 3077 break; |
| 3063 } | 3078 } |
| 3064 key = new Literal(string); | 3079 key = new Literal(string); |
| 3065 break; | 3080 break; |
| 3066 } | 3081 } |
| 3067 case Token::NUMBER: { | 3082 case Token::NUMBER: { |
| 3068 Consume(Token::NUMBER); | 3083 Consume(Token::NUMBER); |
| 3069 double value = | 3084 ASSERT(scanner().is_literal_ascii()); |
| 3070 StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS); | 3085 double value = StringToDouble(scanner().literal_ascii_string(), |
| 3086 ALLOW_HEX | ALLOW_OCTALS); |
| 3071 key = NewNumberLiteral(value); | 3087 key = NewNumberLiteral(value); |
| 3072 break; | 3088 break; |
| 3073 } | 3089 } |
| 3074 default: | 3090 default: |
| 3075 if (Token::IsKeyword(next)) { | 3091 if (Token::IsKeyword(next)) { |
| 3076 Consume(next); | 3092 Consume(next); |
| 3077 Handle<String> string = GetSymbol(CHECK_OK); | 3093 Handle<String> string = GetSymbol(CHECK_OK); |
| 3078 key = new Literal(string); | 3094 key = new Literal(string); |
| 3079 } else { | 3095 } else { |
| 3080 // Unexpected token. | 3096 // Unexpected token. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3130 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 3146 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 3131 if (!scanner().ScanRegExpPattern(seen_equal)) { | 3147 if (!scanner().ScanRegExpPattern(seen_equal)) { |
| 3132 Next(); | 3148 Next(); |
| 3133 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 3149 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 3134 *ok = false; | 3150 *ok = false; |
| 3135 return NULL; | 3151 return NULL; |
| 3136 } | 3152 } |
| 3137 | 3153 |
| 3138 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3154 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
| 3139 | 3155 |
| 3140 Handle<String> js_pattern = | 3156 Handle<String> js_pattern = NextLiteralString(TENURED); |
| 3141 Factory::NewStringFromUtf8(scanner().next_literal(), TENURED); | |
| 3142 scanner().ScanRegExpFlags(); | 3157 scanner().ScanRegExpFlags(); |
| 3143 Handle<String> js_flags = | 3158 Handle<String> js_flags = NextLiteralString(TENURED); |
| 3144 Factory::NewStringFromUtf8(scanner().next_literal(), TENURED); | |
| 3145 Next(); | 3159 Next(); |
| 3146 | 3160 |
| 3147 return new RegExpLiteral(js_pattern, js_flags, literal_index); | 3161 return new RegExpLiteral(js_pattern, js_flags, literal_index); |
| 3148 } | 3162 } |
| 3149 | 3163 |
| 3150 | 3164 |
| 3151 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3165 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 3152 // Arguments :: | 3166 // Arguments :: |
| 3153 // '(' (AssignmentExpression)*[','] ')' | 3167 // '(' (AssignmentExpression)*[','] ')' |
| 3154 | 3168 |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3416 | 3430 |
| 3417 // This function reads an identifier and determines whether or not it | 3431 // This function reads an identifier and determines whether or not it |
| 3418 // is 'get' or 'set'. The reason for not using ParseIdentifier and | 3432 // is 'get' or 'set'. The reason for not using ParseIdentifier and |
| 3419 // checking on the output is that this involves heap allocation which | 3433 // checking on the output is that this involves heap allocation which |
| 3420 // we can't do during preparsing. | 3434 // we can't do during preparsing. |
| 3421 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, | 3435 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, |
| 3422 bool* is_set, | 3436 bool* is_set, |
| 3423 bool* ok) { | 3437 bool* ok) { |
| 3424 Expect(Token::IDENTIFIER, ok); | 3438 Expect(Token::IDENTIFIER, ok); |
| 3425 if (!*ok) return Handle<String>(); | 3439 if (!*ok) return Handle<String>(); |
| 3426 if (scanner().literal_length() == 3) { | 3440 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { |
| 3427 const char* token = scanner().literal_string(); | 3441 const char* token = scanner().literal_ascii_string().start(); |
| 3428 *is_get = strcmp(token, "get") == 0; | 3442 *is_get = strncmp(token, "get", 3) == 0; |
| 3429 *is_set = !*is_get && strcmp(token, "set") == 0; | 3443 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
| 3430 } | 3444 } |
| 3431 return GetSymbol(ok); | 3445 return GetSymbol(ok); |
| 3432 } | 3446 } |
| 3433 | 3447 |
| 3434 | 3448 |
| 3435 // ---------------------------------------------------------------------------- | 3449 // ---------------------------------------------------------------------------- |
| 3436 // Parser support | 3450 // Parser support |
| 3437 | 3451 |
| 3438 | 3452 |
| 3439 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 3453 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3597 } | 3611 } |
| 3598 return result; | 3612 return result; |
| 3599 } | 3613 } |
| 3600 | 3614 |
| 3601 | 3615 |
| 3602 Handle<String> JsonParser::GetString() { | 3616 Handle<String> JsonParser::GetString() { |
| 3603 int literal_length = scanner_.literal_length(); | 3617 int literal_length = scanner_.literal_length(); |
| 3604 if (literal_length == 0) { | 3618 if (literal_length == 0) { |
| 3605 return Factory::empty_string(); | 3619 return Factory::empty_string(); |
| 3606 } | 3620 } |
| 3607 const char* literal_string = scanner_.literal_string(); | 3621 if (scanner_.is_literal_ascii()) { |
| 3608 Vector<const char> literal(literal_string, literal_length); | 3622 return Factory::NewStringFromAscii(scanner_.literal_ascii_string()); |
| 3609 return Factory::NewStringFromUtf8(literal); | 3623 } else { |
| 3624 return Factory::NewStringFromTwoByte(scanner_.literal_uc16_string()); |
| 3625 } |
| 3610 } | 3626 } |
| 3611 | 3627 |
| 3612 | 3628 |
| 3613 // Parse any JSON value. | 3629 // Parse any JSON value. |
| 3614 Handle<Object> JsonParser::ParseJsonValue() { | 3630 Handle<Object> JsonParser::ParseJsonValue() { |
| 3615 Token::Value token = scanner_.Next(); | 3631 Token::Value token = scanner_.Next(); |
| 3616 switch (token) { | 3632 switch (token) { |
| 3617 case Token::STRING: { | 3633 case Token::STRING: { |
| 3618 return GetString(); | 3634 return GetString(); |
| 3619 } | 3635 } |
| 3620 case Token::NUMBER: { | 3636 case Token::NUMBER: { |
| 3621 double value = StringToDouble(scanner_.literal(), | 3637 ASSERT(scanner_.is_literal_ascii()); |
| 3638 double value = StringToDouble(scanner_.literal_ascii_string(), |
| 3622 NO_FLAGS, // Hex, octal or trailing junk. | 3639 NO_FLAGS, // Hex, octal or trailing junk. |
| 3623 OS::nan_value()); | 3640 OS::nan_value()); |
| 3624 return Factory::NewNumber(value); | 3641 return Factory::NewNumber(value); |
| 3625 } | 3642 } |
| 3626 case Token::FALSE_LITERAL: | 3643 case Token::FALSE_LITERAL: |
| 3627 return Factory::false_value(); | 3644 return Factory::false_value(); |
| 3628 case Token::TRUE_LITERAL: | 3645 case Token::TRUE_LITERAL: |
| 3629 return Factory::true_value(); | 3646 return Factory::true_value(); |
| 3630 case Token::NULL_LITERAL: | 3647 case Token::NULL_LITERAL: |
| 3631 return Factory::null_value(); | 3648 return Factory::null_value(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3656 return ReportUnexpectedToken(); | 3673 return ReportUnexpectedToken(); |
| 3657 } | 3674 } |
| 3658 Handle<String> key = GetString(); | 3675 Handle<String> key = GetString(); |
| 3659 if (scanner_.Next() != Token::COLON) { | 3676 if (scanner_.Next() != Token::COLON) { |
| 3660 return ReportUnexpectedToken(); | 3677 return ReportUnexpectedToken(); |
| 3661 } | 3678 } |
| 3662 Handle<Object> value = ParseJsonValue(); | 3679 Handle<Object> value = ParseJsonValue(); |
| 3663 if (value.is_null()) return Handle<Object>::null(); | 3680 if (value.is_null()) return Handle<Object>::null(); |
| 3664 uint32_t index; | 3681 uint32_t index; |
| 3665 if (key->AsArrayIndex(&index)) { | 3682 if (key->AsArrayIndex(&index)) { |
| 3666 SetElement(json_object, index, value); | 3683 CALL_HEAP_FUNCTION_INLINE( |
| 3684 (*json_object)->SetElement(index, *value, true)); |
| 3667 } else { | 3685 } else { |
| 3668 SetProperty(json_object, key, value, NONE); | 3686 CALL_HEAP_FUNCTION_INLINE( |
| 3687 (*json_object)->SetPropertyPostInterceptor(*key, *value, NONE)); |
| 3669 } | 3688 } |
| 3670 } while (scanner_.Next() == Token::COMMA); | 3689 } while (scanner_.Next() == Token::COMMA); |
| 3671 if (scanner_.current_token() != Token::RBRACE) { | 3690 if (scanner_.current_token() != Token::RBRACE) { |
| 3672 return ReportUnexpectedToken(); | 3691 return ReportUnexpectedToken(); |
| 3673 } | 3692 } |
| 3674 } | 3693 } |
| 3675 return json_object; | 3694 return json_object; |
| 3676 } | 3695 } |
| 3677 | 3696 |
| 3678 | 3697 |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4590 data++; | 4609 data++; |
| 4591 } | 4610 } |
| 4592 *source = data; | 4611 *source = data; |
| 4593 return result; | 4612 return result; |
| 4594 } | 4613 } |
| 4595 | 4614 |
| 4596 | 4615 |
| 4597 // Create a Scanner for the preparser to use as input, and preparse the source. | 4616 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 4598 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, | 4617 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, |
| 4599 bool allow_lazy, | 4618 bool allow_lazy, |
| 4600 ParserRecorder* recorder, | 4619 ParserRecorder* recorder) { |
| 4601 int literal_flags) { | |
| 4602 V8JavaScriptScanner scanner; | 4620 V8JavaScriptScanner scanner; |
| 4603 scanner.Initialize(source, literal_flags); | 4621 scanner.Initialize(source); |
| 4604 intptr_t stack_limit = StackGuard::real_climit(); | 4622 intptr_t stack_limit = StackGuard::real_climit(); |
| 4605 if (!preparser::PreParser::PreParseProgram(&scanner, | 4623 if (!preparser::PreParser::PreParseProgram(&scanner, |
| 4606 recorder, | 4624 recorder, |
| 4607 allow_lazy, | 4625 allow_lazy, |
| 4608 stack_limit)) { | 4626 stack_limit)) { |
| 4609 Top::StackOverflow(); | 4627 Top::StackOverflow(); |
| 4610 return NULL; | 4628 return NULL; |
| 4611 } | 4629 } |
| 4612 | 4630 |
| 4613 // Extract the accumulated data from the recorder as a single | 4631 // Extract the accumulated data from the recorder as a single |
| 4614 // contiguous vector that we are responsible for disposing. | 4632 // contiguous vector that we are responsible for disposing. |
| 4615 Vector<unsigned> store = recorder->ExtractData(); | 4633 Vector<unsigned> store = recorder->ExtractData(); |
| 4616 return new ScriptDataImpl(store); | 4634 return new ScriptDataImpl(store); |
| 4617 } | 4635 } |
| 4618 | 4636 |
| 4619 | 4637 |
| 4620 // Preparse, but only collect data that is immediately useful, | 4638 // Preparse, but only collect data that is immediately useful, |
| 4621 // even if the preparser data is only used once. | 4639 // even if the preparser data is only used once. |
| 4622 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, | 4640 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, |
| 4623 v8::Extension* extension) { | 4641 v8::Extension* extension) { |
| 4624 bool allow_lazy = FLAG_lazy && (extension == NULL); | 4642 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 4625 if (!allow_lazy) { | 4643 if (!allow_lazy) { |
| 4626 // Partial preparsing is only about lazily compiled functions. | 4644 // Partial preparsing is only about lazily compiled functions. |
| 4627 // If we don't allow lazy compilation, the log data will be empty. | 4645 // If we don't allow lazy compilation, the log data will be empty. |
| 4628 return NULL; | 4646 return NULL; |
| 4629 } | 4647 } |
| 4630 PartialParserRecorder recorder; | 4648 PartialParserRecorder recorder; |
| 4631 return DoPreParse(source, allow_lazy, &recorder, | 4649 return DoPreParse(source, allow_lazy, &recorder); |
| 4632 JavaScriptScanner::kNoLiterals); | |
| 4633 } | 4650 } |
| 4634 | 4651 |
| 4635 | 4652 |
| 4636 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, | 4653 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, |
| 4637 v8::Extension* extension) { | 4654 v8::Extension* extension) { |
| 4638 Handle<Script> no_script; | 4655 Handle<Script> no_script; |
| 4639 bool allow_lazy = FLAG_lazy && (extension == NULL); | 4656 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 4640 CompleteParserRecorder recorder; | 4657 CompleteParserRecorder recorder; |
| 4641 int kPreParseLiteralsFlags = | 4658 return DoPreParse(source, allow_lazy, &recorder); |
| 4642 JavaScriptScanner::kLiteralString | JavaScriptScanner::kLiteralIdentifier; | |
| 4643 return DoPreParse(source, allow_lazy, &recorder, kPreParseLiteralsFlags); | |
| 4644 } | 4659 } |
| 4645 | 4660 |
| 4646 | 4661 |
| 4647 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 4662 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 4648 bool multiline, | 4663 bool multiline, |
| 4649 RegExpCompileData* result) { | 4664 RegExpCompileData* result) { |
| 4650 ASSERT(result != NULL); | 4665 ASSERT(result != NULL); |
| 4651 RegExpParser parser(input, &result->error, multiline); | 4666 RegExpParser parser(input, &result->error, multiline); |
| 4652 RegExpTree* tree = parser.ParsePattern(); | 4667 RegExpTree* tree = parser.ParsePattern(); |
| 4653 if (parser.failed()) { | 4668 if (parser.failed()) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4693 Handle<String> source = Handle<String>(String::cast(script->source())); | 4708 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 4694 result = parser.ParseProgram(source, info->is_global()); | 4709 result = parser.ParseProgram(source, info->is_global()); |
| 4695 } | 4710 } |
| 4696 } | 4711 } |
| 4697 | 4712 |
| 4698 info->SetFunction(result); | 4713 info->SetFunction(result); |
| 4699 return (result != NULL); | 4714 return (result != NULL); |
| 4700 } | 4715 } |
| 4701 | 4716 |
| 4702 } } // namespace v8::internal | 4717 } } // namespace v8::internal |
| OLD | NEW |