summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/builtins-async-gen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/builtins-async-gen.cc')
-rw-r--r--deps/v8/src/builtins/builtins-async-gen.cc122
1 files changed, 118 insertions, 4 deletions
diff --git a/deps/v8/src/builtins/builtins-async-gen.cc b/deps/v8/src/builtins/builtins-async-gen.cc
index ba0226d7b3..c7e3c5cdeb 100644
--- a/deps/v8/src/builtins/builtins-async-gen.cc
+++ b/deps/v8/src/builtins/builtins-async-gen.cc
@@ -6,6 +6,7 @@
#include "src/builtins/builtins-utils-gen.h"
#include "src/heap/factory-inl.h"
+#include "src/objects/js-promise.h"
#include "src/objects/shared-function-info.h"
namespace v8 {
@@ -97,10 +98,9 @@ Node* AsyncBuiltinsAssembler::Await(
{
// Add PromiseHooks if needed
Label next(this);
- GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &next);
- CallRuntime(Runtime::kPromiseHookInit, context, wrapped_value,
- outer_promise);
- CallRuntime(Runtime::kPromiseHookInit, context, throwaway, wrapped_value);
+ GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &next);
+ CallRuntime(Runtime::kAwaitPromisesInit, context, wrapped_value,
+ outer_promise, throwaway);
Goto(&next);
BIND(&next);
}
@@ -147,6 +147,120 @@ Node* AsyncBuiltinsAssembler::Await(
on_resolve, on_reject, throwaway);
}
+Node* AsyncBuiltinsAssembler::AwaitOptimized(
+ Node* context, Node* generator, Node* value, Node* outer_promise,
+ int context_length, const ContextInitializer& init_closure_context,
+ Node* on_resolve_context_index, Node* on_reject_context_index,
+ Node* is_predicted_as_caught) {
+ DCHECK_GE(context_length, Context::MIN_CONTEXT_SLOTS);
+
+ Node* const native_context = LoadNativeContext(context);
+ Node* const promise_fun =
+ LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
+ CSA_ASSERT(this, IsFunctionWithPrototypeSlotMap(LoadMap(promise_fun)));
+ CSA_ASSERT(this, IsConstructor(promise_fun));
+
+ static const int kThrowawayPromiseOffset =
+ FixedArray::SizeFor(context_length);
+ static const int kResolveClosureOffset =
+ kThrowawayPromiseOffset + JSPromise::kSizeWithEmbedderFields;
+ static const int kRejectClosureOffset =
+ kResolveClosureOffset + JSFunction::kSizeWithoutPrototype;
+ static const int kTotalSize =
+ kRejectClosureOffset + JSFunction::kSizeWithoutPrototype;
+
+ // 2. Let promise be ? PromiseResolve(« promise »).
+ Node* const promise =
+ CallBuiltin(Builtins::kPromiseResolve, context, promise_fun, value);
+
+ Node* const base = AllocateInNewSpace(kTotalSize);
+ Node* const closure_context = base;
+ {
+ // Initialize closure context
+ InitializeFunctionContext(native_context, closure_context, context_length);
+ init_closure_context(closure_context);
+ }
+
+ Node* const promise_map =
+ LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
+ // Assert that the JSPromise map has an instance size is
+ // JSPromise::kSizeWithEmbedderFields.
+ CSA_ASSERT(this, WordEqual(LoadMapInstanceSizeInWords(promise_map),
+ IntPtrConstant(JSPromise::kSizeWithEmbedderFields /
+ kPointerSize)));
+ Node* const throwaway = InnerAllocate(base, kThrowawayPromiseOffset);
+ {
+ // Initialize throwawayPromise
+ StoreMapNoWriteBarrier(throwaway, promise_map);
+ InitializeJSObjectFromMap(
+ throwaway, promise_map,
+ IntPtrConstant(JSPromise::kSizeWithEmbedderFields));
+ PromiseInit(throwaway);
+ }
+
+ Node* const on_resolve = InnerAllocate(base, kResolveClosureOffset);
+ {
+ // Initialize resolve handler
+ InitializeNativeClosure(closure_context, native_context, on_resolve,
+ on_resolve_context_index);
+ }
+
+ Node* const on_reject = InnerAllocate(base, kRejectClosureOffset);
+ {
+ // Initialize reject handler
+ InitializeNativeClosure(closure_context, native_context, on_reject,
+ on_reject_context_index);
+ }
+
+ {
+ // Add PromiseHooks if needed
+ Label next(this);
+ GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &next);
+ CallRuntime(Runtime::kAwaitPromisesInit, context, promise, outer_promise,
+ throwaway);
+ Goto(&next);
+ BIND(&next);
+ }
+
+ // The Promise will be thrown away and not handled, but it shouldn't trigger
+ // unhandled reject events as its work is done
+ PromiseSetHasHandler(throwaway);
+
+ Label do_perform_promise_then(this);
+ GotoIfNot(IsDebugActive(), &do_perform_promise_then);
+ {
+ Label common(this);
+ GotoIf(TaggedIsSmi(value), &common);
+ GotoIfNot(HasInstanceType(value, JS_PROMISE_TYPE), &common);
+ {
+ // Mark the reject handler callback to be a forwarding edge, rather
+ // than a meaningful catch handler
+ Node* const key =
+ HeapConstant(factory()->promise_forwarding_handler_symbol());
+ CallRuntime(Runtime::kSetProperty, context, on_reject, key,
+ TrueConstant(), SmiConstant(LanguageMode::kStrict));
+
+ GotoIf(IsFalse(is_predicted_as_caught), &common);
+ PromiseSetHandledHint(value);
+ }
+
+ Goto(&common);
+ BIND(&common);
+ // Mark the dependency to outer Promise in case the throwaway Promise is
+ // found on the Promise stack
+ CSA_SLOW_ASSERT(this, HasInstanceType(outer_promise, JS_PROMISE_TYPE));
+
+ Node* const key = HeapConstant(factory()->promise_handled_by_symbol());
+ CallRuntime(Runtime::kSetProperty, context, throwaway, key, outer_promise,
+ SmiConstant(LanguageMode::kStrict));
+ }
+
+ Goto(&do_perform_promise_then);
+ BIND(&do_perform_promise_then);
+ return CallBuiltin(Builtins::kPerformPromiseThen, native_context, promise,
+ on_resolve, on_reject, throwaway);
+}
+
void AsyncBuiltinsAssembler::InitializeNativeClosure(Node* context,
Node* native_context,
Node* function,