| 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 |