| Index: src/isolate.cc
|
| diff --git a/src/isolate.cc b/src/isolate.cc
|
| index 06df1f67c25bc380097c2cc8ca471105ec65b071..a07451a9bed2ffc3f375b5b38b533626a9b9529f 100644
|
| --- a/src/isolate.cc
|
| +++ b/src/isolate.cc
|
| @@ -2232,13 +2232,13 @@ void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
|
|
|
| void Isolate::FireCallCompletedCallback() {
|
| bool has_call_completed_callbacks = !call_completed_callbacks_.is_empty();
|
| - bool run_microtasks = autorun_microtasks() && microtask_pending();
|
| + bool run_microtasks = autorun_microtasks() && pending_microtask_count();
|
| if (!has_call_completed_callbacks && !run_microtasks) return;
|
|
|
| if (!handle_scope_implementer()->CallDepthIsZero()) return;
|
| + if (run_microtasks) RunMicrotasks();
|
| // Fire callbacks. Increase call depth to prevent recursive callbacks.
|
| handle_scope_implementer()->IncrementCallDepth();
|
| - if (run_microtasks) Execution::RunMicrotasks(this);
|
| for (int i = 0; i < call_completed_callbacks_.length(); i++) {
|
| call_completed_callbacks_.at(i)();
|
| }
|
| @@ -2246,15 +2246,46 @@ void Isolate::FireCallCompletedCallback() {
|
| }
|
|
|
|
|
| -void Isolate::RunMicrotasks() {
|
| - if (!microtask_pending())
|
| - return;
|
| +void Isolate::EnqueueMicrotask(Handle<JSFunction> microtask) {
|
| + Handle<FixedArray> queue(heap()->microtask_queue(), this);
|
| + int num_tasks = pending_microtask_count();
|
| + ASSERT(num_tasks <= queue->length());
|
| + if (num_tasks == 0) {
|
| + queue = factory()->NewFixedArray(8);
|
| + heap()->set_microtask_queue(*queue);
|
| + } else if (num_tasks == queue->length()) {
|
| + queue = FixedArray::CopySize(queue, num_tasks * 2);
|
| + heap()->set_microtask_queue(*queue);
|
| + }
|
| + ASSERT(queue->get(num_tasks)->IsUndefined());
|
| + queue->set(num_tasks, *microtask);
|
| + set_pending_microtask_count(num_tasks + 1);
|
| +}
|
| +
|
|
|
| +void Isolate::RunMicrotasks() {
|
| ASSERT(handle_scope_implementer()->CallDepthIsZero());
|
|
|
| // Increase call depth to prevent recursive callbacks.
|
| handle_scope_implementer()->IncrementCallDepth();
|
| - Execution::RunMicrotasks(this);
|
| +
|
| + while (pending_microtask_count() > 0) {
|
| + HandleScope scope(this);
|
| + int num_tasks = pending_microtask_count();
|
| + Handle<FixedArray> queue(heap()->microtask_queue(), this);
|
| + ASSERT(num_tasks <= queue->length());
|
| + set_pending_microtask_count(0);
|
| + heap()->set_microtask_queue(heap()->empty_fixed_array());
|
| +
|
| + for (int i = 0; i < num_tasks; i++) {
|
| + HandleScope scope(this);
|
| + Handle<JSFunction> microtask(JSFunction::cast(queue->get(i)), this);
|
| + // TODO(adamk): This should ignore/clear exceptions instead of Checking.
|
| + Execution::Call(this, microtask, factory()->undefined_value(),
|
| + 0, NULL).Check();
|
| + }
|
| + }
|
| +
|
| handle_scope_implementer()->DecrementCallDepth();
|
| }
|
|
|
|
|