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

Unified Diff: runtime/vm/parser.cc

Issue 188703004: Fix invocation of closures via .call in the VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 33570)
+++ runtime/vm/parser.cc (working copy)
@@ -810,6 +810,10 @@
node_sequence =
parser.ParseInvokeFieldDispatcher(func, default_parameter_values);
break;
+ case RawFunction::kInvokeClosureDispatcher:
+ node_sequence =
+ parser.ParseInvokeClosureDispatcher(func, default_parameter_values);
+ break;
default:
UNREACHABLE();
}
@@ -1405,6 +1409,53 @@
}
+SequenceNode* Parser::ParseInvokeClosureDispatcher(const Function& func,
+ Array& default_values) {
+ TRACE_PARSER("ParseInvokeClosureDispatcher");
+
+ ASSERT(func.IsInvokeClosureDispatcher());
+ intptr_t token_pos = func.token_pos();
+ ASSERT(func.token_pos() == 0);
+ ASSERT(current_class().raw() == func.Owner());
+
+ const Array& args_desc = Array::Handle(func.saved_args_desc());
+ ArgumentsDescriptor desc(args_desc);
+ ASSERT(desc.Count() > 0);
+
+ // Set up scope for this function.
+ BuildDispatcherScope(func, desc, default_values);
+
+ // Receiver is local 0.
+ LocalScope* scope = current_block_->scope;
+ LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0));
+
+ // Pass arguments 1..n to the closure call.
+ ArgumentListNode* closure_args = new ArgumentListNode(token_pos);
+ const Array& names = Array::Handle(Array::New(desc.NamedCount(), Heap::kOld));
+ // Positional parameters.
+ intptr_t i = 1;
+ for (; i < desc.PositionalCount(); ++i) {
+ closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
+ }
+ // Named parameters.
+ for (; i < desc.Count(); i++) {
+ closure_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
+ intptr_t index = i - desc.PositionalCount();
+ names.SetAt(index, String::Handle(desc.NameAt(index)));
+ }
+ closure_args->set_names(names);
+
+ EnsureSavedCurrentContext();
+ ClosureCallNode* closure_call = new ClosureCallNode(token_pos,
+ receiver,
+ closure_args);
+
+ ReturnNode* return_node = new ReturnNode(token_pos, closure_call);
+ current_block_->statements->Add(return_node);
+ return CloseBlock();
+}
+
+
void Parser::SkipBlock() {
ASSERT(CurrentToken() == Token::kLBRACE);
GrowableArray<Token::Kind> token_stack(8);
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698