| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 136 |
| 137 | 137 |
| 138 void RegExpBuilder::AddQuantifierToAtom( | 138 void RegExpBuilder::AddQuantifierToAtom( |
| 139 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) { | 139 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) { |
| 140 if (pending_empty_) { | 140 if (pending_empty_) { |
| 141 pending_empty_ = false; | 141 pending_empty_ = false; |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 RegExpTree* atom; | 144 RegExpTree* atom; |
| 145 if (characters_ != NULL) { | 145 if (characters_ != NULL) { |
| 146 ASSERT(last_added_ == ADD_CHAR); | 146 DCHECK(last_added_ == ADD_CHAR); |
| 147 // Last atom was character. | 147 // Last atom was character. |
| 148 Vector<const uc16> char_vector = characters_->ToConstVector(); | 148 Vector<const uc16> char_vector = characters_->ToConstVector(); |
| 149 int num_chars = char_vector.length(); | 149 int num_chars = char_vector.length(); |
| 150 if (num_chars > 1) { | 150 if (num_chars > 1) { |
| 151 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); | 151 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); |
| 152 text_.Add(new(zone()) RegExpAtom(prefix), zone()); | 152 text_.Add(new(zone()) RegExpAtom(prefix), zone()); |
| 153 char_vector = char_vector.SubVector(num_chars - 1, num_chars); | 153 char_vector = char_vector.SubVector(num_chars - 1, num_chars); |
| 154 } | 154 } |
| 155 characters_ = NULL; | 155 characters_ = NULL; |
| 156 atom = new(zone()) RegExpAtom(char_vector); | 156 atom = new(zone()) RegExpAtom(char_vector); |
| 157 FlushText(); | 157 FlushText(); |
| 158 } else if (text_.length() > 0) { | 158 } else if (text_.length() > 0) { |
| 159 ASSERT(last_added_ == ADD_ATOM); | 159 DCHECK(last_added_ == ADD_ATOM); |
| 160 atom = text_.RemoveLast(); | 160 atom = text_.RemoveLast(); |
| 161 FlushText(); | 161 FlushText(); |
| 162 } else if (terms_.length() > 0) { | 162 } else if (terms_.length() > 0) { |
| 163 ASSERT(last_added_ == ADD_ATOM); | 163 DCHECK(last_added_ == ADD_ATOM); |
| 164 atom = terms_.RemoveLast(); | 164 atom = terms_.RemoveLast(); |
| 165 if (atom->max_match() == 0) { | 165 if (atom->max_match() == 0) { |
| 166 // Guaranteed to only match an empty string. | 166 // Guaranteed to only match an empty string. |
| 167 LAST(ADD_TERM); | 167 LAST(ADD_TERM); |
| 168 if (min == 0) { | 168 if (min == 0) { |
| 169 return; | 169 return; |
| 170 } | 170 } |
| 171 terms_.Add(atom, zone()); | 171 terms_.Add(atom, zone()); |
| 172 return; | 172 return; |
| 173 } | 173 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 | 250 |
| 251 int ParseData::FunctionsSize() { | 251 int ParseData::FunctionsSize() { |
| 252 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); | 252 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); |
| 253 } | 253 } |
| 254 | 254 |
| 255 | 255 |
| 256 void Parser::SetCachedData() { | 256 void Parser::SetCachedData() { |
| 257 if (compile_options() == ScriptCompiler::kNoCompileOptions) { | 257 if (compile_options() == ScriptCompiler::kNoCompileOptions) { |
| 258 cached_parse_data_ = NULL; | 258 cached_parse_data_ = NULL; |
| 259 } else { | 259 } else { |
| 260 ASSERT(info_->cached_data() != NULL); | 260 DCHECK(info_->cached_data() != NULL); |
| 261 if (compile_options() == ScriptCompiler::kConsumeParserCache) { | 261 if (compile_options() == ScriptCompiler::kConsumeParserCache) { |
| 262 cached_parse_data_ = new ParseData(*info_->cached_data()); | 262 cached_parse_data_ = new ParseData(*info_->cached_data()); |
| 263 } | 263 } |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 | 266 |
| 267 | 267 |
| 268 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { | 268 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
| 269 ASSERT(ast_value_factory_); | 269 DCHECK(ast_value_factory_); |
| 270 Scope* result = | 270 Scope* result = |
| 271 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); | 271 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); |
| 272 result->Initialize(); | 272 result->Initialize(); |
| 273 return result; | 273 return result; |
| 274 } | 274 } |
| 275 | 275 |
| 276 | 276 |
| 277 // ---------------------------------------------------------------------------- | 277 // ---------------------------------------------------------------------------- |
| 278 // Target is a support class to facilitate manipulation of the | 278 // Target is a support class to facilitate manipulation of the |
| 279 // Parser's target_stack_ (the stack of potential 'break' and | 279 // Parser's target_stack_ (the stack of potential 'break' and |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 // ---------------------------------------------------------------------------- | 341 // ---------------------------------------------------------------------------- |
| 342 // Implementation of Parser | 342 // Implementation of Parser |
| 343 | 343 |
| 344 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { | 344 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { |
| 345 return identifier == parser_->ast_value_factory_->eval_string() || | 345 return identifier == parser_->ast_value_factory_->eval_string() || |
| 346 identifier == parser_->ast_value_factory_->arguments_string(); | 346 identifier == parser_->ast_value_factory_->arguments_string(); |
| 347 } | 347 } |
| 348 | 348 |
| 349 | 349 |
| 350 bool ParserTraits::IsThisProperty(Expression* expression) { | 350 bool ParserTraits::IsThisProperty(Expression* expression) { |
| 351 ASSERT(expression != NULL); | 351 DCHECK(expression != NULL); |
| 352 Property* property = expression->AsProperty(); | 352 Property* property = expression->AsProperty(); |
| 353 return property != NULL && | 353 return property != NULL && |
| 354 property->obj()->AsVariableProxy() != NULL && | 354 property->obj()->AsVariableProxy() != NULL && |
| 355 property->obj()->AsVariableProxy()->is_this(); | 355 property->obj()->AsVariableProxy()->is_this(); |
| 356 } | 356 } |
| 357 | 357 |
| 358 | 358 |
| 359 bool ParserTraits::IsIdentifier(Expression* expression) { | 359 bool ParserTraits::IsIdentifier(Expression* expression) { |
| 360 VariableProxy* operand = expression->AsVariableProxy(); | 360 VariableProxy* operand = expression->AsVariableProxy(); |
| 361 return operand != NULL && !operand->is_this(); | 361 return operand != NULL && !operand->is_this(); |
| 362 } | 362 } |
| 363 | 363 |
| 364 | 364 |
| 365 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, | 365 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, |
| 366 Expression* expression) { | 366 Expression* expression) { |
| 367 if (expression->IsPropertyName()) { | 367 if (expression->IsPropertyName()) { |
| 368 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); | 368 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); |
| 369 } else { | 369 } else { |
| 370 fni->PushLiteralName( | 370 fni->PushLiteralName( |
| 371 parser_->ast_value_factory_->anonymous_function_string()); | 371 parser_->ast_value_factory_->anonymous_function_string()); |
| 372 } | 372 } |
| 373 } | 373 } |
| 374 | 374 |
| 375 | 375 |
| 376 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 376 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
| 377 Expression* right) { | 377 Expression* right) { |
| 378 ASSERT(left != NULL); | 378 DCHECK(left != NULL); |
| 379 if (left->AsProperty() != NULL && | 379 if (left->AsProperty() != NULL && |
| 380 right->AsFunctionLiteral() != NULL) { | 380 right->AsFunctionLiteral() != NULL) { |
| 381 right->AsFunctionLiteral()->set_pretenure(); | 381 right->AsFunctionLiteral()->set_pretenure(); |
| 382 } | 382 } |
| 383 } | 383 } |
| 384 | 384 |
| 385 | 385 |
| 386 void ParserTraits::CheckPossibleEvalCall(Expression* expression, | 386 void ParserTraits::CheckPossibleEvalCall(Expression* expression, |
| 387 Scope* scope) { | 387 Scope* scope) { |
| 388 VariableProxy* callee = expression->AsVariableProxy(); | 388 VariableProxy* callee = expression->AsVariableProxy(); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 break; | 457 break; |
| 458 } | 458 } |
| 459 } | 459 } |
| 460 return false; | 460 return false; |
| 461 } | 461 } |
| 462 | 462 |
| 463 | 463 |
| 464 Expression* ParserTraits::BuildUnaryExpression( | 464 Expression* ParserTraits::BuildUnaryExpression( |
| 465 Expression* expression, Token::Value op, int pos, | 465 Expression* expression, Token::Value op, int pos, |
| 466 AstNodeFactory<AstConstructionVisitor>* factory) { | 466 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 467 ASSERT(expression != NULL); | 467 DCHECK(expression != NULL); |
| 468 if (expression->IsLiteral()) { | 468 if (expression->IsLiteral()) { |
| 469 const AstValue* literal = expression->AsLiteral()->raw_value(); | 469 const AstValue* literal = expression->AsLiteral()->raw_value(); |
| 470 if (op == Token::NOT) { | 470 if (op == Token::NOT) { |
| 471 // Convert the literal to a boolean condition and negate it. | 471 // Convert the literal to a boolean condition and negate it. |
| 472 bool condition = literal->BooleanValue(); | 472 bool condition = literal->BooleanValue(); |
| 473 return factory->NewBooleanLiteral(!condition, pos); | 473 return factory->NewBooleanLiteral(!condition, pos); |
| 474 } else if (literal->IsNumber()) { | 474 } else if (literal->IsNumber()) { |
| 475 // Compute some expressions involving only number literals. | 475 // Compute some expressions involving only number literals. |
| 476 double value = literal->AsNumber(); | 476 double value = literal->AsNumber(); |
| 477 switch (op) { | 477 switch (op) { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 parser_->pending_error_message_ = message; | 597 parser_->pending_error_message_ = message; |
| 598 parser_->pending_error_char_arg_ = NULL; | 598 parser_->pending_error_char_arg_ = NULL; |
| 599 parser_->pending_error_arg_ = arg; | 599 parser_->pending_error_arg_ = arg; |
| 600 parser_->pending_error_is_reference_error_ = is_reference_error; | 600 parser_->pending_error_is_reference_error_ = is_reference_error; |
| 601 } | 601 } |
| 602 | 602 |
| 603 | 603 |
| 604 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) { | 604 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) { |
| 605 const AstRawString* result = | 605 const AstRawString* result = |
| 606 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory_); | 606 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory_); |
| 607 ASSERT(result != NULL); | 607 DCHECK(result != NULL); |
| 608 return result; | 608 return result; |
| 609 } | 609 } |
| 610 | 610 |
| 611 | 611 |
| 612 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) { | 612 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) { |
| 613 return parser_->scanner()->NextSymbol(parser_->ast_value_factory_); | 613 return parser_->scanner()->NextSymbol(parser_->ast_value_factory_); |
| 614 } | 614 } |
| 615 | 615 |
| 616 | 616 |
| 617 Expression* ParserTraits::ThisExpression( | 617 Expression* ParserTraits::ThisExpression( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 629 return factory->NewNullLiteral(pos); | 629 return factory->NewNullLiteral(pos); |
| 630 case Token::TRUE_LITERAL: | 630 case Token::TRUE_LITERAL: |
| 631 return factory->NewBooleanLiteral(true, pos); | 631 return factory->NewBooleanLiteral(true, pos); |
| 632 case Token::FALSE_LITERAL: | 632 case Token::FALSE_LITERAL: |
| 633 return factory->NewBooleanLiteral(false, pos); | 633 return factory->NewBooleanLiteral(false, pos); |
| 634 case Token::NUMBER: { | 634 case Token::NUMBER: { |
| 635 double value = scanner->DoubleValue(); | 635 double value = scanner->DoubleValue(); |
| 636 return factory->NewNumberLiteral(value, pos); | 636 return factory->NewNumberLiteral(value, pos); |
| 637 } | 637 } |
| 638 default: | 638 default: |
| 639 ASSERT(false); | 639 DCHECK(false); |
| 640 } | 640 } |
| 641 return NULL; | 641 return NULL; |
| 642 } | 642 } |
| 643 | 643 |
| 644 | 644 |
| 645 Expression* ParserTraits::ExpressionFromIdentifier( | 645 Expression* ParserTraits::ExpressionFromIdentifier( |
| 646 const AstRawString* name, int pos, Scope* scope, | 646 const AstRawString* name, int pos, Scope* scope, |
| 647 AstNodeFactory<AstConstructionVisitor>* factory) { | 647 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 648 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 648 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
| 649 // The name may refer to a module instance object, so its type is unknown. | 649 // The name may refer to a module instance object, so its type is unknown. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 reusable_preparser_(NULL), | 702 reusable_preparser_(NULL), |
| 703 original_scope_(NULL), | 703 original_scope_(NULL), |
| 704 target_stack_(NULL), | 704 target_stack_(NULL), |
| 705 cached_parse_data_(NULL), | 705 cached_parse_data_(NULL), |
| 706 ast_value_factory_(NULL), | 706 ast_value_factory_(NULL), |
| 707 info_(info), | 707 info_(info), |
| 708 has_pending_error_(false), | 708 has_pending_error_(false), |
| 709 pending_error_message_(NULL), | 709 pending_error_message_(NULL), |
| 710 pending_error_arg_(NULL), | 710 pending_error_arg_(NULL), |
| 711 pending_error_char_arg_(NULL) { | 711 pending_error_char_arg_(NULL) { |
| 712 ASSERT(!script_.is_null()); | 712 DCHECK(!script_.is_null()); |
| 713 isolate_->set_ast_node_id(0); | 713 isolate_->set_ast_node_id(0); |
| 714 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 714 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 715 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 715 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 716 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 716 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 717 set_allow_lazy(false); // Must be explicitly enabled. | 717 set_allow_lazy(false); // Must be explicitly enabled. |
| 718 set_allow_generators(FLAG_harmony_generators); | 718 set_allow_generators(FLAG_harmony_generators); |
| 719 set_allow_for_of(FLAG_harmony_iteration); | 719 set_allow_for_of(FLAG_harmony_iteration); |
| 720 set_allow_arrow_functions(FLAG_harmony_arrow_functions); | 720 set_allow_arrow_functions(FLAG_harmony_arrow_functions); |
| 721 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 721 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 722 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 722 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 779 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 780 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 780 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); |
| 781 log_ = NULL; | 781 log_ = NULL; |
| 782 } | 782 } |
| 783 return result; | 783 return result; |
| 784 } | 784 } |
| 785 | 785 |
| 786 | 786 |
| 787 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 787 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 788 Handle<String> source) { | 788 Handle<String> source) { |
| 789 ASSERT(scope_ == NULL); | 789 DCHECK(scope_ == NULL); |
| 790 ASSERT(target_stack_ == NULL); | 790 DCHECK(target_stack_ == NULL); |
| 791 | 791 |
| 792 FunctionLiteral* result = NULL; | 792 FunctionLiteral* result = NULL; |
| 793 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 793 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 794 info->SetGlobalScope(scope); | 794 info->SetGlobalScope(scope); |
| 795 if (!info->context().is_null() && !info->context()->IsNativeContext()) { | 795 if (!info->context().is_null() && !info->context()->IsNativeContext()) { |
| 796 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 796 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 797 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 797 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
| 798 // means the Parser cannot operate independent of the V8 heap. Tell the | 798 // means the Parser cannot operate independent of the V8 heap. Tell the |
| 799 // string table to internalize strings and values right after they're | 799 // string table to internalize strings and values right after they're |
| 800 // created. | 800 // created. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 result->set_dont_optimize_reason( | 865 result->set_dont_optimize_reason( |
| 866 factory()->visitor()->dont_optimize_reason()); | 866 factory()->visitor()->dont_optimize_reason()); |
| 867 } else if (stack_overflow()) { | 867 } else if (stack_overflow()) { |
| 868 isolate()->StackOverflow(); | 868 isolate()->StackOverflow(); |
| 869 } else { | 869 } else { |
| 870 ThrowPendingError(); | 870 ThrowPendingError(); |
| 871 } | 871 } |
| 872 } | 872 } |
| 873 | 873 |
| 874 // Make sure the target stack is empty. | 874 // Make sure the target stack is empty. |
| 875 ASSERT(target_stack_ == NULL); | 875 DCHECK(target_stack_ == NULL); |
| 876 | 876 |
| 877 return result; | 877 return result; |
| 878 } | 878 } |
| 879 | 879 |
| 880 | 880 |
| 881 FunctionLiteral* Parser::ParseLazy() { | 881 FunctionLiteral* Parser::ParseLazy() { |
| 882 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); | 882 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); |
| 883 Handle<String> source(String::cast(script_->source())); | 883 Handle<String> source(String::cast(script_->source())); |
| 884 isolate()->counters()->total_parse_size()->Increment(source->length()); | 884 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 885 base::ElapsedTimer timer; | 885 base::ElapsedTimer timer; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 909 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); | 909 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); |
| 910 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); | 910 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); |
| 911 } | 911 } |
| 912 return result; | 912 return result; |
| 913 } | 913 } |
| 914 | 914 |
| 915 | 915 |
| 916 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 916 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
| 917 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 917 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 918 scanner_.Initialize(source); | 918 scanner_.Initialize(source); |
| 919 ASSERT(scope_ == NULL); | 919 DCHECK(scope_ == NULL); |
| 920 ASSERT(target_stack_ == NULL); | 920 DCHECK(target_stack_ == NULL); |
| 921 | 921 |
| 922 Handle<String> name(String::cast(shared_info->name())); | 922 Handle<String> name(String::cast(shared_info->name())); |
| 923 ASSERT(ast_value_factory_); | 923 DCHECK(ast_value_factory_); |
| 924 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); | 924 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
| 925 const AstRawString* raw_name = ast_value_factory_->GetString(name); | 925 const AstRawString* raw_name = ast_value_factory_->GetString(name); |
| 926 fni_->PushEnclosingName(raw_name); | 926 fni_->PushEnclosingName(raw_name); |
| 927 | 927 |
| 928 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 928 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 929 | 929 |
| 930 // Place holder for the result. | 930 // Place holder for the result. |
| 931 FunctionLiteral* result = NULL; | 931 FunctionLiteral* result = NULL; |
| 932 | 932 |
| 933 { | 933 { |
| 934 // Parse the function literal. | 934 // Parse the function literal. |
| 935 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 935 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 936 info()->SetGlobalScope(scope); | 936 info()->SetGlobalScope(scope); |
| 937 if (!info()->closure().is_null()) { | 937 if (!info()->closure().is_null()) { |
| 938 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 938 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
| 939 zone()); | 939 zone()); |
| 940 } | 940 } |
| 941 original_scope_ = scope; | 941 original_scope_ = scope; |
| 942 FunctionState function_state(&function_state_, &scope_, scope, zone(), | 942 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 943 ast_value_factory_); | 943 ast_value_factory_); |
| 944 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); | 944 DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); |
| 945 ASSERT(info()->strict_mode() == shared_info->strict_mode()); | 945 DCHECK(info()->strict_mode() == shared_info->strict_mode()); |
| 946 scope->SetStrictMode(shared_info->strict_mode()); | 946 scope->SetStrictMode(shared_info->strict_mode()); |
| 947 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 947 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 948 ? (shared_info->is_anonymous() | 948 ? (shared_info->is_anonymous() |
| 949 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 949 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 950 : FunctionLiteral::NAMED_EXPRESSION) | 950 : FunctionLiteral::NAMED_EXPRESSION) |
| 951 : FunctionLiteral::DECLARATION; | 951 : FunctionLiteral::DECLARATION; |
| 952 bool is_generator = shared_info->is_generator(); | 952 bool is_generator = shared_info->is_generator(); |
| 953 bool ok = true; | 953 bool ok = true; |
| 954 | 954 |
| 955 if (shared_info->is_arrow()) { | 955 if (shared_info->is_arrow()) { |
| 956 ASSERT(!is_generator); | 956 DCHECK(!is_generator); |
| 957 Expression* expression = ParseExpression(false, &ok); | 957 Expression* expression = ParseExpression(false, &ok); |
| 958 ASSERT(expression->IsFunctionLiteral()); | 958 DCHECK(expression->IsFunctionLiteral()); |
| 959 result = expression->AsFunctionLiteral(); | 959 result = expression->AsFunctionLiteral(); |
| 960 } else { | 960 } else { |
| 961 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), | 961 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), |
| 962 false, // Strict mode name already checked. | 962 false, // Strict mode name already checked. |
| 963 is_generator, RelocInfo::kNoPosition, | 963 is_generator, RelocInfo::kNoPosition, |
| 964 function_type, | 964 function_type, |
| 965 FunctionLiteral::NORMAL_ARITY, &ok); | 965 FunctionLiteral::NORMAL_ARITY, &ok); |
| 966 } | 966 } |
| 967 // Make sure the results agree. | 967 // Make sure the results agree. |
| 968 ASSERT(ok == (result != NULL)); | 968 DCHECK(ok == (result != NULL)); |
| 969 } | 969 } |
| 970 | 970 |
| 971 // Make sure the target stack is empty. | 971 // Make sure the target stack is empty. |
| 972 ASSERT(target_stack_ == NULL); | 972 DCHECK(target_stack_ == NULL); |
| 973 | 973 |
| 974 ast_value_factory_->Internalize(isolate()); | 974 ast_value_factory_->Internalize(isolate()); |
| 975 if (result == NULL) { | 975 if (result == NULL) { |
| 976 if (stack_overflow()) { | 976 if (stack_overflow()) { |
| 977 isolate()->StackOverflow(); | 977 isolate()->StackOverflow(); |
| 978 } else { | 978 } else { |
| 979 ThrowPendingError(); | 979 ThrowPendingError(); |
| 980 } | 980 } |
| 981 } else { | 981 } else { |
| 982 Handle<String> inferred_name(shared_info->inferred_name()); | 982 Handle<String> inferred_name(shared_info->inferred_name()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 993 bool* ok) { | 993 bool* ok) { |
| 994 // SourceElements :: | 994 // SourceElements :: |
| 995 // (ModuleElement)* <end_token> | 995 // (ModuleElement)* <end_token> |
| 996 | 996 |
| 997 // Allocate a target stack to use for this set of source | 997 // Allocate a target stack to use for this set of source |
| 998 // elements. This way, all scripts and functions get their own | 998 // elements. This way, all scripts and functions get their own |
| 999 // target stack thus avoiding illegal breaks and continues across | 999 // target stack thus avoiding illegal breaks and continues across |
| 1000 // functions. | 1000 // functions. |
| 1001 TargetScope scope(&this->target_stack_); | 1001 TargetScope scope(&this->target_stack_); |
| 1002 | 1002 |
| 1003 ASSERT(processor != NULL); | 1003 DCHECK(processor != NULL); |
| 1004 bool directive_prologue = true; // Parsing directive prologue. | 1004 bool directive_prologue = true; // Parsing directive prologue. |
| 1005 | 1005 |
| 1006 while (peek() != end_token) { | 1006 while (peek() != end_token) { |
| 1007 if (directive_prologue && peek() != Token::STRING) { | 1007 if (directive_prologue && peek() != Token::STRING) { |
| 1008 directive_prologue = false; | 1008 directive_prologue = false; |
| 1009 } | 1009 } |
| 1010 | 1010 |
| 1011 Scanner::Location token_loc = scanner()->peek_location(); | 1011 Scanner::Location token_loc = scanner()->peek_location(); |
| 1012 Statement* stat; | 1012 Statement* stat; |
| 1013 if (is_global && !is_eval) { | 1013 if (is_global && !is_eval) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1034 literal->raw_value()->AsString() == | 1034 literal->raw_value()->AsString() == |
| 1035 ast_value_factory_->use_strict_string() && | 1035 ast_value_factory_->use_strict_string() && |
| 1036 token_loc.end_pos - token_loc.beg_pos == | 1036 token_loc.end_pos - token_loc.beg_pos == |
| 1037 ast_value_factory_->use_strict_string()->length() + 2) { | 1037 ast_value_factory_->use_strict_string()->length() + 2) { |
| 1038 // TODO(mstarzinger): Global strict eval calls, need their own scope | 1038 // TODO(mstarzinger): Global strict eval calls, need their own scope |
| 1039 // as specified in ES5 10.4.2(3). The correct fix would be to always | 1039 // as specified in ES5 10.4.2(3). The correct fix would be to always |
| 1040 // add this scope in DoParseProgram(), but that requires adaptations | 1040 // add this scope in DoParseProgram(), but that requires adaptations |
| 1041 // all over the code base, so we go with a quick-fix for now. | 1041 // all over the code base, so we go with a quick-fix for now. |
| 1042 // In the same manner, we have to patch the parsing mode. | 1042 // In the same manner, we have to patch the parsing mode. |
| 1043 if (is_eval && !scope_->is_eval_scope()) { | 1043 if (is_eval && !scope_->is_eval_scope()) { |
| 1044 ASSERT(scope_->is_global_scope()); | 1044 DCHECK(scope_->is_global_scope()); |
| 1045 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 1045 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
| 1046 scope->set_start_position(scope_->start_position()); | 1046 scope->set_start_position(scope_->start_position()); |
| 1047 scope->set_end_position(scope_->end_position()); | 1047 scope->set_end_position(scope_->end_position()); |
| 1048 scope_ = scope; | 1048 scope_ = scope; |
| 1049 mode_ = PARSE_EAGERLY; | 1049 mode_ = PARSE_EAGERLY; |
| 1050 } | 1050 } |
| 1051 scope_->SetStrictMode(STRICT); | 1051 scope_->SetStrictMode(STRICT); |
| 1052 // "use strict" is the only directive for now. | 1052 // "use strict" is the only directive for now. |
| 1053 directive_prologue = false; | 1053 directive_prologue = false; |
| 1054 } else if (literal->raw_value()->AsString() == | 1054 } else if (literal->raw_value()->AsString() == |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 switch (peek()) { | 1091 switch (peek()) { |
| 1092 case Token::FUNCTION: | 1092 case Token::FUNCTION: |
| 1093 return ParseFunctionDeclaration(NULL, ok); | 1093 return ParseFunctionDeclaration(NULL, ok); |
| 1094 case Token::IMPORT: | 1094 case Token::IMPORT: |
| 1095 return ParseImportDeclaration(ok); | 1095 return ParseImportDeclaration(ok); |
| 1096 case Token::EXPORT: | 1096 case Token::EXPORT: |
| 1097 return ParseExportDeclaration(ok); | 1097 return ParseExportDeclaration(ok); |
| 1098 case Token::CONST: | 1098 case Token::CONST: |
| 1099 return ParseVariableStatement(kModuleElement, NULL, ok); | 1099 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 1100 case Token::LET: | 1100 case Token::LET: |
| 1101 ASSERT(allow_harmony_scoping()); | 1101 DCHECK(allow_harmony_scoping()); |
| 1102 if (strict_mode() == STRICT) { | 1102 if (strict_mode() == STRICT) { |
| 1103 return ParseVariableStatement(kModuleElement, NULL, ok); | 1103 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 1104 } | 1104 } |
| 1105 // Fall through. | 1105 // Fall through. |
| 1106 default: { | 1106 default: { |
| 1107 Statement* stmt = ParseStatement(labels, CHECK_OK); | 1107 Statement* stmt = ParseStatement(labels, CHECK_OK); |
| 1108 // Handle 'module' as a context-sensitive keyword. | 1108 // Handle 'module' as a context-sensitive keyword. |
| 1109 if (FLAG_harmony_modules && | 1109 if (FLAG_harmony_modules && |
| 1110 peek() == Token::IDENTIFIER && | 1110 peek() == Token::IDENTIFIER && |
| 1111 !scanner()->HasAnyLineTerminatorBeforeNext() && | 1111 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1227 for (Interface::Iterator it = interface->iterator(); | 1227 for (Interface::Iterator it = interface->iterator(); |
| 1228 !it.done(); it.Advance()) { | 1228 !it.done(); it.Advance()) { |
| 1229 if (scope->LookupLocal(it.name()) == NULL) { | 1229 if (scope->LookupLocal(it.name()) == NULL) { |
| 1230 ParserTraits::ReportMessage("module_export_undefined", it.name()); | 1230 ParserTraits::ReportMessage("module_export_undefined", it.name()); |
| 1231 *ok = false; | 1231 *ok = false; |
| 1232 return NULL; | 1232 return NULL; |
| 1233 } | 1233 } |
| 1234 } | 1234 } |
| 1235 | 1235 |
| 1236 interface->MakeModule(ok); | 1236 interface->MakeModule(ok); |
| 1237 ASSERT(*ok); | 1237 DCHECK(*ok); |
| 1238 interface->Freeze(ok); | 1238 interface->Freeze(ok); |
| 1239 ASSERT(*ok); | 1239 DCHECK(*ok); |
| 1240 return factory()->NewModuleLiteral(body, interface, pos); | 1240 return factory()->NewModuleLiteral(body, interface, pos); |
| 1241 } | 1241 } |
| 1242 | 1242 |
| 1243 | 1243 |
| 1244 Module* Parser::ParseModulePath(bool* ok) { | 1244 Module* Parser::ParseModulePath(bool* ok) { |
| 1245 // ModulePath: | 1245 // ModulePath: |
| 1246 // Identifier | 1246 // Identifier |
| 1247 // ModulePath '.' Identifier | 1247 // ModulePath '.' Identifier |
| 1248 | 1248 |
| 1249 int pos = peek_position(); | 1249 int pos = peek_position(); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 #endif | 1310 #endif |
| 1311 | 1311 |
| 1312 // Create an empty literal as long as the feature isn't finished. | 1312 // Create an empty literal as long as the feature isn't finished. |
| 1313 USE(symbol); | 1313 USE(symbol); |
| 1314 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1314 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| 1315 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 1315 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 1316 body->set_scope(scope); | 1316 body->set_scope(scope); |
| 1317 Interface* interface = scope->interface(); | 1317 Interface* interface = scope->interface(); |
| 1318 Module* result = factory()->NewModuleLiteral(body, interface, pos); | 1318 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
| 1319 interface->Freeze(ok); | 1319 interface->Freeze(ok); |
| 1320 ASSERT(*ok); | 1320 DCHECK(*ok); |
| 1321 interface->Unify(scope->interface(), zone(), ok); | 1321 interface->Unify(scope->interface(), zone(), ok); |
| 1322 ASSERT(*ok); | 1322 DCHECK(*ok); |
| 1323 return result; | 1323 return result; |
| 1324 } | 1324 } |
| 1325 | 1325 |
| 1326 | 1326 |
| 1327 Module* Parser::ParseModuleSpecifier(bool* ok) { | 1327 Module* Parser::ParseModuleSpecifier(bool* ok) { |
| 1328 // ModuleSpecifier: | 1328 // ModuleSpecifier: |
| 1329 // String | 1329 // String |
| 1330 // ModulePath | 1330 // ModulePath |
| 1331 | 1331 |
| 1332 if (peek() == Token::STRING) { | 1332 if (peek() == Token::STRING) { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 return NULL; | 1468 return NULL; |
| 1469 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1469 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1470 USE(proxy); | 1470 USE(proxy); |
| 1471 // TODO(rossberg): Rethink whether we actually need to store export | 1471 // TODO(rossberg): Rethink whether we actually need to store export |
| 1472 // declarations (for compilation?). | 1472 // declarations (for compilation?). |
| 1473 // ExportDeclaration* declaration = | 1473 // ExportDeclaration* declaration = |
| 1474 // factory()->NewExportDeclaration(proxy, scope_, position); | 1474 // factory()->NewExportDeclaration(proxy, scope_, position); |
| 1475 // scope_->AddDeclaration(declaration); | 1475 // scope_->AddDeclaration(declaration); |
| 1476 } | 1476 } |
| 1477 | 1477 |
| 1478 ASSERT(result != NULL); | 1478 DCHECK(result != NULL); |
| 1479 return result; | 1479 return result; |
| 1480 } | 1480 } |
| 1481 | 1481 |
| 1482 | 1482 |
| 1483 Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels, | 1483 Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels, |
| 1484 bool* ok) { | 1484 bool* ok) { |
| 1485 // (Ecma 262 5th Edition, clause 14): | 1485 // (Ecma 262 5th Edition, clause 14): |
| 1486 // SourceElement: | 1486 // SourceElement: |
| 1487 // Statement | 1487 // Statement |
| 1488 // FunctionDeclaration | 1488 // FunctionDeclaration |
| 1489 // | 1489 // |
| 1490 // In harmony mode we allow additionally the following productions | 1490 // In harmony mode we allow additionally the following productions |
| 1491 // BlockElement (aka SourceElement): | 1491 // BlockElement (aka SourceElement): |
| 1492 // LetDeclaration | 1492 // LetDeclaration |
| 1493 // ConstDeclaration | 1493 // ConstDeclaration |
| 1494 // GeneratorDeclaration | 1494 // GeneratorDeclaration |
| 1495 | 1495 |
| 1496 switch (peek()) { | 1496 switch (peek()) { |
| 1497 case Token::FUNCTION: | 1497 case Token::FUNCTION: |
| 1498 return ParseFunctionDeclaration(NULL, ok); | 1498 return ParseFunctionDeclaration(NULL, ok); |
| 1499 case Token::CONST: | 1499 case Token::CONST: |
| 1500 return ParseVariableStatement(kModuleElement, NULL, ok); | 1500 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 1501 case Token::LET: | 1501 case Token::LET: |
| 1502 ASSERT(allow_harmony_scoping()); | 1502 DCHECK(allow_harmony_scoping()); |
| 1503 if (strict_mode() == STRICT) { | 1503 if (strict_mode() == STRICT) { |
| 1504 return ParseVariableStatement(kModuleElement, NULL, ok); | 1504 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 1505 } | 1505 } |
| 1506 // Fall through. | 1506 // Fall through. |
| 1507 default: | 1507 default: |
| 1508 return ParseStatement(labels, ok); | 1508 return ParseStatement(labels, ok); |
| 1509 } | 1509 } |
| 1510 } | 1510 } |
| 1511 | 1511 |
| 1512 | 1512 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 } | 1608 } |
| 1609 | 1609 |
| 1610 case Token::DEBUGGER: | 1610 case Token::DEBUGGER: |
| 1611 return ParseDebuggerStatement(ok); | 1611 return ParseDebuggerStatement(ok); |
| 1612 | 1612 |
| 1613 case Token::VAR: | 1613 case Token::VAR: |
| 1614 case Token::CONST: | 1614 case Token::CONST: |
| 1615 return ParseVariableStatement(kStatement, NULL, ok); | 1615 return ParseVariableStatement(kStatement, NULL, ok); |
| 1616 | 1616 |
| 1617 case Token::LET: | 1617 case Token::LET: |
| 1618 ASSERT(allow_harmony_scoping()); | 1618 DCHECK(allow_harmony_scoping()); |
| 1619 if (strict_mode() == STRICT) { | 1619 if (strict_mode() == STRICT) { |
| 1620 return ParseVariableStatement(kStatement, NULL, ok); | 1620 return ParseVariableStatement(kStatement, NULL, ok); |
| 1621 } | 1621 } |
| 1622 // Fall through. | 1622 // Fall through. |
| 1623 default: | 1623 default: |
| 1624 return ParseExpressionOrLabelledStatement(labels, ok); | 1624 return ParseExpressionOrLabelledStatement(labels, ok); |
| 1625 } | 1625 } |
| 1626 } | 1626 } |
| 1627 | 1627 |
| 1628 | 1628 |
| 1629 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1629 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
| 1630 VariableMode mode, Interface* interface) { | 1630 VariableMode mode, Interface* interface) { |
| 1631 // If we are inside a function, a declaration of a var/const variable is a | 1631 // If we are inside a function, a declaration of a var/const variable is a |
| 1632 // truly local variable, and the scope of the variable is always the function | 1632 // truly local variable, and the scope of the variable is always the function |
| 1633 // scope. | 1633 // scope. |
| 1634 // Let/const variables in harmony mode are always added to the immediately | 1634 // Let/const variables in harmony mode are always added to the immediately |
| 1635 // enclosing scope. | 1635 // enclosing scope. |
| 1636 return DeclarationScope(mode)->NewUnresolved( | 1636 return DeclarationScope(mode)->NewUnresolved( |
| 1637 factory(), name, interface, position()); | 1637 factory(), name, interface, position()); |
| 1638 } | 1638 } |
| 1639 | 1639 |
| 1640 | 1640 |
| 1641 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1641 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
| 1642 VariableProxy* proxy = declaration->proxy(); | 1642 VariableProxy* proxy = declaration->proxy(); |
| 1643 ASSERT(proxy->raw_name() != NULL); | 1643 DCHECK(proxy->raw_name() != NULL); |
| 1644 const AstRawString* name = proxy->raw_name(); | 1644 const AstRawString* name = proxy->raw_name(); |
| 1645 VariableMode mode = declaration->mode(); | 1645 VariableMode mode = declaration->mode(); |
| 1646 Scope* declaration_scope = DeclarationScope(mode); | 1646 Scope* declaration_scope = DeclarationScope(mode); |
| 1647 Variable* var = NULL; | 1647 Variable* var = NULL; |
| 1648 | 1648 |
| 1649 // If a suitable scope exists, then we can statically declare this | 1649 // If a suitable scope exists, then we can statically declare this |
| 1650 // variable and also set its mode. In any case, a Declaration node | 1650 // variable and also set its mode. In any case, a Declaration node |
| 1651 // will be added to the scope so that the declaration can be added | 1651 // will be added to the scope so that the declaration can be added |
| 1652 // to the corresponding activation frame at runtime if necessary. | 1652 // to the corresponding activation frame at runtime if necessary. |
| 1653 // For instance declarations inside an eval scope need to be added | 1653 // For instance declarations inside an eval scope need to be added |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1680 // compatibility). There is similar code in runtime.cc in the Declare | 1680 // compatibility). There is similar code in runtime.cc in the Declare |
| 1681 // functions. The function CheckConflictingVarDeclarations checks for | 1681 // functions. The function CheckConflictingVarDeclarations checks for |
| 1682 // var and let bindings from different scopes whereas this is a check for | 1682 // var and let bindings from different scopes whereas this is a check for |
| 1683 // conflicting declarations within the same scope. This check also covers | 1683 // conflicting declarations within the same scope. This check also covers |
| 1684 // the special case | 1684 // the special case |
| 1685 // | 1685 // |
| 1686 // function () { let x; { var x; } } | 1686 // function () { let x; { var x; } } |
| 1687 // | 1687 // |
| 1688 // because the var declaration is hoisted to the function scope where 'x' | 1688 // because the var declaration is hoisted to the function scope where 'x' |
| 1689 // is already bound. | 1689 // is already bound. |
| 1690 ASSERT(IsDeclaredVariableMode(var->mode())); | 1690 DCHECK(IsDeclaredVariableMode(var->mode())); |
| 1691 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 1691 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 1692 // In harmony we treat re-declarations as early errors. See | 1692 // In harmony we treat re-declarations as early errors. See |
| 1693 // ES5 16 for a definition of early errors. | 1693 // ES5 16 for a definition of early errors. |
| 1694 ParserTraits::ReportMessage("var_redeclaration", name); | 1694 ParserTraits::ReportMessage("var_redeclaration", name); |
| 1695 *ok = false; | 1695 *ok = false; |
| 1696 return; | 1696 return; |
| 1697 } | 1697 } |
| 1698 Expression* expression = NewThrowTypeError( | 1698 Expression* expression = NewThrowTypeError( |
| 1699 "var_redeclaration", name, declaration->position()); | 1699 "var_redeclaration", name, declaration->position()); |
| 1700 declaration_scope->SetIllegalRedeclaration(expression); | 1700 declaration_scope->SetIllegalRedeclaration(expression); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1716 // | 1716 // |
| 1717 // WARNING: This will lead to multiple declaration nodes for the | 1717 // WARNING: This will lead to multiple declaration nodes for the |
| 1718 // same variable if it is declared several times. This is not a | 1718 // same variable if it is declared several times. This is not a |
| 1719 // semantic issue as long as we keep the source order, but it may be | 1719 // semantic issue as long as we keep the source order, but it may be |
| 1720 // a performance issue since it may lead to repeated | 1720 // a performance issue since it may lead to repeated |
| 1721 // RuntimeHidden_DeclareLookupSlot calls. | 1721 // RuntimeHidden_DeclareLookupSlot calls. |
| 1722 declaration_scope->AddDeclaration(declaration); | 1722 declaration_scope->AddDeclaration(declaration); |
| 1723 | 1723 |
| 1724 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) { | 1724 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) { |
| 1725 // For global const variables we bind the proxy to a variable. | 1725 // For global const variables we bind the proxy to a variable. |
| 1726 ASSERT(resolve); // should be set by all callers | 1726 DCHECK(resolve); // should be set by all callers |
| 1727 Variable::Kind kind = Variable::NORMAL; | 1727 Variable::Kind kind = Variable::NORMAL; |
| 1728 var = new (zone()) | 1728 var = new (zone()) |
| 1729 Variable(declaration_scope, name, mode, true, kind, | 1729 Variable(declaration_scope, name, mode, true, kind, |
| 1730 kNeedsInitialization, kNotAssigned, proxy->interface()); | 1730 kNeedsInitialization, kNotAssigned, proxy->interface()); |
| 1731 } else if (declaration_scope->is_eval_scope() && | 1731 } else if (declaration_scope->is_eval_scope() && |
| 1732 declaration_scope->strict_mode() == SLOPPY) { | 1732 declaration_scope->strict_mode() == SLOPPY) { |
| 1733 // For variable declarations in a sloppy eval scope the proxy is bound | 1733 // For variable declarations in a sloppy eval scope the proxy is bound |
| 1734 // to a lookup variable to force a dynamic declaration using the | 1734 // to a lookup variable to force a dynamic declaration using the |
| 1735 // DeclareLookupSlot runtime function. | 1735 // DeclareLookupSlot runtime function. |
| 1736 Variable::Kind kind = Variable::NORMAL; | 1736 Variable::Kind kind = Variable::NORMAL; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2019 init_op = Token::INIT_CONST; | 2019 init_op = Token::INIT_CONST; |
| 2020 } else { | 2020 } else { |
| 2021 ReportMessage("strict_const"); | 2021 ReportMessage("strict_const"); |
| 2022 *ok = false; | 2022 *ok = false; |
| 2023 return NULL; | 2023 return NULL; |
| 2024 } | 2024 } |
| 2025 } | 2025 } |
| 2026 is_const = true; | 2026 is_const = true; |
| 2027 needs_init = true; | 2027 needs_init = true; |
| 2028 } else if (peek() == Token::LET && strict_mode() == STRICT) { | 2028 } else if (peek() == Token::LET && strict_mode() == STRICT) { |
| 2029 ASSERT(allow_harmony_scoping()); | 2029 DCHECK(allow_harmony_scoping()); |
| 2030 Consume(Token::LET); | 2030 Consume(Token::LET); |
| 2031 if (var_context == kStatement) { | 2031 if (var_context == kStatement) { |
| 2032 // Let declarations are only allowed in source element positions. | 2032 // Let declarations are only allowed in source element positions. |
| 2033 ReportMessage("unprotected_let"); | 2033 ReportMessage("unprotected_let"); |
| 2034 *ok = false; | 2034 *ok = false; |
| 2035 return NULL; | 2035 return NULL; |
| 2036 } | 2036 } |
| 2037 mode = LET; | 2037 mode = LET; |
| 2038 needs_init = true; | 2038 needs_init = true; |
| 2039 init_op = Token::INIT_LET; | 2039 init_op = Token::INIT_LET; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2221 zone()); | 2221 zone()); |
| 2222 } | 2222 } |
| 2223 } else if (needs_init) { | 2223 } else if (needs_init) { |
| 2224 // Constant initializations always assign to the declared constant which | 2224 // Constant initializations always assign to the declared constant which |
| 2225 // is always at the function scope level. This is only relevant for | 2225 // is always at the function scope level. This is only relevant for |
| 2226 // dynamically looked-up variables and constants (the start context for | 2226 // dynamically looked-up variables and constants (the start context for |
| 2227 // constant lookups is always the function context, while it is the top | 2227 // constant lookups is always the function context, while it is the top |
| 2228 // context for var declared variables). Sigh... | 2228 // context for var declared variables). Sigh... |
| 2229 // For 'let' and 'const' declared variables in harmony mode the | 2229 // For 'let' and 'const' declared variables in harmony mode the |
| 2230 // initialization also always assigns to the declared variable. | 2230 // initialization also always assigns to the declared variable. |
| 2231 ASSERT(proxy != NULL); | 2231 DCHECK(proxy != NULL); |
| 2232 ASSERT(proxy->var() != NULL); | 2232 DCHECK(proxy->var() != NULL); |
| 2233 ASSERT(value != NULL); | 2233 DCHECK(value != NULL); |
| 2234 Assignment* assignment = | 2234 Assignment* assignment = |
| 2235 factory()->NewAssignment(init_op, proxy, value, pos); | 2235 factory()->NewAssignment(init_op, proxy, value, pos); |
| 2236 block->AddStatement( | 2236 block->AddStatement( |
| 2237 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 2237 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
| 2238 zone()); | 2238 zone()); |
| 2239 value = NULL; | 2239 value = NULL; |
| 2240 } | 2240 } |
| 2241 | 2241 |
| 2242 // Add an assignment node to the initialization statement block if we still | 2242 // Add an assignment node to the initialization statement block if we still |
| 2243 // have a pending initialization value. | 2243 // have a pending initialization value. |
| 2244 if (value != NULL) { | 2244 if (value != NULL) { |
| 2245 ASSERT(mode == VAR); | 2245 DCHECK(mode == VAR); |
| 2246 // 'var' initializations are simply assignments (with all the consequences | 2246 // 'var' initializations are simply assignments (with all the consequences |
| 2247 // if they are inside a 'with' statement - they may change a 'with' object | 2247 // if they are inside a 'with' statement - they may change a 'with' object |
| 2248 // property). | 2248 // property). |
| 2249 VariableProxy* proxy = | 2249 VariableProxy* proxy = |
| 2250 initialization_scope->NewUnresolved(factory(), name, interface); | 2250 initialization_scope->NewUnresolved(factory(), name, interface); |
| 2251 Assignment* assignment = | 2251 Assignment* assignment = |
| 2252 factory()->NewAssignment(init_op, proxy, value, pos); | 2252 factory()->NewAssignment(init_op, proxy, value, pos); |
| 2253 block->AddStatement( | 2253 block->AddStatement( |
| 2254 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 2254 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
| 2255 zone()); | 2255 zone()); |
| 2256 } | 2256 } |
| 2257 | 2257 |
| 2258 if (fni_ != NULL) fni_->Leave(); | 2258 if (fni_ != NULL) fni_->Leave(); |
| 2259 } while (peek() == Token::COMMA); | 2259 } while (peek() == Token::COMMA); |
| 2260 | 2260 |
| 2261 // If there was a single non-const declaration, return it in the output | 2261 // If there was a single non-const declaration, return it in the output |
| 2262 // parameter for possible use by for/in. | 2262 // parameter for possible use by for/in. |
| 2263 if (nvars == 1 && !is_const) { | 2263 if (nvars == 1 && !is_const) { |
| 2264 *out = name; | 2264 *out = name; |
| 2265 } | 2265 } |
| 2266 | 2266 |
| 2267 return block; | 2267 return block; |
| 2268 } | 2268 } |
| 2269 | 2269 |
| 2270 | 2270 |
| 2271 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, | 2271 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, |
| 2272 const AstRawString* label) { | 2272 const AstRawString* label) { |
| 2273 ASSERT(label != NULL); | 2273 DCHECK(label != NULL); |
| 2274 if (labels != NULL) { | 2274 if (labels != NULL) { |
| 2275 for (int i = labels->length(); i-- > 0; ) { | 2275 for (int i = labels->length(); i-- > 0; ) { |
| 2276 if (labels->at(i) == label) { | 2276 if (labels->at(i) == label) { |
| 2277 return true; | 2277 return true; |
| 2278 } | 2278 } |
| 2279 } | 2279 } |
| 2280 } | 2280 } |
| 2281 return false; | 2281 return false; |
| 2282 } | 2282 } |
| 2283 | 2283 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2642 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR; | 2642 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR; |
| 2643 catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | 2643 catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
| 2644 BlockState block_state(&scope_, catch_scope); | 2644 BlockState block_state(&scope_, catch_scope); |
| 2645 catch_block = ParseBlock(NULL, CHECK_OK); | 2645 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2646 | 2646 |
| 2647 catch_scope->set_end_position(scanner()->location().end_pos); | 2647 catch_scope->set_end_position(scanner()->location().end_pos); |
| 2648 tok = peek(); | 2648 tok = peek(); |
| 2649 } | 2649 } |
| 2650 | 2650 |
| 2651 Block* finally_block = NULL; | 2651 Block* finally_block = NULL; |
| 2652 ASSERT(tok == Token::FINALLY || catch_block != NULL); | 2652 DCHECK(tok == Token::FINALLY || catch_block != NULL); |
| 2653 if (tok == Token::FINALLY) { | 2653 if (tok == Token::FINALLY) { |
| 2654 Consume(Token::FINALLY); | 2654 Consume(Token::FINALLY); |
| 2655 finally_block = ParseBlock(NULL, CHECK_OK); | 2655 finally_block = ParseBlock(NULL, CHECK_OK); |
| 2656 } | 2656 } |
| 2657 | 2657 |
| 2658 // Simplify the AST nodes by converting: | 2658 // Simplify the AST nodes by converting: |
| 2659 // 'try B0 catch B1 finally B2' | 2659 // 'try B0 catch B1 finally B2' |
| 2660 // to: | 2660 // to: |
| 2661 // 'try { try B0 catch B1 } finally B2' | 2661 // 'try { try B0 catch B1 } finally B2' |
| 2662 | 2662 |
| 2663 if (catch_block != NULL && finally_block != NULL) { | 2663 if (catch_block != NULL && finally_block != NULL) { |
| 2664 // If we have both, create an inner try/catch. | 2664 // If we have both, create an inner try/catch. |
| 2665 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2665 DCHECK(catch_scope != NULL && catch_variable != NULL); |
| 2666 int index = function_state_->NextHandlerIndex(); | 2666 int index = function_state_->NextHandlerIndex(); |
| 2667 TryCatchStatement* statement = factory()->NewTryCatchStatement( | 2667 TryCatchStatement* statement = factory()->NewTryCatchStatement( |
| 2668 index, try_block, catch_scope, catch_variable, catch_block, | 2668 index, try_block, catch_scope, catch_variable, catch_block, |
| 2669 RelocInfo::kNoPosition); | 2669 RelocInfo::kNoPosition); |
| 2670 statement->set_escaping_targets(try_collector.targets()); | 2670 statement->set_escaping_targets(try_collector.targets()); |
| 2671 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 2671 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 2672 try_block->AddStatement(statement, zone()); | 2672 try_block->AddStatement(statement, zone()); |
| 2673 catch_block = NULL; // Clear to indicate it's been handled. | 2673 catch_block = NULL; // Clear to indicate it's been handled. |
| 2674 } | 2674 } |
| 2675 | 2675 |
| 2676 TryStatement* result = NULL; | 2676 TryStatement* result = NULL; |
| 2677 if (catch_block != NULL) { | 2677 if (catch_block != NULL) { |
| 2678 ASSERT(finally_block == NULL); | 2678 DCHECK(finally_block == NULL); |
| 2679 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2679 DCHECK(catch_scope != NULL && catch_variable != NULL); |
| 2680 int index = function_state_->NextHandlerIndex(); | 2680 int index = function_state_->NextHandlerIndex(); |
| 2681 result = factory()->NewTryCatchStatement( | 2681 result = factory()->NewTryCatchStatement( |
| 2682 index, try_block, catch_scope, catch_variable, catch_block, pos); | 2682 index, try_block, catch_scope, catch_variable, catch_block, pos); |
| 2683 } else { | 2683 } else { |
| 2684 ASSERT(finally_block != NULL); | 2684 DCHECK(finally_block != NULL); |
| 2685 int index = function_state_->NextHandlerIndex(); | 2685 int index = function_state_->NextHandlerIndex(); |
| 2686 result = factory()->NewTryFinallyStatement( | 2686 result = factory()->NewTryFinallyStatement( |
| 2687 index, try_block, finally_block, pos); | 2687 index, try_block, finally_block, pos); |
| 2688 // Combine the jump targets of the try block and the possible catch block. | 2688 // Combine the jump targets of the try block and the possible catch block. |
| 2689 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2689 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
| 2690 } | 2690 } |
| 2691 | 2691 |
| 2692 result->set_escaping_targets(try_collector.targets()); | 2692 result->set_escaping_targets(try_collector.targets()); |
| 2693 return result; | 2693 return result; |
| 2694 } | 2694 } |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2867 // if (cond) { | 2867 // if (cond) { |
| 2868 // <empty> | 2868 // <empty> |
| 2869 // } else { | 2869 // } else { |
| 2870 // break; | 2870 // break; |
| 2871 // } | 2871 // } |
| 2872 // b | 2872 // b |
| 2873 // temp_x = x; | 2873 // temp_x = x; |
| 2874 // } | 2874 // } |
| 2875 // } | 2875 // } |
| 2876 | 2876 |
| 2877 ASSERT(names->length() > 0); | 2877 DCHECK(names->length() > 0); |
| 2878 Scope* for_scope = scope_; | 2878 Scope* for_scope = scope_; |
| 2879 ZoneList<Variable*> temps(names->length(), zone()); | 2879 ZoneList<Variable*> temps(names->length(), zone()); |
| 2880 | 2880 |
| 2881 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, | 2881 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, |
| 2882 RelocInfo::kNoPosition); | 2882 RelocInfo::kNoPosition); |
| 2883 outer_block->AddStatement(init, zone()); | 2883 outer_block->AddStatement(init, zone()); |
| 2884 | 2884 |
| 2885 const AstRawString* temp_name = ast_value_factory_->dot_for_string(); | 2885 const AstRawString* temp_name = ast_value_factory_->dot_for_string(); |
| 2886 | 2886 |
| 2887 // For each let variable x: | 2887 // For each let variable x: |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3039 scope_->NewUnresolved(factory(), name, interface); | 3039 scope_->NewUnresolved(factory(), name, interface); |
| 3040 Statement* body = ParseStatement(NULL, CHECK_OK); | 3040 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 3041 InitializeForEachStatement(loop, each, enumerable, body); | 3041 InitializeForEachStatement(loop, each, enumerable, body); |
| 3042 Block* result = | 3042 Block* result = |
| 3043 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3043 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 3044 result->AddStatement(variable_statement, zone()); | 3044 result->AddStatement(variable_statement, zone()); |
| 3045 result->AddStatement(loop, zone()); | 3045 result->AddStatement(loop, zone()); |
| 3046 scope_ = saved_scope; | 3046 scope_ = saved_scope; |
| 3047 for_scope->set_end_position(scanner()->location().end_pos); | 3047 for_scope->set_end_position(scanner()->location().end_pos); |
| 3048 for_scope = for_scope->FinalizeBlockScope(); | 3048 for_scope = for_scope->FinalizeBlockScope(); |
| 3049 ASSERT(for_scope == NULL); | 3049 DCHECK(for_scope == NULL); |
| 3050 // Parsed for-in loop w/ variable/const declaration. | 3050 // Parsed for-in loop w/ variable/const declaration. |
| 3051 return result; | 3051 return result; |
| 3052 } else { | 3052 } else { |
| 3053 init = variable_statement; | 3053 init = variable_statement; |
| 3054 } | 3054 } |
| 3055 } else if (peek() == Token::LET && strict_mode() == STRICT) { | 3055 } else if (peek() == Token::LET && strict_mode() == STRICT) { |
| 3056 ASSERT(allow_harmony_scoping()); | 3056 DCHECK(allow_harmony_scoping()); |
| 3057 const AstRawString* name = NULL; | 3057 const AstRawString* name = NULL; |
| 3058 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3058 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3059 Block* variable_statement = | 3059 Block* variable_statement = |
| 3060 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3060 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
| 3061 &name, CHECK_OK); | 3061 &name, CHECK_OK); |
| 3062 bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3062 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
| 3063 bool accept_OF = decl_props == kHasNoInitializers; | 3063 bool accept_OF = decl_props == kHasNoInitializers; |
| 3064 ForEachStatement::VisitMode mode; | 3064 ForEachStatement::VisitMode mode; |
| 3065 | 3065 |
| 3066 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { | 3066 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3130 Target target(&this->target_stack_, loop); | 3130 Target target(&this->target_stack_, loop); |
| 3131 | 3131 |
| 3132 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3132 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3133 Expect(Token::RPAREN, CHECK_OK); | 3133 Expect(Token::RPAREN, CHECK_OK); |
| 3134 | 3134 |
| 3135 Statement* body = ParseStatement(NULL, CHECK_OK); | 3135 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 3136 InitializeForEachStatement(loop, expression, enumerable, body); | 3136 InitializeForEachStatement(loop, expression, enumerable, body); |
| 3137 scope_ = saved_scope; | 3137 scope_ = saved_scope; |
| 3138 for_scope->set_end_position(scanner()->location().end_pos); | 3138 for_scope->set_end_position(scanner()->location().end_pos); |
| 3139 for_scope = for_scope->FinalizeBlockScope(); | 3139 for_scope = for_scope->FinalizeBlockScope(); |
| 3140 ASSERT(for_scope == NULL); | 3140 DCHECK(for_scope == NULL); |
| 3141 // Parsed for-in loop. | 3141 // Parsed for-in loop. |
| 3142 return loop; | 3142 return loop; |
| 3143 | 3143 |
| 3144 } else { | 3144 } else { |
| 3145 init = factory()->NewExpressionStatement( | 3145 init = factory()->NewExpressionStatement( |
| 3146 expression, RelocInfo::kNoPosition); | 3146 expression, RelocInfo::kNoPosition); |
| 3147 } | 3147 } |
| 3148 } | 3148 } |
| 3149 } | 3149 } |
| 3150 | 3150 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3193 if (for_scope) { | 3193 if (for_scope) { |
| 3194 // Rewrite a for statement of the form | 3194 // Rewrite a for statement of the form |
| 3195 // for (const x = i; c; n) b | 3195 // for (const x = i; c; n) b |
| 3196 // | 3196 // |
| 3197 // into | 3197 // into |
| 3198 // | 3198 // |
| 3199 // { | 3199 // { |
| 3200 // const x = i; | 3200 // const x = i; |
| 3201 // for (; c; n) b | 3201 // for (; c; n) b |
| 3202 // } | 3202 // } |
| 3203 ASSERT(init != NULL); | 3203 DCHECK(init != NULL); |
| 3204 Block* block = | 3204 Block* block = |
| 3205 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3205 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 3206 block->AddStatement(init, zone()); | 3206 block->AddStatement(init, zone()); |
| 3207 block->AddStatement(loop, zone()); | 3207 block->AddStatement(loop, zone()); |
| 3208 block->set_scope(for_scope); | 3208 block->set_scope(for_scope); |
| 3209 loop->Initialize(NULL, cond, next, body); | 3209 loop->Initialize(NULL, cond, next, body); |
| 3210 result = block; | 3210 result = block; |
| 3211 } else { | 3211 } else { |
| 3212 loop->Initialize(init, cond, next, body); | 3212 loop->Initialize(init, cond, next, body); |
| 3213 result = loop; | 3213 result = loop; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3234 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3234 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| 3235 if (expression->IsLiteral()) return true; | 3235 if (expression->IsLiteral()) return true; |
| 3236 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3236 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
| 3237 return lit != NULL && lit->is_simple(); | 3237 return lit != NULL && lit->is_simple(); |
| 3238 } | 3238 } |
| 3239 | 3239 |
| 3240 | 3240 |
| 3241 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, | 3241 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, |
| 3242 Expression* expression) { | 3242 Expression* expression) { |
| 3243 Factory* factory = isolate->factory(); | 3243 Factory* factory = isolate->factory(); |
| 3244 ASSERT(IsCompileTimeValue(expression)); | 3244 DCHECK(IsCompileTimeValue(expression)); |
| 3245 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED); | 3245 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED); |
| 3246 ObjectLiteral* object_literal = expression->AsObjectLiteral(); | 3246 ObjectLiteral* object_literal = expression->AsObjectLiteral(); |
| 3247 if (object_literal != NULL) { | 3247 if (object_literal != NULL) { |
| 3248 ASSERT(object_literal->is_simple()); | 3248 DCHECK(object_literal->is_simple()); |
| 3249 if (object_literal->fast_elements()) { | 3249 if (object_literal->fast_elements()) { |
| 3250 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); | 3250 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); |
| 3251 } else { | 3251 } else { |
| 3252 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); | 3252 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); |
| 3253 } | 3253 } |
| 3254 result->set(kElementsSlot, *object_literal->constant_properties()); | 3254 result->set(kElementsSlot, *object_literal->constant_properties()); |
| 3255 } else { | 3255 } else { |
| 3256 ArrayLiteral* array_literal = expression->AsArrayLiteral(); | 3256 ArrayLiteral* array_literal = expression->AsArrayLiteral(); |
| 3257 ASSERT(array_literal != NULL && array_literal->is_simple()); | 3257 DCHECK(array_literal != NULL && array_literal->is_simple()); |
| 3258 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL)); | 3258 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL)); |
| 3259 result->set(kElementsSlot, *array_literal->constant_elements()); | 3259 result->set(kElementsSlot, *array_literal->constant_elements()); |
| 3260 } | 3260 } |
| 3261 return result; | 3261 return result; |
| 3262 } | 3262 } |
| 3263 | 3263 |
| 3264 | 3264 |
| 3265 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType( | 3265 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType( |
| 3266 Handle<FixedArray> value) { | 3266 Handle<FixedArray> value) { |
| 3267 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); | 3267 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3495 // instead of Variables and Proxis as is the case now. | 3495 // instead of Variables and Proxis as is the case now. |
| 3496 Variable* fvar = NULL; | 3496 Variable* fvar = NULL; |
| 3497 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3497 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| 3498 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3498 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3499 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3499 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 3500 fvar_init_op = Token::INIT_CONST; | 3500 fvar_init_op = Token::INIT_CONST; |
| 3501 } | 3501 } |
| 3502 VariableMode fvar_mode = | 3502 VariableMode fvar_mode = |
| 3503 allow_harmony_scoping() && strict_mode() == STRICT | 3503 allow_harmony_scoping() && strict_mode() == STRICT |
| 3504 ? CONST : CONST_LEGACY; | 3504 ? CONST : CONST_LEGACY; |
| 3505 ASSERT(function_name != NULL); | 3505 DCHECK(function_name != NULL); |
| 3506 fvar = new (zone()) | 3506 fvar = new (zone()) |
| 3507 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */, | 3507 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */, |
| 3508 Variable::NORMAL, kCreatedInitialized, kNotAssigned, | 3508 Variable::NORMAL, kCreatedInitialized, kNotAssigned, |
| 3509 Interface::NewConst()); | 3509 Interface::NewConst()); |
| 3510 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3510 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 3511 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3511 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 3512 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3512 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 3513 scope_->DeclareFunctionVar(fvar_declaration); | 3513 scope_->DeclareFunctionVar(fvar_declaration); |
| 3514 } | 3514 } |
| 3515 | 3515 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3649 Expect(Token::RBRACE, ok); | 3649 Expect(Token::RBRACE, ok); |
| 3650 if (!*ok) { | 3650 if (!*ok) { |
| 3651 return; | 3651 return; |
| 3652 } | 3652 } |
| 3653 isolate()->counters()->total_preparse_skipped()->Increment( | 3653 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3654 scope_->end_position() - function_block_pos); | 3654 scope_->end_position() - function_block_pos); |
| 3655 *materialized_literal_count = logger.literals(); | 3655 *materialized_literal_count = logger.literals(); |
| 3656 *expected_property_count = logger.properties(); | 3656 *expected_property_count = logger.properties(); |
| 3657 scope_->SetStrictMode(logger.strict_mode()); | 3657 scope_->SetStrictMode(logger.strict_mode()); |
| 3658 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 3658 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 3659 ASSERT(log_); | 3659 DCHECK(log_); |
| 3660 // Position right after terminal '}'. | 3660 // Position right after terminal '}'. |
| 3661 int body_end = scanner()->location().end_pos; | 3661 int body_end = scanner()->location().end_pos; |
| 3662 log_->LogFunction(function_block_pos, body_end, | 3662 log_->LogFunction(function_block_pos, body_end, |
| 3663 *materialized_literal_count, | 3663 *materialized_literal_count, |
| 3664 *expected_property_count, | 3664 *expected_property_count, |
| 3665 scope_->strict_mode()); | 3665 scope_->strict_mode()); |
| 3666 } | 3666 } |
| 3667 } | 3667 } |
| 3668 } | 3668 } |
| 3669 | 3669 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3723 Expect(Token::RBRACE, CHECK_OK); | 3723 Expect(Token::RBRACE, CHECK_OK); |
| 3724 scope_->set_end_position(scanner()->location().end_pos); | 3724 scope_->set_end_position(scanner()->location().end_pos); |
| 3725 | 3725 |
| 3726 return body; | 3726 return body; |
| 3727 } | 3727 } |
| 3728 | 3728 |
| 3729 | 3729 |
| 3730 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 3730 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
| 3731 SingletonLogger* logger) { | 3731 SingletonLogger* logger) { |
| 3732 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 3732 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 3733 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); | 3733 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
| 3734 | 3734 |
| 3735 if (reusable_preparser_ == NULL) { | 3735 if (reusable_preparser_ == NULL) { |
| 3736 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 3736 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 3737 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); | 3737 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); |
| 3738 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 3738 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 3739 reusable_preparser_->set_allow_modules(allow_modules()); | 3739 reusable_preparser_->set_allow_modules(allow_modules()); |
| 3740 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 3740 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 3741 reusable_preparser_->set_allow_lazy(true); | 3741 reusable_preparser_->set_allow_lazy(true); |
| 3742 reusable_preparser_->set_allow_generators(allow_generators()); | 3742 reusable_preparser_->set_allow_generators(allow_generators()); |
| 3743 reusable_preparser_->set_allow_for_of(allow_for_of()); | 3743 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3859 } | 3859 } |
| 3860 | 3860 |
| 3861 | 3861 |
| 3862 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, | 3862 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, |
| 3863 bool* ok) { | 3863 bool* ok) { |
| 3864 bool anonymous = label == NULL; | 3864 bool anonymous = label == NULL; |
| 3865 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3865 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3866 IterationStatement* stat = t->node()->AsIterationStatement(); | 3866 IterationStatement* stat = t->node()->AsIterationStatement(); |
| 3867 if (stat == NULL) continue; | 3867 if (stat == NULL) continue; |
| 3868 | 3868 |
| 3869 ASSERT(stat->is_target_for_anonymous()); | 3869 DCHECK(stat->is_target_for_anonymous()); |
| 3870 if (anonymous || ContainsLabel(stat->labels(), label)) { | 3870 if (anonymous || ContainsLabel(stat->labels(), label)) { |
| 3871 RegisterTargetUse(stat->continue_target(), t->previous()); | 3871 RegisterTargetUse(stat->continue_target(), t->previous()); |
| 3872 return stat; | 3872 return stat; |
| 3873 } | 3873 } |
| 3874 } | 3874 } |
| 3875 return NULL; | 3875 return NULL; |
| 3876 } | 3876 } |
| 3877 | 3877 |
| 3878 | 3878 |
| 3879 void Parser::RegisterTargetUse(Label* target, Target* stop) { | 3879 void Parser::RegisterTargetUse(Label* target, Target* stop) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3894 } | 3894 } |
| 3895 if (scanner_.source_mapping_url()->length() > 0) { | 3895 if (scanner_.source_mapping_url()->length() > 0) { |
| 3896 Handle<String> source_mapping_url = | 3896 Handle<String> source_mapping_url = |
| 3897 scanner_.source_mapping_url()->Internalize(isolate()); | 3897 scanner_.source_mapping_url()->Internalize(isolate()); |
| 3898 info_->script()->set_source_mapping_url(*source_mapping_url); | 3898 info_->script()->set_source_mapping_url(*source_mapping_url); |
| 3899 } | 3899 } |
| 3900 } | 3900 } |
| 3901 | 3901 |
| 3902 | 3902 |
| 3903 void Parser::ThrowPendingError() { | 3903 void Parser::ThrowPendingError() { |
| 3904 ASSERT(ast_value_factory_->IsInternalized()); | 3904 DCHECK(ast_value_factory_->IsInternalized()); |
| 3905 if (has_pending_error_) { | 3905 if (has_pending_error_) { |
| 3906 MessageLocation location(script_, | 3906 MessageLocation location(script_, |
| 3907 pending_error_location_.beg_pos, | 3907 pending_error_location_.beg_pos, |
| 3908 pending_error_location_.end_pos); | 3908 pending_error_location_.end_pos); |
| 3909 Factory* factory = isolate()->factory(); | 3909 Factory* factory = isolate()->factory(); |
| 3910 bool has_arg = | 3910 bool has_arg = |
| 3911 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; | 3911 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; |
| 3912 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | 3912 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); |
| 3913 if (pending_error_arg_ != NULL) { | 3913 if (pending_error_arg_ != NULL) { |
| 3914 Handle<String> arg_string = pending_error_arg_->string(); | 3914 Handle<String> arg_string = pending_error_arg_->string(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4018 current_ = kEndMarker; | 4018 current_ = kEndMarker; |
| 4019 next_pos_ = in()->length(); | 4019 next_pos_ = in()->length(); |
| 4020 return NULL; | 4020 return NULL; |
| 4021 } | 4021 } |
| 4022 | 4022 |
| 4023 | 4023 |
| 4024 // Pattern :: | 4024 // Pattern :: |
| 4025 // Disjunction | 4025 // Disjunction |
| 4026 RegExpTree* RegExpParser::ParsePattern() { | 4026 RegExpTree* RegExpParser::ParsePattern() { |
| 4027 RegExpTree* result = ParseDisjunction(CHECK_FAILED); | 4027 RegExpTree* result = ParseDisjunction(CHECK_FAILED); |
| 4028 ASSERT(!has_more()); | 4028 DCHECK(!has_more()); |
| 4029 // If the result of parsing is a literal string atom, and it has the | 4029 // If the result of parsing is a literal string atom, and it has the |
| 4030 // same length as the input, then the atom is identical to the input. | 4030 // same length as the input, then the atom is identical to the input. |
| 4031 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) { | 4031 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) { |
| 4032 simple_ = true; | 4032 simple_ = true; |
| 4033 } | 4033 } |
| 4034 return result; | 4034 return result; |
| 4035 } | 4035 } |
| 4036 | 4036 |
| 4037 | 4037 |
| 4038 // Disjunction :: | 4038 // Disjunction :: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4051 RegExpParserState* stored_state = &initial_state; | 4051 RegExpParserState* stored_state = &initial_state; |
| 4052 // Cache the builder in a local variable for quick access. | 4052 // Cache the builder in a local variable for quick access. |
| 4053 RegExpBuilder* builder = initial_state.builder(); | 4053 RegExpBuilder* builder = initial_state.builder(); |
| 4054 while (true) { | 4054 while (true) { |
| 4055 switch (current()) { | 4055 switch (current()) { |
| 4056 case kEndMarker: | 4056 case kEndMarker: |
| 4057 if (stored_state->IsSubexpression()) { | 4057 if (stored_state->IsSubexpression()) { |
| 4058 // Inside a parenthesized group when hitting end of input. | 4058 // Inside a parenthesized group when hitting end of input. |
| 4059 ReportError(CStrVector("Unterminated group") CHECK_FAILED); | 4059 ReportError(CStrVector("Unterminated group") CHECK_FAILED); |
| 4060 } | 4060 } |
| 4061 ASSERT_EQ(INITIAL, stored_state->group_type()); | 4061 DCHECK_EQ(INITIAL, stored_state->group_type()); |
| 4062 // Parsing completed successfully. | 4062 // Parsing completed successfully. |
| 4063 return builder->ToRegExp(); | 4063 return builder->ToRegExp(); |
| 4064 case ')': { | 4064 case ')': { |
| 4065 if (!stored_state->IsSubexpression()) { | 4065 if (!stored_state->IsSubexpression()) { |
| 4066 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); | 4066 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); |
| 4067 } | 4067 } |
| 4068 ASSERT_NE(INITIAL, stored_state->group_type()); | 4068 DCHECK_NE(INITIAL, stored_state->group_type()); |
| 4069 | 4069 |
| 4070 Advance(); | 4070 Advance(); |
| 4071 // End disjunction parsing and convert builder content to new single | 4071 // End disjunction parsing and convert builder content to new single |
| 4072 // regexp atom. | 4072 // regexp atom. |
| 4073 RegExpTree* body = builder->ToRegExp(); | 4073 RegExpTree* body = builder->ToRegExp(); |
| 4074 | 4074 |
| 4075 int end_capture_index = captures_started(); | 4075 int end_capture_index = captures_started(); |
| 4076 | 4076 |
| 4077 int capture_index = stored_state->capture_index(); | 4077 int capture_index = stored_state->capture_index(); |
| 4078 SubexpressionType group_type = stored_state->group_type(); | 4078 SubexpressionType group_type = stored_state->group_type(); |
| 4079 | 4079 |
| 4080 // Restore previous state. | 4080 // Restore previous state. |
| 4081 stored_state = stored_state->previous_state(); | 4081 stored_state = stored_state->previous_state(); |
| 4082 builder = stored_state->builder(); | 4082 builder = stored_state->builder(); |
| 4083 | 4083 |
| 4084 // Build result of subexpression. | 4084 // Build result of subexpression. |
| 4085 if (group_type == CAPTURE) { | 4085 if (group_type == CAPTURE) { |
| 4086 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); | 4086 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); |
| 4087 captures_->at(capture_index - 1) = capture; | 4087 captures_->at(capture_index - 1) = capture; |
| 4088 body = capture; | 4088 body = capture; |
| 4089 } else if (group_type != GROUPING) { | 4089 } else if (group_type != GROUPING) { |
| 4090 ASSERT(group_type == POSITIVE_LOOKAHEAD || | 4090 DCHECK(group_type == POSITIVE_LOOKAHEAD || |
| 4091 group_type == NEGATIVE_LOOKAHEAD); | 4091 group_type == NEGATIVE_LOOKAHEAD); |
| 4092 bool is_positive = (group_type == POSITIVE_LOOKAHEAD); | 4092 bool is_positive = (group_type == POSITIVE_LOOKAHEAD); |
| 4093 body = new(zone()) RegExpLookahead(body, | 4093 body = new(zone()) RegExpLookahead(body, |
| 4094 is_positive, | 4094 is_positive, |
| 4095 end_capture_index - capture_index, | 4095 end_capture_index - capture_index, |
| 4096 capture_index); | 4096 capture_index); |
| 4097 } | 4097 } |
| 4098 builder->AddAtom(body); | 4098 builder->AddAtom(body); |
| 4099 // For compatability with JSC and ES3, we allow quantifiers after | 4099 // For compatability with JSC and ES3, we allow quantifiers after |
| 4100 // lookaheads, and break in all cases. | 4100 // lookaheads, and break in all cases. |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4364 // FLAG_regexp_possessive_quantifier is a debug-only flag. | 4364 // FLAG_regexp_possessive_quantifier is a debug-only flag. |
| 4365 quantifier_type = RegExpQuantifier::POSSESSIVE; | 4365 quantifier_type = RegExpQuantifier::POSSESSIVE; |
| 4366 Advance(); | 4366 Advance(); |
| 4367 } | 4367 } |
| 4368 builder->AddQuantifierToAtom(min, max, quantifier_type); | 4368 builder->AddQuantifierToAtom(min, max, quantifier_type); |
| 4369 } | 4369 } |
| 4370 } | 4370 } |
| 4371 | 4371 |
| 4372 | 4372 |
| 4373 #ifdef DEBUG | 4373 #ifdef DEBUG |
| 4374 // Currently only used in an ASSERT. | 4374 // Currently only used in an DCHECK. |
| 4375 static bool IsSpecialClassEscape(uc32 c) { | 4375 static bool IsSpecialClassEscape(uc32 c) { |
| 4376 switch (c) { | 4376 switch (c) { |
| 4377 case 'd': case 'D': | 4377 case 'd': case 'D': |
| 4378 case 's': case 'S': | 4378 case 's': case 'S': |
| 4379 case 'w': case 'W': | 4379 case 'w': case 'W': |
| 4380 return true; | 4380 return true; |
| 4381 default: | 4381 default: |
| 4382 return false; | 4382 return false; |
| 4383 } | 4383 } |
| 4384 } | 4384 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4418 if (current() != '?') capture_count++; | 4418 if (current() != '?') capture_count++; |
| 4419 break; | 4419 break; |
| 4420 } | 4420 } |
| 4421 } | 4421 } |
| 4422 capture_count_ = capture_count; | 4422 capture_count_ = capture_count; |
| 4423 is_scanned_for_captures_ = true; | 4423 is_scanned_for_captures_ = true; |
| 4424 } | 4424 } |
| 4425 | 4425 |
| 4426 | 4426 |
| 4427 bool RegExpParser::ParseBackReferenceIndex(int* index_out) { | 4427 bool RegExpParser::ParseBackReferenceIndex(int* index_out) { |
| 4428 ASSERT_EQ('\\', current()); | 4428 DCHECK_EQ('\\', current()); |
| 4429 ASSERT('1' <= Next() && Next() <= '9'); | 4429 DCHECK('1' <= Next() && Next() <= '9'); |
| 4430 // Try to parse a decimal literal that is no greater than the total number | 4430 // Try to parse a decimal literal that is no greater than the total number |
| 4431 // of left capturing parentheses in the input. | 4431 // of left capturing parentheses in the input. |
| 4432 int start = position(); | 4432 int start = position(); |
| 4433 int value = Next() - '0'; | 4433 int value = Next() - '0'; |
| 4434 Advance(2); | 4434 Advance(2); |
| 4435 while (true) { | 4435 while (true) { |
| 4436 uc32 c = current(); | 4436 uc32 c = current(); |
| 4437 if (IsDecimalDigit(c)) { | 4437 if (IsDecimalDigit(c)) { |
| 4438 value = 10 * value + (c - '0'); | 4438 value = 10 * value + (c - '0'); |
| 4439 if (value > kMaxCaptures) { | 4439 if (value > kMaxCaptures) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4462 | 4462 |
| 4463 | 4463 |
| 4464 // QuantifierPrefix :: | 4464 // QuantifierPrefix :: |
| 4465 // { DecimalDigits } | 4465 // { DecimalDigits } |
| 4466 // { DecimalDigits , } | 4466 // { DecimalDigits , } |
| 4467 // { DecimalDigits , DecimalDigits } | 4467 // { DecimalDigits , DecimalDigits } |
| 4468 // | 4468 // |
| 4469 // Returns true if parsing succeeds, and set the min_out and max_out | 4469 // Returns true if parsing succeeds, and set the min_out and max_out |
| 4470 // values. Values are truncated to RegExpTree::kInfinity if they overflow. | 4470 // values. Values are truncated to RegExpTree::kInfinity if they overflow. |
| 4471 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) { | 4471 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) { |
| 4472 ASSERT_EQ(current(), '{'); | 4472 DCHECK_EQ(current(), '{'); |
| 4473 int start = position(); | 4473 int start = position(); |
| 4474 Advance(); | 4474 Advance(); |
| 4475 int min = 0; | 4475 int min = 0; |
| 4476 if (!IsDecimalDigit(current())) { | 4476 if (!IsDecimalDigit(current())) { |
| 4477 Reset(start); | 4477 Reset(start); |
| 4478 return false; | 4478 return false; |
| 4479 } | 4479 } |
| 4480 while (IsDecimalDigit(current())) { | 4480 while (IsDecimalDigit(current())) { |
| 4481 int next = current() - '0'; | 4481 int next = current() - '0'; |
| 4482 if (min > (RegExpTree::kInfinity - next) / 10) { | 4482 if (min > (RegExpTree::kInfinity - next) / 10) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4522 Reset(start); | 4522 Reset(start); |
| 4523 return false; | 4523 return false; |
| 4524 } | 4524 } |
| 4525 *min_out = min; | 4525 *min_out = min; |
| 4526 *max_out = max; | 4526 *max_out = max; |
| 4527 return true; | 4527 return true; |
| 4528 } | 4528 } |
| 4529 | 4529 |
| 4530 | 4530 |
| 4531 uc32 RegExpParser::ParseOctalLiteral() { | 4531 uc32 RegExpParser::ParseOctalLiteral() { |
| 4532 ASSERT(('0' <= current() && current() <= '7') || current() == kEndMarker); | 4532 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker); |
| 4533 // For compatibility with some other browsers (not all), we parse | 4533 // For compatibility with some other browsers (not all), we parse |
| 4534 // up to three octal digits with a value below 256. | 4534 // up to three octal digits with a value below 256. |
| 4535 uc32 value = current() - '0'; | 4535 uc32 value = current() - '0'; |
| 4536 Advance(); | 4536 Advance(); |
| 4537 if ('0' <= current() && current() <= '7') { | 4537 if ('0' <= current() && current() <= '7') { |
| 4538 value = value * 8 + current() - '0'; | 4538 value = value * 8 + current() - '0'; |
| 4539 Advance(); | 4539 Advance(); |
| 4540 if (value < 32 && '0' <= current() && current() <= '7') { | 4540 if (value < 32 && '0' <= current() && current() <= '7') { |
| 4541 value = value * 8 + current() - '0'; | 4541 value = value * 8 + current() - '0'; |
| 4542 Advance(); | 4542 Advance(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4562 if (i == length - 1) { | 4562 if (i == length - 1) { |
| 4563 done = true; | 4563 done = true; |
| 4564 } | 4564 } |
| 4565 } | 4565 } |
| 4566 *value = val; | 4566 *value = val; |
| 4567 return true; | 4567 return true; |
| 4568 } | 4568 } |
| 4569 | 4569 |
| 4570 | 4570 |
| 4571 uc32 RegExpParser::ParseClassCharacterEscape() { | 4571 uc32 RegExpParser::ParseClassCharacterEscape() { |
| 4572 ASSERT(current() == '\\'); | 4572 DCHECK(current() == '\\'); |
| 4573 ASSERT(has_next() && !IsSpecialClassEscape(Next())); | 4573 DCHECK(has_next() && !IsSpecialClassEscape(Next())); |
| 4574 Advance(); | 4574 Advance(); |
| 4575 switch (current()) { | 4575 switch (current()) { |
| 4576 case 'b': | 4576 case 'b': |
| 4577 Advance(); | 4577 Advance(); |
| 4578 return '\b'; | 4578 return '\b'; |
| 4579 // ControlEscape :: one of | 4579 // ControlEscape :: one of |
| 4580 // f n r t v | 4580 // f n r t v |
| 4581 case 'f': | 4581 case 'f': |
| 4582 Advance(); | 4582 Advance(); |
| 4583 return '\f'; | 4583 return '\f'; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4643 uc32 result = current(); | 4643 uc32 result = current(); |
| 4644 Advance(); | 4644 Advance(); |
| 4645 return result; | 4645 return result; |
| 4646 } | 4646 } |
| 4647 } | 4647 } |
| 4648 return 0; | 4648 return 0; |
| 4649 } | 4649 } |
| 4650 | 4650 |
| 4651 | 4651 |
| 4652 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) { | 4652 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) { |
| 4653 ASSERT_EQ(0, *char_class); | 4653 DCHECK_EQ(0, *char_class); |
| 4654 uc32 first = current(); | 4654 uc32 first = current(); |
| 4655 if (first == '\\') { | 4655 if (first == '\\') { |
| 4656 switch (Next()) { | 4656 switch (Next()) { |
| 4657 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': { | 4657 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': { |
| 4658 *char_class = Next(); | 4658 *char_class = Next(); |
| 4659 Advance(2); | 4659 Advance(2); |
| 4660 return CharacterRange::Singleton(0); // Return dummy value. | 4660 return CharacterRange::Singleton(0); // Return dummy value. |
| 4661 } | 4661 } |
| 4662 case kEndMarker: | 4662 case kEndMarker: |
| 4663 return ReportError(CStrVector("\\ at end of pattern")); | 4663 return ReportError(CStrVector("\\ at end of pattern")); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4686 } else { | 4686 } else { |
| 4687 ranges->Add(range, zone); | 4687 ranges->Add(range, zone); |
| 4688 } | 4688 } |
| 4689 } | 4689 } |
| 4690 | 4690 |
| 4691 | 4691 |
| 4692 RegExpTree* RegExpParser::ParseCharacterClass() { | 4692 RegExpTree* RegExpParser::ParseCharacterClass() { |
| 4693 static const char* kUnterminated = "Unterminated character class"; | 4693 static const char* kUnterminated = "Unterminated character class"; |
| 4694 static const char* kRangeOutOfOrder = "Range out of order in character class"; | 4694 static const char* kRangeOutOfOrder = "Range out of order in character class"; |
| 4695 | 4695 |
| 4696 ASSERT_EQ(current(), '['); | 4696 DCHECK_EQ(current(), '['); |
| 4697 Advance(); | 4697 Advance(); |
| 4698 bool is_negated = false; | 4698 bool is_negated = false; |
| 4699 if (current() == '^') { | 4699 if (current() == '^') { |
| 4700 is_negated = true; | 4700 is_negated = true; |
| 4701 Advance(); | 4701 Advance(); |
| 4702 } | 4702 } |
| 4703 ZoneList<CharacterRange>* ranges = | 4703 ZoneList<CharacterRange>* ranges = |
| 4704 new(zone()) ZoneList<CharacterRange>(2, zone()); | 4704 new(zone()) ZoneList<CharacterRange>(2, zone()); |
| 4705 while (has_more() && current() != ']') { | 4705 while (has_more() && current() != ']') { |
| 4706 uc16 char_class = kNoCharClass; | 4706 uc16 char_class = kNoCharClass; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4745 } | 4745 } |
| 4746 | 4746 |
| 4747 | 4747 |
| 4748 // ---------------------------------------------------------------------------- | 4748 // ---------------------------------------------------------------------------- |
| 4749 // The Parser interface. | 4749 // The Parser interface. |
| 4750 | 4750 |
| 4751 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 4751 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 4752 bool multiline, | 4752 bool multiline, |
| 4753 RegExpCompileData* result, | 4753 RegExpCompileData* result, |
| 4754 Zone* zone) { | 4754 Zone* zone) { |
| 4755 ASSERT(result != NULL); | 4755 DCHECK(result != NULL); |
| 4756 RegExpParser parser(input, &result->error, multiline, zone); | 4756 RegExpParser parser(input, &result->error, multiline, zone); |
| 4757 RegExpTree* tree = parser.ParsePattern(); | 4757 RegExpTree* tree = parser.ParsePattern(); |
| 4758 if (parser.failed()) { | 4758 if (parser.failed()) { |
| 4759 ASSERT(tree == NULL); | 4759 DCHECK(tree == NULL); |
| 4760 ASSERT(!result->error.is_null()); | 4760 DCHECK(!result->error.is_null()); |
| 4761 } else { | 4761 } else { |
| 4762 ASSERT(tree != NULL); | 4762 DCHECK(tree != NULL); |
| 4763 ASSERT(result->error.is_null()); | 4763 DCHECK(result->error.is_null()); |
| 4764 result->tree = tree; | 4764 result->tree = tree; |
| 4765 int capture_count = parser.captures_started(); | 4765 int capture_count = parser.captures_started(); |
| 4766 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 4766 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
| 4767 result->contains_anchor = parser.contains_anchor(); | 4767 result->contains_anchor = parser.contains_anchor(); |
| 4768 result->capture_count = capture_count; | 4768 result->capture_count = capture_count; |
| 4769 } | 4769 } |
| 4770 return !parser.failed(); | 4770 return !parser.failed(); |
| 4771 } | 4771 } |
| 4772 | 4772 |
| 4773 | 4773 |
| 4774 bool Parser::Parse() { | 4774 bool Parser::Parse() { |
| 4775 ASSERT(info()->function() == NULL); | 4775 DCHECK(info()->function() == NULL); |
| 4776 FunctionLiteral* result = NULL; | 4776 FunctionLiteral* result = NULL; |
| 4777 ast_value_factory_ = info()->ast_value_factory(); | 4777 ast_value_factory_ = info()->ast_value_factory(); |
| 4778 if (ast_value_factory_ == NULL) { | 4778 if (ast_value_factory_ == NULL) { |
| 4779 ast_value_factory_ = | 4779 ast_value_factory_ = |
| 4780 new AstValueFactory(zone(), isolate()->heap()->HashSeed()); | 4780 new AstValueFactory(zone(), isolate()->heap()->HashSeed()); |
| 4781 } | 4781 } |
| 4782 if (allow_natives_syntax() || extension_ != NULL) { | 4782 if (allow_natives_syntax() || extension_ != NULL) { |
| 4783 // If intrinsics are allowed, the Parser cannot operate independent of the | 4783 // If intrinsics are allowed, the Parser cannot operate independent of the |
| 4784 // V8 heap because of Rumtime. Tell the string table to internalize strings | 4784 // V8 heap because of Rumtime. Tell the string table to internalize strings |
| 4785 // and values right after they're created. | 4785 // and values right after they're created. |
| 4786 ast_value_factory_->Internalize(isolate()); | 4786 ast_value_factory_->Internalize(isolate()); |
| 4787 } | 4787 } |
| 4788 | 4788 |
| 4789 if (info()->is_lazy()) { | 4789 if (info()->is_lazy()) { |
| 4790 ASSERT(!info()->is_eval()); | 4790 DCHECK(!info()->is_eval()); |
| 4791 if (info()->shared_info()->is_function()) { | 4791 if (info()->shared_info()->is_function()) { |
| 4792 result = ParseLazy(); | 4792 result = ParseLazy(); |
| 4793 } else { | 4793 } else { |
| 4794 result = ParseProgram(); | 4794 result = ParseProgram(); |
| 4795 } | 4795 } |
| 4796 } else { | 4796 } else { |
| 4797 SetCachedData(); | 4797 SetCachedData(); |
| 4798 result = ParseProgram(); | 4798 result = ParseProgram(); |
| 4799 } | 4799 } |
| 4800 info()->SetFunction(result); | 4800 info()->SetFunction(result); |
| 4801 ASSERT(ast_value_factory_->IsInternalized()); | 4801 DCHECK(ast_value_factory_->IsInternalized()); |
| 4802 // info takes ownership of ast_value_factory_. | 4802 // info takes ownership of ast_value_factory_. |
| 4803 if (info()->ast_value_factory() == NULL) { | 4803 if (info()->ast_value_factory() == NULL) { |
| 4804 info()->SetAstValueFactory(ast_value_factory_); | 4804 info()->SetAstValueFactory(ast_value_factory_); |
| 4805 } | 4805 } |
| 4806 ast_value_factory_ = NULL; | 4806 ast_value_factory_ = NULL; |
| 4807 | 4807 |
| 4808 InternalizeUseCounts(); | 4808 InternalizeUseCounts(); |
| 4809 | 4809 |
| 4810 return (result != NULL); | 4810 return (result != NULL); |
| 4811 } | 4811 } |
| 4812 | 4812 |
| 4813 } } // namespace v8::internal | 4813 } } // namespace v8::internal |
| OLD | NEW |