Chromium Code Reviews| Index: runtime/vm/isolate.cc |
| =================================================================== |
| --- runtime/vm/isolate.cc (revision 41942) |
| +++ runtime/vm/isolate.cc (working copy) |
| @@ -52,6 +52,21 @@ |
| #define I (isolate()) |
| +static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| + void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| + return reinterpret_cast<uint8_t*>(new_ptr); |
| +} |
| + |
| + |
| +static void SerializeObject(const Instance& obj, |
| + uint8_t** obj_data, |
| + intptr_t* obj_len) { |
| + MessageWriter writer(obj_data, &allocator); |
| + writer.WriteMessage(obj); |
| + *obj_len = writer.BytesWritten(); |
| +} |
| + |
| + |
| void Isolate::RegisterClass(const Class& cls) { |
| class_table()->Register(cls); |
| } |
| @@ -89,7 +104,12 @@ |
| // Keep in sync with isolate_patch.dart. |
| enum { |
| kPauseMsg = 1, |
| - kResumeMsg |
| + kResumeMsg = 2, |
| + kPingMsg = 3, |
| + |
| + kImmediateAction = 0, |
| + kBeforeNextEventAction = 1, |
| + kAsEventAction = 2 |
| }; |
| void HandleLibMessage(const Array& message); |
| @@ -147,6 +167,50 @@ |
| } |
| break; |
| } |
| + case kPingMsg: { |
| + // [ OOB, kPingMsg, responsePort, pingType ] |
| + if (message.Length() != 4) return; |
| + const Object& obj2 = Object::Handle(I, message.At(2)); |
| + if (!obj2.IsSendPort()) return; |
| + const SendPort& send_port = SendPort::Cast(obj2); |
| + const Object& obj3 = Object::Handle(I, message.At(3)); |
| + if (!obj3.IsSmi()) return; |
| + const Smi& ping_type = Smi::Cast(obj3); |
|
siva
2014/12/01 19:48:05
why not
intptr_t ping_value = Smi::Cast(obj3).Valu
Ivan Posva
2014/12/12 20:21:46
Done.
|
| + if (ping_type.Value() == kImmediateAction) { |
| + uint8_t* data = NULL; |
| + intptr_t len = 0; |
| + SerializeObject(Object::null_instance(), &data, &len); |
| + PortMap::PostMessage(new Message(send_port.Id(), |
| + data, len, |
| + Message::kNormalPriority)); |
|
siva
2014/12/01 19:48:05
How does the spec resolve a potential Denial of Se
Ivan Posva
2014/12/12 20:21:46
If you control the isolate, then you can do other
|
| + } else if (ping_type.Value() == kBeforeNextEventAction) { |
| + // Update the message so that it will be handled immediately when it |
| + // is picked up from the message queue the next time. |
| + message.SetAt( |
| + 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
| + message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); |
| + uint8_t* data = NULL; |
| + intptr_t len = 0; |
| + SerializeObject(message, &data, &len); |
| + this->PostMessage(new Message(Message::kIllegalPort, |
| + data, len, |
| + Message::kNormalPriority), |
| + true /* at_head */); |
| + } else if (ping_type.Value() == kAsEventAction) { |
| + // Update the message so that it will be handled immediately when it |
| + // is picked up from the message queue the next time. |
| + message.SetAt( |
| + 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
| + message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); |
| + uint8_t* data = NULL; |
| + intptr_t len = 0; |
| + SerializeObject(message, &data, &len); |
| + this->PostMessage(new Message(Message::kIllegalPort, |
| + data, len, |
| + Message::kNormalPriority)); |
| + } |
| + break; |
| + } |
| #if defined(DEBUG) |
| // Malformed OOB messages are silently ignored in release builds. |
| default: |
| @@ -180,8 +244,10 @@ |
| // If the message is in band we lookup the handler to dispatch to. If the |
| // receive port was closed, we drop the message without deserializing it. |
| + // Illegal port is a special case for artificially enqueued isolate library |
| + // messages which are handled in C++ code below. |
| Object& msg_handler = Object::Handle(I); |
| - if (!message->IsOOB()) { |
| + if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { |
| msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); |
| if (msg_handler.IsError()) { |
| delete message; |
| @@ -251,6 +317,20 @@ |
| } |
| } |
| } |
| + } else if (message->dest_port() == Message::kIllegalPort) { |
| + // Check whether this is a delayed OOB message which needed handling as |
| + // part of the regular message dispatch. All other messages are dropped on |
| + // the floor. |
| + if (msg.IsArray()) { |
| + const Array& msg_arr = Array::Cast(msg); |
| + if (msg_arr.Length() > 0) { |
| + const Object& oob_tag = Object::Handle(I, msg_arr.At(0)); |
| + if (oob_tag.IsSmi() && |
| + (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { |
| + HandleLibMessage(Array::Cast(msg_arr)); |
| + } |
| + } |
| + } |
| } else { |
| const Object& result = Object::Handle(I, |
| DartLibraryCalls::HandleMessage(msg_handler, msg)); |
| @@ -1409,21 +1489,6 @@ |
| } |
| -static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| - void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| - return reinterpret_cast<uint8_t*>(new_ptr); |
| -} |
| - |
| - |
| -static void SerializeObject(const Instance& obj, |
| - uint8_t** obj_data, |
| - intptr_t* obj_len) { |
| - MessageWriter writer(obj_data, &allocator); |
| - writer.WriteMessage(obj); |
| - *obj_len = writer.BytesWritten(); |
| -} |
| - |
| - |
| static RawInstance* DeserializeObject(Isolate* isolate, |
| uint8_t* obj_data, |
| intptr_t obj_len) { |