| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 case RawFunction::kInvokeFieldDispatcher: | 827 case RawFunction::kInvokeFieldDispatcher: |
| 828 node_sequence = | 828 node_sequence = |
| 829 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values); | 829 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values); |
| 830 break; | 830 break; |
| 831 default: | 831 default: |
| 832 UNREACHABLE(); | 832 UNREACHABLE(); |
| 833 } | 833 } |
| 834 | 834 |
| 835 if (!HasReturnNode(node_sequence)) { | 835 if (!HasReturnNode(node_sequence)) { |
| 836 // Add implicit return node. | 836 // Add implicit return node. |
| 837 node_sequence->Add(new ReturnNode(func.end_token_pos())); | 837 ReturnNode* implicit_return = |
| 838 new(Isolate::Current()) ReturnNode(func.end_token_pos(), |
| 839 node_sequence->scope()); |
| 840 node_sequence->Add(implicit_return); |
| 838 } | 841 } |
| 839 if (parsed_function->has_expression_temp_var()) { | 842 if (parsed_function->has_expression_temp_var()) { |
| 840 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | 843 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); |
| 841 } | 844 } |
| 842 if (parsed_function->has_saved_current_context_var()) { | 845 if (parsed_function->has_saved_current_context_var()) { |
| 843 node_sequence->scope()->AddVariable( | 846 node_sequence->scope()->AddVariable( |
| 844 parsed_function->saved_current_context_var()); | 847 parsed_function->saved_current_context_var()); |
| 845 } | 848 } |
| 846 parsed_function->SetNodeSequence(node_sequence); | 849 parsed_function->SetNodeSequence(node_sequence); |
| 847 | 850 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 // We don't want to use ParseConstExpr() here because we don't want | 1012 // We don't want to use ParseConstExpr() here because we don't want |
| 1010 // the constant folding code to create, compile and execute a code | 1013 // the constant folding code to create, compile and execute a code |
| 1011 // fragment to evaluate the expression. Instead, we just make sure | 1014 // fragment to evaluate the expression. Instead, we just make sure |
| 1012 // the static const field initializer is a constant expression and | 1015 // the static const field initializer is a constant expression and |
| 1013 // leave the evaluation to the getter function. | 1016 // leave the evaluation to the getter function. |
| 1014 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1017 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1015 // This getter will only be called once at compile time. | 1018 // This getter will only be called once at compile time. |
| 1016 if (expr->EvalConstExpr() == NULL) { | 1019 if (expr->EvalConstExpr() == NULL) { |
| 1017 ReportError(expr_pos, "initializer is not a valid compile-time constant"); | 1020 ReportError(expr_pos, "initializer is not a valid compile-time constant"); |
| 1018 } | 1021 } |
| 1019 ReturnNode* return_node = new ReturnNode(ident_pos, expr); | 1022 ReturnNode* return_node = |
| 1023 new ReturnNode(ident_pos, expr, current_block_->scope); |
| 1020 current_block_->statements->Add(return_node); | 1024 current_block_->statements->Add(return_node); |
| 1021 } else { | 1025 } else { |
| 1022 // This getter may be called each time the static field is accessed. | 1026 // This getter may be called each time the static field is accessed. |
| 1023 // The following generated code lazily initializes the field: | 1027 // The following generated code lazily initializes the field: |
| 1024 // if (field.value === transition_sentinel) { | 1028 // if (field.value === transition_sentinel) { |
| 1025 // field.value = null; | 1029 // field.value = null; |
| 1026 // throw("circular dependency in field initialization"); | 1030 // throw("circular dependency in field initialization"); |
| 1027 // } | 1031 // } |
| 1028 // if (field.value === sentinel) { | 1032 // if (field.value === sentinel) { |
| 1029 // field.value = transition_sentinel; | 1033 // field.value = transition_sentinel; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 new StaticCallNode(expr_pos, init_function, arguments); | 1084 new StaticCallNode(expr_pos, init_function, arguments); |
| 1081 initialize_field->Add(init_call); | 1085 initialize_field->Add(init_call); |
| 1082 | 1086 |
| 1083 AstNode* uninitialized_check = | 1087 AstNode* uninitialized_check = |
| 1084 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); | 1088 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); |
| 1085 current_block_->statements->Add(uninitialized_check); | 1089 current_block_->statements->Add(uninitialized_check); |
| 1086 | 1090 |
| 1087 // Generate code returning the field value. | 1091 // Generate code returning the field value. |
| 1088 ReturnNode* return_node = | 1092 ReturnNode* return_node = |
| 1089 new ReturnNode(ident_pos, | 1093 new ReturnNode(ident_pos, |
| 1090 new LoadStaticFieldNode(ident_pos, field)); | 1094 new LoadStaticFieldNode(ident_pos, field), |
| 1095 current_block_->scope); |
| 1091 current_block_->statements->Add(return_node); | 1096 current_block_->statements->Add(return_node); |
| 1092 } | 1097 } |
| 1093 return CloseBlock(); | 1098 return CloseBlock(); |
| 1094 } | 1099 } |
| 1095 | 1100 |
| 1096 | 1101 |
| 1097 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { | 1102 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { |
| 1098 TRACE_PARSER("ParseStaticInitializer"); | 1103 TRACE_PARSER("ParseStaticInitializer"); |
| 1099 ParamList params; | 1104 ParamList params; |
| 1100 ASSERT(func.num_fixed_parameters() == 0); // static. | 1105 ASSERT(func.num_fixed_parameters() == 0); // static. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1227 ASSERT(IsIdentifier()); | 1232 ASSERT(IsIdentifier()); |
| 1228 const String& field_name = *CurrentLiteral(); | 1233 const String& field_name = *CurrentLiteral(); |
| 1229 const Class& field_class = Class::Handle(I, func.Owner()); | 1234 const Class& field_class = Class::Handle(I, func.Owner()); |
| 1230 const Field& field = | 1235 const Field& field = |
| 1231 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); | 1236 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); |
| 1232 | 1237 |
| 1233 LoadInstanceFieldNode* load_field = | 1238 LoadInstanceFieldNode* load_field = |
| 1234 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1239 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
| 1235 | 1240 |
| 1236 ReturnNode* return_node = | 1241 ReturnNode* return_node = |
| 1237 new ReturnNode(Scanner::kNoSourcePos, load_field); | 1242 new ReturnNode(Scanner::kNoSourcePos, load_field, current_block_->scope); |
| 1238 current_block_->statements->Add(return_node); | 1243 current_block_->statements->Add(return_node); |
| 1239 return CloseBlock(); | 1244 return CloseBlock(); |
| 1240 } | 1245 } |
| 1241 | 1246 |
| 1242 | 1247 |
| 1243 // Create AstNodes for an implicit instance setter method: | 1248 // Create AstNodes for an implicit instance setter method: |
| 1244 // LoadLocalNode 0 ('this') | 1249 // LoadLocalNode 0 ('this') |
| 1245 // LoadLocalNode 1 ('value') | 1250 // LoadLocalNode 1 ('value') |
| 1246 // SetInstanceField (field_name); | 1251 // SetInstanceField (field_name); |
| 1247 // ReturnNode (void); | 1252 // ReturnNode (void); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1271 | 1276 |
| 1272 LoadLocalNode* receiver = | 1277 LoadLocalNode* receiver = |
| 1273 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); | 1278 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); |
| 1274 LoadLocalNode* value = | 1279 LoadLocalNode* value = |
| 1275 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); | 1280 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); |
| 1276 | 1281 |
| 1277 EnsureExpressionTemp(); | 1282 EnsureExpressionTemp(); |
| 1278 StoreInstanceFieldNode* store_field = | 1283 StoreInstanceFieldNode* store_field = |
| 1279 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1284 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
| 1280 current_block_->statements->Add(store_field); | 1285 current_block_->statements->Add(store_field); |
| 1281 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 1286 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos, NULL)); |
| 1282 return CloseBlock(); | 1287 return CloseBlock(); |
| 1283 } | 1288 } |
| 1284 | 1289 |
| 1285 | 1290 |
| 1286 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1291 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
| 1287 TRACE_PARSER("ParseMethodExtractor"); | 1292 TRACE_PARSER("ParseMethodExtractor"); |
| 1288 ParamList params; | 1293 ParamList params; |
| 1289 | 1294 |
| 1290 const intptr_t ident_pos = func.token_pos(); | 1295 const intptr_t ident_pos = func.token_pos(); |
| 1291 ASSERT(func.token_pos() == 0); | 1296 ASSERT(func.token_pos() == 0); |
| 1292 ASSERT(current_class().raw() == func.Owner()); | 1297 ASSERT(current_class().raw() == func.Owner()); |
| 1293 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1298 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1294 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1299 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
| 1295 ASSERT(!func.HasOptionalParameters()); | 1300 ASSERT(!func.HasOptionalParameters()); |
| 1296 | 1301 |
| 1297 // Build local scope for function and populate with the formal parameters. | 1302 // Build local scope for function and populate with the formal parameters. |
| 1298 OpenFunctionBlock(func); | 1303 OpenFunctionBlock(func); |
| 1299 AddFormalParamsToScope(¶ms, current_block_->scope); | 1304 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1300 | 1305 |
| 1301 // Receiver is local 0. | 1306 // Receiver is local 0. |
| 1302 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1307 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1303 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1308 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1304 | 1309 |
| 1305 ClosureNode* closure = new ClosureNode( | 1310 ClosureNode* closure = new ClosureNode( |
| 1306 ident_pos, | 1311 ident_pos, |
| 1307 Function::ZoneHandle(I, func.extracted_method_closure()), | 1312 Function::ZoneHandle(I, func.extracted_method_closure()), |
| 1308 load_receiver, | 1313 load_receiver, |
| 1309 NULL); | 1314 NULL); |
| 1310 | 1315 |
| 1311 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure); | 1316 ReturnNode* return_node = |
| 1317 new ReturnNode(Scanner::kNoSourcePos, closure, current_block_->scope); |
| 1312 current_block_->statements->Add(return_node); | 1318 current_block_->statements->Add(return_node); |
| 1313 return CloseBlock(); | 1319 return CloseBlock(); |
| 1314 } | 1320 } |
| 1315 | 1321 |
| 1316 | 1322 |
| 1317 void Parser::BuildDispatcherScope(const Function& func, | 1323 void Parser::BuildDispatcherScope(const Function& func, |
| 1318 const ArgumentsDescriptor& desc, | 1324 const ArgumentsDescriptor& desc, |
| 1319 Array* default_values) { | 1325 Array* default_values) { |
| 1320 ParamList params; | 1326 ParamList params; |
| 1321 // Receiver first. | 1327 // Receiver first. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1398 if (no_such_method.IsNull()) { | 1404 if (no_such_method.IsNull()) { |
| 1399 // If noSuchMethod(i) is not found, call Object:noSuchMethod. | 1405 // If noSuchMethod(i) is not found, call Object:noSuchMethod. |
| 1400 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( | 1406 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( |
| 1401 Class::Handle(I, I->object_store()->object_class()), | 1407 Class::Handle(I, I->object_store()->object_class()), |
| 1402 Symbols::NoSuchMethod(), | 1408 Symbols::NoSuchMethod(), |
| 1403 args_desc); | 1409 args_desc); |
| 1404 } | 1410 } |
| 1405 StaticCallNode* call = | 1411 StaticCallNode* call = |
| 1406 new StaticCallNode(token_pos, no_such_method, arguments); | 1412 new StaticCallNode(token_pos, no_such_method, arguments); |
| 1407 | 1413 |
| 1408 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1414 ReturnNode* return_node = new ReturnNode(token_pos, call, NULL); |
| 1409 current_block_->statements->Add(return_node); | 1415 current_block_->statements->Add(return_node); |
| 1410 return CloseBlock(); | 1416 return CloseBlock(); |
| 1411 } | 1417 } |
| 1412 | 1418 |
| 1413 | 1419 |
| 1414 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, | 1420 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, |
| 1415 Array* default_values) { | 1421 Array* default_values) { |
| 1416 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1422 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
| 1417 | 1423 |
| 1418 ASSERT(func.IsInvokeFieldDispatcher()); | 1424 ASSERT(func.IsInvokeFieldDispatcher()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1458 const Class& owner = Class::Handle(I, func.Owner()); | 1464 const Class& owner = Class::Handle(I, func.Owner()); |
| 1459 ASSERT(!owner.IsNull()); | 1465 ASSERT(!owner.IsNull()); |
| 1460 AstNode* result = NULL; | 1466 AstNode* result = NULL; |
| 1461 if (owner.IsSignatureClass() && name.Equals(Symbols::Call())) { | 1467 if (owner.IsSignatureClass() && name.Equals(Symbols::Call())) { |
| 1462 EnsureSavedCurrentContext(); | 1468 EnsureSavedCurrentContext(); |
| 1463 result = new ClosureCallNode(token_pos, getter_call, args); | 1469 result = new ClosureCallNode(token_pos, getter_call, args); |
| 1464 } else { | 1470 } else { |
| 1465 result = BuildClosureCall(token_pos, getter_call, args); | 1471 result = BuildClosureCall(token_pos, getter_call, args); |
| 1466 } | 1472 } |
| 1467 | 1473 |
| 1468 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1474 ReturnNode* return_node = new ReturnNode(token_pos, result, NULL); |
| 1469 current_block_->statements->Add(return_node); | 1475 current_block_->statements->Add(return_node); |
| 1470 return CloseBlock(); | 1476 return CloseBlock(); |
| 1471 } | 1477 } |
| 1472 | 1478 |
| 1473 | 1479 |
| 1474 AstNode* Parser::BuildClosureCall(intptr_t token_pos, | 1480 AstNode* Parser::BuildClosureCall(intptr_t token_pos, |
| 1475 AstNode* closure, | 1481 AstNode* closure, |
| 1476 ArgumentListNode* arguments) { | 1482 ArgumentListNode* arguments) { |
| 1477 return new InstanceCallNode(token_pos, | 1483 return new InstanceCallNode(token_pos, |
| 1478 closure, | 1484 closure, |
| (...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2569 } | 2575 } |
| 2570 } | 2576 } |
| 2571 | 2577 |
| 2572 GenerateSuperConstructorCall(current_class(), | 2578 GenerateSuperConstructorCall(current_class(), |
| 2573 Scanner::kNoSourcePos, | 2579 Scanner::kNoSourcePos, |
| 2574 receiver, | 2580 receiver, |
| 2575 forwarding_args); | 2581 forwarding_args); |
| 2576 CheckFieldsInitialized(current_class()); | 2582 CheckFieldsInitialized(current_class()); |
| 2577 | 2583 |
| 2578 // Empty constructor body. | 2584 // Empty constructor body. |
| 2579 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 2585 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos, NULL)); |
| 2580 SequenceNode* statements = CloseBlock(); | 2586 SequenceNode* statements = CloseBlock(); |
| 2581 return statements; | 2587 return statements; |
| 2582 } | 2588 } |
| 2583 | 2589 |
| 2584 | 2590 |
| 2585 void Parser::CheckRecursiveInvocation() { | 2591 void Parser::CheckRecursiveInvocation() { |
| 2586 const GrowableObjectArray& pending_functions = | 2592 const GrowableObjectArray& pending_functions = |
| 2587 GrowableObjectArray::Handle(I, | 2593 GrowableObjectArray::Handle(I, |
| 2588 I->object_store()->pending_functions()); | 2594 I->object_store()->pending_functions()); |
| 2589 for (int i = 0; i < pending_functions.Length(); i++) { | 2595 for (int i = 0; i < pending_functions.Length(); i++) { |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2888 AstNode* comparison = | 2894 AstNode* comparison = |
| 2889 new ComparisonNode(Scanner::kNoSourcePos, | 2895 new ComparisonNode(Scanner::kNoSourcePos, |
| 2890 Token::kNE_STRICT, | 2896 Token::kNE_STRICT, |
| 2891 phase_check, | 2897 phase_check, |
| 2892 new LiteralNode(body_pos, | 2898 new LiteralNode(body_pos, |
| 2893 Smi::ZoneHandle(Smi::New(0)))); | 2899 Smi::ZoneHandle(Smi::New(0)))); |
| 2894 AstNode* guarded_block_statements = | 2900 AstNode* guarded_block_statements = |
| 2895 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); | 2901 new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL); |
| 2896 current_block_->statements->Add(guarded_block_statements); | 2902 current_block_->statements->Add(guarded_block_statements); |
| 2897 } | 2903 } |
| 2898 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 2904 current_block_->statements->Add(new ReturnNode(func.end_token_pos(), NULL)); |
| 2899 SequenceNode* statements = CloseBlock(); | 2905 SequenceNode* statements = CloseBlock(); |
| 2900 return statements; | 2906 return statements; |
| 2901 } | 2907 } |
| 2902 | 2908 |
| 2903 | 2909 |
| 2904 // TODO(mlippautz): Once we know where these classes should come from, adjust | 2910 // TODO(mlippautz): Once we know where these classes should come from, adjust |
| 2905 // how we get their definition. | 2911 // how we get their definition. |
| 2906 RawClass* Parser::GetClassForAsync(const String& class_name) { | 2912 RawClass* Parser::GetClassForAsync(const String& class_name) { |
| 2907 const Class& cls = Class::Handle(library_.LookupClass(class_name)); | 2913 const Class& cls = Class::Handle(library_.LookupClass(class_name)); |
| 2908 if (cls.IsNull()) { | 2914 if (cls.IsNull()) { |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3047 if (String::Handle(I, func.name()).Equals( | 3053 if (String::Handle(I, func.name()).Equals( |
| 3048 Symbols::EqualOperator())) { | 3054 Symbols::EqualOperator())) { |
| 3049 const Class& owner = Class::Handle(I, func.Owner()); | 3055 const Class& owner = Class::Handle(I, func.Owner()); |
| 3050 if (!owner.IsObjectClass()) { | 3056 if (!owner.IsObjectClass()) { |
| 3051 AddEqualityNullCheck(); | 3057 AddEqualityNullCheck(); |
| 3052 } | 3058 } |
| 3053 } | 3059 } |
| 3054 const intptr_t expr_pos = TokenPos(); | 3060 const intptr_t expr_pos = TokenPos(); |
| 3055 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 3061 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 3056 ASSERT(expr != NULL); | 3062 ASSERT(expr != NULL); |
| 3057 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3063 current_block_->statements->Add( |
| 3064 new ReturnNode(expr_pos, expr, current_block_->scope)); |
| 3058 end_token_pos = TokenPos(); | 3065 end_token_pos = TokenPos(); |
| 3059 } else if (IsLiteral("native")) { | 3066 } else if (IsLiteral("native")) { |
| 3060 if (String::Handle(I, func.name()).Equals( | 3067 if (String::Handle(I, func.name()).Equals( |
| 3061 Symbols::EqualOperator())) { | 3068 Symbols::EqualOperator())) { |
| 3062 const Class& owner = Class::Handle(I, func.Owner()); | 3069 const Class& owner = Class::Handle(I, func.Owner()); |
| 3063 if (!owner.IsObjectClass()) { | 3070 if (!owner.IsObjectClass()) { |
| 3064 AddEqualityNullCheck(); | 3071 AddEqualityNullCheck(); |
| 3065 } | 3072 } |
| 3066 } | 3073 } |
| 3067 ParseNativeFunctionBlock(¶ms, func); | 3074 ParseNativeFunctionBlock(¶ms, func); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3111 new ComparisonNode(Scanner::kNoSourcePos, | 3118 new ComparisonNode(Scanner::kNoSourcePos, |
| 3112 Token::kEQ_STRICT, | 3119 Token::kEQ_STRICT, |
| 3113 argument, | 3120 argument, |
| 3114 null_operand); | 3121 null_operand); |
| 3115 ComparisonNode* result = | 3122 ComparisonNode* result = |
| 3116 new ComparisonNode(Scanner::kNoSourcePos, | 3123 new ComparisonNode(Scanner::kNoSourcePos, |
| 3117 Token::kEQ_STRICT, | 3124 Token::kEQ_STRICT, |
| 3118 LoadReceiver(Scanner::kNoSourcePos), | 3125 LoadReceiver(Scanner::kNoSourcePos), |
| 3119 null_operand); | 3126 null_operand); |
| 3120 SequenceNode* arg_is_null = new SequenceNode(Scanner::kNoSourcePos, NULL); | 3127 SequenceNode* arg_is_null = new SequenceNode(Scanner::kNoSourcePos, NULL); |
| 3121 arg_is_null->Add(new ReturnNode(Scanner::kNoSourcePos, result)); | 3128 arg_is_null->Add( |
| 3129 new ReturnNode(Scanner::kNoSourcePos, result, current_block_->scope)); |
| 3122 IfNode* if_arg_null = new IfNode(Scanner::kNoSourcePos, | 3130 IfNode* if_arg_null = new IfNode(Scanner::kNoSourcePos, |
| 3123 check_arg, | 3131 check_arg, |
| 3124 arg_is_null, | 3132 arg_is_null, |
| 3125 NULL); | 3133 NULL); |
| 3126 current_block_->statements->Add(if_arg_null); | 3134 current_block_->statements->Add(if_arg_null); |
| 3127 } | 3135 } |
| 3128 | 3136 |
| 3129 | 3137 |
| 3130 void Parser::SkipIf(Token::Kind token) { | 3138 void Parser::SkipIf(Token::Kind token) { |
| 3131 if (CurrentToken() == token) { | 3139 if (CurrentToken() == token) { |
| (...skipping 2512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5644 | 5652 |
| 5645 // Add to AST: | 5653 // Add to AST: |
| 5646 // return :async_completer.future; | 5654 // return :async_completer.future; |
| 5647 ReturnNode* return_node = new (I) ReturnNode( | 5655 ReturnNode* return_node = new (I) ReturnNode( |
| 5648 Scanner::kNoSourcePos, | 5656 Scanner::kNoSourcePos, |
| 5649 new (I) InstanceGetterNode( | 5657 new (I) InstanceGetterNode( |
| 5650 Scanner::kNoSourcePos, | 5658 Scanner::kNoSourcePos, |
| 5651 new (I) LoadLocalNode( | 5659 new (I) LoadLocalNode( |
| 5652 Scanner::kNoSourcePos, | 5660 Scanner::kNoSourcePos, |
| 5653 async_completer), | 5661 async_completer), |
| 5654 Symbols::CompleterFuture())); | 5662 Symbols::CompleterFuture()), |
| 5663 current_block_->scope); |
| 5655 current_block_->statements->Add(return_node); | 5664 current_block_->statements->Add(return_node); |
| 5656 return CloseBlock(); | 5665 return CloseBlock(); |
| 5657 } | 5666 } |
| 5658 | 5667 |
| 5659 | 5668 |
| 5660 void Parser::CloseAsyncClosure(SequenceNode* body) { | 5669 void Parser::CloseAsyncClosure(SequenceNode* body) { |
| 5661 ASSERT(body != NULL); | 5670 // We need a temporary expression to store intermediate return values. |
| 5662 // Replace an optional ReturnNode with the appropriate completer calls. | 5671 parsed_function()->EnsureExpressionTemp(); |
| 5663 intptr_t last_index = body->length() - 1; | |
| 5664 AstNode* last = NULL; | |
| 5665 if (last_index >= 0) { | |
| 5666 // Non-empty async closure. | |
| 5667 last = body->NodeAt(last_index); | |
| 5668 } | |
| 5669 ArgumentListNode* args = new (I) ArgumentListNode(Scanner::kNoSourcePos); | |
| 5670 LocalVariable* completer = body->scope()->LookupVariable( | |
| 5671 Symbols::AsyncCompleter(), false); | |
| 5672 ASSERT(completer != NULL); | |
| 5673 if (last != NULL && last->IsReturnNode()) { | |
| 5674 // Replace | |
| 5675 // return <expr>; | |
| 5676 // with | |
| 5677 // completer.complete(<expr>); | |
| 5678 args->Add(body->NodeAt(last_index)->AsReturnNode()->value()); | |
| 5679 body->ReplaceNodeAt(last_index, | |
| 5680 new (I) InstanceCallNode( | |
| 5681 Scanner::kNoSourcePos, | |
| 5682 new (I) LoadLocalNode(Scanner::kNoSourcePos, completer), | |
| 5683 Symbols::CompleterComplete(), | |
| 5684 args)); | |
| 5685 } else { | |
| 5686 // Add to AST: | |
| 5687 // completer.complete(); | |
| 5688 body->Add( | |
| 5689 new (I) InstanceCallNode( | |
| 5690 Scanner::kNoSourcePos, | |
| 5691 new (I) LoadLocalNode(Scanner::kNoSourcePos, completer), | |
| 5692 Symbols::CompleterComplete(), | |
| 5693 args)); | |
| 5694 } | |
| 5695 } | 5672 } |
| 5696 | 5673 |
| 5697 | 5674 |
| 5698 // Set up default values for all optional parameters to the function. | 5675 // Set up default values for all optional parameters to the function. |
| 5699 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 5676 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
| 5700 Array* default_values) { | 5677 Array* default_values) { |
| 5701 if (params->num_optional_parameters > 0) { | 5678 if (params->num_optional_parameters > 0) { |
| 5702 // Build array of default parameter values. | 5679 // Build array of default parameter values. |
| 5703 ParamDesc* param = | 5680 ParamDesc* param = |
| 5704 params->parameters->data() + params->num_fixed_parameters; | 5681 params->parameters->data() + params->num_fixed_parameters; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5793 ReportError(native_pos, | 5770 ReportError(native_pos, |
| 5794 "native function '%s' (%" Pd " arguments) cannot be found", | 5771 "native function '%s' (%" Pd " arguments) cannot be found", |
| 5795 native_name.ToCString(), func.NumParameters()); | 5772 native_name.ToCString(), func.NumParameters()); |
| 5796 } | 5773 } |
| 5797 func.SetIsNativeAutoSetupScope(auto_setup_scope); | 5774 func.SetIsNativeAutoSetupScope(auto_setup_scope); |
| 5798 | 5775 |
| 5799 // Now add the NativeBodyNode and return statement. | 5776 // Now add the NativeBodyNode and return statement. |
| 5800 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); | 5777 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); |
| 5801 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); | 5778 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); |
| 5802 current_block_->statements->Add(new(I) ReturnNode( | 5779 current_block_->statements->Add(new(I) ReturnNode( |
| 5803 TokenPos(), new(I) NativeBodyNode( | 5780 TokenPos(), |
| 5781 new(I) NativeBodyNode( |
| 5804 TokenPos(), | 5782 TokenPos(), |
| 5805 Function::ZoneHandle(I, func.raw()), | 5783 Function::ZoneHandle(I, func.raw()), |
| 5806 native_name, | 5784 native_name, |
| 5807 native_function, | 5785 native_function, |
| 5808 current_block_->scope, | 5786 current_block_->scope, |
| 5809 is_bootstrap_native))); | 5787 is_bootstrap_native), |
| 5788 NULL)); |
| 5810 } | 5789 } |
| 5811 | 5790 |
| 5812 | 5791 |
| 5813 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 5792 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
| 5814 ASSERT(!current_function().is_static()); | 5793 ASSERT(!current_function().is_static()); |
| 5815 return from_scope->LookupVariable(Symbols::This(), test_only); | 5794 return from_scope->LookupVariable(Symbols::This(), test_only); |
| 5816 } | 5795 } |
| 5817 | 5796 |
| 5818 | 5797 |
| 5819 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, | 5798 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, |
| (...skipping 1877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7697 } else if (token == Token::kRETURN) { | 7676 } else if (token == Token::kRETURN) { |
| 7698 const intptr_t return_pos = TokenPos(); | 7677 const intptr_t return_pos = TokenPos(); |
| 7699 ConsumeToken(); | 7678 ConsumeToken(); |
| 7700 if (CurrentToken() != Token::kSEMICOLON) { | 7679 if (CurrentToken() != Token::kSEMICOLON) { |
| 7701 if (current_function().IsConstructor() && | 7680 if (current_function().IsConstructor() && |
| 7702 (current_block_->scope->function_level() == 0)) { | 7681 (current_block_->scope->function_level() == 0)) { |
| 7703 ReportError(return_pos, | 7682 ReportError(return_pos, |
| 7704 "return of a value not allowed in constructors"); | 7683 "return of a value not allowed in constructors"); |
| 7705 } | 7684 } |
| 7706 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 7685 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 7707 statement = new(I) ReturnNode(statement_pos, expr); | 7686 statement = new(I) ReturnNode(statement_pos, expr, current_block_->scope); |
| 7708 } else { | 7687 } else { |
| 7709 statement = new(I) ReturnNode(statement_pos); | 7688 statement = new(I) ReturnNode(statement_pos, current_block_->scope); |
| 7710 } | 7689 } |
| 7711 AddNodeForFinallyInlining(statement); | 7690 AddNodeForFinallyInlining(statement); |
| 7712 ExpectSemicolon(); | 7691 ExpectSemicolon(); |
| 7713 } else if (token == Token::kIF) { | 7692 } else if (token == Token::kIF) { |
| 7714 statement = ParseIfStatement(label_name); | 7693 statement = ParseIfStatement(label_name); |
| 7715 } else if (token == Token::kASSERT) { | 7694 } else if (token == Token::kASSERT) { |
| 7716 statement = ParseAssertStatement(); | 7695 statement = ParseAssertStatement(); |
| 7717 ExpectSemicolon(); | 7696 ExpectSemicolon(); |
| 7718 } else if (IsVariableDeclaration()) { | 7697 } else if (IsVariableDeclaration()) { |
| 7719 statement = ParseVariableDeclarationList(); | 7698 statement = ParseVariableDeclarationList(); |
| (...skipping 3247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10967 } else if (expr->IsLoadStaticFieldNode()) { | 10946 } else if (expr->IsLoadStaticFieldNode()) { |
| 10968 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 10947 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
| 10969 // We already checked that this field is const and has been | 10948 // We already checked that this field is const and has been |
| 10970 // initialized. | 10949 // initialized. |
| 10971 ASSERT(field.is_const()); | 10950 ASSERT(field.is_const()); |
| 10972 ASSERT(field.value() != Object::sentinel().raw()); | 10951 ASSERT(field.value() != Object::sentinel().raw()); |
| 10973 ASSERT(field.value() != Object::transition_sentinel().raw()); | 10952 ASSERT(field.value() != Object::transition_sentinel().raw()); |
| 10974 return Instance::ZoneHandle(I, field.value()); | 10953 return Instance::ZoneHandle(I, field.value()); |
| 10975 } else { | 10954 } else { |
| 10976 ASSERT(expr->EvalConstExpr() != NULL); | 10955 ASSERT(expr->EvalConstExpr() != NULL); |
| 10977 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr); | 10956 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr, NULL); |
| 10978 // Compile time constant expressions cannot reference anything from a | 10957 // Compile time constant expressions cannot reference anything from a |
| 10979 // local scope. | 10958 // local scope. |
| 10980 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); | 10959 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); |
| 10981 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), | 10960 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), |
| 10982 empty_scope); | 10961 empty_scope); |
| 10983 seq->Add(ret); | 10962 seq->Add(ret); |
| 10984 | 10963 |
| 10985 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); | 10964 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); |
| 10986 if (result.IsError()) { | 10965 if (result.IsError()) { |
| 10987 ReportErrors(Error::Cast(result), | 10966 ReportErrors(Error::Cast(result), |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11325 void Parser::SkipQualIdent() { | 11304 void Parser::SkipQualIdent() { |
| 11326 ASSERT(IsIdentifier()); | 11305 ASSERT(IsIdentifier()); |
| 11327 ConsumeToken(); | 11306 ConsumeToken(); |
| 11328 if (CurrentToken() == Token::kPERIOD) { | 11307 if (CurrentToken() == Token::kPERIOD) { |
| 11329 ConsumeToken(); // Consume the kPERIOD token. | 11308 ConsumeToken(); // Consume the kPERIOD token. |
| 11330 ExpectIdentifier("identifier expected after '.'"); | 11309 ExpectIdentifier("identifier expected after '.'"); |
| 11331 } | 11310 } |
| 11332 } | 11311 } |
| 11333 | 11312 |
| 11334 } // namespace dart | 11313 } // namespace dart |
| OLD | NEW |