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 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 | 1400 |
1401 const String& name = String::Handle(func.name()); | 1401 const String& name = String::Handle(func.name()); |
1402 const String& getter_name = | 1402 const String& getter_name = |
1403 String::ZoneHandle(Symbols::New(String::Handle(Field::GetterName(name)))); | 1403 String::ZoneHandle(Symbols::New(String::Handle(Field::GetterName(name)))); |
1404 InstanceCallNode* getter_call = new InstanceCallNode(token_pos, | 1404 InstanceCallNode* getter_call = new InstanceCallNode(token_pos, |
1405 receiver, | 1405 receiver, |
1406 getter_name, | 1406 getter_name, |
1407 no_args); | 1407 no_args); |
1408 | 1408 |
1409 // Pass arguments 1..n to the closure call. | 1409 // Pass arguments 1..n to the closure call. |
1410 ArgumentListNode* closure_args = new ArgumentListNode(token_pos); | 1410 ArgumentListNode* args = new ArgumentListNode(token_pos); |
1411 const Array& names = Array::Handle(Array::New(desc.NamedCount(), Heap::kOld)); | 1411 const Array& names = Array::Handle(Array::New(desc.NamedCount(), Heap::kOld)); |
1412 // Positional parameters. | 1412 // Positional parameters. |
1413 intptr_t i = 1; | 1413 intptr_t i = 1; |
1414 for (; i < desc.PositionalCount(); ++i) { | 1414 for (; i < desc.PositionalCount(); ++i) { |
1415 closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1415 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
1416 } | 1416 } |
1417 // Named parameters. | 1417 // Named parameters. |
1418 for (; i < desc.Count(); i++) { | 1418 for (; i < desc.Count(); i++) { |
1419 closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1419 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
1420 intptr_t index = i - desc.PositionalCount(); | 1420 intptr_t index = i - desc.PositionalCount(); |
1421 names.SetAt(index, String::Handle(desc.NameAt(index))); | 1421 names.SetAt(index, String::Handle(desc.NameAt(index))); |
1422 } | 1422 } |
1423 closure_args->set_names(names); | 1423 args->set_names(names); |
1424 | 1424 |
1425 EnsureSavedCurrentContext(); | 1425 const Class& owner = Class::Handle(func.Owner()); |
1426 ClosureCallNode* closure_call = new ClosureCallNode(token_pos, | 1426 ASSERT(!owner.IsNull()); |
1427 getter_call, | 1427 AstNode* result = NULL; |
1428 closure_args); | 1428 if (owner.IsSignatureClass() && name.Equals(Symbols::Call())) { |
| 1429 EnsureSavedCurrentContext(); |
| 1430 result = new ClosureCallNode(token_pos, getter_call, args); |
| 1431 } else { |
| 1432 result = BuildClosureCall(token_pos, getter_call, args); |
| 1433 } |
1429 | 1434 |
1430 ReturnNode* return_node = new ReturnNode(token_pos, closure_call); | 1435 ReturnNode* return_node = new ReturnNode(token_pos, result); |
1431 current_block_->statements->Add(return_node); | 1436 current_block_->statements->Add(return_node); |
1432 return CloseBlock(); | 1437 return CloseBlock(); |
1433 } | 1438 } |
1434 | 1439 |
1435 | 1440 |
| 1441 AstNode* Parser::BuildClosureCall(intptr_t token_pos, |
| 1442 AstNode* closure, |
| 1443 ArgumentListNode* arguments) { |
| 1444 return new InstanceCallNode(token_pos, |
| 1445 closure, |
| 1446 Symbols::Call(), |
| 1447 arguments); |
| 1448 } |
| 1449 |
| 1450 |
1436 void Parser::SkipBlock() { | 1451 void Parser::SkipBlock() { |
1437 ASSERT(CurrentToken() == Token::kLBRACE); | 1452 ASSERT(CurrentToken() == Token::kLBRACE); |
1438 GrowableArray<Token::Kind> token_stack(8); | 1453 GrowableArray<Token::Kind> token_stack(8); |
1439 // Adding the first kLBRACE here, because it will be consumed in the loop | 1454 // Adding the first kLBRACE here, because it will be consumed in the loop |
1440 // right away. | 1455 // right away. |
1441 token_stack.Add(CurrentToken()); | 1456 token_stack.Add(CurrentToken()); |
1442 const intptr_t block_start_pos = TokenPos(); | 1457 const intptr_t block_start_pos = TokenPos(); |
1443 bool is_match = true; | 1458 bool is_match = true; |
1444 bool unexpected_token_found = false; | 1459 bool unexpected_token_found = false; |
1445 Token::Kind token; | 1460 Token::Kind token; |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 LoadReceiver(supercall_pos), | 1909 LoadReceiver(supercall_pos), |
1895 /* is_super_getter */ true, | 1910 /* is_super_getter */ true, |
1896 super_class, | 1911 super_class, |
1897 function_name); | 1912 function_name); |
1898 EnsureSavedCurrentContext(); | 1913 EnsureSavedCurrentContext(); |
1899 // 'this' is not passed as parameter to the closure. | 1914 // 'this' is not passed as parameter to the closure. |
1900 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); | 1915 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); |
1901 for (int i = 1; i < arguments->length(); i++) { | 1916 for (int i = 1; i < arguments->length(); i++) { |
1902 closure_arguments->Add(arguments->NodeAt(i)); | 1917 closure_arguments->Add(arguments->NodeAt(i)); |
1903 } | 1918 } |
1904 return new ClosureCallNode(supercall_pos, closure, closure_arguments); | 1919 return BuildClosureCall(supercall_pos, closure, closure_arguments); |
1905 } | 1920 } |
1906 if (is_no_such_method) { | 1921 if (is_no_such_method) { |
1907 arguments = BuildNoSuchMethodArguments( | 1922 arguments = BuildNoSuchMethodArguments( |
1908 supercall_pos, function_name, *arguments, NULL, true); | 1923 supercall_pos, function_name, *arguments, NULL, true); |
1909 } | 1924 } |
1910 return new StaticCallNode(supercall_pos, super_function, arguments); | 1925 return new StaticCallNode(supercall_pos, super_function, arguments); |
1911 } | 1926 } |
1912 | 1927 |
1913 | 1928 |
1914 // Simple test if a node is side effect free. | 1929 // Simple test if a node is side effect free. |
(...skipping 4800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6715 } | 6730 } |
6716 | 6731 |
6717 | 6732 |
6718 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { | 6733 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { |
6719 if (condition->IsClosureNode() || | 6734 if (condition->IsClosureNode() || |
6720 (condition->IsStoreLocalNode() && | 6735 (condition->IsStoreLocalNode() && |
6721 condition->AsStoreLocalNode()->value()->IsClosureNode())) { | 6736 condition->AsStoreLocalNode()->value()->IsClosureNode())) { |
6722 EnsureSavedCurrentContext(); | 6737 EnsureSavedCurrentContext(); |
6723 // Function literal in assert implies a call. | 6738 // Function literal in assert implies a call. |
6724 const intptr_t pos = condition->token_pos(); | 6739 const intptr_t pos = condition->token_pos(); |
6725 condition = new ClosureCallNode(pos, condition, new ArgumentListNode(pos)); | 6740 condition = BuildClosureCall(pos, condition, new ArgumentListNode(pos)); |
6726 } else if (condition->IsConditionalExprNode()) { | 6741 } else if (condition->IsConditionalExprNode()) { |
6727 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); | 6742 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); |
6728 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); | 6743 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); |
6729 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); | 6744 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); |
6730 } | 6745 } |
6731 return condition; | 6746 return condition; |
6732 } | 6747 } |
6733 | 6748 |
6734 | 6749 |
6735 AstNode* Parser::ParseAssertStatement() { | 6750 AstNode* Parser::ParseAssertStatement() { |
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8234 kNumArguments, | 8249 kNumArguments, |
8235 Object::empty_array()); | 8250 Object::empty_array()); |
8236 if (!func.IsNull()) { | 8251 if (!func.IsNull()) { |
8237 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 8252 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
8238 EnsureSavedCurrentContext(); | 8253 EnsureSavedCurrentContext(); |
8239 closure = new StaticGetterNode(call_pos, | 8254 closure = new StaticGetterNode(call_pos, |
8240 NULL, | 8255 NULL, |
8241 false, | 8256 false, |
8242 Class::ZoneHandle(cls.raw()), | 8257 Class::ZoneHandle(cls.raw()), |
8243 func_name); | 8258 func_name); |
8244 return new ClosureCallNode(call_pos, closure, arguments); | 8259 return BuildClosureCall(call_pos, closure, arguments); |
8245 } | 8260 } |
8246 } else { | 8261 } else { |
8247 EnsureSavedCurrentContext(); | 8262 EnsureSavedCurrentContext(); |
8248 closure = GenerateStaticFieldLookup(field, call_pos); | 8263 closure = GenerateStaticFieldLookup(field, call_pos); |
8249 return new ClosureCallNode(call_pos, closure, arguments); | 8264 return BuildClosureCall(call_pos, closure, arguments); |
8250 } | 8265 } |
8251 // Could not resolve static method: throw a NoSuchMethodError. | 8266 // Could not resolve static method: throw a NoSuchMethodError. |
8252 return ThrowNoSuchMethodError(ident_pos, | 8267 return ThrowNoSuchMethodError(ident_pos, |
8253 cls, | 8268 cls, |
8254 func_name, | 8269 func_name, |
8255 arguments, | 8270 arguments, |
8256 InvocationMirror::kStatic, | 8271 InvocationMirror::kStatic, |
8257 InvocationMirror::kMethod, | 8272 InvocationMirror::kMethod, |
8258 NULL); // No existing function. | 8273 NULL); // No existing function. |
8259 } else if (cls.IsTopLevel() && | 8274 } else if (cls.IsTopLevel() && |
(...skipping 19 matching lines...) Expand all Loading... |
8279 return new InstanceCallNode(call_pos, receiver, func_name, arguments); | 8294 return new InstanceCallNode(call_pos, receiver, func_name, arguments); |
8280 } | 8295 } |
8281 | 8296 |
8282 | 8297 |
8283 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 8298 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
8284 TRACE_PARSER("ParseClosureCall"); | 8299 TRACE_PARSER("ParseClosureCall"); |
8285 const intptr_t call_pos = TokenPos(); | 8300 const intptr_t call_pos = TokenPos(); |
8286 ASSERT(CurrentToken() == Token::kLPAREN); | 8301 ASSERT(CurrentToken() == Token::kLPAREN); |
8287 EnsureSavedCurrentContext(); | 8302 EnsureSavedCurrentContext(); |
8288 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 8303 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
8289 return new ClosureCallNode(call_pos, closure, arguments); | 8304 return BuildClosureCall(call_pos, closure, arguments); |
8290 } | 8305 } |
8291 | 8306 |
8292 | 8307 |
8293 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 8308 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
8294 intptr_t ident_pos) { | 8309 intptr_t ident_pos) { |
8295 // If the static field has an initializer, initialize the field at compile | 8310 // If the static field has an initializer, initialize the field at compile |
8296 // time, which is only possible if the field is const. | 8311 // time, which is only possible if the field is const. |
8297 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 8312 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
8298 if (initializing_getter != NULL) { | 8313 if (initializing_getter != NULL) { |
8299 // The field is not yet initialized and could not be initialized at compile | 8314 // The field is not yet initialized and could not be initialized at compile |
(...skipping 2619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10919 void Parser::SkipQualIdent() { | 10934 void Parser::SkipQualIdent() { |
10920 ASSERT(IsIdentifier()); | 10935 ASSERT(IsIdentifier()); |
10921 ConsumeToken(); | 10936 ConsumeToken(); |
10922 if (CurrentToken() == Token::kPERIOD) { | 10937 if (CurrentToken() == Token::kPERIOD) { |
10923 ConsumeToken(); // Consume the kPERIOD token. | 10938 ConsumeToken(); // Consume the kPERIOD token. |
10924 ExpectIdentifier("identifier expected after '.'"); | 10939 ExpectIdentifier("identifier expected after '.'"); |
10925 } | 10940 } |
10926 } | 10941 } |
10927 | 10942 |
10928 } // namespace dart | 10943 } // namespace dart |
OLD | NEW |