OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "include/dart_native_api.h" | 5 #include "include/dart_native_api.h" |
6 #include "platform/assert.h" | 6 #include "platform/assert.h" |
7 #include "vm/bootstrap_natives.h" | 7 #include "vm/bootstrap_natives.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/dart.h" | 9 #include "vm/dart.h" |
10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 intptr_t old_size, | 34 intptr_t old_size, |
35 intptr_t new_size) { | 35 intptr_t new_size) { |
36 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 36 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
37 return reinterpret_cast<uint8_t*>(new_ptr); | 37 return reinterpret_cast<uint8_t*>(new_ptr); |
38 } | 38 } |
39 | 39 |
40 static void malloc_deallocator(uint8_t* ptr) { | 40 static void malloc_deallocator(uint8_t* ptr) { |
41 free(reinterpret_cast<void*>(ptr)); | 41 free(reinterpret_cast<void*>(ptr)); |
42 } | 42 } |
43 | 43 |
44 | |
45 DEFINE_NATIVE_ENTRY(CapabilityImpl_factory, 1) { | 44 DEFINE_NATIVE_ENTRY(CapabilityImpl_factory, 1) { |
46 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull()); | 45 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull()); |
47 uint64_t id = isolate->random()->NextUInt64(); | 46 uint64_t id = isolate->random()->NextUInt64(); |
48 return Capability::New(id); | 47 return Capability::New(id); |
49 } | 48 } |
50 | 49 |
51 | |
52 DEFINE_NATIVE_ENTRY(CapabilityImpl_equals, 2) { | 50 DEFINE_NATIVE_ENTRY(CapabilityImpl_equals, 2) { |
53 GET_NON_NULL_NATIVE_ARGUMENT(Capability, recv, arguments->NativeArgAt(0)); | 51 GET_NON_NULL_NATIVE_ARGUMENT(Capability, recv, arguments->NativeArgAt(0)); |
54 GET_NON_NULL_NATIVE_ARGUMENT(Capability, other, arguments->NativeArgAt(1)); | 52 GET_NON_NULL_NATIVE_ARGUMENT(Capability, other, arguments->NativeArgAt(1)); |
55 return (recv.Id() == other.Id()) ? Bool::True().raw() : Bool::False().raw(); | 53 return (recv.Id() == other.Id()) ? Bool::True().raw() : Bool::False().raw(); |
56 } | 54 } |
57 | 55 |
58 | |
59 DEFINE_NATIVE_ENTRY(CapabilityImpl_get_hashcode, 1) { | 56 DEFINE_NATIVE_ENTRY(CapabilityImpl_get_hashcode, 1) { |
60 GET_NON_NULL_NATIVE_ARGUMENT(Capability, cap, arguments->NativeArgAt(0)); | 57 GET_NON_NULL_NATIVE_ARGUMENT(Capability, cap, arguments->NativeArgAt(0)); |
61 int64_t id = cap.Id(); | 58 int64_t id = cap.Id(); |
62 int32_t hi = static_cast<int32_t>(id >> 32); | 59 int32_t hi = static_cast<int32_t>(id >> 32); |
63 int32_t lo = static_cast<int32_t>(id); | 60 int32_t lo = static_cast<int32_t>(id); |
64 int32_t hash = (hi ^ lo) & kSmiMax; | 61 int32_t hash = (hi ^ lo) & kSmiMax; |
65 return Smi::New(hash); | 62 return Smi::New(hash); |
66 } | 63 } |
67 | 64 |
68 | |
69 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 1) { | 65 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 1) { |
70 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull()); | 66 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull()); |
71 Dart_Port port_id = PortMap::CreatePort(isolate->message_handler()); | 67 Dart_Port port_id = PortMap::CreatePort(isolate->message_handler()); |
72 return ReceivePort::New(port_id, false /* not control port */); | 68 return ReceivePort::New(port_id, false /* not control port */); |
73 } | 69 } |
74 | 70 |
75 | |
76 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_id, 1) { | 71 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_id, 1) { |
77 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); | 72 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); |
78 return Integer::NewFromUint64(port.Id()); | 73 return Integer::NewFromUint64(port.Id()); |
79 } | 74 } |
80 | 75 |
81 | |
82 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_sendport, 1) { | 76 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_sendport, 1) { |
83 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); | 77 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); |
84 return port.send_port(); | 78 return port.send_port(); |
85 } | 79 } |
86 | 80 |
87 | |
88 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_closeInternal, 1) { | 81 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_closeInternal, 1) { |
89 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); | 82 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); |
90 Dart_Port id = port.Id(); | 83 Dart_Port id = port.Id(); |
91 PortMap::ClosePort(id); | 84 PortMap::ClosePort(id); |
92 return Integer::NewFromUint64(id); | 85 return Integer::NewFromUint64(id); |
93 } | 86 } |
94 | 87 |
95 | |
96 DEFINE_NATIVE_ENTRY(SendPortImpl_get_id, 1) { | 88 DEFINE_NATIVE_ENTRY(SendPortImpl_get_id, 1) { |
97 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 89 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
98 return Integer::NewFromUint64(port.Id()); | 90 return Integer::NewFromUint64(port.Id()); |
99 } | 91 } |
100 | 92 |
101 | |
102 DEFINE_NATIVE_ENTRY(SendPortImpl_get_hashcode, 1) { | 93 DEFINE_NATIVE_ENTRY(SendPortImpl_get_hashcode, 1) { |
103 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 94 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
104 int64_t id = port.Id(); | 95 int64_t id = port.Id(); |
105 int32_t hi = static_cast<int32_t>(id >> 32); | 96 int32_t hi = static_cast<int32_t>(id >> 32); |
106 int32_t lo = static_cast<int32_t>(id); | 97 int32_t lo = static_cast<int32_t>(id); |
107 int32_t hash = (hi ^ lo) & kSmiMax; | 98 int32_t hash = (hi ^ lo) & kSmiMax; |
108 return Smi::New(hash); | 99 return Smi::New(hash); |
109 } | 100 } |
110 | 101 |
111 | |
112 DEFINE_NATIVE_ENTRY(SendPortImpl_sendInternal_, 2) { | 102 DEFINE_NATIVE_ENTRY(SendPortImpl_sendInternal_, 2) { |
113 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 103 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
114 // TODO(iposva): Allow for arbitrary messages to be sent. | 104 // TODO(iposva): Allow for arbitrary messages to be sent. |
115 GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1)); | 105 GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1)); |
116 | 106 |
117 const Dart_Port destination_port_id = port.Id(); | 107 const Dart_Port destination_port_id = port.Id(); |
118 const bool can_send_any_object = isolate->origin_id() == port.origin_id(); | 108 const bool can_send_any_object = isolate->origin_id() == port.origin_id(); |
119 | 109 |
120 if (ApiObjectConverter::CanConvert(obj.raw())) { | 110 if (ApiObjectConverter::CanConvert(obj.raw())) { |
121 PortMap::PostMessage( | 111 PortMap::PostMessage( |
122 new Message(destination_port_id, obj.raw(), Message::kNormalPriority)); | 112 new Message(destination_port_id, obj.raw(), Message::kNormalPriority)); |
123 } else { | 113 } else { |
124 uint8_t* data = NULL; | 114 uint8_t* data = NULL; |
125 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, | 115 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, |
126 can_send_any_object); | 116 can_send_any_object); |
127 writer.WriteMessage(obj); | 117 writer.WriteMessage(obj); |
128 | 118 |
129 // TODO(turnidge): Throw an exception when the return value is false? | 119 // TODO(turnidge): Throw an exception when the return value is false? |
130 PortMap::PostMessage(new Message(destination_port_id, data, | 120 PortMap::PostMessage(new Message(destination_port_id, data, |
131 writer.BytesWritten(), | 121 writer.BytesWritten(), |
132 Message::kNormalPriority)); | 122 Message::kNormalPriority)); |
133 } | 123 } |
134 return Object::null(); | 124 return Object::null(); |
135 } | 125 } |
136 | 126 |
137 | |
138 static void ThrowIsolateSpawnException(const String& message) { | 127 static void ThrowIsolateSpawnException(const String& message) { |
139 const Array& args = Array::Handle(Array::New(1)); | 128 const Array& args = Array::Handle(Array::New(1)); |
140 args.SetAt(0, message); | 129 args.SetAt(0, message); |
141 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); | 130 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); |
142 } | 131 } |
143 | 132 |
144 | |
145 class SpawnIsolateTask : public ThreadPool::Task { | 133 class SpawnIsolateTask : public ThreadPool::Task { |
146 public: | 134 public: |
147 explicit SpawnIsolateTask(IsolateSpawnState* state) : state_(state) {} | 135 explicit SpawnIsolateTask(IsolateSpawnState* state) : state_(state) {} |
148 | 136 |
149 virtual void Run() { | 137 virtual void Run() { |
150 // Create a new isolate. | 138 // Create a new isolate. |
151 char* error = NULL; | 139 char* error = NULL; |
152 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); | 140 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); |
153 if (callback == NULL) { | 141 if (callback == NULL) { |
154 state_->DecrementSpawnCount(); | 142 state_->DecrementSpawnCount(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 // Perhaps the parent isolate died or closed the port before we | 185 // Perhaps the parent isolate died or closed the port before we |
198 // could report the error. Ignore. | 186 // could report the error. Ignore. |
199 } | 187 } |
200 } | 188 } |
201 | 189 |
202 IsolateSpawnState* state_; | 190 IsolateSpawnState* state_; |
203 | 191 |
204 DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask); | 192 DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask); |
205 }; | 193 }; |
206 | 194 |
207 | |
208 static const char* String2UTF8(const String& str) { | 195 static const char* String2UTF8(const String& str) { |
209 intptr_t len = Utf8::Length(str); | 196 intptr_t len = Utf8::Length(str); |
210 char* result = new char[len + 1]; | 197 char* result = new char[len + 1]; |
211 str.ToUTF8(reinterpret_cast<uint8_t*>(result), len); | 198 str.ToUTF8(reinterpret_cast<uint8_t*>(result), len); |
212 result[len] = 0; | 199 result[len] = 0; |
213 | 200 |
214 return result; | 201 return result; |
215 } | 202 } |
216 | 203 |
217 | |
218 DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 10) { | 204 DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 10) { |
219 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 205 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
220 GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1)); | 206 GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1)); |
221 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(2)); | 207 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(2)); |
222 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3)); | 208 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3)); |
223 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); | 209 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); |
224 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(5)); | 210 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(5)); |
225 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(6)); | 211 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(6)); |
226 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(7)); | 212 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(7)); |
227 GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(8)); | 213 GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(8)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 } | 272 } |
287 return Object::null(); | 273 return Object::null(); |
288 } | 274 } |
289 } | 275 } |
290 const String& msg = String::Handle(String::New( | 276 const String& msg = String::Handle(String::New( |
291 "Isolate.spawn expects to be passed a static or top-level function")); | 277 "Isolate.spawn expects to be passed a static or top-level function")); |
292 Exceptions::ThrowArgumentError(msg); | 278 Exceptions::ThrowArgumentError(msg); |
293 return Object::null(); | 279 return Object::null(); |
294 } | 280 } |
295 | 281 |
296 | |
297 static const char* CanonicalizeUri(Thread* thread, | 282 static const char* CanonicalizeUri(Thread* thread, |
298 const Library& library, | 283 const Library& library, |
299 const String& uri, | 284 const String& uri, |
300 char** error) { | 285 char** error) { |
301 const char* result = NULL; | 286 const char* result = NULL; |
302 Zone* zone = thread->zone(); | 287 Zone* zone = thread->zone(); |
303 Isolate* isolate = thread->isolate(); | 288 Isolate* isolate = thread->isolate(); |
304 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); | 289 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); |
305 if (handler != NULL) { | 290 if (handler != NULL) { |
306 TransitionVMToNative transition(thread); | 291 TransitionVMToNative transition(thread); |
(...skipping 17 matching lines...) Expand all Loading... |
324 } | 309 } |
325 Dart_ExitScope(); | 310 Dart_ExitScope(); |
326 } else { | 311 } else { |
327 *error = zone->PrintToString( | 312 *error = zone->PrintToString( |
328 "Unable to canonicalize uri '%s': no library tag handler found.", | 313 "Unable to canonicalize uri '%s': no library tag handler found.", |
329 uri.ToCString()); | 314 uri.ToCString()); |
330 } | 315 } |
331 return result; | 316 return result; |
332 } | 317 } |
333 | 318 |
334 | |
335 DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) { | 319 DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) { |
336 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 320 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
337 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1)); | 321 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1)); |
338 | 322 |
339 GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2)); | 323 GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2)); |
340 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3)); | 324 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3)); |
341 | 325 |
342 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); | 326 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); |
343 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); | 327 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); |
344 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); | 328 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 // Running on the thread pool failed. Clean up everything. | 411 // Running on the thread pool failed. Clean up everything. |
428 state->DecrementSpawnCount(); | 412 state->DecrementSpawnCount(); |
429 delete state; | 413 delete state; |
430 state = NULL; | 414 state = NULL; |
431 delete spawn_task; | 415 delete spawn_task; |
432 spawn_task = NULL; | 416 spawn_task = NULL; |
433 } | 417 } |
434 return Object::null(); | 418 return Object::null(); |
435 } | 419 } |
436 | 420 |
437 | |
438 DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) { | 421 DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) { |
439 const Array& result = Array::Handle(Array::New(3)); | 422 const Array& result = Array::Handle(Array::New(3)); |
440 result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port()))); | 423 result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port()))); |
441 result.SetAt( | 424 result.SetAt( |
442 1, Capability::Handle(Capability::New(isolate->pause_capability()))); | 425 1, Capability::Handle(Capability::New(isolate->pause_capability()))); |
443 result.SetAt( | 426 result.SetAt( |
444 2, Capability::Handle(Capability::New(isolate->terminate_capability()))); | 427 2, Capability::Handle(Capability::New(isolate->terminate_capability()))); |
445 return result.raw(); | 428 return result.raw(); |
446 } | 429 } |
447 | 430 |
448 | |
449 DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0) { | 431 DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0) { |
450 const Library& root_lib = | 432 const Library& root_lib = |
451 Library::Handle(zone, isolate->object_store()->root_library()); | 433 Library::Handle(zone, isolate->object_store()->root_library()); |
452 return root_lib.url(); | 434 return root_lib.url(); |
453 } | 435 } |
454 | 436 |
455 | |
456 DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) { | 437 DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) { |
457 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 438 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
458 GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1)); | 439 GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1)); |
459 | 440 |
460 // Make sure to route this request to the isolate library OOB mesage handler. | 441 // Make sure to route this request to the isolate library OOB mesage handler. |
461 msg.SetAt(0, Smi::Handle(Smi::New(Message::kIsolateLibOOBMsg))); | 442 msg.SetAt(0, Smi::Handle(Smi::New(Message::kIsolateLibOOBMsg))); |
462 | 443 |
463 uint8_t* data = NULL; | 444 uint8_t* data = NULL; |
464 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 445 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
465 writer.WriteMessage(msg); | 446 writer.WriteMessage(msg); |
466 | 447 |
467 PortMap::PostMessage(new Message(port.Id(), data, writer.BytesWritten(), | 448 PortMap::PostMessage(new Message(port.Id(), data, writer.BytesWritten(), |
468 Message::kOOBPriority)); | 449 Message::kOOBPriority)); |
469 return Object::null(); | 450 return Object::null(); |
470 } | 451 } |
471 | 452 |
472 } // namespace dart | 453 } // namespace dart |
OLD | NEW |