Index: runtime/vm/isolate.cc |
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
index 1327ef24db29e36369f887c28b2f51cbaff245db..cf787fec95309c4547aeb0866d0160f4cd02727f 100644 |
--- a/runtime/vm/isolate.cc |
+++ b/runtime/vm/isolate.cc |
@@ -492,6 +492,15 @@ bool IsolateMessageHandler::HandleMessage(Message* message) { |
} |
} |
delete message; |
+ if (success) { |
+ const Object& result = |
+ Object::Handle(zone, I->InvokePendingExtensionCalls()); |
+ if (result.IsError()) { |
+ success = ProcessUnhandledException(Error::Cast(result)); |
Ivan Posva
2015/08/20 20:46:05
We should propagate errors to the service isolate
Cutch
2015/08/21 14:18:56
Done.
|
+ } else { |
+ ASSERT(result.IsNull()); |
+ } |
+ } |
return success; |
} |
@@ -696,6 +705,7 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags) |
default_tag_(UserTag::null()), |
collected_closures_(GrowableObjectArray::null()), |
deoptimized_code_array_(GrowableObjectArray::null()), |
+ pending_extension_calls_(GrowableObjectArray::null()), |
metrics_list_head_(NULL), |
compilation_allowed_(true), |
cha_(NULL), |
@@ -1620,6 +1630,10 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, |
visitor->VisitPointer( |
reinterpret_cast<RawObject**>(&deoptimized_code_array_)); |
+ // Visit the pending service extension calls. |
+ visitor->VisitPointer( |
+ reinterpret_cast<RawObject**>(&pending_extension_calls_)); |
+ |
// Visit objects in the debugger. |
debugger()->VisitObjectPointers(visitor); |
@@ -1825,6 +1839,56 @@ void Isolate::TrackDeoptimizedCode(const Code& code) { |
} |
+void Isolate::set_pending_extension_calls(const GrowableObjectArray& value) { |
+ pending_extension_calls_ = value.raw(); |
+} |
+ |
+ |
+RawObject* Isolate::InvokePendingExtensionCalls() { |
+ GrowableObjectArray& calls = |
+ GrowableObjectArray::Handle(GetAndClearPendingExtensionCalls()); |
+ if (calls.IsNull()) { |
+ return Object::null(); |
+ } |
+ const Array& arguments = Array::Handle(Array::New(1, Heap::kNew)); |
+ Object& result = Object::Handle(); |
+ Instance& closure = Instance::Handle(); |
+ for (intptr_t i = 0; i < calls.Length(); i++) { |
+ closure ^= calls.At(i); |
+ ASSERT(!closure.IsNull()); |
+ arguments.SetAt(0, closure); |
+ result = DartEntry::InvokeClosure(arguments); |
+ if (result.IsError()) { |
+ return result.raw(); |
Ivan Posva
2015/08/20 20:46:05
Maybe we want to requeue the non-handled extension
Cutch
2015/08/21 14:18:56
Done.
|
+ } |
+ result = DartLibraryCalls::DrainMicrotaskQueue(); |
+ if (result.IsError()) { |
+ return result.raw(); |
+ } |
+ } |
+ return Object::null(); |
+} |
+ |
+ |
+RawGrowableObjectArray* Isolate::GetAndClearPendingExtensionCalls() { |
+ RawGrowableObjectArray* r = pending_extension_calls_; |
+ pending_extension_calls_ = GrowableObjectArray::null(); |
+ return r; |
+} |
+ |
+ |
+void Isolate::AppendExtensionCall(const Instance& closure) { |
+ GrowableObjectArray& calls = |
+ GrowableObjectArray::Handle(pending_extension_calls()); |
+ if (calls.IsNull()) { |
+ calls ^= GrowableObjectArray::New(Heap::kOld); |
+ ASSERT(!calls.IsNull()); |
+ set_pending_extension_calls(calls); |
+ } |
+ calls.Add(closure, Heap::kOld); |
+} |
+ |
+ |
void Isolate::WakePauseEventHandler(Dart_Isolate isolate) { |
Isolate* iso = reinterpret_cast<Isolate*>(isolate); |
MonitorLocker ml(iso->pause_loop_monitor_); |