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