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