| 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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 DECLARE_FLAG(bool, load_deferred_eagerly); | 59 DECLARE_FLAG(bool, load_deferred_eagerly); |
| 60 DECLARE_FLAG(bool, profile_vm); | 60 DECLARE_FLAG(bool, profile_vm); |
| 61 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 61 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 62 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 62 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 63 | 63 |
| 64 // Quick access to the current thread, isolate and zone. | 64 // Quick access to the current thread, isolate and zone. |
| 65 #define T (thread()) | 65 #define T (thread()) |
| 66 #define I (isolate()) | 66 #define I (isolate()) |
| 67 #define Z (zone()) | 67 #define Z (zone()) |
| 68 | 68 |
| 69 // Quick synthetic token position. |
| 70 #define ST(token_pos) Token::ToSynthetic(token_pos) |
| 69 | 71 |
| 70 #if defined(DEBUG) | 72 #if defined(DEBUG) |
| 71 class TraceParser : public ValueObject { | 73 class TraceParser : public ValueObject { |
| 72 public: | 74 public: |
| 73 TraceParser(intptr_t token_pos, | 75 TraceParser(intptr_t token_pos, |
| 74 const Script& script, | 76 const Script& script, |
| 75 intptr_t* trace_indent, | 77 intptr_t* trace_indent, |
| 76 const char* msg) { | 78 const char* msg) { |
| 77 indent_ = trace_indent; | 79 indent_ = trace_indent; |
| 78 if (FLAG_trace_parser) { | 80 if (FLAG_trace_parser) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 &found_captured_variables); | 234 &found_captured_variables); |
| 233 | 235 |
| 234 // Frame indices are relative to the frame pointer and are decreasing. | 236 // Frame indices are relative to the frame pointer and are decreasing. |
| 235 ASSERT(next_free_frame_index <= first_stack_local_index_); | 237 ASSERT(next_free_frame_index <= first_stack_local_index_); |
| 236 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; | 238 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; |
| 237 } | 239 } |
| 238 | 240 |
| 239 | 241 |
| 240 struct CatchParamDesc { | 242 struct CatchParamDesc { |
| 241 CatchParamDesc() | 243 CatchParamDesc() |
| 242 : token_pos(Scanner::kNoSourcePos), type(NULL), name(NULL), var(NULL) { } | 244 : token_pos(Token::kNoSourcePos), type(NULL), name(NULL), var(NULL) { } |
| 243 intptr_t token_pos; | 245 intptr_t token_pos; |
| 244 const AbstractType* type; | 246 const AbstractType* type; |
| 245 const String* name; | 247 const String* name; |
| 246 LocalVariable* var; | 248 LocalVariable* var; |
| 247 }; | 249 }; |
| 248 | 250 |
| 249 | 251 |
| 250 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 252 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
| 251 ASSERT(function().IsIrregexpFunction()); | 253 ASSERT(function().IsIrregexpFunction()); |
| 252 ASSERT(function().NumOptionalParameters() == 0); | 254 ASSERT(function().NumOptionalParameters() == 0); |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 i.ToCString()); | 514 i.ToCString()); |
| 513 } | 515 } |
| 514 } | 516 } |
| 515 return ri; | 517 return ri; |
| 516 } | 518 } |
| 517 | 519 |
| 518 | 520 |
| 519 struct ParamDesc { | 521 struct ParamDesc { |
| 520 ParamDesc() | 522 ParamDesc() |
| 521 : type(NULL), | 523 : type(NULL), |
| 522 name_pos(Scanner::kNoSourcePos), | 524 name_pos(Token::kNoSourcePos), |
| 523 name(NULL), | 525 name(NULL), |
| 524 default_value(NULL), | 526 default_value(NULL), |
| 525 metadata(NULL), | 527 metadata(NULL), |
| 526 var(NULL), | 528 var(NULL), |
| 527 is_final(false), | 529 is_final(false), |
| 528 is_field_initializer(false), | 530 is_field_initializer(false), |
| 529 has_explicit_type(false) { } | 531 has_explicit_type(false) { } |
| 530 const AbstractType* type; | 532 const AbstractType* type; |
| 531 intptr_t name_pos; | 533 intptr_t name_pos; |
| 532 const String* name; | 534 const String* name; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 void Clear() { | 619 void Clear() { |
| 618 has_abstract = false; | 620 has_abstract = false; |
| 619 has_external = false; | 621 has_external = false; |
| 620 has_final = false; | 622 has_final = false; |
| 621 has_const = false; | 623 has_const = false; |
| 622 has_static = false; | 624 has_static = false; |
| 623 has_var = false; | 625 has_var = false; |
| 624 has_factory = false; | 626 has_factory = false; |
| 625 has_operator = false; | 627 has_operator = false; |
| 626 has_native = false; | 628 has_native = false; |
| 627 metadata_pos = Scanner::kNoSourcePos; | 629 metadata_pos = Token::kNoSourcePos; |
| 628 operator_token = Token::kILLEGAL; | 630 operator_token = Token::kILLEGAL; |
| 629 type = NULL; | 631 type = NULL; |
| 630 name_pos = Scanner::kNoSourcePos; | 632 name_pos = Token::kNoSourcePos; |
| 631 name = NULL; | 633 name = NULL; |
| 632 redirect_name = NULL; | 634 redirect_name = NULL; |
| 633 dict_name = NULL; | 635 dict_name = NULL; |
| 634 params.Clear(); | 636 params.Clear(); |
| 635 kind = RawFunction::kRegularFunction; | 637 kind = RawFunction::kRegularFunction; |
| 636 field_ = NULL; | 638 field_ = NULL; |
| 637 } | 639 } |
| 638 | 640 |
| 639 bool IsConstructor() const { | 641 bool IsConstructor() const { |
| 640 return (kind == RawFunction::kConstructor) && !has_static; | 642 return (kind == RawFunction::kConstructor) && !has_static; |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 field_name = Field::NameFromGetter(field_name); | 1307 field_name = Field::NameFromGetter(field_name); |
| 1306 | 1308 |
| 1307 const Class& field_class = Class::Handle(Z, func.Owner()); | 1309 const Class& field_class = Class::Handle(Z, func.Owner()); |
| 1308 const Field& field = | 1310 const Field& field = |
| 1309 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | 1311 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
| 1310 ASSERT(!field.IsNull()); | 1312 ASSERT(!field.IsNull()); |
| 1311 | 1313 |
| 1312 LoadInstanceFieldNode* load_field = | 1314 LoadInstanceFieldNode* load_field = |
| 1313 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1315 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
| 1314 | 1316 |
| 1315 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, load_field); | 1317 ReturnNode* return_node = new ReturnNode(ST(ident_pos), load_field); |
| 1316 current_block_->statements->Add(return_node); | 1318 current_block_->statements->Add(return_node); |
| 1317 return CloseBlock(); | 1319 return CloseBlock(); |
| 1318 } | 1320 } |
| 1319 | 1321 |
| 1320 | 1322 |
| 1321 // Create AstNodes for an implicit instance setter method: | 1323 // Create AstNodes for an implicit instance setter method: |
| 1322 // LoadLocalNode 0 ('this') | 1324 // LoadLocalNode 0 ('this') |
| 1323 // LoadLocalNode 1 ('value') | 1325 // LoadLocalNode 1 ('value') |
| 1324 // SetInstanceField (field_name); | 1326 // SetInstanceField (field_name); |
| 1325 // ReturnNode (void); | 1327 // ReturnNode (void); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1349 | 1351 |
| 1350 LoadLocalNode* receiver = | 1352 LoadLocalNode* receiver = |
| 1351 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); | 1353 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); |
| 1352 LoadLocalNode* value = | 1354 LoadLocalNode* value = |
| 1353 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); | 1355 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); |
| 1354 | 1356 |
| 1355 EnsureExpressionTemp(); | 1357 EnsureExpressionTemp(); |
| 1356 StoreInstanceFieldNode* store_field = | 1358 StoreInstanceFieldNode* store_field = |
| 1357 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1359 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
| 1358 current_block_->statements->Add(store_field); | 1360 current_block_->statements->Add(store_field); |
| 1359 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 1361 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); |
| 1360 return CloseBlock(); | 1362 return CloseBlock(); |
| 1361 } | 1363 } |
| 1362 | 1364 |
| 1363 | 1365 |
| 1364 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { | 1366 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { |
| 1365 TRACE_PARSER("ParseConstructorClosure"); | 1367 TRACE_PARSER("ParseConstructorClosure"); |
| 1366 const intptr_t token_pos = func.token_pos(); | 1368 const intptr_t token_pos = func.token_pos(); |
| 1367 | 1369 |
| 1368 Function& constructor = Function::ZoneHandle(Z); | 1370 Function& constructor = Function::ZoneHandle(Z); |
| 1369 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); | 1371 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 return CloseBlock(); | 1479 return CloseBlock(); |
| 1478 } | 1480 } |
| 1479 | 1481 |
| 1480 | 1482 |
| 1481 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1483 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
| 1482 TRACE_PARSER("ParseMethodExtractor"); | 1484 TRACE_PARSER("ParseMethodExtractor"); |
| 1483 | 1485 |
| 1484 ParamList params; | 1486 ParamList params; |
| 1485 | 1487 |
| 1486 const intptr_t ident_pos = func.token_pos(); | 1488 const intptr_t ident_pos = func.token_pos(); |
| 1487 ASSERT(func.token_pos() == 0); | 1489 ASSERT(func.token_pos() == ClassifyingTokenPositions::kMethodExtractor); |
| 1488 ASSERT(current_class().raw() == func.Owner()); | 1490 ASSERT(current_class().raw() == func.Owner()); |
| 1489 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1491 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1490 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1492 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
| 1491 ASSERT(!func.HasOptionalParameters()); | 1493 ASSERT(!func.HasOptionalParameters()); |
| 1492 | 1494 |
| 1493 // Build local scope for function and populate with the formal parameters. | 1495 // Build local scope for function and populate with the formal parameters. |
| 1494 OpenFunctionBlock(func); | 1496 OpenFunctionBlock(func); |
| 1495 AddFormalParamsToScope(¶ms, current_block_->scope); | 1497 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1496 | 1498 |
| 1497 // Receiver is local 0. | 1499 // Receiver is local 0. |
| 1498 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1500 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1499 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1501 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1500 | 1502 |
| 1501 ClosureNode* closure = new ClosureNode( | 1503 ClosureNode* closure = new ClosureNode( |
| 1502 ident_pos, | 1504 ident_pos, |
| 1503 Function::ZoneHandle(Z, func.extracted_method_closure()), | 1505 Function::ZoneHandle(Z, func.extracted_method_closure()), |
| 1504 load_receiver, | 1506 load_receiver, |
| 1505 NULL); | 1507 NULL); |
| 1506 | 1508 |
| 1507 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure); | 1509 ReturnNode* return_node = new ReturnNode(ident_pos, closure); |
| 1508 current_block_->statements->Add(return_node); | 1510 current_block_->statements->Add(return_node); |
| 1509 return CloseBlock(); | 1511 return CloseBlock(); |
| 1510 } | 1512 } |
| 1511 | 1513 |
| 1512 | 1514 |
| 1513 void Parser::BuildDispatcherScope(const Function& func, | 1515 void Parser::BuildDispatcherScope(const Function& func, |
| 1514 const ArgumentsDescriptor& desc) { | 1516 const ArgumentsDescriptor& desc) { |
| 1515 ParamList params; | 1517 ParamList params; |
| 1516 // Receiver first. | 1518 // Receiver first. |
| 1517 intptr_t token_pos = func.token_pos(); | 1519 intptr_t token_pos = func.token_pos(); |
| (...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2872 } | 2874 } |
| 2873 | 2875 |
| 2874 | 2876 |
| 2875 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 2877 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 2876 ASSERT(func.IsGenerativeConstructor()); | 2878 ASSERT(func.IsGenerativeConstructor()); |
| 2877 ASSERT(func.Owner() == current_class().raw()); | 2879 ASSERT(func.Owner() == current_class().raw()); |
| 2878 const intptr_t ctor_pos = TokenPos(); | 2880 const intptr_t ctor_pos = TokenPos(); |
| 2879 OpenFunctionBlock(func); | 2881 OpenFunctionBlock(func); |
| 2880 | 2882 |
| 2881 LocalVariable* receiver = new LocalVariable( | 2883 LocalVariable* receiver = new LocalVariable( |
| 2882 Scanner::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); | 2884 Token::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); |
| 2883 current_block_->scope->InsertParameterAt(0, receiver); | 2885 current_block_->scope->InsertParameterAt(0, receiver); |
| 2884 | 2886 |
| 2885 // Parse expressions of instance fields that have an explicit | 2887 // Parse expressions of instance fields that have an explicit |
| 2886 // initializer expression. | 2888 // initializer expression. |
| 2887 // The receiver must not be visible to field initializer expressions. | 2889 // The receiver must not be visible to field initializer expressions. |
| 2888 receiver->set_invisible(true); | 2890 receiver->set_invisible(true); |
| 2889 GrowableArray<Field*> initialized_fields; | 2891 GrowableArray<Field*> initialized_fields; |
| 2890 ParseInitializedInstanceFields( | 2892 ParseInitializedInstanceFields( |
| 2891 current_class(), receiver, &initialized_fields); | 2893 current_class(), receiver, &initialized_fields); |
| 2892 receiver->set_invisible(false); | 2894 receiver->set_invisible(false); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2915 "forwarding to a super class constructor with optional " | 2917 "forwarding to a super class constructor with optional " |
| 2916 "parameters; add a constructor without optional parameters " | 2918 "parameters; add a constructor without optional parameters " |
| 2917 "to class '%s' that redirects to the constructor with " | 2919 "to class '%s' that redirects to the constructor with " |
| 2918 "optional parameters and invoke it via super from a " | 2920 "optional parameters and invoke it via super from a " |
| 2919 "constructor of the class extending the mixin application", | 2921 "constructor of the class extending the mixin application", |
| 2920 String::Handle(Z, super_class.Name()).ToCString()); | 2922 String::Handle(Z, super_class.Name()).ToCString()); |
| 2921 } | 2923 } |
| 2922 | 2924 |
| 2923 // Prepare user-defined arguments to be forwarded to super call. | 2925 // Prepare user-defined arguments to be forwarded to super call. |
| 2924 // The first user-defined argument is at position 1. | 2926 // The first user-defined argument is at position 1. |
| 2925 forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos); | 2927 forwarding_args = new ArgumentListNode(ST(ctor_pos)); |
| 2926 for (int i = 1; i < func.NumParameters(); i++) { | 2928 for (int i = 1; i < func.NumParameters(); i++) { |
| 2927 LocalVariable* param = new LocalVariable( | 2929 LocalVariable* param = new LocalVariable( |
| 2928 Scanner::kNoSourcePos, | 2930 Token::kNoSourcePos, |
| 2929 String::ZoneHandle(Z, func.ParameterNameAt(i)), | 2931 String::ZoneHandle(Z, func.ParameterNameAt(i)), |
| 2930 Object::dynamic_type()); | 2932 Object::dynamic_type()); |
| 2931 current_block_->scope->InsertParameterAt(i, param); | 2933 current_block_->scope->InsertParameterAt(i, param); |
| 2932 forwarding_args->Add(new LoadLocalNode(Scanner::kNoSourcePos, param)); | 2934 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); |
| 2933 } | 2935 } |
| 2934 } | 2936 } |
| 2935 | 2937 |
| 2936 AstNode* super_call = GenerateSuperConstructorCall( | 2938 AstNode* super_call = GenerateSuperConstructorCall( |
| 2937 current_class(), | 2939 current_class(), |
| 2938 Scanner::kNoSourcePos, | 2940 ctor_pos, |
| 2939 receiver, | 2941 receiver, |
| 2940 forwarding_args); | 2942 forwarding_args); |
| 2941 if (super_call != NULL) { | 2943 if (super_call != NULL) { |
| 2942 current_block_->statements->Add(super_call); | 2944 current_block_->statements->Add(super_call); |
| 2943 } | 2945 } |
| 2944 CheckFieldsInitialized(current_class()); | 2946 CheckFieldsInitialized(current_class()); |
| 2945 | 2947 |
| 2946 // Empty constructor body. | 2948 // Empty constructor body. |
| 2947 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 2949 current_block_->statements->Add(new ReturnNode(ST(ctor_pos))); |
| 2948 SequenceNode* statements = CloseBlock(); | 2950 SequenceNode* statements = CloseBlock(); |
| 2949 return statements; | 2951 return statements; |
| 2950 } | 2952 } |
| 2951 | 2953 |
| 2952 | 2954 |
| 2953 void Parser::CheckRecursiveInvocation() { | 2955 void Parser::CheckRecursiveInvocation() { |
| 2954 const GrowableObjectArray& pending_functions = | 2956 const GrowableObjectArray& pending_functions = |
| 2955 GrowableObjectArray::Handle(Z, T->pending_functions()); | 2957 GrowableObjectArray::Handle(Z, T->pending_functions()); |
| 2956 for (int i = 0; i < pending_functions.Length(); i++) { | 2958 for (int i = 0; i < pending_functions.Length(); i++) { |
| 2957 if (pending_functions.At(i) == current_function().raw()) { | 2959 if (pending_functions.At(i) == current_function().raw()) { |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3314 func.set_is_debuggable(false); | 3316 func.set_is_debuggable(false); |
| 3315 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos()); | 3317 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos()); |
| 3316 } else if (func.IsAsyncGenClosure()) { | 3318 } else if (func.IsAsyncGenClosure()) { |
| 3317 // The closure containing the body of an async* function is debuggable. | 3319 // The closure containing the body of an async* function is debuggable. |
| 3318 ASSERT(func.is_debuggable()); | 3320 ASSERT(func.is_debuggable()); |
| 3319 OpenAsyncGeneratorClosure(); | 3321 OpenAsyncGeneratorClosure(); |
| 3320 } | 3322 } |
| 3321 | 3323 |
| 3322 BoolScope allow_await(&this->await_is_keyword_, | 3324 BoolScope allow_await(&this->await_is_keyword_, |
| 3323 func.IsAsyncOrGenerator() || func.is_generated_body()); | 3325 func.IsAsyncOrGenerator() || func.is_generated_body()); |
| 3324 intptr_t end_token_pos = Scanner::kNoSourcePos; | 3326 intptr_t end_token_pos = Token::kNoSourcePos; |
| 3325 if (CurrentToken() == Token::kLBRACE) { | 3327 if (CurrentToken() == Token::kLBRACE) { |
| 3326 ConsumeToken(); | 3328 ConsumeToken(); |
| 3327 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { | 3329 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { |
| 3328 const Class& owner = Class::Handle(Z, func.Owner()); | 3330 const Class& owner = Class::Handle(Z, func.Owner()); |
| 3329 if (!owner.IsObjectClass()) { | 3331 if (!owner.IsObjectClass()) { |
| 3330 AddEqualityNullCheck(); | 3332 AddEqualityNullCheck(); |
| 3331 } | 3333 } |
| 3332 } | 3334 } |
| 3333 ParseStatementSequence(); | 3335 ParseStatementSequence(); |
| 3334 end_token_pos = TokenPos(); | 3336 end_token_pos = TokenPos(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3407 current_block_->statements->Add(body); | 3409 current_block_->statements->Add(body); |
| 3408 innermost_function_ = saved_innermost_function.raw(); | 3410 innermost_function_ = saved_innermost_function.raw(); |
| 3409 last_used_try_index_ = saved_try_index; | 3411 last_used_try_index_ = saved_try_index; |
| 3410 async_temp_scope_ = saved_async_temp_scope; | 3412 async_temp_scope_ = saved_async_temp_scope; |
| 3411 return CloseBlock(); | 3413 return CloseBlock(); |
| 3412 } | 3414 } |
| 3413 | 3415 |
| 3414 | 3416 |
| 3415 void Parser::AddEqualityNullCheck() { | 3417 void Parser::AddEqualityNullCheck() { |
| 3416 AstNode* argument = | 3418 AstNode* argument = |
| 3417 new LoadLocalNode(Scanner::kNoSourcePos, | 3419 new LoadLocalNode(Token::kNoSourcePos, |
| 3418 current_block_->scope->parent()->VariableAt(1)); | 3420 current_block_->scope->parent()->VariableAt(1)); |
| 3419 LiteralNode* null_operand = | 3421 LiteralNode* null_operand = |
| 3420 new LiteralNode(Scanner::kNoSourcePos, Instance::ZoneHandle(Z)); | 3422 new LiteralNode(Token::kNoSourcePos, Instance::ZoneHandle(Z)); |
| 3421 ComparisonNode* check_arg = | 3423 ComparisonNode* check_arg = |
| 3422 new ComparisonNode(Scanner::kNoSourcePos, | 3424 new ComparisonNode(Token::kNoSourcePos, |
| 3423 Token::kEQ_STRICT, | 3425 Token::kEQ_STRICT, |
| 3424 argument, | 3426 argument, |
| 3425 null_operand); | 3427 null_operand); |
| 3426 ComparisonNode* result = | 3428 ComparisonNode* result = |
| 3427 new ComparisonNode(Scanner::kNoSourcePos, | 3429 new ComparisonNode(Token::kNoSourcePos, |
| 3428 Token::kEQ_STRICT, | 3430 Token::kEQ_STRICT, |
| 3429 LoadReceiver(Scanner::kNoSourcePos), | 3431 LoadReceiver(Token::kNoSourcePos), |
| 3430 null_operand); | 3432 null_operand); |
| 3431 SequenceNode* arg_is_null = new SequenceNode(Scanner::kNoSourcePos, | 3433 SequenceNode* arg_is_null = new SequenceNode(Token::kNoSourcePos, |
| 3432 current_block_->scope); | 3434 current_block_->scope); |
| 3433 arg_is_null->Add(new ReturnNode(Scanner::kNoSourcePos, result)); | 3435 arg_is_null->Add(new ReturnNode(Token::kNoSourcePos, result)); |
| 3434 IfNode* if_arg_null = new IfNode(Scanner::kNoSourcePos, | 3436 IfNode* if_arg_null = new IfNode(Token::kNoSourcePos, |
| 3435 check_arg, | 3437 check_arg, |
| 3436 arg_is_null, | 3438 arg_is_null, |
| 3437 NULL); | 3439 NULL); |
| 3438 current_block_->statements->Add(if_arg_null); | 3440 current_block_->statements->Add(if_arg_null); |
| 3439 } | 3441 } |
| 3440 | 3442 |
| 3441 | 3443 |
| 3442 void Parser::SkipIf(Token::Kind token) { | 3444 void Parser::SkipIf(Token::Kind token) { |
| 3443 if (CurrentToken() == token) { | 3445 if (CurrentToken() == token) { |
| 3444 ConsumeToken(); | 3446 ConsumeToken(); |
| (...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5071 } else if (token_kind_ == Token::kSHR) { | 5073 } else if (token_kind_ == Token::kSHR) { |
| 5072 token_kind_ = Token::kGT; | 5074 token_kind_ = Token::kGT; |
| 5073 } else { | 5075 } else { |
| 5074 UNREACHABLE(); | 5076 UNREACHABLE(); |
| 5075 } | 5077 } |
| 5076 } | 5078 } |
| 5077 | 5079 |
| 5078 | 5080 |
| 5079 intptr_t Parser::SkipMetadata() { | 5081 intptr_t Parser::SkipMetadata() { |
| 5080 if (CurrentToken() != Token::kAT) { | 5082 if (CurrentToken() != Token::kAT) { |
| 5081 return Scanner::kNoSourcePos; | 5083 return Token::kNoSourcePos; |
| 5082 } | 5084 } |
| 5083 intptr_t metadata_pos = TokenPos(); | 5085 intptr_t metadata_pos = TokenPos(); |
| 5084 while (CurrentToken() == Token::kAT) { | 5086 while (CurrentToken() == Token::kAT) { |
| 5085 ConsumeToken(); | 5087 ConsumeToken(); |
| 5086 ExpectIdentifier("identifier expected"); | 5088 ExpectIdentifier("identifier expected"); |
| 5087 if (CurrentToken() == Token::kPERIOD) { | 5089 if (CurrentToken() == Token::kPERIOD) { |
| 5088 ConsumeToken(); | 5090 ConsumeToken(); |
| 5089 ExpectIdentifier("identifier expected"); | 5091 ExpectIdentifier("identifier expected"); |
| 5090 if (CurrentToken() == Token::kPERIOD) { | 5092 if (CurrentToken() == Token::kPERIOD) { |
| 5091 ConsumeToken(); | 5093 ConsumeToken(); |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5830 if (url.Length() == 0) { | 5832 if (url.Length() == 0) { |
| 5831 ReportError("library url expected"); | 5833 ReportError("library url expected"); |
| 5832 } | 5834 } |
| 5833 bool is_deferred_import = false; | 5835 bool is_deferred_import = false; |
| 5834 if (is_import && (IsSymbol(Symbols::Deferred()))) { | 5836 if (is_import && (IsSymbol(Symbols::Deferred()))) { |
| 5835 is_deferred_import = true; | 5837 is_deferred_import = true; |
| 5836 ConsumeToken(); | 5838 ConsumeToken(); |
| 5837 CheckToken(Token::kAS, "'as' expected"); | 5839 CheckToken(Token::kAS, "'as' expected"); |
| 5838 } | 5840 } |
| 5839 String& prefix = String::Handle(Z); | 5841 String& prefix = String::Handle(Z); |
| 5840 intptr_t prefix_pos = Scanner::kNoSourcePos; | 5842 intptr_t prefix_pos = Token::kNoSourcePos; |
| 5841 if (is_import && (CurrentToken() == Token::kAS)) { | 5843 if (is_import && (CurrentToken() == Token::kAS)) { |
| 5842 ConsumeToken(); | 5844 ConsumeToken(); |
| 5843 prefix_pos = TokenPos(); | 5845 prefix_pos = TokenPos(); |
| 5844 prefix = ExpectIdentifier("prefix identifier expected")->raw(); | 5846 prefix = ExpectIdentifier("prefix identifier expected")->raw(); |
| 5845 } | 5847 } |
| 5846 | 5848 |
| 5847 Array& show_names = Array::Handle(Z); | 5849 Array& show_names = Array::Handle(Z); |
| 5848 Array& hide_names = Array::Handle(Z); | 5850 Array& hide_names = Array::Handle(Z); |
| 5849 if (is_deferred_import || | 5851 if (is_deferred_import || |
| 5850 IsSymbol(Symbols::Show()) || | 5852 IsSymbol(Symbols::Show()) || |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6186 // The try-block (closure body code) has been parsed. We are now | 6188 // The try-block (closure body code) has been parsed. We are now |
| 6187 // generating the code for the catch block. | 6189 // generating the code for the catch block. |
| 6188 LocalScope* try_scope = current_block_->scope; | 6190 LocalScope* try_scope = current_block_->scope; |
| 6189 try_stack_->enter_catch(); | 6191 try_stack_->enter_catch(); |
| 6190 OpenBlock(); // Catch handler list. | 6192 OpenBlock(); // Catch handler list. |
| 6191 OpenBlock(); // Catch block. | 6193 OpenBlock(); // Catch block. |
| 6192 | 6194 |
| 6193 // Add the exception and stack trace parameters to the scope. | 6195 // Add the exception and stack trace parameters to the scope. |
| 6194 CatchParamDesc exception_param; | 6196 CatchParamDesc exception_param; |
| 6195 CatchParamDesc stack_trace_param; | 6197 CatchParamDesc stack_trace_param; |
| 6196 exception_param.token_pos = Scanner::kNoSourcePos; | 6198 exception_param.token_pos = Token::kNoSourcePos; |
| 6197 exception_param.type = &Object::dynamic_type(); | 6199 exception_param.type = &Object::dynamic_type(); |
| 6198 exception_param.name = &Symbols::ExceptionParameter(); | 6200 exception_param.name = &Symbols::ExceptionParameter(); |
| 6199 stack_trace_param.token_pos = Scanner::kNoSourcePos; | 6201 stack_trace_param.token_pos = Token::kNoSourcePos; |
| 6200 stack_trace_param.type = &Object::dynamic_type(); | 6202 stack_trace_param.type = &Object::dynamic_type(); |
| 6201 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6203 stack_trace_param.name = &Symbols::StackTraceParameter(); |
| 6202 | 6204 |
| 6203 AddCatchParamsToScope( | 6205 AddCatchParamsToScope( |
| 6204 &exception_param, &stack_trace_param, current_block_->scope); | 6206 &exception_param, &stack_trace_param, current_block_->scope); |
| 6205 | 6207 |
| 6206 // Generate code to save the exception object and stack trace | 6208 // Generate code to save the exception object and stack trace |
| 6207 // in local variables. | 6209 // in local variables. |
| 6208 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6210 LocalVariable* context_var = try_scope->LocalLookupVariable( |
| 6209 Symbols::SavedTryContextVar()); | 6211 Symbols::SavedTryContextVar()); |
| 6210 ASSERT(context_var != NULL); | 6212 ASSERT(context_var != NULL); |
| 6211 | 6213 |
| 6212 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6214 LocalVariable* exception_var = try_scope->LocalLookupVariable( |
| 6213 Symbols::ExceptionVar()); | 6215 Symbols::ExceptionVar()); |
| 6214 ASSERT(exception_var != NULL); | 6216 ASSERT(exception_var != NULL); |
| 6215 if (exception_param.var != NULL) { | 6217 if (exception_param.var != NULL) { |
| 6216 // Generate code to load the exception object (:exception_var) into | 6218 // Generate code to load the exception object (:exception_var) into |
| 6217 // the exception variable specified in this block. | 6219 // the exception variable specified in this block. |
| 6218 current_block_->statements->Add(new(Z) StoreLocalNode( | 6220 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6219 Scanner::kNoSourcePos, | 6221 Token::kNoSourcePos, |
| 6220 exception_param.var, | 6222 exception_param.var, |
| 6221 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); | 6223 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); |
| 6222 } | 6224 } |
| 6223 | 6225 |
| 6224 LocalVariable* stack_trace_var = | 6226 LocalVariable* stack_trace_var = |
| 6225 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6227 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 6226 ASSERT(stack_trace_var != NULL); | 6228 ASSERT(stack_trace_var != NULL); |
| 6227 if (stack_trace_param.var != NULL) { | 6229 if (stack_trace_param.var != NULL) { |
| 6228 // A stack trace variable is specified in this block, so generate code | 6230 // A stack trace variable is specified in this block, so generate code |
| 6229 // to load the stack trace object (:stack_trace_var) into the stack | 6231 // to load the stack trace object (:stack_trace_var) into the stack |
| 6230 // trace variable specified in this block. | 6232 // trace variable specified in this block. |
| 6231 current_block_->statements->Add(new(Z) StoreLocalNode( | 6233 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6232 Scanner::kNoSourcePos, | 6234 Token::kNoSourcePos, |
| 6233 stack_trace_param.var, | 6235 stack_trace_param.var, |
| 6234 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 6236 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); |
| 6235 } | 6237 } |
| 6236 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6238 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( |
| 6237 Symbols::SavedExceptionVar()); | 6239 Symbols::SavedExceptionVar()); |
| 6238 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6240 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( |
| 6239 Symbols::SavedStackTraceVar()); | 6241 Symbols::SavedStackTraceVar()); |
| 6240 SaveExceptionAndStacktrace(current_block_->statements, | 6242 SaveExceptionAndStacktrace(current_block_->statements, |
| 6241 exception_var, | 6243 exception_var, |
| 6242 stack_trace_var, | 6244 stack_trace_var, |
| 6243 saved_exception_var, | 6245 saved_exception_var, |
| 6244 saved_stack_trace_var); | 6246 saved_stack_trace_var); |
| 6245 | 6247 |
| 6246 // Catch block: add the error to the stream. | 6248 // Catch block: add the error to the stream. |
| 6247 // :controller.AddError(:exception, :stack_trace); | 6249 // :controller.AddError(:exception, :stack_trace); |
| 6248 // return; // The finally block will close the stream. | 6250 // return; // The finally block will close the stream. |
| 6249 LocalVariable* controller = | 6251 LocalVariable* controller = |
| 6250 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6252 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
| 6251 ASSERT(controller != NULL); | 6253 ASSERT(controller != NULL); |
| 6252 ArgumentListNode* args = | 6254 ArgumentListNode* args = |
| 6253 new(Z) ArgumentListNode(Scanner::kNoSourcePos); | 6255 new(Z) ArgumentListNode(Token::kNoSourcePos); |
| 6254 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); | 6256 args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var)); |
| 6255 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var)); | 6257 args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var)); |
| 6256 current_block_->statements->Add( | 6258 current_block_->statements->Add( |
| 6257 new(Z) InstanceCallNode(try_end_pos, | 6259 new(Z) InstanceCallNode(try_end_pos, |
| 6258 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller), | 6260 new(Z) LoadLocalNode(Token::kNoSourcePos, controller), |
| 6259 Symbols::AddError(), | 6261 Symbols::AddError(), |
| 6260 args)); | 6262 args)); |
| 6261 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos); | 6263 ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos); |
| 6262 AddNodeForFinallyInlining(return_node); | 6264 AddNodeForFinallyInlining(return_node); |
| 6263 current_block_->statements->Add(return_node); | 6265 current_block_->statements->Add(return_node); |
| 6264 AstNode* catch_block = CloseBlock(); | 6266 AstNode* catch_block = CloseBlock(); |
| 6265 current_block_->statements->Add(catch_block); | 6267 current_block_->statements->Add(catch_block); |
| 6266 SequenceNode* catch_handler_list = CloseBlock(); | 6268 SequenceNode* catch_handler_list = CloseBlock(); |
| 6267 | 6269 |
| 6268 TryStack* try_statement = PopTry(); | 6270 TryStack* try_statement = PopTry(); |
| 6269 ASSERT(try_stack_ == NULL); // We popped the outermost try block. | 6271 ASSERT(try_stack_ == NULL); // We popped the outermost try block. |
| 6270 | 6272 |
| 6271 // Finally block: closing the stream and returning. Instead of simply | 6273 // Finally block: closing the stream and returning. Instead of simply |
| 6272 // returning, create an await state and suspend. There may be outstanding | 6274 // returning, create an await state and suspend. There may be outstanding |
| 6273 // calls to schedule the generator body. This suspension ensures that we | 6275 // calls to schedule the generator body. This suspension ensures that we |
| 6274 // do not repeat any code of the generator body. | 6276 // do not repeat any code of the generator body. |
| 6275 // :controller.close(); | 6277 // :controller.close(); |
| 6276 // suspend; | 6278 // suspend; |
| 6277 // We need to inline this code in all recorded exit points. | 6279 // We need to inline this code in all recorded exit points. |
| 6278 intptr_t node_index = 0; | 6280 intptr_t node_index = 0; |
| 6279 SequenceNode* finally_clause = NULL; | 6281 SequenceNode* finally_clause = NULL; |
| 6280 if (try_stack_ != NULL) { | 6282 if (try_stack_ != NULL) { |
| 6281 try_stack_->enter_finally(); | 6283 try_stack_->enter_finally(); |
| 6282 } | 6284 } |
| 6283 do { | 6285 do { |
| 6284 OpenBlock(); | 6286 OpenBlock(); |
| 6285 ArgumentListNode* no_args = | 6287 ArgumentListNode* no_args = |
| 6286 new(Z) ArgumentListNode(Scanner::kNoSourcePos); | 6288 new(Z) ArgumentListNode(Token::kNoSourcePos); |
| 6287 current_block_->statements->Add( | 6289 current_block_->statements->Add( |
| 6288 new(Z) InstanceCallNode(try_end_pos, | 6290 new(Z) InstanceCallNode(try_end_pos, |
| 6289 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller), | 6291 new(Z) LoadLocalNode(Token::kNoSourcePos, controller), |
| 6290 Symbols::Close(), | 6292 Symbols::Close(), |
| 6291 no_args)); | 6293 no_args)); |
| 6292 | 6294 |
| 6293 // Suspend after the close. | 6295 // Suspend after the close. |
| 6294 AwaitMarkerNode* await_marker = | 6296 AwaitMarkerNode* await_marker = |
| 6295 new(Z) AwaitMarkerNode(async_temp_scope_, | 6297 new(Z) AwaitMarkerNode(async_temp_scope_, |
| 6296 current_block_->scope, | 6298 current_block_->scope, |
| 6297 Scanner::kNoSourcePos); | 6299 Token::kNoSourcePos); |
| 6298 current_block_->statements->Add(await_marker); | 6300 current_block_->statements->Add(await_marker); |
| 6299 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); | 6301 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); |
| 6300 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); | 6302 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); |
| 6301 current_block_->statements->Add(continuation_ret); | 6303 current_block_->statements->Add(continuation_ret); |
| 6302 | 6304 |
| 6303 finally_clause = CloseBlock(); | 6305 finally_clause = CloseBlock(); |
| 6304 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 6306 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
| 6305 if (node_to_inline != NULL) { | 6307 if (node_to_inline != NULL) { |
| 6306 InlinedFinallyNode* node = | 6308 InlinedFinallyNode* node = |
| 6307 new(Z) InlinedFinallyNode(try_end_pos, | 6309 new(Z) InlinedFinallyNode(try_end_pos, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 6318 if (try_stack_ != NULL) { | 6320 if (try_stack_ != NULL) { |
| 6319 try_stack_->exit_finally(); | 6321 try_stack_->exit_finally(); |
| 6320 } | 6322 } |
| 6321 | 6323 |
| 6322 const GrowableObjectArray& handler_types = | 6324 const GrowableObjectArray& handler_types = |
| 6323 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6325 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 6324 // Catch block handles all exceptions. | 6326 // Catch block handles all exceptions. |
| 6325 handler_types.Add(Object::dynamic_type()); | 6327 handler_types.Add(Object::dynamic_type()); |
| 6326 | 6328 |
| 6327 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 6329 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( |
| 6328 Scanner::kNoSourcePos, | 6330 Token::kNoSourcePos, |
| 6329 catch_handler_list, | 6331 catch_handler_list, |
| 6330 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6332 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 6331 context_var, | 6333 context_var, |
| 6332 exception_var, | 6334 exception_var, |
| 6333 stack_trace_var, | 6335 stack_trace_var, |
| 6334 saved_exception_var, | 6336 saved_exception_var, |
| 6335 saved_stack_trace_var, | 6337 saved_stack_trace_var, |
| 6336 AllocateTryIndex(), | 6338 AllocateTryIndex(), |
| 6337 true); | 6339 true); |
| 6338 | 6340 |
| 6339 const intptr_t try_index = try_statement->try_index(); | 6341 const intptr_t try_index = try_statement->try_index(); |
| 6340 | 6342 |
| 6341 AstNode* try_catch_node = | 6343 AstNode* try_catch_node = |
| 6342 new(Z) TryCatchNode(Scanner::kNoSourcePos, | 6344 new(Z) TryCatchNode(Token::kNoSourcePos, |
| 6343 body, | 6345 body, |
| 6344 context_var, | 6346 context_var, |
| 6345 catch_clause, | 6347 catch_clause, |
| 6346 finally_clause, | 6348 finally_clause, |
| 6347 try_index, | 6349 try_index, |
| 6348 finally_clause); | 6350 finally_clause); |
| 6349 current_block_->statements->Add(try_catch_node); | 6351 current_block_->statements->Add(try_catch_node); |
| 6350 return CloseBlock(); | 6352 return CloseBlock(); |
| 6351 } | 6353 } |
| 6352 | 6354 |
| 6353 | 6355 |
| 6354 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { | 6356 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { |
| 6355 // This is the outermost try-catch of the function. | 6357 // This is the outermost try-catch of the function. |
| 6356 ASSERT(try_stack_ != NULL); | 6358 ASSERT(try_stack_ != NULL); |
| 6357 ASSERT(try_stack_->outer_try() == NULL); | 6359 ASSERT(try_stack_->outer_try() == NULL); |
| 6358 ASSERT(innermost_function().IsAsyncClosure()); | 6360 ASSERT(innermost_function().IsAsyncClosure()); |
| 6359 LocalScope* try_scope = current_block_->scope; | 6361 LocalScope* try_scope = current_block_->scope; |
| 6360 | 6362 |
| 6361 try_stack_->enter_catch(); | 6363 try_stack_->enter_catch(); |
| 6362 | 6364 |
| 6363 OpenBlock(); // Catch handler list. | 6365 OpenBlock(); // Catch handler list. |
| 6364 OpenBlock(); // Catch block. | 6366 OpenBlock(); // Catch block. |
| 6365 CatchParamDesc exception_param; | 6367 CatchParamDesc exception_param; |
| 6366 CatchParamDesc stack_trace_param; | 6368 CatchParamDesc stack_trace_param; |
| 6367 exception_param.token_pos = Scanner::kNoSourcePos; | 6369 exception_param.token_pos = Token::kNoSourcePos; |
| 6368 exception_param.type = &Object::dynamic_type(); | 6370 exception_param.type = &Object::dynamic_type(); |
| 6369 exception_param.name = &Symbols::ExceptionParameter(); | 6371 exception_param.name = &Symbols::ExceptionParameter(); |
| 6370 stack_trace_param.token_pos = Scanner::kNoSourcePos; | 6372 stack_trace_param.token_pos = Token::kNoSourcePos; |
| 6371 stack_trace_param.type = &Object::dynamic_type(); | 6373 stack_trace_param.type = &Object::dynamic_type(); |
| 6372 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6374 stack_trace_param.name = &Symbols::StackTraceParameter(); |
| 6373 | 6375 |
| 6374 AddCatchParamsToScope( | 6376 AddCatchParamsToScope( |
| 6375 &exception_param, &stack_trace_param, current_block_->scope); | 6377 &exception_param, &stack_trace_param, current_block_->scope); |
| 6376 | 6378 |
| 6377 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6379 LocalVariable* context_var = try_scope->LocalLookupVariable( |
| 6378 Symbols::SavedTryContextVar()); | 6380 Symbols::SavedTryContextVar()); |
| 6379 ASSERT(context_var != NULL); | 6381 ASSERT(context_var != NULL); |
| 6380 | 6382 |
| 6381 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6383 LocalVariable* exception_var = try_scope->LocalLookupVariable( |
| 6382 Symbols::ExceptionVar()); | 6384 Symbols::ExceptionVar()); |
| 6383 if (exception_param.var != NULL) { | 6385 if (exception_param.var != NULL) { |
| 6384 // Generate code to load the exception object (:exception_var) into | 6386 // Generate code to load the exception object (:exception_var) into |
| 6385 // the exception variable specified in this block. | 6387 // the exception variable specified in this block. |
| 6386 ASSERT(exception_var != NULL); | 6388 ASSERT(exception_var != NULL); |
| 6387 current_block_->statements->Add(new(Z) StoreLocalNode( | 6389 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6388 Scanner::kNoSourcePos, | 6390 Token::kNoSourcePos, |
| 6389 exception_param.var, | 6391 exception_param.var, |
| 6390 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); | 6392 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); |
| 6391 } | 6393 } |
| 6392 | 6394 |
| 6393 LocalVariable* stack_trace_var = | 6395 LocalVariable* stack_trace_var = |
| 6394 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6396 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 6395 if (stack_trace_param.var != NULL) { | 6397 if (stack_trace_param.var != NULL) { |
| 6396 // A stack trace variable is specified in this block, so generate code | 6398 // A stack trace variable is specified in this block, so generate code |
| 6397 // to load the stack trace object (:stack_trace_var) into the stack | 6399 // to load the stack trace object (:stack_trace_var) into the stack |
| 6398 // trace variable specified in this block. | 6400 // trace variable specified in this block. |
| 6399 ASSERT(stack_trace_var != NULL); | 6401 ASSERT(stack_trace_var != NULL); |
| 6400 current_block_->statements->Add(new(Z) StoreLocalNode( | 6402 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6401 Scanner::kNoSourcePos, | 6403 Token::kNoSourcePos, |
| 6402 stack_trace_param.var, | 6404 stack_trace_param.var, |
| 6403 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 6405 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); |
| 6404 } | 6406 } |
| 6405 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6407 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( |
| 6406 Symbols::SavedExceptionVar()); | 6408 Symbols::SavedExceptionVar()); |
| 6407 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6409 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( |
| 6408 Symbols::SavedStackTraceVar()); | 6410 Symbols::SavedStackTraceVar()); |
| 6409 SaveExceptionAndStacktrace(current_block_->statements, | 6411 SaveExceptionAndStacktrace(current_block_->statements, |
| 6410 exception_var, | 6412 exception_var, |
| 6411 stack_trace_var, | 6413 stack_trace_var, |
| 6412 saved_exception_var, | 6414 saved_exception_var, |
| 6413 saved_stack_trace_var); | 6415 saved_stack_trace_var); |
| 6414 | 6416 |
| 6415 // Complete the async future with an error. This catch block executes | 6417 // Complete the async future with an error. This catch block executes |
| 6416 // unconditionally, there is no need to generate a type check for. | 6418 // unconditionally, there is no need to generate a type check for. |
| 6417 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 6419 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
| 6418 Symbols::AsyncCompleter(), false); | 6420 Symbols::AsyncCompleter(), false); |
| 6419 ASSERT(async_completer != NULL); | 6421 ASSERT(async_completer != NULL); |
| 6420 ArgumentListNode* completer_args = | 6422 ArgumentListNode* completer_args = |
| 6421 new (Z) ArgumentListNode(Scanner::kNoSourcePos); | 6423 new (Z) ArgumentListNode(Token::kNoSourcePos); |
| 6422 completer_args->Add( | 6424 completer_args->Add( |
| 6423 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); | 6425 new (Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var)); |
| 6424 completer_args->Add( | 6426 completer_args->Add( |
| 6425 new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var)); | 6427 new (Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var)); |
| 6426 current_block_->statements->Add(new (Z) InstanceCallNode( | 6428 current_block_->statements->Add(new (Z) InstanceCallNode( |
| 6427 TokenPos(), | 6429 TokenPos(), |
| 6428 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_completer), | 6430 new (Z) LoadLocalNode(Token::kNoSourcePos, async_completer), |
| 6429 Symbols::CompleterCompleteError(), | 6431 Symbols::CompleterCompleteError(), |
| 6430 completer_args)); | 6432 completer_args)); |
| 6431 ReturnNode* return_node = new (Z) ReturnNode(Scanner::kNoSourcePos); | 6433 ReturnNode* return_node = new (Z) ReturnNode(Token::kNoSourcePos); |
| 6432 // Behavior like a continuation return, i.e,. don't call a completer. | 6434 // Behavior like a continuation return, i.e,. don't call a completer. |
| 6433 return_node->set_return_type(ReturnNode::kContinuation); | 6435 return_node->set_return_type(ReturnNode::kContinuation); |
| 6434 current_block_->statements->Add(return_node); | 6436 current_block_->statements->Add(return_node); |
| 6435 AstNode* catch_block = CloseBlock(); | 6437 AstNode* catch_block = CloseBlock(); |
| 6436 current_block_->statements->Add(catch_block); | 6438 current_block_->statements->Add(catch_block); |
| 6437 SequenceNode* catch_handler_list = CloseBlock(); | 6439 SequenceNode* catch_handler_list = CloseBlock(); |
| 6438 | 6440 |
| 6439 const GrowableObjectArray& handler_types = | 6441 const GrowableObjectArray& handler_types = |
| 6440 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6442 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 6441 handler_types.SetLength(0); | 6443 handler_types.SetLength(0); |
| 6442 handler_types.Add(*exception_param.type); | 6444 handler_types.Add(*exception_param.type); |
| 6443 | 6445 |
| 6444 TryStack* try_statement = PopTry(); | 6446 TryStack* try_statement = PopTry(); |
| 6445 const intptr_t try_index = try_statement->try_index(); | 6447 const intptr_t try_index = try_statement->try_index(); |
| 6446 | 6448 |
| 6447 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( | 6449 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
| 6448 Scanner::kNoSourcePos, | 6450 Token::kNoSourcePos, |
| 6449 catch_handler_list, | 6451 catch_handler_list, |
| 6450 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6452 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 6451 context_var, | 6453 context_var, |
| 6452 exception_var, | 6454 exception_var, |
| 6453 stack_trace_var, | 6455 stack_trace_var, |
| 6454 saved_exception_var, | 6456 saved_exception_var, |
| 6455 saved_stack_trace_var, | 6457 saved_stack_trace_var, |
| 6456 CatchClauseNode::kInvalidTryIndex, | 6458 CatchClauseNode::kInvalidTryIndex, |
| 6457 true); | 6459 true); |
| 6458 AstNode* try_catch_node = new (Z) TryCatchNode( | 6460 AstNode* try_catch_node = new (Z) TryCatchNode( |
| 6459 Scanner::kNoSourcePos, | 6461 Token::kNoSourcePos, |
| 6460 try_block, | 6462 try_block, |
| 6461 context_var, | 6463 context_var, |
| 6462 catch_clause, | 6464 catch_clause, |
| 6463 NULL, // No finally clause. | 6465 NULL, // No finally clause. |
| 6464 try_index, | 6466 try_index, |
| 6465 NULL); // No rethrow-finally clause. | 6467 NULL); // No rethrow-finally clause. |
| 6466 current_block_->statements->Add(try_catch_node); | 6468 current_block_->statements->Add(try_catch_node); |
| 6467 return CloseBlock(); | 6469 return CloseBlock(); |
| 6468 } | 6470 } |
| 6469 | 6471 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6587 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 6589 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6588 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6590 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
| 6589 existing_var = | 6591 existing_var = |
| 6590 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | 6592 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
| 6591 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6593 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
| 6592 | 6594 |
| 6593 // :await_jump_var = -1; | 6595 // :await_jump_var = -1; |
| 6594 LocalVariable* jump_var = | 6596 LocalVariable* jump_var = |
| 6595 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6597 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6596 LiteralNode* init_value = | 6598 LiteralNode* init_value = |
| 6597 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6599 new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); |
| 6598 current_block_->statements->Add( | 6600 current_block_->statements->Add( |
| 6599 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); | 6601 new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value)); |
| 6600 | 6602 |
| 6601 // return new SyncIterable(body_closure); | 6603 // return new SyncIterable(body_closure); |
| 6602 const Class& iterable_class = | 6604 const Class& iterable_class = |
| 6603 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); | 6605 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); |
| 6604 ASSERT(!iterable_class.IsNull()); | 6606 ASSERT(!iterable_class.IsNull()); |
| 6605 const Function& iterable_constructor = Function::ZoneHandle(Z, | 6607 const Function& iterable_constructor = Function::ZoneHandle(Z, |
| 6606 iterable_class.LookupConstructorAllowPrivate( | 6608 iterable_class.LookupConstructorAllowPrivate( |
| 6607 Symbols::_SyncIterableConstructor())); | 6609 Symbols::_SyncIterableConstructor())); |
| 6608 ASSERT(!iterable_constructor.IsNull()); | 6610 ASSERT(!iterable_constructor.IsNull()); |
| 6609 | 6611 |
| 6610 const String& closure_name = String::Handle(Z, closure.name()); | 6612 const String& closure_name = String::Handle(Z, closure.name()); |
| 6611 ASSERT(closure_name.IsSymbol()); | 6613 ASSERT(closure_name.IsSymbol()); |
| 6612 | 6614 |
| 6613 ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos); | 6615 ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos); |
| 6614 ClosureNode* closure_obj = new(Z) ClosureNode( | 6616 ClosureNode* closure_obj = new(Z) ClosureNode( |
| 6615 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); | 6617 Token::kNoSourcePos, closure, NULL, closure_body->scope()); |
| 6616 arguments->Add(closure_obj); | 6618 arguments->Add(closure_obj); |
| 6617 ConstructorCallNode* new_iterable = | 6619 ConstructorCallNode* new_iterable = |
| 6618 new(Z) ConstructorCallNode(Scanner::kNoSourcePos, | 6620 new(Z) ConstructorCallNode(Token::kNoSourcePos, |
| 6619 TypeArguments::ZoneHandle(Z), | 6621 TypeArguments::ZoneHandle(Z), |
| 6620 iterable_constructor, | 6622 iterable_constructor, |
| 6621 arguments); | 6623 arguments); |
| 6622 ReturnNode* return_node = | 6624 ReturnNode* return_node = |
| 6623 new (Z) ReturnNode(Scanner::kNoSourcePos, new_iterable); | 6625 new (Z) ReturnNode(Token::kNoSourcePos, new_iterable); |
| 6624 current_block_->statements->Add(return_node); | 6626 current_block_->statements->Add(return_node); |
| 6625 return CloseBlock(); | 6627 return CloseBlock(); |
| 6626 } | 6628 } |
| 6627 | 6629 |
| 6628 | 6630 |
| 6629 void Parser::AddAsyncClosureParameters(ParamList* params) { | 6631 void Parser::AddAsyncClosureParameters(ParamList* params) { |
| 6630 // Async closures have three optional parameters: | 6632 // Async closures have three optional parameters: |
| 6631 // * A continuation result. | 6633 // * A continuation result. |
| 6632 // * A continuation error. | 6634 // * A continuation error. |
| 6633 // * A continuation stack trace. | 6635 // * A continuation stack trace. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6715 async_temp_scope_ = current_block_->scope; | 6717 async_temp_scope_ = current_block_->scope; |
| 6716 return closure.raw(); | 6718 return closure.raw(); |
| 6717 } | 6719 } |
| 6718 | 6720 |
| 6719 | 6721 |
| 6720 void Parser::AddContinuationVariables() { | 6722 void Parser::AddContinuationVariables() { |
| 6721 // Add to current block's scope: | 6723 // Add to current block's scope: |
| 6722 // var :await_jump_var; | 6724 // var :await_jump_var; |
| 6723 // var :await_ctx_var; | 6725 // var :await_ctx_var; |
| 6724 LocalVariable* await_jump_var = new (Z) LocalVariable( | 6726 LocalVariable* await_jump_var = new (Z) LocalVariable( |
| 6725 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type()); | 6727 Token::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type()); |
| 6726 current_block_->scope->AddVariable(await_jump_var); | 6728 current_block_->scope->AddVariable(await_jump_var); |
| 6727 LocalVariable* await_ctx_var = new (Z) LocalVariable( | 6729 LocalVariable* await_ctx_var = new (Z) LocalVariable( |
| 6728 Scanner::kNoSourcePos, | 6730 Token::kNoSourcePos, |
| 6729 Symbols::AwaitContextVar(), | 6731 Symbols::AwaitContextVar(), |
| 6730 Object::dynamic_type()); | 6732 Object::dynamic_type()); |
| 6731 current_block_->scope->AddVariable(await_ctx_var); | 6733 current_block_->scope->AddVariable(await_ctx_var); |
| 6732 } | 6734 } |
| 6733 | 6735 |
| 6734 | 6736 |
| 6735 void Parser::AddAsyncClosureVariables() { | 6737 void Parser::AddAsyncClosureVariables() { |
| 6736 // Add to current block's scope: | 6738 // Add to current block's scope: |
| 6737 // var :async_op; | 6739 // var :async_op; |
| 6738 // var :async_then_callback; | 6740 // var :async_then_callback; |
| 6739 // var :async_catch_error_callback; | 6741 // var :async_catch_error_callback; |
| 6740 // var :async_completer; | 6742 // var :async_completer; |
| 6741 LocalVariable* async_op_var = new(Z) LocalVariable( | 6743 LocalVariable* async_op_var = new(Z) LocalVariable( |
| 6742 Scanner::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); | 6744 Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); |
| 6743 current_block_->scope->AddVariable(async_op_var); | 6745 current_block_->scope->AddVariable(async_op_var); |
| 6744 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6746 LocalVariable* async_then_callback_var = new(Z) LocalVariable( |
| 6745 Scanner::kNoSourcePos, | 6747 Token::kNoSourcePos, |
| 6746 Symbols::AsyncThenCallback(), | 6748 Symbols::AsyncThenCallback(), |
| 6747 Object::dynamic_type()); | 6749 Object::dynamic_type()); |
| 6748 current_block_->scope->AddVariable(async_then_callback_var); | 6750 current_block_->scope->AddVariable(async_then_callback_var); |
| 6749 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6751 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( |
| 6750 Scanner::kNoSourcePos, | 6752 Token::kNoSourcePos, |
| 6751 Symbols::AsyncCatchErrorCallback(), | 6753 Symbols::AsyncCatchErrorCallback(), |
| 6752 Object::dynamic_type()); | 6754 Object::dynamic_type()); |
| 6753 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6755 current_block_->scope->AddVariable(async_catch_error_callback_var); |
| 6754 LocalVariable* async_completer = new(Z) LocalVariable( | 6756 LocalVariable* async_completer = new(Z) LocalVariable( |
| 6755 Scanner::kNoSourcePos, | 6757 Token::kNoSourcePos, |
| 6756 Symbols::AsyncCompleter(), | 6758 Symbols::AsyncCompleter(), |
| 6757 Object::dynamic_type()); | 6759 Object::dynamic_type()); |
| 6758 current_block_->scope->AddVariable(async_completer); | 6760 current_block_->scope->AddVariable(async_completer); |
| 6759 } | 6761 } |
| 6760 | 6762 |
| 6761 | 6763 |
| 6762 void Parser::AddAsyncGeneratorVariables() { | 6764 void Parser::AddAsyncGeneratorVariables() { |
| 6763 // Add to current block's scope: | 6765 // Add to current block's scope: |
| 6764 // var :controller; | 6766 // var :controller; |
| 6765 // The :controller variable is used by the async generator closure to | 6767 // The :controller variable is used by the async generator closure to |
| 6766 // store the StreamController object to which the yielded expressions | 6768 // store the StreamController object to which the yielded expressions |
| 6767 // are added. | 6769 // are added. |
| 6768 // var :async_op; | 6770 // var :async_op; |
| 6769 // var :async_then_callback; | 6771 // var :async_then_callback; |
| 6770 // var :async_catch_error_callback; | 6772 // var :async_catch_error_callback; |
| 6771 // These variables are used to store the async generator closure containing | 6773 // These variables are used to store the async generator closure containing |
| 6772 // the body of the async* function. They are used by the await operator. | 6774 // the body of the async* function. They are used by the await operator. |
| 6773 LocalVariable* controller_var = new(Z) LocalVariable( | 6775 LocalVariable* controller_var = new(Z) LocalVariable( |
| 6774 Scanner::kNoSourcePos, Symbols::Controller(), Object::dynamic_type()); | 6776 Token::kNoSourcePos, Symbols::Controller(), Object::dynamic_type()); |
| 6775 current_block_->scope->AddVariable(controller_var); | 6777 current_block_->scope->AddVariable(controller_var); |
| 6776 LocalVariable* async_op_var = new(Z) LocalVariable( | 6778 LocalVariable* async_op_var = new(Z) LocalVariable( |
| 6777 Scanner::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); | 6779 Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); |
| 6778 current_block_->scope->AddVariable(async_op_var); | 6780 current_block_->scope->AddVariable(async_op_var); |
| 6779 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6781 LocalVariable* async_then_callback_var = new(Z) LocalVariable( |
| 6780 Scanner::kNoSourcePos, | 6782 Token::kNoSourcePos, |
| 6781 Symbols::AsyncThenCallback(), | 6783 Symbols::AsyncThenCallback(), |
| 6782 Object::dynamic_type()); | 6784 Object::dynamic_type()); |
| 6783 current_block_->scope->AddVariable(async_then_callback_var); | 6785 current_block_->scope->AddVariable(async_then_callback_var); |
| 6784 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6786 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( |
| 6785 Scanner::kNoSourcePos, | 6787 Token::kNoSourcePos, |
| 6786 Symbols::AsyncCatchErrorCallback(), | 6788 Symbols::AsyncCatchErrorCallback(), |
| 6787 Object::dynamic_type()); | 6789 Object::dynamic_type()); |
| 6788 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6790 current_block_->scope->AddVariable(async_catch_error_callback_var); |
| 6789 } | 6791 } |
| 6790 | 6792 |
| 6791 | 6793 |
| 6792 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) { | 6794 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) { |
| 6793 TRACE_PARSER("OpenAsyncGeneratorFunction"); | 6795 TRACE_PARSER("OpenAsyncGeneratorFunction"); |
| 6794 AddContinuationVariables(); | 6796 AddContinuationVariables(); |
| 6795 AddAsyncGeneratorVariables(); | 6797 AddAsyncGeneratorVariables(); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6902 Symbols::_AsyncStarStreamController())); | 6904 Symbols::_AsyncStarStreamController())); |
| 6903 ASSERT(!controller_class.IsNull()); | 6905 ASSERT(!controller_class.IsNull()); |
| 6904 const Function& controller_constructor = Function::ZoneHandle(Z, | 6906 const Function& controller_constructor = Function::ZoneHandle(Z, |
| 6905 controller_class.LookupConstructorAllowPrivate( | 6907 controller_class.LookupConstructorAllowPrivate( |
| 6906 Symbols::_AsyncStarStreamControllerConstructor())); | 6908 Symbols::_AsyncStarStreamControllerConstructor())); |
| 6907 | 6909 |
| 6908 // :await_jump_var = -1; | 6910 // :await_jump_var = -1; |
| 6909 LocalVariable* jump_var = | 6911 LocalVariable* jump_var = |
| 6910 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6912 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6911 LiteralNode* init_value = | 6913 LiteralNode* init_value = |
| 6912 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6914 new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); |
| 6913 current_block_->statements->Add( | 6915 current_block_->statements->Add( |
| 6914 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); | 6916 new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value)); |
| 6915 | 6917 |
| 6916 // Add to AST: | 6918 // Add to AST: |
| 6917 // :async_op = <closure>; (containing the original body) | 6919 // :async_op = <closure>; (containing the original body) |
| 6918 LocalVariable* async_op_var = | 6920 LocalVariable* async_op_var = |
| 6919 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); | 6921 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
| 6920 ClosureNode* closure_obj = new(Z) ClosureNode( | 6922 ClosureNode* closure_obj = new(Z) ClosureNode( |
| 6921 Scanner::kNoSourcePos, closure_func, NULL, closure_body->scope()); | 6923 Token::kNoSourcePos, closure_func, NULL, closure_body->scope()); |
| 6922 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( | 6924 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( |
| 6923 Scanner::kNoSourcePos, | 6925 Token::kNoSourcePos, |
| 6924 async_op_var, | 6926 async_op_var, |
| 6925 closure_obj); | 6927 closure_obj); |
| 6926 | 6928 |
| 6927 current_block_->statements->Add(store_async_op); | 6929 current_block_->statements->Add(store_async_op); |
| 6928 | 6930 |
| 6929 // :async_then_callback = _asyncThenWrapperHelper(:async_op) | 6931 // :async_then_callback = _asyncThenWrapperHelper(:async_op) |
| 6930 const Function& async_then_wrapper_helper = Function::ZoneHandle( | 6932 const Function& async_then_wrapper_helper = Function::ZoneHandle( |
| 6931 Z, async_lib.LookupFunctionAllowPrivate( | 6933 Z, async_lib.LookupFunctionAllowPrivate( |
| 6932 Symbols::AsyncThenWrapperHelper())); | 6934 Symbols::AsyncThenWrapperHelper())); |
| 6933 ASSERT(!async_then_wrapper_helper.IsNull()); | 6935 ASSERT(!async_then_wrapper_helper.IsNull()); |
| 6934 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( | 6936 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( |
| 6935 Scanner::kNoSourcePos); | 6937 Token::kNoSourcePos); |
| 6936 async_then_wrapper_helper_args->Add( | 6938 async_then_wrapper_helper_args->Add( |
| 6937 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var)); | 6939 new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); |
| 6938 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( | 6940 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( |
| 6939 Scanner::kNoSourcePos, | 6941 Token::kNoSourcePos, |
| 6940 async_then_wrapper_helper, | 6942 async_then_wrapper_helper, |
| 6941 async_then_wrapper_helper_args); | 6943 async_then_wrapper_helper_args); |
| 6942 LocalVariable* async_then_callback_var = | 6944 LocalVariable* async_then_callback_var = |
| 6943 current_block_->scope->LookupVariable( | 6945 current_block_->scope->LookupVariable( |
| 6944 Symbols::AsyncThenCallback(), false); | 6946 Symbols::AsyncThenCallback(), false); |
| 6945 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( | 6947 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( |
| 6946 Scanner::kNoSourcePos, | 6948 Token::kNoSourcePos, |
| 6947 async_then_callback_var, | 6949 async_then_callback_var, |
| 6948 then_wrapper_call); | 6950 then_wrapper_call); |
| 6949 | 6951 |
| 6950 current_block_->statements->Add(store_async_then_callback); | 6952 current_block_->statements->Add(store_async_then_callback); |
| 6951 | 6953 |
| 6952 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) | 6954 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) |
| 6953 | 6955 |
| 6954 const Function& async_error_wrapper_helper = Function::ZoneHandle( | 6956 const Function& async_error_wrapper_helper = Function::ZoneHandle( |
| 6955 Z, async_lib.LookupFunctionAllowPrivate( | 6957 Z, async_lib.LookupFunctionAllowPrivate( |
| 6956 Symbols::AsyncErrorWrapperHelper())); | 6958 Symbols::AsyncErrorWrapperHelper())); |
| 6957 ASSERT(!async_error_wrapper_helper.IsNull()); | 6959 ASSERT(!async_error_wrapper_helper.IsNull()); |
| 6958 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( | 6960 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( |
| 6959 Scanner::kNoSourcePos); | 6961 Token::kNoSourcePos); |
| 6960 async_error_wrapper_helper_args->Add( | 6962 async_error_wrapper_helper_args->Add( |
| 6961 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var)); | 6963 new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); |
| 6962 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( | 6964 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( |
| 6963 Scanner::kNoSourcePos, | 6965 Token::kNoSourcePos, |
| 6964 async_error_wrapper_helper, | 6966 async_error_wrapper_helper, |
| 6965 async_error_wrapper_helper_args); | 6967 async_error_wrapper_helper_args); |
| 6966 LocalVariable* async_catch_error_callback_var = | 6968 LocalVariable* async_catch_error_callback_var = |
| 6967 current_block_->scope->LookupVariable( | 6969 current_block_->scope->LookupVariable( |
| 6968 Symbols::AsyncCatchErrorCallback(), false); | 6970 Symbols::AsyncCatchErrorCallback(), false); |
| 6969 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( | 6971 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( |
| 6970 Scanner::kNoSourcePos, | 6972 Token::kNoSourcePos, |
| 6971 async_catch_error_callback_var, | 6973 async_catch_error_callback_var, |
| 6972 error_wrapper_call); | 6974 error_wrapper_call); |
| 6973 | 6975 |
| 6974 current_block_->statements->Add(store_async_catch_error_callback); | 6976 current_block_->statements->Add(store_async_catch_error_callback); |
| 6975 | 6977 |
| 6976 // :controller = new _AsyncStarStreamController(body_closure); | 6978 // :controller = new _AsyncStarStreamController(body_closure); |
| 6977 ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos); | 6979 ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos); |
| 6978 arguments->Add(new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var)); | 6980 arguments->Add(new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); |
| 6979 ConstructorCallNode* controller_constructor_call = | 6981 ConstructorCallNode* controller_constructor_call = |
| 6980 new(Z) ConstructorCallNode(Scanner::kNoSourcePos, | 6982 new(Z) ConstructorCallNode(Token::kNoSourcePos, |
| 6981 TypeArguments::ZoneHandle(Z), | 6983 TypeArguments::ZoneHandle(Z), |
| 6982 controller_constructor, | 6984 controller_constructor, |
| 6983 arguments); | 6985 arguments); |
| 6984 LocalVariable* controller_var = | 6986 LocalVariable* controller_var = |
| 6985 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6987 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
| 6986 StoreLocalNode* store_controller = | 6988 StoreLocalNode* store_controller = |
| 6987 new(Z) StoreLocalNode(Scanner::kNoSourcePos, | 6989 new(Z) StoreLocalNode(Token::kNoSourcePos, |
| 6988 controller_var, | 6990 controller_var, |
| 6989 controller_constructor_call); | 6991 controller_constructor_call); |
| 6990 current_block_->statements->Add(store_controller); | 6992 current_block_->statements->Add(store_controller); |
| 6991 | 6993 |
| 6992 // return :controller.stream; | 6994 // return :controller.stream; |
| 6993 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos, | 6995 ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos, |
| 6994 new(Z) InstanceGetterNode(Scanner::kNoSourcePos, | 6996 new(Z) InstanceGetterNode(Token::kNoSourcePos, |
| 6995 new(Z) LoadLocalNode(Scanner::kNoSourcePos, | 6997 new(Z) LoadLocalNode(Token::kNoSourcePos, |
| 6996 controller_var), | 6998 controller_var), |
| 6997 Symbols::Stream())); | 6999 Symbols::Stream())); |
| 6998 current_block_->statements->Add(return_node); | 7000 current_block_->statements->Add(return_node); |
| 6999 return CloseBlock(); | 7001 return CloseBlock(); |
| 7000 } | 7002 } |
| 7001 | 7003 |
| 7002 | 7004 |
| 7003 void Parser::OpenAsyncGeneratorClosure() { | 7005 void Parser::OpenAsyncGeneratorClosure() { |
| 7004 async_temp_scope_ = current_block_->scope; | 7006 async_temp_scope_ = current_block_->scope; |
| 7005 OpenAsyncTryBlock(); | 7007 OpenAsyncTryBlock(); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7079 const Class& completer = | 7081 const Class& completer = |
| 7080 Class::ZoneHandle(Z, I->object_store()->completer_class()); | 7082 Class::ZoneHandle(Z, I->object_store()->completer_class()); |
| 7081 ASSERT(!completer.IsNull()); | 7083 ASSERT(!completer.IsNull()); |
| 7082 const Function& completer_constructor = Function::ZoneHandle(Z, | 7084 const Function& completer_constructor = Function::ZoneHandle(Z, |
| 7083 completer.LookupFunction(Symbols::CompleterSyncConstructor())); | 7085 completer.LookupFunction(Symbols::CompleterSyncConstructor())); |
| 7084 ASSERT(!completer_constructor.IsNull()); | 7086 ASSERT(!completer_constructor.IsNull()); |
| 7085 | 7087 |
| 7086 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 7088 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
| 7087 Symbols::AsyncCompleter(), false); | 7089 Symbols::AsyncCompleter(), false); |
| 7088 | 7090 |
| 7091 const intptr_t token_pos = ST(closure_body->token_pos()); |
| 7089 // Add to AST: | 7092 // Add to AST: |
| 7090 // :async_completer = new Completer.sync(); | 7093 // :async_completer = new Completer.sync(); |
| 7091 ArgumentListNode* empty_args = | 7094 ArgumentListNode* empty_args = |
| 7092 new (Z) ArgumentListNode(Scanner::kNoSourcePos); | 7095 new (Z) ArgumentListNode(token_pos); |
| 7093 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( | 7096 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( |
| 7094 Scanner::kNoSourcePos, | 7097 token_pos, |
| 7095 TypeArguments::ZoneHandle(Z), | 7098 TypeArguments::ZoneHandle(Z), |
| 7096 completer_constructor, | 7099 completer_constructor, |
| 7097 empty_args); | 7100 empty_args); |
| 7098 StoreLocalNode* store_completer = new (Z) StoreLocalNode( | 7101 StoreLocalNode* store_completer = new (Z) StoreLocalNode( |
| 7099 Scanner::kNoSourcePos, | 7102 token_pos, |
| 7100 async_completer, | 7103 async_completer, |
| 7101 completer_constructor_node); | 7104 completer_constructor_node); |
| 7102 current_block_->statements->Add(store_completer); | 7105 current_block_->statements->Add(store_completer); |
| 7103 | 7106 |
| 7104 // :await_jump_var = -1; | 7107 // :await_jump_var = -1; |
| 7105 LocalVariable* jump_var = | 7108 LocalVariable* jump_var = |
| 7106 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 7109 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 7107 LiteralNode* init_value = | 7110 LiteralNode* init_value = |
| 7108 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 7111 new(Z) LiteralNode(token_pos, |
| 7112 Smi::ZoneHandle(Smi::New(-1))); |
| 7109 current_block_->statements->Add( | 7113 current_block_->statements->Add( |
| 7110 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); | 7114 new(Z) StoreLocalNode(token_pos, jump_var, init_value)); |
| 7111 | 7115 |
| 7112 // Add to AST: | 7116 // Add to AST: |
| 7113 // :async_op = <closure>; (containing the original body) | 7117 // :async_op = <closure>; (containing the original body) |
| 7114 LocalVariable* async_op_var = current_block_->scope->LookupVariable( | 7118 LocalVariable* async_op_var = current_block_->scope->LookupVariable( |
| 7115 Symbols::AsyncOperation(), false); | 7119 Symbols::AsyncOperation(), false); |
| 7116 ClosureNode* cn = new(Z) ClosureNode( | 7120 ClosureNode* cn = new(Z) ClosureNode( |
| 7117 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); | 7121 token_pos, closure, NULL, closure_body->scope()); |
| 7118 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( | 7122 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( |
| 7119 Scanner::kNoSourcePos, | 7123 token_pos, |
| 7120 async_op_var, | 7124 async_op_var, |
| 7121 cn); | 7125 cn); |
| 7122 current_block_->statements->Add(store_async_op); | 7126 current_block_->statements->Add(store_async_op); |
| 7123 | 7127 |
| 7124 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | 7128 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); |
| 7125 // :async_then_callback = _asyncThenWrapperHelper(:async_op) | 7129 // :async_then_callback = _asyncThenWrapperHelper(:async_op) |
| 7126 const Function& async_then_wrapper_helper = Function::ZoneHandle( | 7130 const Function& async_then_wrapper_helper = Function::ZoneHandle( |
| 7127 Z, async_lib.LookupFunctionAllowPrivate( | 7131 Z, async_lib.LookupFunctionAllowPrivate( |
| 7128 Symbols::AsyncThenWrapperHelper())); | 7132 Symbols::AsyncThenWrapperHelper())); |
| 7129 ASSERT(!async_then_wrapper_helper.IsNull()); | 7133 ASSERT(!async_then_wrapper_helper.IsNull()); |
| 7130 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( | 7134 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( |
| 7131 Scanner::kNoSourcePos); | 7135 token_pos); |
| 7132 async_then_wrapper_helper_args->Add( | 7136 async_then_wrapper_helper_args->Add( |
| 7133 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var)); | 7137 new (Z) LoadLocalNode(token_pos, async_op_var)); |
| 7134 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( | 7138 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( |
| 7135 Scanner::kNoSourcePos, | 7139 token_pos, |
| 7136 async_then_wrapper_helper, | 7140 async_then_wrapper_helper, |
| 7137 async_then_wrapper_helper_args); | 7141 async_then_wrapper_helper_args); |
| 7138 LocalVariable* async_then_callback_var = | 7142 LocalVariable* async_then_callback_var = |
| 7139 current_block_->scope->LookupVariable( | 7143 current_block_->scope->LookupVariable( |
| 7140 Symbols::AsyncThenCallback(), false); | 7144 Symbols::AsyncThenCallback(), false); |
| 7141 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( | 7145 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( |
| 7142 Scanner::kNoSourcePos, | 7146 token_pos, |
| 7143 async_then_callback_var, | 7147 async_then_callback_var, |
| 7144 then_wrapper_call); | 7148 then_wrapper_call); |
| 7145 | 7149 |
| 7146 current_block_->statements->Add(store_async_then_callback); | 7150 current_block_->statements->Add(store_async_then_callback); |
| 7147 | 7151 |
| 7148 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) | 7152 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) |
| 7149 | 7153 |
| 7150 const Function& async_error_wrapper_helper = Function::ZoneHandle( | 7154 const Function& async_error_wrapper_helper = Function::ZoneHandle( |
| 7151 Z, async_lib.LookupFunctionAllowPrivate( | 7155 Z, async_lib.LookupFunctionAllowPrivate( |
| 7152 Symbols::AsyncErrorWrapperHelper())); | 7156 Symbols::AsyncErrorWrapperHelper())); |
| 7153 ASSERT(!async_error_wrapper_helper.IsNull()); | 7157 ASSERT(!async_error_wrapper_helper.IsNull()); |
| 7154 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( | 7158 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( |
| 7155 Scanner::kNoSourcePos); | 7159 token_pos); |
| 7156 async_error_wrapper_helper_args->Add( | 7160 async_error_wrapper_helper_args->Add( |
| 7157 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var)); | 7161 new (Z) LoadLocalNode(token_pos, async_op_var)); |
| 7158 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( | 7162 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( |
| 7159 Scanner::kNoSourcePos, | 7163 token_pos, |
| 7160 async_error_wrapper_helper, | 7164 async_error_wrapper_helper, |
| 7161 async_error_wrapper_helper_args); | 7165 async_error_wrapper_helper_args); |
| 7162 LocalVariable* async_catch_error_callback_var = | 7166 LocalVariable* async_catch_error_callback_var = |
| 7163 current_block_->scope->LookupVariable( | 7167 current_block_->scope->LookupVariable( |
| 7164 Symbols::AsyncCatchErrorCallback(), false); | 7168 Symbols::AsyncCatchErrorCallback(), false); |
| 7165 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( | 7169 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( |
| 7166 Scanner::kNoSourcePos, | 7170 token_pos, |
| 7167 async_catch_error_callback_var, | 7171 async_catch_error_callback_var, |
| 7168 error_wrapper_call); | 7172 error_wrapper_call); |
| 7169 | 7173 |
| 7170 current_block_->statements->Add(store_async_catch_error_callback); | 7174 current_block_->statements->Add(store_async_catch_error_callback); |
| 7171 | 7175 |
| 7172 // Add to AST: | 7176 // Add to AST: |
| 7173 // new Future.microtask(:async_op); | 7177 // new Future.microtask(:async_op); |
| 7174 ArgumentListNode* arguments = new (Z) ArgumentListNode(Scanner::kNoSourcePos); | 7178 ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos); |
| 7175 arguments->Add(new (Z) LoadLocalNode( | 7179 arguments->Add(new (Z) LoadLocalNode( |
| 7176 Scanner::kNoSourcePos, async_op_var)); | 7180 token_pos, async_op_var)); |
| 7177 ConstructorCallNode* future_node = new (Z) ConstructorCallNode( | 7181 ConstructorCallNode* future_node = new (Z) ConstructorCallNode( |
| 7178 Scanner::kNoSourcePos, TypeArguments::ZoneHandle(Z), constructor, | 7182 token_pos, TypeArguments::ZoneHandle(Z), constructor, |
| 7179 arguments); | 7183 arguments); |
| 7180 current_block_->statements->Add(future_node); | 7184 current_block_->statements->Add(future_node); |
| 7181 | 7185 |
| 7182 // Add to AST: | 7186 // Add to AST: |
| 7183 // return :async_completer.future; | 7187 // return :async_completer.future; |
| 7184 ReturnNode* return_node = new (Z) ReturnNode( | 7188 ReturnNode* return_node = new (Z) ReturnNode( |
| 7185 Scanner::kNoSourcePos, | 7189 token_pos, |
| 7186 new (Z) InstanceGetterNode( | 7190 new (Z) InstanceGetterNode( |
| 7187 Scanner::kNoSourcePos, | 7191 token_pos, |
| 7188 new (Z) LoadLocalNode( | 7192 new (Z) LoadLocalNode( |
| 7189 Scanner::kNoSourcePos, | 7193 token_pos, |
| 7190 async_completer), | 7194 async_completer), |
| 7191 Symbols::CompleterFuture())); | 7195 Symbols::CompleterFuture())); |
| 7192 current_block_->statements->Add(return_node); | 7196 current_block_->statements->Add(return_node); |
| 7193 return CloseBlock(); | 7197 return CloseBlock(); |
| 7194 } | 7198 } |
| 7195 | 7199 |
| 7196 | 7200 |
| 7197 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { | 7201 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { |
| 7198 // We need a temporary expression to store intermediate return values. | 7202 // We need a temporary expression to store intermediate return values. |
| 7199 parsed_function()->EnsureExpressionTemp(); | 7203 parsed_function()->EnsureExpressionTemp(); |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7512 | 7516 |
| 7513 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 7517 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 7514 TRACE_PARSER("ParseFunctionStatement"); | 7518 TRACE_PARSER("ParseFunctionStatement"); |
| 7515 AbstractType& result_type = AbstractType::Handle(Z); | 7519 AbstractType& result_type = AbstractType::Handle(Z); |
| 7516 const String* variable_name = NULL; | 7520 const String* variable_name = NULL; |
| 7517 const String* function_name = NULL; | 7521 const String* function_name = NULL; |
| 7518 | 7522 |
| 7519 result_type = Type::DynamicType(); | 7523 result_type = Type::DynamicType(); |
| 7520 | 7524 |
| 7521 const intptr_t function_pos = TokenPos(); | 7525 const intptr_t function_pos = TokenPos(); |
| 7522 intptr_t metadata_pos = Scanner::kNoSourcePos; | 7526 intptr_t metadata_pos = Token::kNoSourcePos; |
| 7523 if (is_literal) { | 7527 if (is_literal) { |
| 7524 ASSERT(CurrentToken() == Token::kLPAREN); | 7528 ASSERT(CurrentToken() == Token::kLPAREN); |
| 7525 function_name = &Symbols::AnonymousClosure(); | 7529 function_name = &Symbols::AnonymousClosure(); |
| 7526 } else { | 7530 } else { |
| 7527 metadata_pos = SkipMetadata(); | 7531 metadata_pos = SkipMetadata(); |
| 7528 if (CurrentToken() == Token::kVOID) { | 7532 if (CurrentToken() == Token::kVOID) { |
| 7529 ConsumeToken(); | 7533 ConsumeToken(); |
| 7530 result_type = Type::VoidType(); | 7534 result_type = Type::VoidType(); |
| 7531 } else if ((CurrentToken() == Token::kIDENT) && | 7535 } else if ((CurrentToken() == Token::kIDENT) && |
| 7532 (LookaheadToken(1) != Token::kLPAREN)) { | 7536 (LookaheadToken(1) != Token::kLPAREN)) { |
| (...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8513 } | 8517 } |
| 8514 | 8518 |
| 8515 | 8519 |
| 8516 // Build an AST node for static call to Dart function print(str). | 8520 // Build an AST node for static call to Dart function print(str). |
| 8517 // Used during debugging to insert print in generated dart code. | 8521 // Used during debugging to insert print in generated dart code. |
| 8518 AstNode* Parser::DartPrint(const char* str) { | 8522 AstNode* Parser::DartPrint(const char* str) { |
| 8519 const Library& lib = Library::Handle(Library::CoreLibrary()); | 8523 const Library& lib = Library::Handle(Library::CoreLibrary()); |
| 8520 const Function& print_fn = Function::ZoneHandle( | 8524 const Function& print_fn = Function::ZoneHandle( |
| 8521 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); | 8525 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
| 8522 ASSERT(!print_fn.IsNull()); | 8526 ASSERT(!print_fn.IsNull()); |
| 8523 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Scanner::kNoSourcePos); | 8527 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Token::kNoSourcePos); |
| 8524 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); | 8528 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); |
| 8525 one_arg->Add(new(Z) LiteralNode(Scanner::kNoSourcePos, msg)); | 8529 one_arg->Add(new(Z) LiteralNode(Token::kNoSourcePos, msg)); |
| 8526 AstNode* print_call = | 8530 AstNode* print_call = |
| 8527 new(Z) StaticCallNode(Scanner::kNoSourcePos, print_fn, one_arg); | 8531 new(Z) StaticCallNode(Token::kNoSourcePos, print_fn, one_arg); |
| 8528 return print_call; | 8532 return print_call; |
| 8529 } | 8533 } |
| 8530 | 8534 |
| 8531 | 8535 |
| 8532 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 8536 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
| 8533 TRACE_PARSER("ParseAwaitForStatement"); | 8537 TRACE_PARSER("ParseAwaitForStatement"); |
| 8534 ASSERT(IsAwaitKeyword()); | 8538 ASSERT(IsAwaitKeyword()); |
| 8535 const intptr_t await_for_pos = TokenPos(); | 8539 const intptr_t await_for_pos = TokenPos(); |
| 8536 ConsumeToken(); // await. | 8540 ConsumeToken(); // await. |
| 8537 ASSERT(CurrentToken() == Token::kFOR); | 8541 ASSERT(CurrentToken() == Token::kFOR); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8722 current_block_->statements->Add(while_node); | 8726 current_block_->statements->Add(while_node); |
| 8723 SequenceNode* try_block = CloseBlock(); | 8727 SequenceNode* try_block = CloseBlock(); |
| 8724 | 8728 |
| 8725 // Create an empty "catch all" block that rethrows the current | 8729 // Create an empty "catch all" block that rethrows the current |
| 8726 // exception and stacktrace. | 8730 // exception and stacktrace. |
| 8727 try_stack_->enter_catch(); | 8731 try_stack_->enter_catch(); |
| 8728 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); | 8732 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); |
| 8729 | 8733 |
| 8730 if (outer_saved_try_ctx != NULL) { | 8734 if (outer_saved_try_ctx != NULL) { |
| 8731 catch_block->Add(new (Z) StoreLocalNode( | 8735 catch_block->Add(new (Z) StoreLocalNode( |
| 8732 Scanner::kNoSourcePos, | 8736 Token::kNoSourcePos, |
| 8733 outer_saved_try_ctx, | 8737 outer_saved_try_ctx, |
| 8734 new (Z) LoadLocalNode(Scanner::kNoSourcePos, | 8738 new (Z) LoadLocalNode(Token::kNoSourcePos, |
| 8735 outer_async_saved_try_ctx))); | 8739 outer_async_saved_try_ctx))); |
| 8736 } | 8740 } |
| 8737 | 8741 |
| 8738 // We don't need to copy the current exception and stack trace variables | 8742 // We don't need to copy the current exception and stack trace variables |
| 8739 // into :saved_exception_var and :saved_stack_trace_var here because there | 8743 // into :saved_exception_var and :saved_stack_trace_var here because there |
| 8740 // is no code in the catch clause that could suspend the function. | 8744 // is no code in the catch clause that could suspend the function. |
| 8741 | 8745 |
| 8742 // Rethrow the exception. | 8746 // Rethrow the exception. |
| 8743 catch_block->Add(new(Z) ThrowNode( | 8747 catch_block->Add(new(Z) ThrowNode( |
| 8744 await_for_pos, | 8748 await_for_pos, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8756 | 8760 |
| 8757 // Inline the finally block to the exit points in the try block. | 8761 // Inline the finally block to the exit points in the try block. |
| 8758 intptr_t node_index = 0; | 8762 intptr_t node_index = 0; |
| 8759 SequenceNode* finally_clause = NULL; | 8763 SequenceNode* finally_clause = NULL; |
| 8760 if (try_stack_ != NULL) { | 8764 if (try_stack_ != NULL) { |
| 8761 try_stack_->enter_finally(); | 8765 try_stack_->enter_finally(); |
| 8762 } | 8766 } |
| 8763 do { | 8767 do { |
| 8764 OpenBlock(); | 8768 OpenBlock(); |
| 8765 ArgumentListNode* no_args = | 8769 ArgumentListNode* no_args = |
| 8766 new(Z) ArgumentListNode(Scanner::kNoSourcePos); | 8770 new(Z) ArgumentListNode(Token::kNoSourcePos); |
| 8767 current_block_->statements->Add( | 8771 current_block_->statements->Add( |
| 8768 new(Z) InstanceCallNode(Scanner::kNoSourcePos, | 8772 new(Z) InstanceCallNode(Token::kNoSourcePos, |
| 8769 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_var), | 8773 new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_var), |
| 8770 Symbols::Cancel(), | 8774 Symbols::Cancel(), |
| 8771 no_args)); | 8775 no_args)); |
| 8772 finally_clause = CloseBlock(); | 8776 finally_clause = CloseBlock(); |
| 8773 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 8777 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
| 8774 if (node_to_inline != NULL) { | 8778 if (node_to_inline != NULL) { |
| 8775 InlinedFinallyNode* node = | 8779 InlinedFinallyNode* node = |
| 8776 new(Z) InlinedFinallyNode(Scanner::kNoSourcePos, | 8780 new(Z) InlinedFinallyNode(Token::kNoSourcePos, |
| 8777 finally_clause, | 8781 finally_clause, |
| 8778 context_var, | 8782 context_var, |
| 8779 outer_try_index); | 8783 outer_try_index); |
| 8780 finally_clause = NULL; | 8784 finally_clause = NULL; |
| 8781 AddFinallyClauseToNode(true, node_to_inline, node); | 8785 AddFinallyClauseToNode(true, node_to_inline, node); |
| 8782 node_index++; | 8786 node_index++; |
| 8783 } | 8787 } |
| 8784 } while (finally_clause == NULL); | 8788 } while (finally_clause == NULL); |
| 8785 | 8789 |
| 8786 if (try_stack_ != NULL) { | 8790 if (try_stack_ != NULL) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8822 | 8826 |
| 8823 | 8827 |
| 8824 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 8828 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
| 8825 SourceLabel* label) { | 8829 SourceLabel* label) { |
| 8826 TRACE_PARSER("ParseForInStatement"); | 8830 TRACE_PARSER("ParseForInStatement"); |
| 8827 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8831 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
| 8828 if (CurrentToken() == Token::kCONST) { | 8832 if (CurrentToken() == Token::kCONST) { |
| 8829 ReportError("Loop variable cannot be 'const'"); | 8833 ReportError("Loop variable cannot be 'const'"); |
| 8830 } | 8834 } |
| 8831 const String* loop_var_name = NULL; | 8835 const String* loop_var_name = NULL; |
| 8832 intptr_t loop_var_pos = Scanner::kNoSourcePos; | 8836 intptr_t loop_var_pos = Token::kNoSourcePos; |
| 8833 bool new_loop_var = false; | 8837 bool new_loop_var = false; |
| 8834 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8838 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
| 8835 if (LookaheadToken(1) == Token::kIN) { | 8839 if (LookaheadToken(1) == Token::kIN) { |
| 8836 loop_var_pos = TokenPos(); | 8840 loop_var_pos = TokenPos(); |
| 8837 loop_var_name = ExpectIdentifier("variable name expected"); | 8841 loop_var_name = ExpectIdentifier("variable name expected"); |
| 8838 } else { | 8842 } else { |
| 8839 // The case without a type is handled above, so require a type here. | 8843 // The case without a type is handled above, so require a type here. |
| 8840 // Delay creation of the local variable until we know its actual | 8844 // Delay creation of the local variable until we know its actual |
| 8841 // position, which is inside the loop body. | 8845 // position, which is inside the loop body. |
| 8842 new_loop_var = true; | 8846 new_loop_var = true; |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9123 ASSERT(innermost_function().IsAsyncClosure() || | 9127 ASSERT(innermost_function().IsAsyncClosure() || |
| 9124 innermost_function().IsAsyncFunction() || | 9128 innermost_function().IsAsyncFunction() || |
| 9125 innermost_function().IsSyncGenClosure() || | 9129 innermost_function().IsSyncGenClosure() || |
| 9126 innermost_function().IsSyncGenerator() || | 9130 innermost_function().IsSyncGenerator() || |
| 9127 innermost_function().IsAsyncGenClosure() || | 9131 innermost_function().IsAsyncGenClosure() || |
| 9128 innermost_function().IsAsyncGenerator()); | 9132 innermost_function().IsAsyncGenerator()); |
| 9129 | 9133 |
| 9130 ASSERT(saved_exception_var != NULL); | 9134 ASSERT(saved_exception_var != NULL); |
| 9131 ASSERT(exception_var != NULL); | 9135 ASSERT(exception_var != NULL); |
| 9132 statements->Add(new(Z) StoreLocalNode( | 9136 statements->Add(new(Z) StoreLocalNode( |
| 9133 Scanner::kNoSourcePos, | 9137 Token::kNoSourcePos, |
| 9134 saved_exception_var, | 9138 saved_exception_var, |
| 9135 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); | 9139 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); |
| 9136 | 9140 |
| 9137 ASSERT(saved_stack_trace_var != NULL); | 9141 ASSERT(saved_stack_trace_var != NULL); |
| 9138 ASSERT(stack_trace_var != NULL); | 9142 ASSERT(stack_trace_var != NULL); |
| 9139 statements->Add(new(Z) StoreLocalNode( | 9143 statements->Add(new(Z) StoreLocalNode( |
| 9140 Scanner::kNoSourcePos, | 9144 Token::kNoSourcePos, |
| 9141 saved_stack_trace_var, | 9145 saved_stack_trace_var, |
| 9142 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 9146 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); |
| 9143 } | 9147 } |
| 9144 | 9148 |
| 9145 | 9149 |
| 9146 SequenceNode* Parser::EnsureFinallyClause( | 9150 SequenceNode* Parser::EnsureFinallyClause( |
| 9147 bool parse, | 9151 bool parse, |
| 9148 bool is_async, | 9152 bool is_async, |
| 9149 LocalVariable* exception_var, | 9153 LocalVariable* exception_var, |
| 9150 LocalVariable* stack_trace_var, | 9154 LocalVariable* stack_trace_var, |
| 9151 LocalVariable* rethrow_exception_var, | 9155 LocalVariable* rethrow_exception_var, |
| 9152 LocalVariable* rethrow_stack_trace_var) { | 9156 LocalVariable* rethrow_stack_trace_var) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 9167 if (try_stack_ != NULL) { | 9171 if (try_stack_ != NULL) { |
| 9168 LocalScope* scope = try_stack_->try_block()->scope; | 9172 LocalScope* scope = try_stack_->try_block()->scope; |
| 9169 if (scope->function_level() == current_block_->scope->function_level()) { | 9173 if (scope->function_level() == current_block_->scope->function_level()) { |
| 9170 LocalVariable* saved_try_ctx = | 9174 LocalVariable* saved_try_ctx = |
| 9171 LookupSavedTryContextVar(scope->parent()); | 9175 LookupSavedTryContextVar(scope->parent()); |
| 9172 LocalVariable* async_saved_try_ctx = | 9176 LocalVariable* async_saved_try_ctx = |
| 9173 LookupAsyncSavedTryContextVar(async_temp_scope_, | 9177 LookupAsyncSavedTryContextVar(async_temp_scope_, |
| 9174 try_stack_->try_index()); | 9178 try_stack_->try_index()); |
| 9175 current_block_->statements->Add( | 9179 current_block_->statements->Add( |
| 9176 new (Z) StoreLocalNode( | 9180 new (Z) StoreLocalNode( |
| 9177 Scanner::kNoSourcePos, | 9181 Token::kNoSourcePos, |
| 9178 saved_try_ctx, | 9182 saved_try_ctx, |
| 9179 new (Z) LoadLocalNode(Scanner::kNoSourcePos, | 9183 new (Z) LoadLocalNode(Token::kNoSourcePos, |
| 9180 async_saved_try_ctx))); | 9184 async_saved_try_ctx))); |
| 9181 } | 9185 } |
| 9182 } | 9186 } |
| 9183 // We need to save the exception variables as in catch clauses, whether | 9187 // We need to save the exception variables as in catch clauses, whether |
| 9184 // there is an outer try or not. Note that this is only necessary if the | 9188 // there is an outer try or not. Note that this is only necessary if the |
| 9185 // finally clause contains an await or yield. | 9189 // finally clause contains an await or yield. |
| 9186 // TODO(hausner): Optimize. | 9190 // TODO(hausner): Optimize. |
| 9187 SaveExceptionAndStacktrace(current_block_->statements, | 9191 SaveExceptionAndStacktrace(current_block_->statements, |
| 9188 exception_var, | 9192 exception_var, |
| 9189 stack_trace_var, | 9193 stack_trace_var, |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9440 if (try_block != NULL) { | 9444 if (try_block != NULL) { |
| 9441 LocalScope* scope = try_block->try_block()->scope; | 9445 LocalScope* scope = try_block->try_block()->scope; |
| 9442 if (scope->function_level() == current_block_->scope->function_level()) { | 9446 if (scope->function_level() == current_block_->scope->function_level()) { |
| 9443 LocalVariable* saved_try_ctx = | 9447 LocalVariable* saved_try_ctx = |
| 9444 LookupSavedTryContextVar(scope->parent()); | 9448 LookupSavedTryContextVar(scope->parent()); |
| 9445 LocalVariable* async_saved_try_ctx = | 9449 LocalVariable* async_saved_try_ctx = |
| 9446 LookupAsyncSavedTryContextVar(async_temp_scope_, | 9450 LookupAsyncSavedTryContextVar(async_temp_scope_, |
| 9447 try_block->try_index()); | 9451 try_block->try_index()); |
| 9448 async_code->Add( | 9452 async_code->Add( |
| 9449 new (Z) StoreLocalNode( | 9453 new (Z) StoreLocalNode( |
| 9450 Scanner::kNoSourcePos, | 9454 Token::kNoSourcePos, |
| 9451 saved_try_ctx, | 9455 saved_try_ctx, |
| 9452 new (Z) LoadLocalNode(Scanner::kNoSourcePos, | 9456 new (Z) LoadLocalNode(Token::kNoSourcePos, |
| 9453 async_saved_try_ctx))); | 9457 async_saved_try_ctx))); |
| 9454 } | 9458 } |
| 9455 } | 9459 } |
| 9456 SaveExceptionAndStacktrace(async_code, | 9460 SaveExceptionAndStacktrace(async_code, |
| 9457 exception_var, | 9461 exception_var, |
| 9458 stack_trace_var, | 9462 stack_trace_var, |
| 9459 rethrow_exception_var, | 9463 rethrow_exception_var, |
| 9460 rethrow_stack_trace_var); | 9464 rethrow_stack_trace_var); |
| 9461 // The async_code node sequence contains code to restore the context (if | 9465 // The async_code node sequence contains code to restore the context (if |
| 9462 // an outer try block is present) and code to save the exception and | 9466 // an outer try block is present) and code to save the exception and |
| 9463 // stack trace variables. | 9467 // stack trace variables. |
| 9464 // This async code is inserted before the current node sequence containing | 9468 // This async code is inserted before the current node sequence containing |
| 9465 // the chain of if/then/else handling all catch clauses. | 9469 // the chain of if/then/else handling all catch clauses. |
| 9466 async_code->Add(current); | 9470 async_code->Add(current); |
| 9467 current = async_code; | 9471 current = async_code; |
| 9468 } | 9472 } |
| 9469 return current; | 9473 return current; |
| 9470 } | 9474 } |
| 9471 | 9475 |
| 9472 | 9476 |
| 9473 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 9477 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
| 9474 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, | 9478 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, |
| 9475 Symbols::NewFormatted("%s%d", | 9479 Symbols::NewFormatted("%s%d", |
| 9476 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 9480 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
| 9477 last_used_try_index_ - 1)); | 9481 last_used_try_index_ - 1)); |
| 9478 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( | 9482 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( |
| 9479 Scanner::kNoSourcePos, | 9483 Token::kNoSourcePos, |
| 9480 async_saved_try_ctx_name, | 9484 async_saved_try_ctx_name, |
| 9481 Object::dynamic_type()); | 9485 Object::dynamic_type()); |
| 9482 ASSERT(async_temp_scope_ != NULL); | 9486 ASSERT(async_temp_scope_ != NULL); |
| 9483 async_temp_scope_->AddVariable(async_saved_try_ctx); | 9487 async_temp_scope_->AddVariable(async_saved_try_ctx); |
| 9484 ASSERT(saved_try_context != NULL); | 9488 ASSERT(saved_try_context != NULL); |
| 9485 current_block_->statements->Add(new(Z) StoreLocalNode( | 9489 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 9486 Scanner::kNoSourcePos, | 9490 Token::kNoSourcePos, |
| 9487 async_saved_try_ctx, | 9491 async_saved_try_ctx, |
| 9488 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context))); | 9492 new(Z) LoadLocalNode(Token::kNoSourcePos, saved_try_context))); |
| 9489 } | 9493 } |
| 9490 | 9494 |
| 9491 | 9495 |
| 9492 // We create three variables for exceptions: | 9496 // We create three variables for exceptions: |
| 9493 // ':saved_try_context_var' - Used to save the context before the start of | 9497 // ':saved_try_context_var' - Used to save the context before the start of |
| 9494 // the try block. The context register is | 9498 // the try block. The context register is |
| 9495 // restored from this variable before | 9499 // restored from this variable before |
| 9496 // processing the catch block handler. | 9500 // processing the catch block handler. |
| 9497 // ':exception_var' - Used to save the current exception object that was | 9501 // ':exception_var' - Used to save the current exception object that was |
| 9498 // thrown. | 9502 // thrown. |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9807 LetNode* yield = new(Z) LetNode(yield_pos); | 9811 LetNode* yield = new(Z) LetNode(yield_pos); |
| 9808 if (innermost_function().IsSyncGenerator() || | 9812 if (innermost_function().IsSyncGenerator() || |
| 9809 innermost_function().IsSyncGenClosure()) { | 9813 innermost_function().IsSyncGenClosure()) { |
| 9810 // Yield statement in sync* function. | 9814 // Yield statement in sync* function. |
| 9811 | 9815 |
| 9812 LocalVariable* iterator_param = | 9816 LocalVariable* iterator_param = |
| 9813 LookupLocalScope(Symbols::IteratorParameter()); | 9817 LookupLocalScope(Symbols::IteratorParameter()); |
| 9814 ASSERT(iterator_param != NULL); | 9818 ASSERT(iterator_param != NULL); |
| 9815 // Generate :iterator.current = expr; | 9819 // Generate :iterator.current = expr; |
| 9816 AstNode* iterator = | 9820 AstNode* iterator = |
| 9817 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param); | 9821 new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_param); |
| 9818 AstNode* store_current = | 9822 AstNode* store_current = |
| 9819 new(Z) InstanceSetterNode(Scanner::kNoSourcePos, | 9823 new(Z) InstanceSetterNode(Token::kNoSourcePos, |
| 9820 iterator, | 9824 iterator, |
| 9821 String::ZoneHandle(Symbols::Current().raw()), | 9825 String::ZoneHandle(Symbols::Current().raw()), |
| 9822 expr); | 9826 expr); |
| 9823 yield->AddNode(store_current); | 9827 yield->AddNode(store_current); |
| 9824 if (is_yield_each) { | 9828 if (is_yield_each) { |
| 9825 // Generate :iterator.isYieldEach = true; | 9829 // Generate :iterator.isYieldEach = true; |
| 9826 AstNode* set_is_yield_each = | 9830 AstNode* set_is_yield_each = |
| 9827 new(Z) InstanceSetterNode(Scanner::kNoSourcePos, | 9831 new(Z) InstanceSetterNode(Token::kNoSourcePos, |
| 9828 iterator, | 9832 iterator, |
| 9829 String::ZoneHandle(Symbols::IsYieldEach().raw()), | 9833 String::ZoneHandle(Symbols::IsYieldEach().raw()), |
| 9830 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9834 new(Z) LiteralNode(TokenPos(), Bool::True())); |
| 9831 yield->AddNode(set_is_yield_each); | 9835 yield->AddNode(set_is_yield_each); |
| 9832 } | 9836 } |
| 9833 AwaitMarkerNode* await_marker = | 9837 AwaitMarkerNode* await_marker = |
| 9834 new(Z) AwaitMarkerNode(async_temp_scope_, | 9838 new(Z) AwaitMarkerNode(async_temp_scope_, |
| 9835 current_block_->scope, | 9839 current_block_->scope, |
| 9836 Scanner::kNoSourcePos); | 9840 Token::kNoSourcePos); |
| 9837 yield->AddNode(await_marker); | 9841 yield->AddNode(await_marker); |
| 9838 // Return true to indicate that a value has been generated. | 9842 // Return true to indicate that a value has been generated. |
| 9839 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, | 9843 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, |
| 9840 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9844 new(Z) LiteralNode(TokenPos(), Bool::True())); |
| 9841 return_true->set_return_type(ReturnNode::kContinuationTarget); | 9845 return_true->set_return_type(ReturnNode::kContinuationTarget); |
| 9842 yield->AddNode(return_true); | 9846 yield->AddNode(return_true); |
| 9843 | 9847 |
| 9844 // If this expression is part of a try block, also append the code for | 9848 // If this expression is part of a try block, also append the code for |
| 9845 // restoring the saved try context that lives on the stack and possibly the | 9849 // restoring the saved try context that lives on the stack and possibly the |
| 9846 // saved try context of the outer try block. | 9850 // saved try context of the outer try block. |
| 9847 LocalVariable* saved_try_ctx; | 9851 LocalVariable* saved_try_ctx; |
| 9848 LocalVariable* async_saved_try_ctx; | 9852 LocalVariable* async_saved_try_ctx; |
| 9849 LocalVariable* outer_saved_try_ctx; | 9853 LocalVariable* outer_saved_try_ctx; |
| 9850 LocalVariable* outer_async_saved_try_ctx; | 9854 LocalVariable* outer_async_saved_try_ctx; |
| 9851 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9855 CheckAsyncOpInTryBlock(&saved_try_ctx, |
| 9852 &async_saved_try_ctx, | 9856 &async_saved_try_ctx, |
| 9853 &outer_saved_try_ctx, | 9857 &outer_saved_try_ctx, |
| 9854 &outer_async_saved_try_ctx); | 9858 &outer_async_saved_try_ctx); |
| 9855 if (saved_try_ctx != NULL) { | 9859 if (saved_try_ctx != NULL) { |
| 9856 yield->AddNode(new (Z) StoreLocalNode( | 9860 yield->AddNode(new (Z) StoreLocalNode( |
| 9857 Scanner::kNoSourcePos, | 9861 Token::kNoSourcePos, |
| 9858 saved_try_ctx, | 9862 saved_try_ctx, |
| 9859 new (Z) LoadLocalNode(Scanner::kNoSourcePos, | 9863 new (Z) LoadLocalNode(Token::kNoSourcePos, |
| 9860 async_saved_try_ctx))); | 9864 async_saved_try_ctx))); |
| 9861 if (outer_saved_try_ctx != NULL) { | 9865 if (outer_saved_try_ctx != NULL) { |
| 9862 yield->AddNode(new (Z) StoreLocalNode( | 9866 yield->AddNode(new (Z) StoreLocalNode( |
| 9863 Scanner::kNoSourcePos, | 9867 Token::kNoSourcePos, |
| 9864 outer_saved_try_ctx, | 9868 outer_saved_try_ctx, |
| 9865 new (Z) LoadLocalNode(Scanner::kNoSourcePos, | 9869 new (Z) LoadLocalNode(Token::kNoSourcePos, |
| 9866 outer_async_saved_try_ctx))); | 9870 outer_async_saved_try_ctx))); |
| 9867 } | 9871 } |
| 9868 } else { | 9872 } else { |
| 9869 ASSERT(outer_saved_try_ctx == NULL); | 9873 ASSERT(outer_saved_try_ctx == NULL); |
| 9870 } | 9874 } |
| 9871 } else { | 9875 } else { |
| 9872 // yield statement in async* function. | 9876 // yield statement in async* function. |
| 9873 ASSERT(innermost_function().IsAsyncGenerator() || | 9877 ASSERT(innermost_function().IsAsyncGenerator() || |
| 9874 innermost_function().IsAsyncGenClosure()); | 9878 innermost_function().IsAsyncGenClosure()); |
| 9875 | 9879 |
| 9876 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); | 9880 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); |
| 9877 ASSERT(controller_var != NULL); | 9881 ASSERT(controller_var != NULL); |
| 9878 // :controller.add[Stream](expr); | 9882 // :controller.add[Stream](expr); |
| 9879 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); | 9883 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); |
| 9880 add_args->Add(expr); | 9884 add_args->Add(expr); |
| 9881 AstNode* add_call = | 9885 AstNode* add_call = |
| 9882 new(Z) InstanceCallNode(yield_pos, | 9886 new(Z) InstanceCallNode(yield_pos, |
| 9883 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller_var), | 9887 new(Z) LoadLocalNode(Token::kNoSourcePos, controller_var), |
| 9884 is_yield_each ? Symbols::AddStream() : Symbols::add(), | 9888 is_yield_each ? Symbols::AddStream() : Symbols::add(), |
| 9885 add_args); | 9889 add_args); |
| 9886 | 9890 |
| 9887 // if (:controller.add[Stream](expr)) { | 9891 // if (:controller.add[Stream](expr)) { |
| 9888 // return; | 9892 // return; |
| 9889 // } | 9893 // } |
| 9890 // await_marker; | 9894 // await_marker; |
| 9891 // continuation_return; | 9895 // continuation_return; |
| 9892 // restore saved_try_context | 9896 // restore saved_try_context |
| 9893 | 9897 |
| 9894 SequenceNode* true_branch = | 9898 SequenceNode* true_branch = |
| 9895 new(Z) SequenceNode(Scanner::kNoSourcePos, NULL); | 9899 new(Z) SequenceNode(Token::kNoSourcePos, NULL); |
| 9896 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); | 9900 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); |
| 9897 true_branch->Add(return_from_generator); | 9901 true_branch->Add(return_from_generator); |
| 9898 AddNodeForFinallyInlining(return_from_generator); | 9902 AddNodeForFinallyInlining(return_from_generator); |
| 9899 AstNode* if_is_cancelled = | 9903 AstNode* if_is_cancelled = |
| 9900 new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL); | 9904 new(Z) IfNode(Token::kNoSourcePos, add_call, true_branch, NULL); |
| 9901 yield->AddNode(if_is_cancelled); | 9905 yield->AddNode(if_is_cancelled); |
| 9902 | 9906 |
| 9903 AwaitMarkerNode* await_marker = | 9907 AwaitMarkerNode* await_marker = |
| 9904 new(Z) AwaitMarkerNode(async_temp_scope_, | 9908 new(Z) AwaitMarkerNode(async_temp_scope_, |
| 9905 current_block_->scope, | 9909 current_block_->scope, |
| 9906 Scanner::kNoSourcePos); | 9910 Token::kNoSourcePos); |
| 9907 yield->AddNode(await_marker); | 9911 yield->AddNode(await_marker); |
| 9908 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); | 9912 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); |
| 9909 continuation_return->set_return_type(ReturnNode::kContinuationTarget); | 9913 continuation_return->set_return_type(ReturnNode::kContinuationTarget); |
| 9910 yield->AddNode(continuation_return); | 9914 yield->AddNode(continuation_return); |
| 9911 | 9915 |
| 9912 // If this expression is part of a try block, also append the code for | 9916 // If this expression is part of a try block, also append the code for |
| 9913 // restoring the saved try context that lives on the stack and possibly the | 9917 // restoring the saved try context that lives on the stack and possibly the |
| 9914 // saved try context of the outer try block. | 9918 // saved try context of the outer try block. |
| 9915 LocalVariable* saved_try_ctx; | 9919 LocalVariable* saved_try_ctx; |
| 9916 LocalVariable* async_saved_try_ctx; | 9920 LocalVariable* async_saved_try_ctx; |
| 9917 LocalVariable* outer_saved_try_ctx; | 9921 LocalVariable* outer_saved_try_ctx; |
| 9918 LocalVariable* outer_async_saved_try_ctx; | 9922 LocalVariable* outer_async_saved_try_ctx; |
| 9919 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9923 CheckAsyncOpInTryBlock(&saved_try_ctx, |
| 9920 &async_saved_try_ctx, | 9924 &async_saved_try_ctx, |
| 9921 &outer_saved_try_ctx, | 9925 &outer_saved_try_ctx, |
| 9922 &outer_async_saved_try_ctx); | 9926 &outer_async_saved_try_ctx); |
| 9923 if (saved_try_ctx != NULL) { | 9927 if (saved_try_ctx != NULL) { |
| 9924 yield->AddNode(new (Z) StoreLocalNode( | 9928 yield->AddNode(new (Z) StoreLocalNode( |
| 9925 Scanner::kNoSourcePos, | 9929 Token::kNoSourcePos, |
| 9926 saved_try_ctx, | 9930 saved_try_ctx, |
| 9927 new (Z) LoadLocalNode(Scanner::kNoSourcePos, | 9931 new (Z) LoadLocalNode(Token::kNoSourcePos, |
| 9928 async_saved_try_ctx))); | 9932 async_saved_try_ctx))); |
| 9929 if (outer_saved_try_ctx != NULL) { | 9933 if (outer_saved_try_ctx != NULL) { |
| 9930 yield->AddNode(new (Z) StoreLocalNode( | 9934 yield->AddNode(new (Z) StoreLocalNode( |
| 9931 Scanner::kNoSourcePos, | 9935 Token::kNoSourcePos, |
| 9932 outer_saved_try_ctx, | 9936 outer_saved_try_ctx, |
| 9933 new (Z) LoadLocalNode(Scanner::kNoSourcePos, | 9937 new (Z) LoadLocalNode(Token::kNoSourcePos, |
| 9934 outer_async_saved_try_ctx))); | 9938 outer_async_saved_try_ctx))); |
| 9935 } | 9939 } |
| 9936 } else { | 9940 } else { |
| 9937 ASSERT(outer_saved_try_ctx == NULL); | 9941 ASSERT(outer_saved_try_ctx == NULL); |
| 9938 } | 9942 } |
| 9939 } | 9943 } |
| 9940 return yield; | 9944 return yield; |
| 9941 } | 9945 } |
| 9942 | 9946 |
| 9943 | 9947 |
| 9944 AstNode* Parser::ParseStatement() { | 9948 AstNode* Parser::ParseStatement() { |
| 9945 TRACE_PARSER("ParseStatement"); | 9949 TRACE_PARSER("ParseStatement"); |
| 9946 AstNode* statement = NULL; | 9950 AstNode* statement = NULL; |
| 9947 intptr_t label_pos = Scanner::kNoSourcePos; | 9951 intptr_t label_pos = Token::kNoSourcePos; |
| 9948 String* label_name = NULL; | 9952 String* label_name = NULL; |
| 9949 if (IsIdentifier()) { | 9953 if (IsIdentifier()) { |
| 9950 if (LookaheadToken(1) == Token::kCOLON) { | 9954 if (LookaheadToken(1) == Token::kCOLON) { |
| 9951 // Statement starts with a label. | 9955 // Statement starts with a label. |
| 9952 label_name = CurrentLiteral(); | 9956 label_name = CurrentLiteral(); |
| 9953 label_pos = TokenPos(); | 9957 label_pos = TokenPos(); |
| 9954 ASSERT(label_pos >= 0); | 9958 ASSERT(label_pos >= 0); |
| 9955 ConsumeToken(); // Consume identifier. | 9959 ConsumeToken(); // Consume identifier. |
| 9956 ConsumeToken(); // Consume colon. | 9960 ConsumeToken(); // Consume colon. |
| 9957 } | 9961 } |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10526 old->token_pos(), old->kind(), old->left(), old->right(), val); | 10530 old->token_pos(), old->kind(), old->left(), old->right(), val); |
| 10527 return binop; | 10531 return binop; |
| 10528 } | 10532 } |
| 10529 } | 10533 } |
| 10530 } | 10534 } |
| 10531 } | 10535 } |
| 10532 if (binary_op == Token::kIFNULL) { | 10536 if (binary_op == Token::kIFNULL) { |
| 10533 // Handle a ?? b. | 10537 // Handle a ?? b. |
| 10534 LetNode* result = new(Z) LetNode(op_pos); | 10538 LetNode* result = new(Z) LetNode(op_pos); |
| 10535 LocalVariable* left_temp = result->AddInitializer(lhs); | 10539 LocalVariable* left_temp = result->AddInitializer(lhs); |
| 10536 const intptr_t no_pos = Scanner::kNoSourcePos; | 10540 const intptr_t no_pos = Token::kNoSourcePos; |
| 10537 LiteralNode* null_operand = | 10541 LiteralNode* null_operand = |
| 10538 new(Z) LiteralNode(no_pos, Object::null_instance()); | 10542 new(Z) LiteralNode(no_pos, Object::null_instance()); |
| 10539 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); | 10543 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); |
| 10540 ComparisonNode* null_compare = | 10544 ComparisonNode* null_compare = |
| 10541 new(Z) ComparisonNode(no_pos, | 10545 new(Z) ComparisonNode(no_pos, |
| 10542 Token::kNE_STRICT, | 10546 Token::kNE_STRICT, |
| 10543 load_left_temp, | 10547 load_left_temp, |
| 10544 null_operand); | 10548 null_operand); |
| 10545 result->AddNode(new(Z) ConditionalExprNode(op_pos, | 10549 result->AddNode(new(Z) ConditionalExprNode(op_pos, |
| 10546 null_compare, | 10550 null_compare, |
| (...skipping 3870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14417 const ArgumentListNode& function_args, | 14421 const ArgumentListNode& function_args, |
| 14418 const LocalVariable* temp_for_last_arg, | 14422 const LocalVariable* temp_for_last_arg, |
| 14419 bool is_super_invocation) { | 14423 bool is_super_invocation) { |
| 14420 UNREACHABLE(); | 14424 UNREACHABLE(); |
| 14421 return NULL; | 14425 return NULL; |
| 14422 } | 14426 } |
| 14423 | 14427 |
| 14424 } // namespace dart | 14428 } // namespace dart |
| 14425 | 14429 |
| 14426 #endif // DART_PRECOMPILED_RUNTIME | 14430 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |