OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/isolate.h" | 5 #include "vm/isolate.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/text_buffer.h" | 10 #include "platform/text_buffer.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 static void SerializeObject(const Instance& obj, | 128 static void SerializeObject(const Instance& obj, |
129 uint8_t** obj_data, | 129 uint8_t** obj_data, |
130 intptr_t* obj_len, | 130 intptr_t* obj_len, |
131 bool allow_any_object) { | 131 bool allow_any_object) { |
132 MessageWriter writer(obj_data, &allocator, allow_any_object); | 132 MessageWriter writer(obj_data, &allocator, allow_any_object); |
133 writer.WriteMessage(obj); | 133 writer.WriteMessage(obj); |
134 *obj_len = writer.BytesWritten(); | 134 *obj_len = writer.BytesWritten(); |
135 } | 135 } |
136 | 136 |
137 | 137 |
138 static Message* SerializeMessage( | |
turnidge
2015/12/11 22:30:48
Instead of having this helper function, how about
Ivan Posva
2015/12/11 22:53:39
Todd,
I tend to agree with your concern about the
zra
2015/12/11 23:44:32
Added TODO here.
| |
139 Dart_Port dest_port, const Instance& obj) { | |
140 if (ApiObjectConverter::CanConvert(obj.raw())) { | |
141 return new Message(dest_port, | |
142 reinterpret_cast<uint8_t*>(obj.raw()), 0, | |
143 Message::kNormalPriority); | |
144 } else { | |
145 uint8_t* obj_data; | |
146 intptr_t obj_len; | |
147 SerializeObject(obj, &obj_data, &obj_len, false); | |
148 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority); | |
149 } | |
150 } | |
151 | |
152 | |
138 void Isolate::RegisterClass(const Class& cls) { | 153 void Isolate::RegisterClass(const Class& cls) { |
139 class_table()->Register(cls); | 154 class_table()->Register(cls); |
140 } | 155 } |
141 | 156 |
142 | 157 |
143 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { | 158 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { |
144 class_table()->RegisterAt(index, cls); | 159 class_table()->RegisterAt(index, cls); |
145 } | 160 } |
146 | 161 |
147 | 162 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 if (!obj2.IsSendPort()) return Error::null(); | 268 if (!obj2.IsSendPort()) return Error::null(); |
254 const SendPort& send_port = SendPort::Cast(obj2); | 269 const SendPort& send_port = SendPort::Cast(obj2); |
255 const Object& obj3 = Object::Handle(zone, message.At(3)); | 270 const Object& obj3 = Object::Handle(zone, message.At(3)); |
256 if (!obj3.IsSmi()) return Error::null(); | 271 if (!obj3.IsSmi()) return Error::null(); |
257 const intptr_t priority = Smi::Cast(obj3).Value(); | 272 const intptr_t priority = Smi::Cast(obj3).Value(); |
258 const Object& obj4 = Object::Handle(zone, message.At(4)); | 273 const Object& obj4 = Object::Handle(zone, message.At(4)); |
259 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); | 274 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); |
260 const Instance& response = | 275 const Instance& response = |
261 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); | 276 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); |
262 if (priority == Isolate::kImmediateAction) { | 277 if (priority == Isolate::kImmediateAction) { |
263 uint8_t* data = NULL; | 278 PortMap::PostMessage(SerializeMessage( |
264 intptr_t len = 0; | 279 send_port.Id(), response)); |
265 SerializeObject(response, &data, &len, false); | |
266 PortMap::PostMessage(new Message(send_port.Id(), | |
267 data, len, | |
268 Message::kNormalPriority)); | |
269 } else { | 280 } else { |
270 ASSERT((priority == Isolate::kBeforeNextEventAction) || | 281 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
271 (priority == Isolate::kAsEventAction)); | 282 (priority == Isolate::kAsEventAction)); |
272 // Update the message so that it will be handled immediately when it | 283 // Update the message so that it will be handled immediately when it |
273 // is picked up from the message queue the next time. | 284 // is picked up from the message queue the next time. |
274 message.SetAt(0, Smi::Handle(zone, | 285 message.SetAt(0, Smi::Handle(zone, |
275 Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 286 Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
276 message.SetAt(3, Smi::Handle(zone, | 287 message.SetAt(3, Smi::Handle(zone, |
277 Smi::New(Isolate::kImmediateAction))); | 288 Smi::New(Isolate::kImmediateAction))); |
278 uint8_t* data = NULL; | 289 this->PostMessage(SerializeMessage( |
279 intptr_t len = 0; | 290 Message::kIllegalPort, message), |
280 SerializeObject(message, &data, &len, false); | |
281 this->PostMessage( | |
282 new Message(Message::kIllegalPort, | |
283 data, len, | |
284 Message::kNormalPriority), | |
285 priority == Isolate::kBeforeNextEventAction /* at_head */); | 291 priority == Isolate::kBeforeNextEventAction /* at_head */); |
286 } | 292 } |
287 break; | 293 break; |
288 } | 294 } |
289 case Isolate::kKillMsg: | 295 case Isolate::kKillMsg: |
290 case Isolate::kInternalKillMsg: | 296 case Isolate::kInternalKillMsg: |
291 case Isolate::kVMRestartMsg: { | 297 case Isolate::kVMRestartMsg: { |
292 // [ OOB, kKillMsg, terminate capability, priority ] | 298 // [ OOB, kKillMsg, terminate capability, priority ] |
293 if (message.Length() != 4) return Error::null(); | 299 if (message.Length() != 4) return Error::null(); |
294 Object& obj = Object::Handle(zone, message.At(3)); | 300 Object& obj = Object::Handle(zone, message.At(3)); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
327 } | 333 } |
328 } else { | 334 } else { |
329 ASSERT((priority == Isolate::kBeforeNextEventAction) || | 335 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
330 (priority == Isolate::kAsEventAction)); | 336 (priority == Isolate::kAsEventAction)); |
331 // Update the message so that it will be handled immediately when it | 337 // Update the message so that it will be handled immediately when it |
332 // is picked up from the message queue the next time. | 338 // is picked up from the message queue the next time. |
333 message.SetAt(0, Smi::Handle(zone, | 339 message.SetAt(0, Smi::Handle(zone, |
334 Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 340 Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
335 message.SetAt(3, Smi::Handle(zone, | 341 message.SetAt(3, Smi::Handle(zone, |
336 Smi::New(Isolate::kImmediateAction))); | 342 Smi::New(Isolate::kImmediateAction))); |
337 uint8_t* data = NULL; | 343 this->PostMessage(SerializeMessage( |
338 intptr_t len = 0; | 344 Message::kIllegalPort, message), |
339 SerializeObject(message, &data, &len, false); | |
340 this->PostMessage( | |
341 new Message(Message::kIllegalPort, | |
342 data, len, | |
343 Message::kNormalPriority), | |
344 priority == Isolate::kBeforeNextEventAction /* at_head */); | 345 priority == Isolate::kBeforeNextEventAction /* at_head */); |
345 } | 346 } |
346 break; | 347 break; |
347 } | 348 } |
348 case Isolate::kInterruptMsg: { | 349 case Isolate::kInterruptMsg: { |
349 // [ OOB, kInterruptMsg, pause capability ] | 350 // [ OOB, kInterruptMsg, pause capability ] |
350 if (message.Length() != 3) return Error::null(); | 351 if (message.Length() != 3) return Error::null(); |
351 Object& obj = Object::Handle(zone, message.At(2)); | 352 Object& obj = Object::Handle(zone, message.At(2)); |
352 if (!I->VerifyPauseCapability(obj)) return Error::null(); | 353 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
353 | 354 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 if (message->RedirectToDeliveryFailurePort()) { | 462 if (message->RedirectToDeliveryFailurePort()) { |
462 PortMap::PostMessage(message); | 463 PortMap::PostMessage(message); |
463 } else { | 464 } else { |
464 delete message; | 465 delete message; |
465 } | 466 } |
466 return kOK; | 467 return kOK; |
467 } | 468 } |
468 } | 469 } |
469 | 470 |
470 // Parse the message. | 471 // Parse the message. |
471 MessageSnapshotReader reader(message->data(), message->len(), thread); | 472 Object& msg_obj = Object::Handle(zone); |
472 const Object& msg_obj = Object::Handle(zone, reader.ReadObject()); | 473 if (message->IsRaw()) { |
474 msg_obj = message->raw_obj(); | |
475 // We should only be sending RawObjects that can be converted to CObjects. | |
476 ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw())); | |
477 } else { | |
478 MessageSnapshotReader reader(message->data(), message->len(), thread); | |
479 msg_obj = reader.ReadObject(); | |
480 } | |
473 if (msg_obj.IsError()) { | 481 if (msg_obj.IsError()) { |
474 // An error occurred while reading the message. | 482 // An error occurred while reading the message. |
475 delete message; | 483 delete message; |
476 return ProcessUnhandledException(Error::Cast(msg_obj)); | 484 return ProcessUnhandledException(Error::Cast(msg_obj)); |
477 } | 485 } |
478 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { | 486 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { |
479 // TODO(turnidge): We need to decide what an isolate does with | 487 // TODO(turnidge): We need to decide what an isolate does with |
480 // malformed messages. If they (eventually) come from a remote | 488 // malformed messages. If they (eventually) come from a remote |
481 // machine, then it might make sense to drop the message entirely. | 489 // machine, then it might make sense to drop the message entirely. |
482 // In the case that the message originated locally, which is | 490 // In the case that the message originated locally, which is |
483 // always true for now, then this should never occur. | 491 // always true for now, then this should never occur. |
484 UNREACHABLE(); | 492 UNREACHABLE(); |
485 } | 493 } |
486 | |
487 Instance& msg = Instance::Handle(zone); | 494 Instance& msg = Instance::Handle(zone); |
488 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. | 495 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. |
489 | 496 |
490 MessageStatus status = kOK; | 497 MessageStatus status = kOK; |
491 if (message->IsOOB()) { | 498 if (message->IsOOB()) { |
492 // OOB messages are expected to be fixed length arrays where the first | 499 // OOB messages are expected to be fixed length arrays where the first |
493 // element is a Smi describing the OOB destination. Messages that do not | 500 // element is a Smi describing the OOB destination. Messages that do not |
494 // confirm to this layout are silently ignored. | 501 // confirm to this layout are silently ignored. |
495 if (msg.IsArray()) { | 502 if (msg.IsArray()) { |
496 const Array& oob_msg = Array::Cast(msg); | 503 const Array& oob_msg = Array::Cast(msg); |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1196 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1203 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1197 current_zone(), this->object_store()->exit_listeners()); | 1204 current_zone(), this->object_store()->exit_listeners()); |
1198 if (listeners.IsNull()) return; | 1205 if (listeners.IsNull()) return; |
1199 | 1206 |
1200 SendPort& listener = SendPort::Handle(current_zone()); | 1207 SendPort& listener = SendPort::Handle(current_zone()); |
1201 Instance& response = Instance::Handle(current_zone()); | 1208 Instance& response = Instance::Handle(current_zone()); |
1202 for (intptr_t i = 0; i < listeners.Length(); i += 2) { | 1209 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
1203 listener ^= listeners.At(i); | 1210 listener ^= listeners.At(i); |
1204 if (!listener.IsNull()) { | 1211 if (!listener.IsNull()) { |
1205 Dart_Port port_id = listener.Id(); | 1212 Dart_Port port_id = listener.Id(); |
1206 uint8_t* data = NULL; | |
1207 intptr_t len = 0; | |
1208 response ^= listeners.At(i + 1); | 1213 response ^= listeners.At(i + 1); |
1209 SerializeObject(response, &data, &len, false); | 1214 PortMap::PostMessage(SerializeMessage(port_id, response)); |
1210 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); | |
1211 PortMap::PostMessage(msg); | |
1212 } | 1215 } |
1213 } | 1216 } |
1214 } | 1217 } |
1215 | 1218 |
1216 | 1219 |
1217 void Isolate::AddErrorListener(const SendPort& listener) { | 1220 void Isolate::AddErrorListener(const SendPort& listener) { |
1218 // Ensure a limit for the number of listeners remembered. | 1221 // Ensure a limit for the number of listeners remembered. |
1219 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); | 1222 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); |
1220 | 1223 |
1221 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1224 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1269 if (listeners.IsNull()) return false; | 1272 if (listeners.IsNull()) return false; |
1270 | 1273 |
1271 const Array& arr = Array::Handle(current_zone(), Array::New(2)); | 1274 const Array& arr = Array::Handle(current_zone(), Array::New(2)); |
1272 arr.SetAt(0, msg); | 1275 arr.SetAt(0, msg); |
1273 arr.SetAt(1, stacktrace); | 1276 arr.SetAt(1, stacktrace); |
1274 SendPort& listener = SendPort::Handle(current_zone()); | 1277 SendPort& listener = SendPort::Handle(current_zone()); |
1275 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1278 for (intptr_t i = 0; i < listeners.Length(); i++) { |
1276 listener ^= listeners.At(i); | 1279 listener ^= listeners.At(i); |
1277 if (!listener.IsNull()) { | 1280 if (!listener.IsNull()) { |
1278 Dart_Port port_id = listener.Id(); | 1281 Dart_Port port_id = listener.Id(); |
1279 uint8_t* data = NULL; | 1282 PortMap::PostMessage(SerializeMessage(port_id, arr)); |
1280 intptr_t len = 0; | |
1281 SerializeObject(arr, &data, &len, false); | |
1282 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); | |
1283 PortMap::PostMessage(msg); | |
1284 } | 1283 } |
1285 } | 1284 } |
1286 return listeners.Length() > 0; | 1285 return listeners.Length() > 0; |
1287 } | 1286 } |
1288 | 1287 |
1289 | 1288 |
1290 static MessageHandler::MessageStatus RunIsolate(uword parameter) { | 1289 static MessageHandler::MessageStatus RunIsolate(uword parameter) { |
1291 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1290 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
1292 IsolateSpawnState* state = NULL; | 1291 IsolateSpawnState* state = NULL; |
1293 { | 1292 { |
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2494 } | 2493 } |
2495 | 2494 |
2496 | 2495 |
2497 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { | 2496 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { |
2498 return DeserializeObject(thread, | 2497 return DeserializeObject(thread, |
2499 serialized_message_, serialized_message_len_); | 2498 serialized_message_, serialized_message_len_); |
2500 } | 2499 } |
2501 | 2500 |
2502 | 2501 |
2503 } // namespace dart | 2502 } // namespace dart |
OLD | NEW |