Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: runtime/vm/parser.cc

Issue 227723002: VM: Implement closure calls as instance calls. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: adjust inlining of dispatchers Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/stub_code.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/stub_code.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698