Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 6709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6720 (found_func.token_pos() == async_func_pos) && | 6720 (found_func.token_pos() == async_func_pos) && |
| 6721 (found_func.script() == innermost_function().script()) && | 6721 (found_func.script() == innermost_function().script()) && |
| 6722 (found_func.parent_function() == innermost_function().raw())) { | 6722 (found_func.parent_function() == innermost_function().raw())) { |
| 6723 ASSERT(found_func.IsAsyncClosure()); | 6723 ASSERT(found_func.IsAsyncClosure()); |
| 6724 closure = found_func.raw(); | 6724 closure = found_func.raw(); |
| 6725 } else { | 6725 } else { |
| 6726 // Create the closure containing the body of this async function. | 6726 // Create the closure containing the body of this async function. |
| 6727 const String& async_func_name = | 6727 const String& async_func_name = |
| 6728 String::Handle(Z, innermost_function().name()); | 6728 String::Handle(Z, innermost_function().name()); |
| 6729 String& closure_name = String::Handle(Z, | 6729 String& closure_name = String::Handle(Z, |
| 6730 String::NewFormatted("<%s_async_body>", async_func_name.ToCString())); | 6730 Symbols::NewFormatted("<%s_async_body>", async_func_name.ToCString())); |
| 6731 closure = Function::NewClosureFunction( | 6731 closure = Function::NewClosureFunction( |
| 6732 String::Handle(Z, Symbols::New(closure_name)), | 6732 closure_name, |
| 6733 innermost_function(), | 6733 innermost_function(), |
| 6734 async_func_pos); | 6734 async_func_pos); |
| 6735 closure.set_is_generated_body(true); | 6735 closure.set_is_generated_body(true); |
| 6736 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); | 6736 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); |
| 6737 is_new_closure = true; | 6737 is_new_closure = true; |
| 6738 } | 6738 } |
| 6739 // Create the parameter list for the async body closure. | 6739 // Create the parameter list for the async body closure. |
| 6740 ParamList closure_params; | 6740 ParamList closure_params; |
| 6741 AddAsyncClosureParameters(&closure_params); | 6741 AddAsyncClosureParameters(&closure_params); |
| 6742 if (is_new_closure) { | 6742 if (is_new_closure) { |
| (...skipping 1765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8508 LocalVariable* var = | 8508 LocalVariable* var = |
| 8509 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 8509 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 8510 ASSERT((var != NULL) && !var->is_captured()); | 8510 ASSERT((var != NULL) && !var->is_captured()); |
| 8511 return var; | 8511 return var; |
| 8512 } | 8512 } |
| 8513 | 8513 |
| 8514 | 8514 |
| 8515 static LocalVariable* LookupAsyncSavedTryContextVar(LocalScope* scope, | 8515 static LocalVariable* LookupAsyncSavedTryContextVar(LocalScope* scope, |
| 8516 uint16_t try_index) { | 8516 uint16_t try_index) { |
| 8517 const String& async_saved_try_ctx_name = | 8517 const String& async_saved_try_ctx_name = |
| 8518 String::ZoneHandle(Symbols::New(String::Handle( | 8518 String::ZoneHandle(Symbols::NewFormatted( |
| 8519 String::NewFormatted( | 8519 "%s%d", |
| 8520 "%s%d", | 8520 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
| 8521 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 8521 try_index)); |
| 8522 try_index)))); | |
| 8523 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); | 8522 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); |
| 8524 ASSERT(var != NULL); | 8523 ASSERT(var != NULL); |
| 8525 return var; | 8524 return var; |
| 8526 } | 8525 } |
| 8527 | 8526 |
| 8528 | 8527 |
| 8529 // If the await or yield being parsed is in a try block, the continuation code | 8528 // If the await or yield being parsed is in a try block, the continuation code |
| 8530 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, | 8529 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, |
| 8531 // and the stack-based variable :saved_try_ctx_var of the outer try block. | 8530 // and the stack-based variable :saved_try_ctx_var of the outer try block. |
| 8532 // The inner :saved_try_ctx_var is used by a finally clause handling an | 8531 // The inner :saved_try_ctx_var is used by a finally clause handling an |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8584 | 8583 |
| 8585 | 8584 |
| 8586 // Build an AST node for static call to Dart function print(str). | 8585 // Build an AST node for static call to Dart function print(str). |
| 8587 // Used during debugging to insert print in generated dart code. | 8586 // Used during debugging to insert print in generated dart code. |
| 8588 AstNode* Parser::DartPrint(const char* str) { | 8587 AstNode* Parser::DartPrint(const char* str) { |
| 8589 const Library& lib = Library::Handle(Library::CoreLibrary()); | 8588 const Library& lib = Library::Handle(Library::CoreLibrary()); |
| 8590 const Function& print_fn = Function::ZoneHandle( | 8589 const Function& print_fn = Function::ZoneHandle( |
| 8591 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); | 8590 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
| 8592 ASSERT(!print_fn.IsNull()); | 8591 ASSERT(!print_fn.IsNull()); |
| 8593 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Scanner::kNoSourcePos); | 8592 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 8594 String& msg = String::Handle(String::NewFormatted("%s", str)); | 8593 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); |
| 8595 one_arg->Add(new(Z) LiteralNode(Scanner::kNoSourcePos, | 8594 one_arg->Add(new(Z) LiteralNode(Scanner::kNoSourcePos, msg)); |
| 8596 String::ZoneHandle(Symbols::New(msg)))); | |
| 8597 AstNode* print_call = | 8595 AstNode* print_call = |
| 8598 new(Z) StaticCallNode(Scanner::kNoSourcePos, print_fn, one_arg); | 8596 new(Z) StaticCallNode(Scanner::kNoSourcePos, print_fn, one_arg); |
| 8599 return print_call; | 8597 return print_call; |
| 8600 } | 8598 } |
| 8601 | 8599 |
| 8602 | 8600 |
| 8603 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 8601 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
| 8604 TRACE_PARSER("ParseAwaitForStatement"); | 8602 TRACE_PARSER("ParseAwaitForStatement"); |
| 8605 ASSERT(IsAwaitKeyword()); | 8603 ASSERT(IsAwaitKeyword()); |
| 8606 const intptr_t await_for_pos = TokenPos(); | 8604 const intptr_t await_for_pos = TokenPos(); |
| (...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9536 // the chain of if/then/else handling all catch clauses. | 9534 // the chain of if/then/else handling all catch clauses. |
| 9537 async_code->Add(current); | 9535 async_code->Add(current); |
| 9538 current = async_code; | 9536 current = async_code; |
| 9539 } | 9537 } |
| 9540 return current; | 9538 return current; |
| 9541 } | 9539 } |
| 9542 | 9540 |
| 9543 | 9541 |
| 9544 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 9542 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
| 9545 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, | 9543 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, |
| 9546 Symbols::New(String::Handle(Z, | 9544 Symbols::NewFormatted("%s%d", |
| 9547 String::NewFormatted("%s%d", | 9545 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
| 9548 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 9546 last_used_try_index_ - 1)); |
| 9549 last_used_try_index_ - 1)))); | |
| 9550 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( | 9547 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( |
| 9551 Scanner::kNoSourcePos, | 9548 Scanner::kNoSourcePos, |
| 9552 async_saved_try_ctx_name, | 9549 async_saved_try_ctx_name, |
| 9553 Type::ZoneHandle(Z, Type::DynamicType())); | 9550 Type::ZoneHandle(Z, Type::DynamicType())); |
| 9554 ASSERT(async_temp_scope_ != NULL); | 9551 ASSERT(async_temp_scope_ != NULL); |
| 9555 async_temp_scope_->AddVariable(async_saved_try_ctx); | 9552 async_temp_scope_->AddVariable(async_saved_try_ctx); |
| 9556 ASSERT(saved_try_context != NULL); | 9553 ASSERT(saved_try_context != NULL); |
| 9557 current_block_->statements->Add(new(Z) StoreLocalNode( | 9554 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 9558 Scanner::kNoSourcePos, | 9555 Scanner::kNoSourcePos, |
| 9559 async_saved_try_ctx, | 9556 async_saved_try_ctx, |
| (...skipping 2380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11940 } | 11937 } |
| 11941 | 11938 |
| 11942 | 11939 |
| 11943 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { | 11940 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { |
| 11944 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11941 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
| 11945 return false; | 11942 return false; |
| 11946 } | 11943 } |
| 11947 // We don't want to allocate anything in the heap here since this code | 11944 // We don't want to allocate anything in the heap here since this code |
| 11948 // is called from the optimizing compiler in the background thread. Allocate | 11945 // is called from the optimizing compiler in the background thread. Allocate |
| 11949 // the key value in the zone instead. | 11946 // the key value in the zone instead. |
| 11950 const char* key = Z->PrintToString("%s_%" Pd "", | 11947 const char* key = Z->PrintToString("%s_%" Pd "", |
|
hausner
2015/09/04 17:35:29
I think you can use Symbol::NewFormatted here too.
srdjan
2015/09/29 23:08:25
Done.
| |
| 11951 String::Handle(Z, script_.url()).ToCString(), | 11948 String::Handle(Z, script_.url()).ToCString(), |
| 11952 token_pos); | 11949 token_pos); |
| 11953 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11950 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
| 11954 bool is_present = false; | 11951 bool is_present = false; |
| 11955 *value ^= constants.GetOrNull<const char *>(key, &is_present); | 11952 *value ^= constants.GetOrNull<const char *>(key, &is_present); |
| 11956 ASSERT(constants.Release().raw() == | 11953 ASSERT(constants.Release().raw() == |
| 11957 isolate()->object_store()->compile_time_constants()); | 11954 isolate()->object_store()->compile_time_constants()); |
| 11958 if (FLAG_compiler_stats && is_present) { | 11955 if (FLAG_compiler_stats && is_present) { |
| 11959 isolate_->compiler_stats()->num_const_cache_hits++; | 11956 isolate_->compiler_stats()->num_const_cache_hits++; |
| 11960 } | 11957 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12061 | 12058 |
| 12062 RawObject* Parser::EvaluateConstConstructorCall( | 12059 RawObject* Parser::EvaluateConstConstructorCall( |
| 12063 const Class& type_class, | 12060 const Class& type_class, |
| 12064 const TypeArguments& type_arguments, | 12061 const TypeArguments& type_arguments, |
| 12065 const Function& constructor, | 12062 const Function& constructor, |
| 12066 ArgumentListNode* arguments) { | 12063 ArgumentListNode* arguments) { |
| 12067 // Factories have one extra argument: the type arguments. | 12064 // Factories have one extra argument: the type arguments. |
| 12068 // Constructors have 2 extra arguments: rcvr and construction phase. | 12065 // Constructors have 2 extra arguments: rcvr and construction phase. |
| 12069 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; | 12066 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; |
| 12070 const int num_arguments = arguments->length() + kNumExtraArgs; | 12067 const int num_arguments = arguments->length() + kNumExtraArgs; |
| 12071 const Array& arg_values = Array::Handle(Z, Array::New(num_arguments)); | 12068 const Array& arg_values = |
| 12069 Array::Handle(Z, Array::New(num_arguments, Heap::kOld)); | |
| 12072 Instance& instance = Instance::Handle(Z); | 12070 Instance& instance = Instance::Handle(Z); |
| 12073 if (!constructor.IsFactory()) { | 12071 if (!constructor.IsFactory()) { |
| 12074 instance = Instance::New(type_class, Heap::kOld); | 12072 instance = Instance::New(type_class, Heap::kOld); |
| 12075 if (!type_arguments.IsNull()) { | 12073 if (!type_arguments.IsNull()) { |
| 12076 if (!type_arguments.IsInstantiated()) { | 12074 if (!type_arguments.IsInstantiated()) { |
| 12077 ReportError("type must be constant in const constructor"); | 12075 ReportError("type must be constant in const constructor"); |
| 12078 } | 12076 } |
| 12079 instance.SetTypeArguments( | 12077 instance.SetTypeArguments( |
| 12080 TypeArguments::Handle(Z, type_arguments.Canonicalize())); | 12078 TypeArguments::Handle(Z, type_arguments.Canonicalize())); |
| 12081 } | 12079 } |
| (...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13029 UnexpectedToken(); | 13027 UnexpectedToken(); |
| 13030 } | 13028 } |
| 13031 return primary; | 13029 return primary; |
| 13032 } | 13030 } |
| 13033 | 13031 |
| 13034 | 13032 |
| 13035 AstNode* Parser::ParseSymbolLiteral() { | 13033 AstNode* Parser::ParseSymbolLiteral() { |
| 13036 ASSERT(CurrentToken() == Token::kHASH); | 13034 ASSERT(CurrentToken() == Token::kHASH); |
| 13037 ConsumeToken(); | 13035 ConsumeToken(); |
| 13038 intptr_t symbol_pos = TokenPos(); | 13036 intptr_t symbol_pos = TokenPos(); |
| 13039 String& symbol = String::Handle(Z); | 13037 String& symbol = String::ZoneHandle(Z); |
| 13040 if (IsIdentifier()) { | 13038 if (IsIdentifier()) { |
| 13041 symbol = CurrentLiteral()->raw(); | 13039 symbol = CurrentLiteral()->raw(); |
| 13042 ConsumeToken(); | 13040 ConsumeToken(); |
| 13041 GrowableHandlePtrArray<const String> pieces(Z, 3); | |
| 13042 pieces.Add(symbol); | |
| 13043 while (CurrentToken() == Token::kPERIOD) { | 13043 while (CurrentToken() == Token::kPERIOD) { |
| 13044 symbol = String::Concat(symbol, Symbols::Dot()); | 13044 pieces.Add(Symbols::Dot()); |
| 13045 ConsumeToken(); | 13045 ConsumeToken(); |
| 13046 symbol = String::Concat(symbol, | 13046 pieces.Add(*ExpectIdentifier("identifier expected")); |
| 13047 *ExpectIdentifier("identifier expected")); | |
| 13048 } | 13047 } |
| 13048 symbol = Symbols::FromConcatAll(pieces); | |
| 13049 } else if (Token::CanBeOverloaded(CurrentToken())) { | 13049 } else if (Token::CanBeOverloaded(CurrentToken())) { |
| 13050 symbol = String::New(Token::Str(CurrentToken())); | 13050 symbol = Symbols::New(Token::Str(CurrentToken())); |
| 13051 ConsumeToken(); | 13051 ConsumeToken(); |
| 13052 } else { | 13052 } else { |
| 13053 ReportError("illegal symbol literal"); | 13053 ReportError("illegal symbol literal"); |
| 13054 } | 13054 } |
| 13055 ASSERT(symbol.IsSymbol()); | |
| 13055 | 13056 |
| 13056 Instance& symbol_instance = Instance::ZoneHandle(Z); | 13057 Instance& symbol_instance = Instance::ZoneHandle(Z); |
| 13057 if (GetCachedConstant(symbol_pos, &symbol_instance)) { | 13058 if (GetCachedConstant(symbol_pos, &symbol_instance)) { |
| 13058 return new(Z) LiteralNode(symbol_pos, symbol_instance); | 13059 return new(Z) LiteralNode(symbol_pos, symbol_instance); |
| 13059 } | 13060 } |
| 13060 | 13061 |
| 13061 // Call Symbol class constructor to create a symbol instance. | 13062 // Call Symbol class constructor to create a symbol instance. |
| 13062 const Class& symbol_class = Class::Handle(I->object_store()->symbol_class()); | 13063 const Class& symbol_class = Class::Handle(I->object_store()->symbol_class()); |
| 13063 ASSERT(!symbol_class.IsNull()); | 13064 ASSERT(!symbol_class.IsNull()); |
| 13064 ArgumentListNode* constr_args = new(Z) ArgumentListNode(symbol_pos); | 13065 ArgumentListNode* constr_args = new(Z) ArgumentListNode(symbol_pos); |
| 13065 constr_args->Add(new(Z) LiteralNode( | 13066 constr_args->Add(new(Z) LiteralNode(symbol_pos, symbol)); |
| 13066 symbol_pos, String::ZoneHandle(Z, Symbols::New(symbol)))); | |
| 13067 const Function& constr = Function::ZoneHandle(Z, | 13067 const Function& constr = Function::ZoneHandle(Z, |
| 13068 symbol_class.LookupConstructor(Symbols::SymbolCtor())); | 13068 symbol_class.LookupConstructor(Symbols::SymbolCtor())); |
| 13069 ASSERT(!constr.IsNull()); | 13069 ASSERT(!constr.IsNull()); |
| 13070 const Object& result = Object::Handle(Z, | 13070 const Object& result = Object::Handle(Z, |
| 13071 EvaluateConstConstructorCall(symbol_class, | 13071 EvaluateConstConstructorCall(symbol_class, |
| 13072 TypeArguments::Handle(Z), | 13072 TypeArguments::Handle(Z), |
| 13073 constr, | 13073 constr, |
| 13074 constr_args)); | 13074 constr_args)); |
| 13075 if (result.IsUnhandledException()) { | 13075 if (result.IsUnhandledException()) { |
| 13076 ReportErrors(Error::Cast(result), | 13076 ReportErrors(Error::Cast(result), |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13351 InvocationMirror::kMethod, | 13351 InvocationMirror::kMethod, |
| 13352 NULL); // No existing function. | 13352 NULL); // No existing function. |
| 13353 } else if (constructor.IsRedirectingFactory()) { | 13353 } else if (constructor.IsRedirectingFactory()) { |
| 13354 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); | 13354 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); |
| 13355 Type& redirect_type = Type::Handle(Z, constructor.RedirectionType()); | 13355 Type& redirect_type = Type::Handle(Z, constructor.RedirectionType()); |
| 13356 if (!redirect_type.IsMalformedOrMalbounded() && | 13356 if (!redirect_type.IsMalformedOrMalbounded() && |
| 13357 !redirect_type.IsInstantiated()) { | 13357 !redirect_type.IsInstantiated()) { |
| 13358 // The type arguments of the redirection type are instantiated from the | 13358 // The type arguments of the redirection type are instantiated from the |
| 13359 // type arguments of the parsed type of the 'new' or 'const' expression. | 13359 // type arguments of the parsed type of the 'new' or 'const' expression. |
| 13360 Error& error = Error::Handle(Z); | 13360 Error& error = Error::Handle(Z); |
| 13361 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); | 13361 redirect_type ^= redirect_type.InstantiateFrom( |
| 13362 type_arguments, | |
| 13363 &error, | |
| 13364 NULL, // trail | |
| 13365 Heap::kOld); | |
| 13362 if (!error.IsNull()) { | 13366 if (!error.IsNull()) { |
| 13363 redirect_type = ClassFinalizer::NewFinalizedMalformedType( | 13367 redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
| 13364 error, | 13368 error, |
| 13365 script_, | 13369 script_, |
| 13366 call_pos, | 13370 call_pos, |
| 13367 "redirecting factory type '%s' cannot be instantiated", | 13371 "redirecting factory type '%s' cannot be instantiated", |
| 13368 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); | 13372 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
| 13369 } | 13373 } |
| 13370 } | 13374 } |
| 13371 if (!redirect_type.HasResolvedTypeClass()) { | 13375 if (!redirect_type.HasResolvedTypeClass()) { |
| (...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14288 void Parser::SkipQualIdent() { | 14292 void Parser::SkipQualIdent() { |
| 14289 ASSERT(IsIdentifier()); | 14293 ASSERT(IsIdentifier()); |
| 14290 ConsumeToken(); | 14294 ConsumeToken(); |
| 14291 if (CurrentToken() == Token::kPERIOD) { | 14295 if (CurrentToken() == Token::kPERIOD) { |
| 14292 ConsumeToken(); // Consume the kPERIOD token. | 14296 ConsumeToken(); // Consume the kPERIOD token. |
| 14293 ExpectIdentifier("identifier expected after '.'"); | 14297 ExpectIdentifier("identifier expected after '.'"); |
| 14294 } | 14298 } |
| 14295 } | 14299 } |
| 14296 | 14300 |
| 14297 } // namespace dart | 14301 } // namespace dart |
| OLD | NEW |