OLD | NEW |
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/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
8 #include "vm/code_generator.h" | 8 #include "vm/code_generator.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 Thread* thread_; | 64 Thread* thread_; |
65 uword saved_stack_limit_; | 65 uword saved_stack_limit_; |
66 }; | 66 }; |
67 | 67 |
68 | 68 |
69 // Clears/restores Thread::long_jump_base on construction/destruction. | 69 // Clears/restores Thread::long_jump_base on construction/destruction. |
70 // Ensures that we do not attempt to long jump across Dart frames. | 70 // Ensures that we do not attempt to long jump across Dart frames. |
71 class SuspendLongJumpScope : public StackResource { | 71 class SuspendLongJumpScope : public StackResource { |
72 public: | 72 public: |
73 explicit SuspendLongJumpScope(Thread* thread) | 73 explicit SuspendLongJumpScope(Thread* thread) |
74 : StackResource(thread), | 74 : StackResource(thread), saved_long_jump_base_(thread->long_jump_base()) { |
75 saved_long_jump_base_(thread->long_jump_base()) { | |
76 thread->set_long_jump_base(NULL); | 75 thread->set_long_jump_base(NULL); |
77 } | 76 } |
78 | 77 |
79 ~SuspendLongJumpScope() { | 78 ~SuspendLongJumpScope() { |
80 ASSERT(thread()->long_jump_base() == NULL); | 79 ASSERT(thread()->long_jump_base() == NULL); |
81 thread()->set_long_jump_base(saved_long_jump_base_); | 80 thread()->set_long_jump_base(saved_long_jump_base_); |
82 } | 81 } |
83 | 82 |
84 private: | 83 private: |
85 LongJumpScope* saved_long_jump_base_; | 84 LongJumpScope* saved_long_jump_base_; |
86 }; | 85 }; |
87 | 86 |
88 | 87 |
89 RawObject* DartEntry::InvokeFunction(const Function& function, | 88 RawObject* DartEntry::InvokeFunction(const Function& function, |
90 const Array& arguments, | 89 const Array& arguments, |
91 const Array& arguments_descriptor) { | 90 const Array& arguments_descriptor) { |
92 // Get the entrypoint corresponding to the function specified, this | 91 // Get the entrypoint corresponding to the function specified, this |
93 // will result in a compilation of the function if it is not already | 92 // will result in a compilation of the function if it is not already |
94 // compiled. | 93 // compiled. |
95 Thread* thread = Thread::Current(); | 94 Thread* thread = Thread::Current(); |
96 Zone* zone = thread->zone(); | 95 Zone* zone = thread->zone(); |
97 ASSERT(thread->IsMutatorThread()); | 96 ASSERT(thread->IsMutatorThread()); |
98 if (!function.HasCode()) { | 97 if (!function.HasCode()) { |
99 const Error& error = Error::Handle( | 98 const Error& error = |
100 zone, Compiler::CompileFunction(thread, function)); | 99 Error::Handle(zone, Compiler::CompileFunction(thread, function)); |
101 if (!error.IsNull()) { | 100 if (!error.IsNull()) { |
102 return error.raw(); | 101 return error.raw(); |
103 } | 102 } |
104 } | 103 } |
105 // Now Call the invoke stub which will invoke the dart function. | 104 // Now Call the invoke stub which will invoke the dart function. |
106 #if !defined(TARGET_ARCH_DBC) | 105 #if !defined(TARGET_ARCH_DBC) |
107 invokestub entrypoint = reinterpret_cast<invokestub>( | 106 invokestub entrypoint = reinterpret_cast<invokestub>( |
108 StubCode::InvokeDartCode_entry()->EntryPoint()); | 107 StubCode::InvokeDartCode_entry()->EntryPoint()); |
109 #endif | 108 #endif |
110 const Code& code = Code::Handle(zone, function.CurrentCode()); | 109 const Code& code = Code::Handle(zone, function.CurrentCode()); |
111 ASSERT(!code.IsNull()); | 110 ASSERT(!code.IsNull()); |
112 ASSERT(thread->no_callback_scope_depth() == 0); | 111 ASSERT(thread->no_callback_scope_depth() == 0); |
113 ScopedIsolateStackLimits stack_limit(thread); | 112 ScopedIsolateStackLimits stack_limit(thread); |
114 SuspendLongJumpScope suspend_long_jump_scope(thread); | 113 SuspendLongJumpScope suspend_long_jump_scope(thread); |
115 TransitionToGenerated transition(thread); | 114 TransitionToGenerated transition(thread); |
116 #if defined(TARGET_ARCH_DBC) | 115 #if defined(TARGET_ARCH_DBC) |
117 return Simulator::Current()->Call(code, | 116 return Simulator::Current()->Call(code, arguments_descriptor, arguments, |
118 arguments_descriptor, | |
119 arguments, | |
120 thread); | 117 thread); |
121 #elif defined(USING_SIMULATOR) | 118 #elif defined(USING_SIMULATOR) |
122 return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call( | 119 return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call( |
123 reinterpret_cast<intptr_t>(entrypoint), | 120 reinterpret_cast<intptr_t>(entrypoint), reinterpret_cast<intptr_t>(&code), |
124 reinterpret_cast<intptr_t>(&code), | |
125 reinterpret_cast<intptr_t>(&arguments_descriptor), | 121 reinterpret_cast<intptr_t>(&arguments_descriptor), |
126 reinterpret_cast<intptr_t>(&arguments), | 122 reinterpret_cast<intptr_t>(&arguments), |
127 reinterpret_cast<intptr_t>(thread))); | 123 reinterpret_cast<intptr_t>(thread))); |
128 #else | 124 #else |
129 return entrypoint(code, | 125 return entrypoint(code, arguments_descriptor, arguments, thread); |
130 arguments_descriptor, | |
131 arguments, | |
132 thread); | |
133 #endif | 126 #endif |
134 } | 127 } |
135 | 128 |
136 | 129 |
137 RawObject* DartEntry::InvokeClosure(const Array& arguments) { | 130 RawObject* DartEntry::InvokeClosure(const Array& arguments) { |
138 const Array& arguments_descriptor = | 131 const Array& arguments_descriptor = |
139 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); | 132 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); |
140 return InvokeClosure(arguments, arguments_descriptor); | 133 return InvokeClosure(arguments, arguments_descriptor); |
141 } | 134 } |
142 | 135 |
143 | 136 |
144 RawObject* DartEntry::InvokeClosure(const Array& arguments, | 137 RawObject* DartEntry::InvokeClosure(const Array& arguments, |
145 const Array& arguments_descriptor) { | 138 const Array& arguments_descriptor) { |
146 Thread* thread = Thread::Current(); | 139 Thread* thread = Thread::Current(); |
147 Zone* zone = thread->zone(); | 140 Zone* zone = thread->zone(); |
148 Instance& instance = Instance::Handle(zone); | 141 Instance& instance = Instance::Handle(zone); |
149 instance ^= arguments.At(0); | 142 instance ^= arguments.At(0); |
150 // Get the entrypoint corresponding to the closure function or to the call | 143 // Get the entrypoint corresponding to the closure function or to the call |
151 // method of the instance. This will result in a compilation of the function | 144 // method of the instance. This will result in a compilation of the function |
152 // if it is not already compiled. | 145 // if it is not already compiled. |
153 Function& function = Function::Handle(zone); | 146 Function& function = Function::Handle(zone); |
154 if (instance.IsCallable(&function)) { | 147 if (instance.IsCallable(&function)) { |
155 // Only invoke the function if its arguments are compatible. | 148 // Only invoke the function if its arguments are compatible. |
156 const ArgumentsDescriptor args_desc(arguments_descriptor); | 149 const ArgumentsDescriptor args_desc(arguments_descriptor); |
157 if (function.AreValidArgumentCounts(args_desc.Count(), | 150 if (function.AreValidArgumentCounts(args_desc.Count(), |
158 args_desc.NamedCount(), | 151 args_desc.NamedCount(), NULL)) { |
159 NULL)) { | |
160 // The closure or non-closure object (receiver) is passed as implicit | 152 // The closure or non-closure object (receiver) is passed as implicit |
161 // first argument. It is already included in the arguments array. | 153 // first argument. It is already included in the arguments array. |
162 return InvokeFunction(function, arguments, arguments_descriptor); | 154 return InvokeFunction(function, arguments, arguments_descriptor); |
163 } | 155 } |
164 } | 156 } |
165 | 157 |
166 // There is no compatible 'call' method, see if there's a getter. | 158 // There is no compatible 'call' method, see if there's a getter. |
167 if (instance.IsClosure()) { | 159 if (instance.IsClosure()) { |
168 // Special case: closures are implemented with a call getter instead of a | 160 // Special case: closures are implemented with a call getter instead of a |
169 // call method. If the arguments didn't match, go to noSuchMethod instead | 161 // call method. If the arguments didn't match, go to noSuchMethod instead |
170 // of infinitely recursing on the getter. | 162 // of infinitely recursing on the getter. |
171 } else { | 163 } else { |
172 const String& getter_name = Symbols::GetCall(); | 164 const String& getter_name = Symbols::GetCall(); |
173 Class& cls = Class::Handle(zone, instance.clazz()); | 165 Class& cls = Class::Handle(zone, instance.clazz()); |
174 while (!cls.IsNull()) { | 166 while (!cls.IsNull()) { |
175 function ^= cls.LookupDynamicFunction(getter_name); | 167 function ^= cls.LookupDynamicFunction(getter_name); |
176 if (!function.IsNull()) { | 168 if (!function.IsNull()) { |
177 Isolate* isolate = thread->isolate(); | 169 Isolate* isolate = thread->isolate(); |
178 volatile uword c_stack_pos = Thread::GetCurrentStackPointer(); | 170 volatile uword c_stack_pos = Thread::GetCurrentStackPointer(); |
179 volatile uword c_stack_limit = OSThread::Current()->stack_base() - | 171 volatile uword c_stack_limit = OSThread::Current()->stack_base() - |
180 OSThread::GetSpecifiedStackSize(); | 172 OSThread::GetSpecifiedStackSize(); |
181 #if !defined(USING_SIMULATOR) | 173 #if !defined(USING_SIMULATOR) |
182 ASSERT(c_stack_limit == thread->saved_stack_limit()); | 174 ASSERT(c_stack_limit == thread->saved_stack_limit()); |
183 #endif | 175 #endif |
184 | 176 |
185 if (c_stack_pos < c_stack_limit) { | 177 if (c_stack_pos < c_stack_limit) { |
186 const Instance& exception = | 178 const Instance& exception = |
187 Instance::Handle(zone, isolate->object_store()->stack_overflow()); | 179 Instance::Handle(zone, isolate->object_store()->stack_overflow()); |
188 return UnhandledException::New(exception, Stacktrace::Handle(zone)); | 180 return UnhandledException::New(exception, Stacktrace::Handle(zone)); |
189 } | 181 } |
190 | 182 |
191 const Array& getter_arguments = Array::Handle(zone, Array::New(1)); | 183 const Array& getter_arguments = Array::Handle(zone, Array::New(1)); |
192 getter_arguments.SetAt(0, instance); | 184 getter_arguments.SetAt(0, instance); |
193 const Object& getter_result = | 185 const Object& getter_result = Object::Handle( |
194 Object::Handle(zone, DartEntry::InvokeFunction(function, | 186 zone, DartEntry::InvokeFunction(function, getter_arguments)); |
195 getter_arguments)); | |
196 if (getter_result.IsError()) { | 187 if (getter_result.IsError()) { |
197 return getter_result.raw(); | 188 return getter_result.raw(); |
198 } | 189 } |
199 ASSERT(getter_result.IsNull() || getter_result.IsInstance()); | 190 ASSERT(getter_result.IsNull() || getter_result.IsInstance()); |
200 | 191 |
201 arguments.SetAt(0, getter_result); | 192 arguments.SetAt(0, getter_result); |
202 // This otherwise unnecessary handle is used to prevent clang from | 193 // This otherwise unnecessary handle is used to prevent clang from |
203 // doing tail call elimination, which would make the stack overflow | 194 // doing tail call elimination, which would make the stack overflow |
204 // check above ineffective. | 195 // check above ineffective. |
205 Object& result = Object::Handle(zone, | 196 Object& result = Object::Handle( |
206 InvokeClosure(arguments, arguments_descriptor)); | 197 zone, InvokeClosure(arguments, arguments_descriptor)); |
207 return result.raw(); | 198 return result.raw(); |
208 } | 199 } |
209 cls = cls.SuperClass(); | 200 cls = cls.SuperClass(); |
210 } | 201 } |
211 } | 202 } |
212 | 203 |
213 // No compatible method or getter so invoke noSuchMethod. | 204 // No compatible method or getter so invoke noSuchMethod. |
214 return InvokeNoSuchMethod(instance, | 205 return InvokeNoSuchMethod(instance, Symbols::Call(), arguments, |
215 Symbols::Call(), | |
216 arguments, | |
217 arguments_descriptor); | 206 arguments_descriptor); |
218 } | 207 } |
219 | 208 |
220 | 209 |
221 RawObject* DartEntry::InvokeNoSuchMethod(const Instance& receiver, | 210 RawObject* DartEntry::InvokeNoSuchMethod(const Instance& receiver, |
222 const String& target_name, | 211 const String& target_name, |
223 const Array& arguments, | 212 const Array& arguments, |
224 const Array& arguments_descriptor) { | 213 const Array& arguments_descriptor) { |
225 ASSERT(receiver.raw() == arguments.At(0)); | 214 ASSERT(receiver.raw() == arguments.At(0)); |
226 // Allocate an Invocation object. | 215 // Allocate an Invocation object. |
227 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 216 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
228 | 217 |
229 Class& invocation_mirror_class = Class::Handle( | 218 Class& invocation_mirror_class = Class::Handle(core_lib.LookupClass( |
230 core_lib.LookupClass( | 219 String::Handle(core_lib.PrivateName(Symbols::InvocationMirror())))); |
231 String::Handle(core_lib.PrivateName(Symbols::InvocationMirror())))); | |
232 ASSERT(!invocation_mirror_class.IsNull()); | 220 ASSERT(!invocation_mirror_class.IsNull()); |
233 const String& function_name = | 221 const String& function_name = |
234 String::Handle(core_lib.PrivateName(Symbols::AllocateInvocationMirror())); | 222 String::Handle(core_lib.PrivateName(Symbols::AllocateInvocationMirror())); |
235 const Function& allocation_function = Function::Handle( | 223 const Function& allocation_function = Function::Handle( |
236 invocation_mirror_class.LookupStaticFunction(function_name)); | 224 invocation_mirror_class.LookupStaticFunction(function_name)); |
237 ASSERT(!allocation_function.IsNull()); | 225 ASSERT(!allocation_function.IsNull()); |
238 const int kNumAllocationArgs = 4; | 226 const int kNumAllocationArgs = 4; |
239 const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs)); | 227 const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs)); |
240 allocation_args.SetAt(0, target_name); | 228 allocation_args.SetAt(0, target_name); |
241 allocation_args.SetAt(1, arguments_descriptor); | 229 allocation_args.SetAt(1, arguments_descriptor); |
242 allocation_args.SetAt(2, arguments); | 230 allocation_args.SetAt(2, arguments); |
243 allocation_args.SetAt(3, Bool::False()); // Not a super invocation. | 231 allocation_args.SetAt(3, Bool::False()); // Not a super invocation. |
244 const Object& invocation_mirror = Object::Handle( | 232 const Object& invocation_mirror = |
245 InvokeFunction(allocation_function, allocation_args)); | 233 Object::Handle(InvokeFunction(allocation_function, allocation_args)); |
246 if (invocation_mirror.IsError()) { | 234 if (invocation_mirror.IsError()) { |
247 Exceptions::PropagateError(Error::Cast(invocation_mirror)); | 235 Exceptions::PropagateError(Error::Cast(invocation_mirror)); |
248 UNREACHABLE(); | 236 UNREACHABLE(); |
249 } | 237 } |
250 | 238 |
251 // Now use the invocation mirror object and invoke NoSuchMethod. | 239 // Now use the invocation mirror object and invoke NoSuchMethod. |
252 const int kNumArguments = 2; | 240 const int kNumArguments = 2; |
253 ArgumentsDescriptor args_desc( | 241 ArgumentsDescriptor args_desc( |
254 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 242 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
255 Function& function = Function::Handle( | 243 Function& function = Function::Handle( |
256 Resolver::ResolveDynamic(receiver, | 244 Resolver::ResolveDynamic(receiver, Symbols::NoSuchMethod(), args_desc)); |
257 Symbols::NoSuchMethod(), | |
258 args_desc)); | |
259 if (function.IsNull()) { | 245 if (function.IsNull()) { |
260 ASSERT(!FLAG_lazy_dispatchers); | 246 ASSERT(!FLAG_lazy_dispatchers); |
261 // If noSuchMethod(invocation) is not found, call Object::noSuchMethod. | 247 // If noSuchMethod(invocation) is not found, call Object::noSuchMethod. |
262 Thread* thread = Thread::Current(); | 248 Thread* thread = Thread::Current(); |
263 function ^= Resolver::ResolveDynamicForReceiverClass( | 249 function ^= Resolver::ResolveDynamicForReceiverClass( |
264 Class::Handle(thread->zone(), | 250 Class::Handle(thread->zone(), |
265 thread->isolate()->object_store()->object_class()), | 251 thread->isolate()->object_store()->object_class()), |
266 Symbols::NoSuchMethod(), | 252 Symbols::NoSuchMethod(), args_desc); |
267 args_desc); | |
268 } | 253 } |
269 ASSERT(!function.IsNull()); | 254 ASSERT(!function.IsNull()); |
270 const Array& args = Array::Handle(Array::New(kNumArguments)); | 255 const Array& args = Array::Handle(Array::New(kNumArguments)); |
271 args.SetAt(0, receiver); | 256 args.SetAt(0, receiver); |
272 args.SetAt(1, invocation_mirror); | 257 args.SetAt(1, invocation_mirror); |
273 return InvokeFunction(function, args); | 258 return InvokeFunction(function, args); |
274 } | 259 } |
275 | 260 |
276 | 261 |
277 ArgumentsDescriptor::ArgumentsDescriptor(const Array& array) | 262 ArgumentsDescriptor::ArgumentsDescriptor(const Array& array) : array_(array) {} |
278 : array_(array) { | |
279 } | |
280 | 263 |
281 | 264 |
282 intptr_t ArgumentsDescriptor::Count() const { | 265 intptr_t ArgumentsDescriptor::Count() const { |
283 return Smi::Cast(Object::Handle(array_.At(kCountIndex))).Value(); | 266 return Smi::Cast(Object::Handle(array_.At(kCountIndex))).Value(); |
284 } | 267 } |
285 | 268 |
286 | 269 |
287 intptr_t ArgumentsDescriptor::PositionalCount() const { | 270 intptr_t ArgumentsDescriptor::PositionalCount() const { |
288 return Smi::Cast(Object::Handle(array_.At(kPositionalCountIndex))).Value(); | 271 return Smi::Cast(Object::Handle(array_.At(kPositionalCountIndex))).Value(); |
289 } | 272 } |
290 | 273 |
291 | 274 |
292 RawString* ArgumentsDescriptor::NameAt(intptr_t index) const { | 275 RawString* ArgumentsDescriptor::NameAt(intptr_t index) const { |
293 const intptr_t offset = kFirstNamedEntryIndex + | 276 const intptr_t offset = |
294 (index * kNamedEntrySize) + | 277 kFirstNamedEntryIndex + (index * kNamedEntrySize) + kNameOffset; |
295 kNameOffset; | |
296 String& result = String::Handle(); | 278 String& result = String::Handle(); |
297 result ^= array_.At(offset); | 279 result ^= array_.At(offset); |
298 return result.raw(); | 280 return result.raw(); |
299 } | 281 } |
300 | 282 |
301 | 283 |
302 intptr_t ArgumentsDescriptor::PositionAt(intptr_t index) const { | 284 intptr_t ArgumentsDescriptor::PositionAt(intptr_t index) const { |
303 const intptr_t offset = kFirstNamedEntryIndex + | 285 const intptr_t offset = |
304 (index * kNamedEntrySize) + | 286 kFirstNamedEntryIndex + (index * kNamedEntrySize) + kPositionOffset; |
305 kPositionOffset; | |
306 return Smi::Value(Smi::RawCast(array_.At(offset))); | 287 return Smi::Value(Smi::RawCast(array_.At(offset))); |
307 } | 288 } |
308 | 289 |
309 | 290 |
310 bool ArgumentsDescriptor::MatchesNameAt(intptr_t index, | 291 bool ArgumentsDescriptor::MatchesNameAt(intptr_t index, |
311 const String& other) const { | 292 const String& other) const { |
312 return NameAt(index) == other.raw(); | 293 return NameAt(index) == other.raw(); |
313 } | 294 } |
314 | 295 |
315 | 296 |
(...skipping 21 matching lines...) Expand all Loading... |
337 } | 318 } |
338 const intptr_t num_pos_args = num_arguments - num_named_args; | 319 const intptr_t num_pos_args = num_arguments - num_named_args; |
339 | 320 |
340 // Build the arguments descriptor array, which consists of the total | 321 // Build the arguments descriptor array, which consists of the total |
341 // argument count; the positional argument count; a sequence of (name, | 322 // argument count; the positional argument count; a sequence of (name, |
342 // position) pairs, sorted by name, for each named optional argument; and | 323 // position) pairs, sorted by name, for each named optional argument; and |
343 // a terminating null to simplify iterating in generated code. | 324 // a terminating null to simplify iterating in generated code. |
344 Thread* thread = Thread::Current(); | 325 Thread* thread = Thread::Current(); |
345 Zone* zone = thread->zone(); | 326 Zone* zone = thread->zone(); |
346 const intptr_t descriptor_len = LengthFor(num_named_args); | 327 const intptr_t descriptor_len = LengthFor(num_named_args); |
347 Array& descriptor = Array::Handle( | 328 Array& descriptor = |
348 zone, Array::New(descriptor_len, Heap::kOld)); | 329 Array::Handle(zone, Array::New(descriptor_len, Heap::kOld)); |
349 | 330 |
350 // Set total number of passed arguments. | 331 // Set total number of passed arguments. |
351 descriptor.SetAt(kCountIndex, Smi::Handle(Smi::New(num_arguments))); | 332 descriptor.SetAt(kCountIndex, Smi::Handle(Smi::New(num_arguments))); |
352 // Set number of positional arguments. | 333 // Set number of positional arguments. |
353 descriptor.SetAt(kPositionalCountIndex, Smi::Handle(Smi::New(num_pos_args))); | 334 descriptor.SetAt(kPositionalCountIndex, Smi::Handle(Smi::New(num_pos_args))); |
354 // Set alphabetically sorted entries for named arguments. | 335 // Set alphabetically sorted entries for named arguments. |
355 String& name = String::Handle(zone); | 336 String& name = String::Handle(zone); |
356 Smi& pos = Smi::Handle(zone); | 337 Smi& pos = Smi::Handle(zone); |
357 String& previous_name = String::Handle(zone); | 338 String& previous_name = String::Handle(zone); |
358 Smi& previous_pos = Smi::Handle(zone); | 339 Smi& previous_pos = Smi::Handle(zone); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 | 378 |
398 | 379 |
399 RawArray* ArgumentsDescriptor::NewNonCached(intptr_t num_arguments, | 380 RawArray* ArgumentsDescriptor::NewNonCached(intptr_t num_arguments, |
400 bool canonicalize) { | 381 bool canonicalize) { |
401 // Build the arguments descriptor array, which consists of the total | 382 // Build the arguments descriptor array, which consists of the total |
402 // argument count; the positional argument count; and | 383 // argument count; the positional argument count; and |
403 // a terminating null to simplify iterating in generated code. | 384 // a terminating null to simplify iterating in generated code. |
404 Thread* thread = Thread::Current(); | 385 Thread* thread = Thread::Current(); |
405 Zone* zone = thread->zone(); | 386 Zone* zone = thread->zone(); |
406 const intptr_t descriptor_len = LengthFor(0); | 387 const intptr_t descriptor_len = LengthFor(0); |
407 Array& descriptor = Array::Handle( | 388 Array& descriptor = |
408 zone, Array::New(descriptor_len, Heap::kOld)); | 389 Array::Handle(zone, Array::New(descriptor_len, Heap::kOld)); |
409 const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments)); | 390 const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments)); |
410 | 391 |
411 // Set total number of passed arguments. | 392 // Set total number of passed arguments. |
412 descriptor.SetAt(kCountIndex, arg_count); | 393 descriptor.SetAt(kCountIndex, arg_count); |
413 | 394 |
414 // Set number of positional arguments. | 395 // Set number of positional arguments. |
415 descriptor.SetAt(kPositionalCountIndex, arg_count); | 396 descriptor.SetAt(kPositionalCountIndex, arg_count); |
416 | 397 |
417 // Set terminating null. | 398 // Set terminating null. |
418 descriptor.SetAt((descriptor_len - 1), Object::null_object()); | 399 descriptor.SetAt((descriptor_len - 1), Object::null_object()); |
(...skipping 18 matching lines...) Expand all Loading... |
437 RawObject* DartLibraryCalls::InstanceCreate(const Library& lib, | 418 RawObject* DartLibraryCalls::InstanceCreate(const Library& lib, |
438 const String& class_name, | 419 const String& class_name, |
439 const String& constructor_name, | 420 const String& constructor_name, |
440 const Array& arguments) { | 421 const Array& arguments) { |
441 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); | 422 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); |
442 ASSERT(!cls.IsNull()); | 423 ASSERT(!cls.IsNull()); |
443 // For now, we only support a non-parameterized or raw type. | 424 // For now, we only support a non-parameterized or raw type. |
444 const int kNumExtraArgs = 1; // implicit rcvr arg. | 425 const int kNumExtraArgs = 1; // implicit rcvr arg. |
445 const Instance& exception_object = Instance::Handle(Instance::New(cls)); | 426 const Instance& exception_object = Instance::Handle(Instance::New(cls)); |
446 const Array& constructor_arguments = | 427 const Array& constructor_arguments = |
447 Array::Handle(Array::New(arguments.Length() + kNumExtraArgs)); | 428 Array::Handle(Array::New(arguments.Length() + kNumExtraArgs)); |
448 constructor_arguments.SetAt(0, exception_object); | 429 constructor_arguments.SetAt(0, exception_object); |
449 Object& obj = Object::Handle(); | 430 Object& obj = Object::Handle(); |
450 for (intptr_t i = 0; i < arguments.Length(); i++) { | 431 for (intptr_t i = 0; i < arguments.Length(); i++) { |
451 obj = arguments.At(i); | 432 obj = arguments.At(i); |
452 constructor_arguments.SetAt((i + kNumExtraArgs), obj); | 433 constructor_arguments.SetAt((i + kNumExtraArgs), obj); |
453 } | 434 } |
454 | 435 |
455 const String& function_name = String::Handle( | 436 const String& function_name = |
456 String::Concat(class_name, constructor_name)); | 437 String::Handle(String::Concat(class_name, constructor_name)); |
457 const Function& constructor = | 438 const Function& constructor = |
458 Function::Handle(cls.LookupConstructorAllowPrivate(function_name)); | 439 Function::Handle(cls.LookupConstructorAllowPrivate(function_name)); |
459 ASSERT(!constructor.IsNull()); | 440 ASSERT(!constructor.IsNull()); |
460 const Object& retval = | 441 const Object& retval = Object::Handle( |
461 Object::Handle(DartEntry::InvokeFunction(constructor, | 442 DartEntry::InvokeFunction(constructor, constructor_arguments)); |
462 constructor_arguments)); | |
463 ASSERT(retval.IsNull() || retval.IsError()); | 443 ASSERT(retval.IsNull() || retval.IsError()); |
464 if (retval.IsError()) { | 444 if (retval.IsError()) { |
465 return retval.raw(); | 445 return retval.raw(); |
466 } | 446 } |
467 return exception_object.raw(); | 447 return exception_object.raw(); |
468 } | 448 } |
469 | 449 |
470 | 450 |
471 RawObject* DartLibraryCalls::ToString(const Instance& receiver) { | 451 RawObject* DartLibraryCalls::ToString(const Instance& receiver) { |
472 const int kNumArguments = 1; // Receiver. | 452 const int kNumArguments = 1; // Receiver. |
473 ArgumentsDescriptor args_desc( | 453 ArgumentsDescriptor args_desc( |
474 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 454 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
475 const Function& function = Function::Handle( | 455 const Function& function = Function::Handle( |
476 Resolver::ResolveDynamic(receiver, | 456 Resolver::ResolveDynamic(receiver, Symbols::toString(), args_desc)); |
477 Symbols::toString(), | |
478 args_desc)); | |
479 ASSERT(!function.IsNull()); | 457 ASSERT(!function.IsNull()); |
480 const Array& args = Array::Handle(Array::New(kNumArguments)); | 458 const Array& args = Array::Handle(Array::New(kNumArguments)); |
481 args.SetAt(0, receiver); | 459 args.SetAt(0, receiver); |
482 const Object& result = Object::Handle(DartEntry::InvokeFunction(function, | 460 const Object& result = |
483 args)); | 461 Object::Handle(DartEntry::InvokeFunction(function, args)); |
484 ASSERT(result.IsInstance() || result.IsError()); | 462 ASSERT(result.IsInstance() || result.IsError()); |
485 return result.raw(); | 463 return result.raw(); |
486 } | 464 } |
487 | 465 |
488 | 466 |
489 RawObject* DartLibraryCalls::HashCode(const Instance& receiver) { | 467 RawObject* DartLibraryCalls::HashCode(const Instance& receiver) { |
490 const int kNumArguments = 1; // Receiver. | 468 const int kNumArguments = 1; // Receiver. |
491 ArgumentsDescriptor args_desc( | 469 ArgumentsDescriptor args_desc( |
492 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 470 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
493 const Function& function = Function::Handle( | 471 const Function& function = Function::Handle( |
494 Resolver::ResolveDynamic(receiver, | 472 Resolver::ResolveDynamic(receiver, Symbols::hashCode(), args_desc)); |
495 Symbols::hashCode(), | |
496 args_desc)); | |
497 ASSERT(!function.IsNull()); | 473 ASSERT(!function.IsNull()); |
498 const Array& args = Array::Handle(Array::New(kNumArguments)); | 474 const Array& args = Array::Handle(Array::New(kNumArguments)); |
499 args.SetAt(0, receiver); | 475 args.SetAt(0, receiver); |
500 const Object& result = Object::Handle(DartEntry::InvokeFunction(function, | 476 const Object& result = |
501 args)); | 477 Object::Handle(DartEntry::InvokeFunction(function, args)); |
502 ASSERT(result.IsInstance() || result.IsError()); | 478 ASSERT(result.IsInstance() || result.IsError()); |
503 return result.raw(); | 479 return result.raw(); |
504 } | 480 } |
505 | 481 |
506 | 482 |
507 RawObject* DartLibraryCalls::Equals(const Instance& left, | 483 RawObject* DartLibraryCalls::Equals(const Instance& left, |
508 const Instance& right) { | 484 const Instance& right) { |
509 const int kNumArguments = 2; | 485 const int kNumArguments = 2; |
510 ArgumentsDescriptor args_desc( | 486 ArgumentsDescriptor args_desc( |
511 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 487 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
512 const Function& function = Function::Handle( | 488 const Function& function = Function::Handle( |
513 Resolver::ResolveDynamic(left, | 489 Resolver::ResolveDynamic(left, Symbols::EqualOperator(), args_desc)); |
514 Symbols::EqualOperator(), | |
515 args_desc)); | |
516 ASSERT(!function.IsNull()); | 490 ASSERT(!function.IsNull()); |
517 | 491 |
518 const Array& args = Array::Handle(Array::New(kNumArguments)); | 492 const Array& args = Array::Handle(Array::New(kNumArguments)); |
519 args.SetAt(0, left); | 493 args.SetAt(0, left); |
520 args.SetAt(1, right); | 494 args.SetAt(1, right); |
521 const Object& result = Object::Handle(DartEntry::InvokeFunction(function, | 495 const Object& result = |
522 args)); | 496 Object::Handle(DartEntry::InvokeFunction(function, args)); |
523 ASSERT(result.IsInstance() || result.IsError()); | 497 ASSERT(result.IsInstance() || result.IsError()); |
524 return result.raw(); | 498 return result.raw(); |
525 } | 499 } |
526 | 500 |
527 | 501 |
528 RawObject* DartLibraryCalls::LookupHandler(Dart_Port port_id) { | 502 RawObject* DartLibraryCalls::LookupHandler(Dart_Port port_id) { |
529 Thread* thread = Thread::Current(); | 503 Thread* thread = Thread::Current(); |
530 Function& function = Function::Handle(thread->zone(), | 504 Function& function = Function::Handle( |
531 thread->isolate()->object_store()->lookup_port_handler()); | 505 thread->zone(), thread->isolate()->object_store()->lookup_port_handler()); |
532 const int kNumArguments = 1; | 506 const int kNumArguments = 1; |
533 if (function.IsNull()) { | 507 if (function.IsNull()) { |
534 Library& isolate_lib = Library::Handle(Library::IsolateLibrary()); | 508 Library& isolate_lib = Library::Handle(Library::IsolateLibrary()); |
535 ASSERT(!isolate_lib.IsNull()); | 509 ASSERT(!isolate_lib.IsNull()); |
536 const String& class_name = | 510 const String& class_name = |
537 String::Handle(isolate_lib.PrivateName(Symbols::_RawReceivePortImpl())); | 511 String::Handle(isolate_lib.PrivateName(Symbols::_RawReceivePortImpl())); |
538 const String& function_name = | 512 const String& function_name = |
539 String::Handle(isolate_lib.PrivateName(Symbols::_lookupHandler())); | 513 String::Handle(isolate_lib.PrivateName(Symbols::_lookupHandler())); |
540 function = Resolver::ResolveStatic(isolate_lib, | 514 function = Resolver::ResolveStatic(isolate_lib, class_name, function_name, |
541 class_name, | 515 kNumArguments, Object::empty_array()); |
542 function_name, | |
543 kNumArguments, | |
544 Object::empty_array()); | |
545 ASSERT(!function.IsNull()); | 516 ASSERT(!function.IsNull()); |
546 thread->isolate()->object_store()->set_lookup_port_handler(function); | 517 thread->isolate()->object_store()->set_lookup_port_handler(function); |
547 } | 518 } |
548 const Array& args = Array::Handle(Array::New(kNumArguments)); | 519 const Array& args = Array::Handle(Array::New(kNumArguments)); |
549 args.SetAt(0, Integer::Handle(Integer::New(port_id))); | 520 args.SetAt(0, Integer::Handle(Integer::New(port_id))); |
550 const Object& result = | 521 const Object& result = |
551 Object::Handle(DartEntry::InvokeFunction(function, args)); | 522 Object::Handle(DartEntry::InvokeFunction(function, args)); |
552 return result.raw(); | 523 return result.raw(); |
553 } | 524 } |
554 | 525 |
555 | 526 |
556 RawObject* DartLibraryCalls::HandleMessage(const Object& handler, | 527 RawObject* DartLibraryCalls::HandleMessage(const Object& handler, |
557 const Instance& message) { | 528 const Instance& message) { |
558 Thread* thread = Thread::Current(); | 529 Thread* thread = Thread::Current(); |
559 Zone* zone = thread->zone(); | 530 Zone* zone = thread->zone(); |
560 Isolate* isolate = thread->isolate(); | 531 Isolate* isolate = thread->isolate(); |
561 Function& function = Function::Handle(zone, | 532 Function& function = Function::Handle( |
562 isolate->object_store()->handle_message_function()); | 533 zone, isolate->object_store()->handle_message_function()); |
563 const int kNumArguments = 2; | 534 const int kNumArguments = 2; |
564 if (function.IsNull()) { | 535 if (function.IsNull()) { |
565 Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary()); | 536 Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary()); |
566 ASSERT(!isolate_lib.IsNull()); | 537 ASSERT(!isolate_lib.IsNull()); |
567 const String& class_name = String::Handle(zone, | 538 const String& class_name = String::Handle( |
568 isolate_lib.PrivateName(Symbols::_RawReceivePortImpl())); | 539 zone, isolate_lib.PrivateName(Symbols::_RawReceivePortImpl())); |
569 const String& function_name = String::Handle(zone, | 540 const String& function_name = String::Handle( |
570 isolate_lib.PrivateName(Symbols::_handleMessage())); | 541 zone, isolate_lib.PrivateName(Symbols::_handleMessage())); |
571 function = Resolver::ResolveStatic(isolate_lib, | 542 function = Resolver::ResolveStatic(isolate_lib, class_name, function_name, |
572 class_name, | 543 kNumArguments, Object::empty_array()); |
573 function_name, | |
574 kNumArguments, | |
575 Object::empty_array()); | |
576 ASSERT(!function.IsNull()); | 544 ASSERT(!function.IsNull()); |
577 isolate->object_store()->set_handle_message_function(function); | 545 isolate->object_store()->set_handle_message_function(function); |
578 } | 546 } |
579 const Array& args = Array::Handle(zone, Array::New(kNumArguments)); | 547 const Array& args = Array::Handle(zone, Array::New(kNumArguments)); |
580 args.SetAt(0, handler); | 548 args.SetAt(0, handler); |
581 args.SetAt(1, message); | 549 args.SetAt(1, message); |
582 if (FLAG_support_debugger && isolate->debugger()->IsStepping()) { | 550 if (FLAG_support_debugger && isolate->debugger()->IsStepping()) { |
583 // If the isolate is being debugged and the debugger was stepping | 551 // If the isolate is being debugged and the debugger was stepping |
584 // through code, enable single stepping so debugger will stop | 552 // through code, enable single stepping so debugger will stop |
585 // at the first location the user is interested in. | 553 // at the first location the user is interested in. |
586 isolate->debugger()->SetSingleStep(); | 554 isolate->debugger()->SetSingleStep(); |
587 } | 555 } |
588 const Object& result = Object::Handle(zone, | 556 const Object& result = |
589 DartEntry::InvokeFunction(function, args)); | 557 Object::Handle(zone, DartEntry::InvokeFunction(function, args)); |
590 ASSERT(result.IsNull() || result.IsError()); | 558 ASSERT(result.IsNull() || result.IsError()); |
591 return result.raw(); | 559 return result.raw(); |
592 } | 560 } |
593 | 561 |
594 | 562 |
595 RawObject* DartLibraryCalls::DrainMicrotaskQueue() { | 563 RawObject* DartLibraryCalls::DrainMicrotaskQueue() { |
596 Zone* zone = Thread::Current()->zone(); | 564 Zone* zone = Thread::Current()->zone(); |
597 Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary()); | 565 Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary()); |
598 ASSERT(!isolate_lib.IsNull()); | 566 ASSERT(!isolate_lib.IsNull()); |
599 Function& function = Function::Handle(zone, | 567 Function& function = |
600 isolate_lib.LookupFunctionAllowPrivate( | 568 Function::Handle(zone, isolate_lib.LookupFunctionAllowPrivate( |
601 Symbols::_runPendingImmediateCallback())); | 569 Symbols::_runPendingImmediateCallback())); |
602 const Object& result = Object::Handle(zone, | 570 const Object& result = Object::Handle( |
603 DartEntry::InvokeFunction(function, Object::empty_array())); | 571 zone, DartEntry::InvokeFunction(function, Object::empty_array())); |
604 ASSERT(result.IsNull() || result.IsError()); | 572 ASSERT(result.IsNull() || result.IsError()); |
605 return result.raw(); | 573 return result.raw(); |
606 } | 574 } |
607 | 575 |
608 | 576 |
609 RawObject* DartLibraryCalls::MapSetAt(const Instance& map, | 577 RawObject* DartLibraryCalls::MapSetAt(const Instance& map, |
610 const Instance& key, | 578 const Instance& key, |
611 const Instance& value) { | 579 const Instance& value) { |
612 const int kNumArguments = 3; | 580 const int kNumArguments = 3; |
613 ArgumentsDescriptor args_desc( | 581 ArgumentsDescriptor args_desc( |
614 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 582 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
615 const Function& function = Function::Handle( | 583 const Function& function = Function::Handle( |
616 Resolver::ResolveDynamic(map, | 584 Resolver::ResolveDynamic(map, Symbols::AssignIndexToken(), args_desc)); |
617 Symbols::AssignIndexToken(), | |
618 args_desc)); | |
619 ASSERT(!function.IsNull()); | 585 ASSERT(!function.IsNull()); |
620 const Array& args = Array::Handle(Array::New(kNumArguments)); | 586 const Array& args = Array::Handle(Array::New(kNumArguments)); |
621 args.SetAt(0, map); | 587 args.SetAt(0, map); |
622 args.SetAt(1, key); | 588 args.SetAt(1, key); |
623 args.SetAt(2, value); | 589 args.SetAt(2, value); |
624 const Object& result = Object::Handle(DartEntry::InvokeFunction(function, | 590 const Object& result = |
625 args)); | 591 Object::Handle(DartEntry::InvokeFunction(function, args)); |
626 return result.raw(); | 592 return result.raw(); |
627 } | 593 } |
628 | 594 |
629 } // namespace dart | 595 } // namespace dart |
OLD | NEW |