Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Unified Diff: src/isolate.cc

Issue 2406343002: [promises] Move PromiseReactionJob to c++ (Closed)
Patch Set: fix build Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/isolate.h ('k') | src/js/promise.js » ('j') | src/objects.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index 20ff7ff899e317ae3f62f84099117d0165e16677..82beb7cefbab3fb114df62801b9a671bc7127128 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -24,6 +24,7 @@
#include "src/crankshaft/hydrogen.h"
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
+#include "src/elements.h"
#include "src/external-reference-table.h"
#include "src/frames-inl.h"
#include "src/ic/access-compiler-data.h"
@@ -3008,15 +3009,82 @@ void Isolate::ReportPromiseReject(Handle<JSObject> promise,
v8::Utils::StackTraceToLocal(stack_trace)));
}
+namespace {
+class PromiseDebugEventHelper {
adamk 2016/10/12 16:18:11 We often name these things scopes, so how about Pr
gsathya 2016/10/12 20:08:53 Done.
+ public:
+ PromiseDebugEventHelper(Isolate* isolate, Handle<Object> before,
adamk 2016/10/12 16:18:11 You could reduce the lines-of-code (or at least en
gsathya 2016/10/12 20:08:53 Done.
+ Handle<Object> after)
+ : isolate_(isolate), before_(before), after_(after) {
+ if (isolate_->debug()->is_active() && before_->IsJSObject()) {
+ isolate_->debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(before_));
+ }
+ }
+
+ ~PromiseDebugEventHelper() {
+ if (isolate_->debug()->is_active() && after_->IsJSObject()) {
+ isolate_->debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(after_));
+ }
+ }
+
+ private:
+ Isolate* isolate_;
+ Handle<Object> before_;
+ Handle<Object> after_;
+};
+} // namespace
+
+void Isolate::PromiseReactionJob(
+ Handle<PromiseReactionJobInfo> promise_reaction_job_info,
+ MaybeHandle<Object>* result, MaybeHandle<Object>* maybe_exception) {
+ Handle<Object> before(promise_reaction_job_info->before_debug_event(), this);
+ Handle<Object> after(promise_reaction_job_info->after_debug_event(), this);
+ PromiseDebugEventHelper helper(this, before, after);
+
+ Handle<Object> value(promise_reaction_job_info->value(), this);
+ Handle<Object> tasks(promise_reaction_job_info->tasks(), this);
+ Handle<JSFunction> promise_handle_fn = promise_handle();
+ Handle<Object> undefined = factory()->undefined_value();
+
+ // If tasks is an array we have multiple onFulfilled/onRejected callbacks
+ // associated with the promise. The deferred object for each callback
+ // is attached to this array as well.
+ // Otherwise, there is a single callback and the deferred object is attached
+ // directly to PromiseReactionJobInfo.
+ if (tasks->IsJSArray()) {
+ Handle<JSArray> array = Handle<JSArray>::cast(tasks);
+ DCHECK(array->length()->IsSmi());
+ int length = Smi::cast(array->length())->value();
+ ElementsAccessor* accessor = array->GetElementsAccessor();
+ DCHECK(length % 2 == 0);
+ for (int i = 0; i < length; i += 2) {
+ DCHECK(accessor->HasElement(array, i));
+ DCHECK(accessor->HasElement(array, i + 1));
+ Handle<Object> argv[] = {value, accessor->Get(array, i),
+ accessor->Get(array, i + 1)};
+ *result = Execution::TryCall(this, promise_handle_fn, undefined,
+ arraysize(argv), argv, maybe_exception);
+ if (result->is_null() && maybe_exception->is_null()) {
adamk 2016/10/12 16:18:11 Copy and paste a comment with this, too: // If ex
gsathya 2016/10/12 20:08:53 Done.
+ return;
+ }
+ }
+ } else {
+ Handle<Object> deferred(promise_reaction_job_info->deferred(), this);
+ Handle<Object> argv[] = {value, tasks, deferred};
+ *result =
+ Execution::TryCall(this, promise_handle(), factory()->undefined_value(),
adamk 2016/10/12 16:18:11 You can pass promise_handle_fn and undefined here
gsathya 2016/10/12 20:08:53 Done.
+ arraysize(argv), argv, maybe_exception);
+ if (result->is_null() && maybe_exception->is_null()) {
adamk 2016/10/12 16:18:11 No need to do anything special in this case, right
gsathya 2016/10/12 20:08:53 Done.
+ return;
+ }
+ }
+}
+
void Isolate::PromiseResolveThenableJob(Handle<PromiseContainer> container,
MaybeHandle<Object>* result,
MaybeHandle<Object>* maybe_exception) {
- if (debug()->is_active()) {
- Handle<Object> before_debug_event(container->before_debug_event(), this);
- if (before_debug_event->IsJSObject()) {
- debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(before_debug_event));
- }
- }
+ Handle<Object> before(container->before_debug_event(), this);
+ Handle<Object> after(container->after_debug_event(), this);
+ PromiseDebugEventHelper helper(this, before, after);
Handle<JSReceiver> thenable(container->thenable(), this);
Handle<JSFunction> resolve(container->resolve(), this);
@@ -3034,18 +3102,12 @@ void Isolate::PromiseResolveThenableJob(Handle<PromiseContainer> container,
Execution::TryCall(this, reject, factory()->undefined_value(),
arraysize(reason_arg), reason_arg, maybe_exception);
}
-
- if (debug()->is_active()) {
- Handle<Object> after_debug_event(container->after_debug_event(), this);
- if (after_debug_event->IsJSObject()) {
- debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(after_debug_event));
- }
- }
}
void Isolate::EnqueueMicrotask(Handle<Object> microtask) {
DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo() ||
- microtask->IsPromiseContainer());
+ microtask->IsPromiseContainer() ||
+ microtask->IsPromiseReactionJobInfo());
Handle<FixedArray> queue(heap()->microtask_queue(), this);
int num_tasks = pending_microtask_count();
DCHECK(num_tasks <= queue->length());
@@ -3097,11 +3159,16 @@ void Isolate::RunMicrotasksInternal() {
callback(data);
} else {
SaveContext save(this);
- Context* context = microtask->IsJSFunction()
- ? Handle<JSFunction>::cast(microtask)->context()
- : Handle<PromiseContainer>::cast(microtask)
- ->resolve()
- ->context();
+ Context* context;
+ if (microtask->IsJSFunction()) {
+ context = Handle<JSFunction>::cast(microtask)->context();
+ } else if (microtask->IsPromiseContainer()) {
+ context =
+ Handle<PromiseContainer>::cast(microtask)->resolve()->context();
+ } else {
+ context = Handle<PromiseReactionJobInfo>::cast(microtask)->context();
+ }
+
set_context(context->native_context());
handle_scope_implementer_->EnterMicrotaskContext(
Handle<Context>(context, this));
@@ -3115,9 +3182,12 @@ void Isolate::RunMicrotasksInternal() {
result = Execution::TryCall(this, microtask_function,
factory()->undefined_value(), 0, NULL,
&maybe_exception);
- } else {
+ } else if (microtask->IsPromiseContainer()) {
PromiseResolveThenableJob(Handle<PromiseContainer>::cast(microtask),
&result, &maybe_exception);
+ } else {
+ PromiseReactionJob(Handle<PromiseReactionJobInfo>::cast(microtask),
+ &result, &maybe_exception);
}
handle_scope_implementer_->LeaveMicrotaskContext();
« no previous file with comments | « src/isolate.h ('k') | src/js/promise.js » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698