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

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

Issue 11636025: Simplify method invocation runtime entries. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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/dart_entry.h ('k') | no next file » | 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/dart_entry.h" 5 #include "vm/dart_entry.h"
6 6
7 #include "vm/code_generator.h" 7 #include "vm/code_generator.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/object_store.h" 9 #include "vm/object_store.h"
10 #include "vm/resolver.h" 10 #include "vm/resolver.h"
11 #include "vm/stub_code.h" 11 #include "vm/stub_code.h"
12 #include "vm/symbols.h" 12 #include "vm/symbols.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 RawObject* DartEntry::InvokeDynamic(const Function& function, 16 RawObject* DartEntry::InvokeDynamic(const Function& function,
17 const Array& arguments) { 17 const Array& arguments) {
18 const Array& arg_desc = 18 const Array& arg_desc =
19 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); 19 Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
20 return InvokeDynamic(function, arguments, arg_desc); 20 return InvokeDynamic(function, arguments, arg_desc);
21 } 21 }
22 22
23 23
24 RawObject* DartEntry::InvokeDynamic(const Function& function, 24 RawObject* DartEntry::InvokeDynamic(const Function& function,
25 const Array& arguments, 25 const Array& arguments,
26 const Array& arg_descriptor) { 26 const Array& arguments_descriptor) {
27 // Get the entrypoint corresponding to the function specified, this 27 // Get the entrypoint corresponding to the function specified, this
28 // will result in a compilation of the function if it is not already 28 // will result in a compilation of the function if it is not already
29 // compiled. 29 // compiled.
30 if (!function.HasCode()) { 30 if (!function.HasCode()) {
31 const Error& error = Error::Handle(Compiler::CompileFunction(function)); 31 const Error& error = Error::Handle(Compiler::CompileFunction(function));
32 if (!error.IsNull()) { 32 if (!error.IsNull()) {
33 return error.raw(); 33 return error.raw();
34 } 34 }
35 } 35 }
36 36
37 // Now Call the invoke stub which will invoke the dart function. 37 // Now Call the invoke stub which will invoke the dart function.
38 invokestub entrypoint = reinterpret_cast<invokestub>( 38 invokestub entrypoint = reinterpret_cast<invokestub>(
39 StubCode::InvokeDartCodeEntryPoint()); 39 StubCode::InvokeDartCodeEntryPoint());
40 const Context& context = 40 const Context& context =
41 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context()); 41 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
42 ASSERT(context.isolate() == Isolate::Current()); 42 ASSERT(context.isolate() == Isolate::Current());
43 const Code& code = Code::Handle(function.CurrentCode()); 43 const Code& code = Code::Handle(function.CurrentCode());
44 ASSERT(!code.IsNull()); 44 ASSERT(!code.IsNull());
45 return entrypoint(code.EntryPoint(), arg_descriptor, arguments, context); 45 return entrypoint(code.EntryPoint(),
46 arguments_descriptor,
47 arguments,
48 context);
46 } 49 }
47 50
48 51
49 RawObject* DartEntry::InvokeStatic(const Function& function, 52 RawObject* DartEntry::InvokeStatic(const Function& function,
50 const Array& arguments) { 53 const Array& arguments) {
51 const Array& arg_desc = 54 const Array& arguments_descriptor =
52 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); 55 Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
53 return InvokeStatic(function, arguments, arg_desc); 56 return InvokeStatic(function, arguments, arguments_descriptor);
54 } 57 }
55 58
56 59
57 RawObject* DartEntry::InvokeStatic(const Function& function, 60 RawObject* DartEntry::InvokeStatic(const Function& function,
58 const Array& arguments, 61 const Array& arguments,
59 const Array& arg_descriptor) { 62 const Array& arguments_descriptor) {
60 // Get the entrypoint corresponding to the function specified, this 63 // Get the entrypoint corresponding to the function specified, this
61 // will result in a compilation of the function if it is not already 64 // will result in a compilation of the function if it is not already
62 // compiled. 65 // compiled.
63 ASSERT(!function.IsNull()); 66 ASSERT(!function.IsNull());
64 if (!function.HasCode()) { 67 if (!function.HasCode()) {
65 const Error& error = Error::Handle(Compiler::CompileFunction(function)); 68 const Error& error = Error::Handle(Compiler::CompileFunction(function));
66 if (!error.IsNull()) { 69 if (!error.IsNull()) {
67 return error.raw(); 70 return error.raw();
68 } 71 }
69 } 72 }
70 // Now Call the invoke stub which will invoke the dart function. 73 // Now Call the invoke stub which will invoke the dart function.
71 invokestub entrypoint = reinterpret_cast<invokestub>( 74 invokestub entrypoint = reinterpret_cast<invokestub>(
72 StubCode::InvokeDartCodeEntryPoint()); 75 StubCode::InvokeDartCodeEntryPoint());
73 const Context& context = 76 const Context& context =
74 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context()); 77 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
75 ASSERT(context.isolate() == Isolate::Current()); 78 ASSERT(context.isolate() == Isolate::Current());
76 const Code& code = Code::Handle(function.CurrentCode()); 79 const Code& code = Code::Handle(function.CurrentCode());
77 ASSERT(!code.IsNull()); 80 ASSERT(!code.IsNull());
78 return entrypoint(code.EntryPoint(), arg_descriptor, arguments, context); 81 return entrypoint(code.EntryPoint(),
82 arguments_descriptor,
83 arguments,
84 context);
79 } 85 }
80 86
81 87
82 RawObject* DartEntry::InvokeClosure(const Instance& closure, 88 RawObject* DartEntry::InvokeClosure(const Instance& closure,
83 const Array& arguments) { 89 const Array& arguments) {
84 const Array& arg_desc = 90 const Array& arguments_descriptor =
85 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); 91 Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
86 return InvokeClosure(closure, arguments, arg_desc); 92 return InvokeClosure(closure, arguments, arguments_descriptor);
87 } 93 }
88 94
89 95
90 RawObject* DartEntry::InvokeClosure(const Instance& instance, 96 RawObject* DartEntry::InvokeClosure(const Instance& instance,
91 const Array& arguments, 97 const Array& arguments,
92 const Array& arg_descriptor) { 98 const Array& arguments_descriptor) {
93 ASSERT(instance.raw() == arguments.At(0)); 99 ASSERT(instance.raw() == arguments.At(0));
94 // Get the entrypoint corresponding to the closure function or to the call 100 // Get the entrypoint corresponding to the closure function or to the call
95 // method of the instance. This will result in a compilation of the function 101 // method of the instance. This will result in a compilation of the function
96 // if it is not already compiled. 102 // if it is not already compiled.
97 Function& function = Function::Handle(); 103 Function& function = Function::Handle();
98 Context& context = Context::Handle(); 104 Context& context = Context::Handle();
99 if (!instance.IsCallable(&function, &context)) { 105 if (instance.IsCallable(&function, &context)) {
100 // Set up arguments to include the receiver as the first argument. 106 // Only invoke the function if its arguments are compatible.
101 const String& call_symbol = String::Handle(Symbols::Call()); 107 const ArgumentsDescriptor args_desc(arguments_descriptor);
102 const Object& null_object = Object::Handle(); 108 if (function.AreValidArgumentCounts(args_desc.Count(),
103 const Array& dart_arguments = Array::Handle(Array::New(4)); 109 args_desc.NamedCount(),
104 dart_arguments.SetAt(0, instance); 110 NULL)) {
105 dart_arguments.SetAt(1, call_symbol); 111 if (!function.HasCode()) {
106 dart_arguments.SetAt(2, arguments); // Includes instance. 112 const Error& error = Error::Handle(Compiler::CompileFunction(function));
107 dart_arguments.SetAt(3, null_object); // TODO(regis): Provide names. 113 if (!error.IsNull()) {
108 // If a function "call" with different arguments exists, it will have been 114 return error.raw();
109 // invoked above, so no need to handle this case here. 115 }
110 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); 116 }
111 UNREACHABLE(); 117 // Now call the invoke stub which will invoke the closure function or
112 return Object::null(); 118 // 'call' function.
113 } 119 // The closure or non-closure object (receiver) is passed as implicit
114 ASSERT(!function.IsNull()); 120 // first argument. It is already included in the arguments array.
115 if (!function.HasCode()) { 121 invokestub entrypoint = reinterpret_cast<invokestub>(
116 const Error& error = Error::Handle(Compiler::CompileFunction(function)); 122 StubCode::InvokeDartCodeEntryPoint());
117 if (!error.IsNull()) { 123 ASSERT(context.isolate() == Isolate::Current());
118 return error.raw(); 124 const Code& code = Code::Handle(function.CurrentCode());
125 ASSERT(!code.IsNull());
126 return entrypoint(code.EntryPoint(),
127 arguments_descriptor,
128 arguments,
129 context);
119 } 130 }
120 } 131 }
121 // Now call the invoke stub which will invoke the closure. 132 // There is no compatible 'call' method, so invoke noSuchMethod.
122 invokestub entrypoint = reinterpret_cast<invokestub>( 133 return InvokeNoSuchMethod(instance,
123 StubCode::InvokeDartCodeEntryPoint()); 134 String::Handle(Symbols::Call()),
124 ASSERT(context.isolate() == Isolate::Current()); 135 arguments,
125 const Code& code = Code::Handle(function.CurrentCode()); 136 arguments_descriptor);
126 ASSERT(!code.IsNull()); 137 }
127 return entrypoint(code.EntryPoint(), arg_descriptor, arguments, context); 138
139
140 RawObject* DartEntry::InvokeNoSuchMethod(const Instance& receiver,
141 const String& target_name,
142 const Array& arguments,
143 const Array& arguments_descriptor) {
144 ASSERT(receiver.raw() == arguments.At(0));
145 // Allocate an InvocationMirror object.
146 const Library& core_lib = Library::Handle(Library::CoreLibrary());
147 const String& invocation_mirror_name =
148 String::Handle(Symbols::InvocationMirror());
149 Class& invocation_mirror_class =
150 Class::Handle(core_lib.LookupClassAllowPrivate(invocation_mirror_name));
151 ASSERT(!invocation_mirror_class.IsNull());
152 const String& allocation_function_name =
153 String::Handle(Symbols::AllocateInvocationMirror());
154 const Function& allocation_function = Function::Handle(
155 Resolver::ResolveStaticByName(invocation_mirror_class,
156 allocation_function_name,
157 Resolver::kIsQualified));
158 ASSERT(!allocation_function.IsNull());
159 const int kNumAllocationArgs = 3;
160 const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs));
161 allocation_args.SetAt(0, target_name);
162 allocation_args.SetAt(1, arguments_descriptor);
163 allocation_args.SetAt(2, arguments);
164 const Object& invocation_mirror = Object::Handle(
165 InvokeStatic(allocation_function, allocation_args));
166
167 // Now use the invocation mirror object and invoke NoSuchMethod.
168 const String& function_name = String::Handle(Symbols::NoSuchMethod());
169 const int kNumArguments = 2;
170 const int kNumNamedArguments = 0;
171 const Function& function = Function::Handle(
172 Resolver::ResolveDynamic(receiver,
173 function_name,
174 kNumArguments,
175 kNumNamedArguments));
176 ASSERT(!function.IsNull());
177 const Array& args = Array::Handle(Array::New(kNumArguments));
178 args.SetAt(0, receiver);
179 args.SetAt(1, invocation_mirror);
180 return InvokeDynamic(function, args);
128 } 181 }
129 182
130 183
131 ArgumentsDescriptor::ArgumentsDescriptor(const Array& array) 184 ArgumentsDescriptor::ArgumentsDescriptor(const Array& array)
132 : array_(array) { 185 : array_(array) {
133 } 186 }
134 187
135 188
136 intptr_t ArgumentsDescriptor::Count() const { 189 intptr_t ArgumentsDescriptor::Count() const {
137 return Smi::CheckedHandle(array_.At(kCountIndex)).Value(); 190 return Smi::CheckedHandle(array_.At(kCountIndex)).Value();
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 const String& func_name = String::Handle(Field::GetterName(field_name)); 449 const String& func_name = String::Handle(Field::GetterName(field_name));
397 const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name)); 450 const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name));
398 ASSERT(!func.IsNull()); 451 ASSERT(!func.IsNull());
399 const Array& args = Array::Handle(Array::New(1)); 452 const Array& args = Array::Handle(Array::New(1));
400 args.SetAt(0, port); 453 args.SetAt(0, port);
401 return DartEntry::InvokeDynamic(func, args); 454 return DartEntry::InvokeDynamic(func, args);
402 } 455 }
403 456
404 457
405 } // namespace dart 458 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/dart_entry.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698