2331 lines
112 KiB
Diff
2331 lines
112 KiB
Diff
|
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
|
||
|
index 43c7527de98..2138b9c73d7 100644
|
||
|
--- a/src/bootstrapper.cc
|
||
|
+++ b/src/bootstrapper.cc
|
||
|
@@ -1584,6 +1584,50 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||
|
native_context()->set_async_iterator_value_unwrap_shared_fun(*info);
|
||
|
}
|
||
|
|
||
|
+ { // --- A s y n c G e n e r a t o r ---
|
||
|
+ Handle<JSFunction> await_caught =
|
||
|
+ SimpleCreateFunction(isolate, factory->empty_string(),
|
||
|
+ Builtins::kAsyncGeneratorAwaitCaught, 1, false);
|
||
|
+ native_context()->set_async_generator_await_caught(*await_caught);
|
||
|
+
|
||
|
+ Handle<JSFunction> await_uncaught =
|
||
|
+ SimpleCreateFunction(isolate, factory->empty_string(),
|
||
|
+ Builtins::kAsyncGeneratorAwaitUncaught, 1, false);
|
||
|
+ native_context()->set_async_generator_await_uncaught(*await_uncaught);
|
||
|
+
|
||
|
+ Handle<SharedFunctionInfo> info = SimpleCreateSharedFunctionInfo(
|
||
|
+ isolate, Builtins::kAsyncGeneratorAwaitResolveClosure,
|
||
|
+ factory->empty_string(), 1);
|
||
|
+ native_context()->set_async_generator_await_resolve_shared_fun(*info);
|
||
|
+
|
||
|
+ info = SimpleCreateSharedFunctionInfo(
|
||
|
+ isolate, Builtins::kAsyncGeneratorAwaitRejectClosure,
|
||
|
+ factory->empty_string(), 1);
|
||
|
+ native_context()->set_async_generator_await_reject_shared_fun(*info);
|
||
|
+
|
||
|
+ info = SimpleCreateSharedFunctionInfo(
|
||
|
+ isolate, Builtins::kAsyncGeneratorYieldResolveClosure,
|
||
|
+ factory->empty_string(), 1);
|
||
|
+ native_context()->set_async_generator_yield_resolve_shared_fun(*info);
|
||
|
+
|
||
|
+ info = SimpleCreateSharedFunctionInfo(
|
||
|
+ isolate, Builtins::kAsyncGeneratorReturnResolveClosure,
|
||
|
+ factory->empty_string(), 1);
|
||
|
+ native_context()->set_async_generator_return_resolve_shared_fun(*info);
|
||
|
+
|
||
|
+ info = SimpleCreateSharedFunctionInfo(
|
||
|
+ isolate, Builtins::kAsyncGeneratorReturnClosedResolveClosure,
|
||
|
+ factory->empty_string(), 1);
|
||
|
+ native_context()->set_async_generator_return_closed_resolve_shared_fun(
|
||
|
+ *info);
|
||
|
+
|
||
|
+ info = SimpleCreateSharedFunctionInfo(
|
||
|
+ isolate, Builtins::kAsyncGeneratorReturnClosedRejectClosure,
|
||
|
+ factory->empty_string(), 1);
|
||
|
+ native_context()->set_async_generator_return_closed_reject_shared_fun(
|
||
|
+ *info);
|
||
|
+ }
|
||
|
+
|
||
|
{ // --- A r r a y ---
|
||
|
Handle<JSFunction> array_function = InstallFunction(
|
||
|
global, "Array", JS_ARRAY_TYPE, JSArray::kSize, 0,
|
||
|
@@ -3998,6 +4042,34 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
|
||
|
JSFunction::SetPrototype(async_function_constructor,
|
||
|
async_function_prototype);
|
||
|
|
||
|
+ {
|
||
|
+ Handle<JSFunction> function =
|
||
|
+ SimpleCreateFunction(isolate, factory->empty_string(),
|
||
|
+ Builtins::kAsyncFunctionAwaitCaught, 2, false);
|
||
|
+ native_context->set_async_function_await_caught(*function);
|
||
|
+ }
|
||
|
+
|
||
|
+ {
|
||
|
+ Handle<JSFunction> function =
|
||
|
+ SimpleCreateFunction(isolate, factory->empty_string(),
|
||
|
+ Builtins::kAsyncFunctionAwaitUncaught, 2, false);
|
||
|
+ native_context->set_async_function_await_uncaught(*function);
|
||
|
+ }
|
||
|
+
|
||
|
+ {
|
||
|
+ Handle<SharedFunctionInfo> info = SimpleCreateSharedFunctionInfo(
|
||
|
+ isolate, Builtins::kAsyncFunctionAwaitRejectClosure,
|
||
|
+ factory->empty_string(), 1);
|
||
|
+ native_context->set_async_function_await_reject_shared_fun(*info);
|
||
|
+ }
|
||
|
+
|
||
|
+ {
|
||
|
+ Handle<SharedFunctionInfo> info = SimpleCreateSharedFunctionInfo(
|
||
|
+ isolate, Builtins::kAsyncFunctionAwaitResolveClosure,
|
||
|
+ factory->empty_string(), 1);
|
||
|
+ native_context->set_async_function_await_resolve_shared_fun(*info);
|
||
|
+ }
|
||
|
+
|
||
|
{
|
||
|
Handle<JSFunction> function =
|
||
|
SimpleCreateFunction(isolate, factory->empty_string(),
|
||
|
diff --git a/src/builtins/builtins-async-function-gen.cc b/src/builtins/builtins-async-function-gen.cc
|
||
|
index 0db53c687e6..0d0e34ee0da 100644
|
||
|
--- a/src/builtins/builtins-async-function-gen.cc
|
||
|
+++ b/src/builtins/builtins-async-function-gen.cc
|
||
|
@@ -21,18 +21,37 @@ class AsyncFunctionBuiltinsAssembler : public AsyncBuiltinsAssembler {
|
||
|
Node* const awaited, Node* const outer_promise,
|
||
|
const bool is_predicted_as_caught);
|
||
|
|
||
|
- void AsyncFunctionAwaitResume(Node* const context, Node* const argument,
|
||
|
- Node* const generator,
|
||
|
- JSGeneratorObject::ResumeMode resume_mode);
|
||
|
+ void AsyncFunctionAwaitResumeClosure(
|
||
|
+ Node* const context, Node* const sent_value,
|
||
|
+ JSGeneratorObject::ResumeMode resume_mode);
|
||
|
};
|
||
|
|
||
|
-void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwaitResume(
|
||
|
- Node* const context, Node* const argument, Node* const generator,
|
||
|
+namespace {
|
||
|
+
|
||
|
+// Describe fields of Context associated with AsyncFunctionAwait resume
|
||
|
+// closures.
|
||
|
+// TODO(jgruber): Refactor to reuse code for upcoming async-generators.
|
||
|
+class AwaitContext {
|
||
|
+ public:
|
||
|
+ enum Fields { kGeneratorSlot = Context::MIN_CONTEXT_SLOTS, kLength };
|
||
|
+};
|
||
|
+
|
||
|
+} // anonymous namespace
|
||
|
+
|
||
|
+void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwaitResumeClosure(
|
||
|
+ Node* context, Node* sent_value,
|
||
|
JSGeneratorObject::ResumeMode resume_mode) {
|
||
|
- CSA_ASSERT(this, IsJSGeneratorObject(generator));
|
||
|
DCHECK(resume_mode == JSGeneratorObject::kNext ||
|
||
|
resume_mode == JSGeneratorObject::kThrow);
|
||
|
|
||
|
+ Node* const generator =
|
||
|
+ LoadContextElement(context, AwaitContext::kGeneratorSlot);
|
||
|
+ CSA_SLOW_ASSERT(this, HasInstanceType(generator, JS_GENERATOR_OBJECT_TYPE));
|
||
|
+
|
||
|
+ // Inline version of GeneratorPrototypeNext / GeneratorPrototypeReturn with
|
||
|
+ // unnecessary runtime checks removed.
|
||
|
+ // TODO(jgruber): Refactor to reuse code from builtins-generator.cc.
|
||
|
+
|
||
|
// Ensure that the generator is neither closed nor running.
|
||
|
CSA_SLOW_ASSERT(
|
||
|
this,
|
||
|
@@ -47,23 +66,31 @@ void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwaitResume(
|
||
|
|
||
|
// Resume the {receiver} using our trampoline.
|
||
|
Callable callable = CodeFactory::ResumeGenerator(isolate());
|
||
|
- TailCallStub(callable, context, argument, generator);
|
||
|
+ CallStub(callable, context, sent_value, generator);
|
||
|
+
|
||
|
+ // The resulting Promise is a throwaway, so it doesn't matter what it
|
||
|
+ // resolves to. What is important is that we don't end up keeping the
|
||
|
+ // whole chain of intermediate Promises alive by returning the return value
|
||
|
+ // of ResumeGenerator, as that would create a memory leak.
|
||
|
}
|
||
|
|
||
|
-TF_BUILTIN(AsyncFunctionAwaitFulfill, AsyncFunctionBuiltinsAssembler) {
|
||
|
- Node* const argument = Parameter(Descriptor::kArgument);
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
+TF_BUILTIN(AsyncFunctionAwaitRejectClosure, AsyncFunctionBuiltinsAssembler) {
|
||
|
+ CSA_ASSERT_JS_ARGC_EQ(this, 1);
|
||
|
+ Node* const sentError = Parameter(Descriptor::kSentError);
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
- AsyncFunctionAwaitResume(context, argument, generator,
|
||
|
- JSGeneratorObject::kNext);
|
||
|
+
|
||
|
+ AsyncFunctionAwaitResumeClosure(context, sentError,
|
||
|
+ JSGeneratorObject::kThrow);
|
||
|
+ Return(UndefinedConstant());
|
||
|
}
|
||
|
|
||
|
-TF_BUILTIN(AsyncFunctionAwaitReject, AsyncFunctionBuiltinsAssembler) {
|
||
|
- Node* const argument = Parameter(Descriptor::kArgument);
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
+TF_BUILTIN(AsyncFunctionAwaitResolveClosure, AsyncFunctionBuiltinsAssembler) {
|
||
|
+ CSA_ASSERT_JS_ARGC_EQ(this, 1);
|
||
|
+ Node* const sentValue = Parameter(Descriptor::kSentValue);
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
- AsyncFunctionAwaitResume(context, argument, generator,
|
||
|
- JSGeneratorObject::kThrow);
|
||
|
+
|
||
|
+ AsyncFunctionAwaitResumeClosure(context, sentValue, JSGeneratorObject::kNext);
|
||
|
+ Return(UndefinedConstant());
|
||
|
}
|
||
|
|
||
|
// ES#abstract-ops-async-function-await
|
||
|
@@ -78,12 +105,25 @@ TF_BUILTIN(AsyncFunctionAwaitReject, AsyncFunctionBuiltinsAssembler) {
|
||
|
void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait(
|
||
|
Node* const context, Node* const generator, Node* const awaited,
|
||
|
Node* const outer_promise, const bool is_predicted_as_caught) {
|
||
|
- CSA_SLOW_ASSERT(this, IsJSGeneratorObject(generator));
|
||
|
- CSA_SLOW_ASSERT(this, IsJSPromise(outer_promise));
|
||
|
-
|
||
|
- Await(context, generator, awaited, outer_promise,
|
||
|
- Builtins::kAsyncFunctionAwaitFulfill,
|
||
|
- Builtins::kAsyncFunctionAwaitReject, is_predicted_as_caught);
|
||
|
+ CSA_SLOW_ASSERT(this, HasInstanceType(generator, JS_GENERATOR_OBJECT_TYPE));
|
||
|
+ CSA_SLOW_ASSERT(this, HasInstanceType(outer_promise, JS_PROMISE_TYPE));
|
||
|
+
|
||
|
+ ContextInitializer init_closure_context = [&](Node* context) {
|
||
|
+ StoreContextElementNoWriteBarrier(context, AwaitContext::kGeneratorSlot,
|
||
|
+ generator);
|
||
|
+ };
|
||
|
+
|
||
|
+ // TODO(jgruber): AsyncBuiltinsAssembler::Await currently does not reuse
|
||
|
+ // the awaited promise if it is already a promise. Reuse is non-spec compliant
|
||
|
+ // but part of our old behavior gives us a couple of percent
|
||
|
+ // performance boost.
|
||
|
+ // TODO(jgruber): Use a faster specialized version of
|
||
|
+ // InternalPerformPromiseThen.
|
||
|
+
|
||
|
+ Await(context, generator, awaited, outer_promise, AwaitContext::kLength,
|
||
|
+ init_closure_context, Context::ASYNC_FUNCTION_AWAIT_RESOLVE_SHARED_FUN,
|
||
|
+ Context::ASYNC_FUNCTION_AWAIT_REJECT_SHARED_FUN,
|
||
|
+ is_predicted_as_caught);
|
||
|
|
||
|
// Return outer promise to avoid adding an load of the outer promise before
|
||
|
// suspending in BytecodeGenerator.
|
||
|
@@ -93,28 +133,30 @@ void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait(
|
||
|
// Called by the parser from the desugaring of 'await' when catch
|
||
|
// prediction indicates that there is a locally surrounding catch block.
|
||
|
TF_BUILTIN(AsyncFunctionAwaitCaught, AsyncFunctionBuiltinsAssembler) {
|
||
|
+ CSA_ASSERT_JS_ARGC_EQ(this, 3);
|
||
|
Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const value = Parameter(Descriptor::kValue);
|
||
|
+ Node* const awaited = Parameter(Descriptor::kAwaited);
|
||
|
Node* const outer_promise = Parameter(Descriptor::kOuterPromise);
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
|
||
|
static const bool kIsPredictedAsCaught = true;
|
||
|
|
||
|
- AsyncFunctionAwait(context, generator, value, outer_promise,
|
||
|
+ AsyncFunctionAwait(context, generator, awaited, outer_promise,
|
||
|
kIsPredictedAsCaught);
|
||
|
}
|
||
|
|
||
|
// Called by the parser from the desugaring of 'await' when catch
|
||
|
// prediction indicates no locally surrounding catch block.
|
||
|
TF_BUILTIN(AsyncFunctionAwaitUncaught, AsyncFunctionBuiltinsAssembler) {
|
||
|
+ CSA_ASSERT_JS_ARGC_EQ(this, 3);
|
||
|
Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const value = Parameter(Descriptor::kValue);
|
||
|
+ Node* const awaited = Parameter(Descriptor::kAwaited);
|
||
|
Node* const outer_promise = Parameter(Descriptor::kOuterPromise);
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
|
||
|
static const bool kIsPredictedAsCaught = false;
|
||
|
|
||
|
- AsyncFunctionAwait(context, generator, value, outer_promise,
|
||
|
+ AsyncFunctionAwait(context, generator, awaited, outer_promise,
|
||
|
kIsPredictedAsCaught);
|
||
|
}
|
||
|
|
||
|
diff --git a/src/builtins/builtins-async-gen.cc b/src/builtins/builtins-async-gen.cc
|
||
|
index 073c96a2e09..ba0226d7b3a 100644
|
||
|
--- a/src/builtins/builtins-async-gen.cc
|
||
|
+++ b/src/builtins/builtins-async-gen.cc
|
||
|
@@ -13,58 +13,6 @@ namespace internal {
|
||
|
|
||
|
using compiler::Node;
|
||
|
|
||
|
-void AsyncBuiltinsAssembler::Await(Node* context, Node* generator, Node* value,
|
||
|
- Node* outer_promise,
|
||
|
- Builtins::Name fulfill_builtin,
|
||
|
- Builtins::Name reject_builtin,
|
||
|
- Node* is_predicted_as_caught) {
|
||
|
- CSA_SLOW_ASSERT(this, Word32Or(IsJSAsyncGeneratorObject(generator),
|
||
|
- IsJSGeneratorObject(generator)));
|
||
|
- CSA_SLOW_ASSERT(this, IsJSPromise(outer_promise));
|
||
|
- CSA_SLOW_ASSERT(this, IsBoolean(is_predicted_as_caught));
|
||
|
-
|
||
|
- Node* const native_context = LoadNativeContext(context);
|
||
|
-
|
||
|
- // TODO(bmeurer): This could be optimized and folded into a single allocation.
|
||
|
- Node* const promise = AllocateAndInitJSPromise(native_context);
|
||
|
- Node* const promise_reactions =
|
||
|
- LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
|
||
|
- Node* const fulfill_handler =
|
||
|
- HeapConstant(Builtins::CallableFor(isolate(), fulfill_builtin).code());
|
||
|
- Node* const reject_handler =
|
||
|
- HeapConstant(Builtins::CallableFor(isolate(), reject_builtin).code());
|
||
|
- Node* const reaction = AllocatePromiseReaction(
|
||
|
- promise_reactions, generator, fulfill_handler, reject_handler);
|
||
|
- StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, reaction);
|
||
|
- PromiseSetHasHandler(promise);
|
||
|
-
|
||
|
- // Perform ! Call(promiseCapability.[[Resolve]], undefined, « value »).
|
||
|
- CallBuiltin(Builtins::kResolvePromise, native_context, promise, value);
|
||
|
-
|
||
|
- // When debugging, we need to link from the {generator} to the
|
||
|
- // {outer_promise} of the async function/generator.
|
||
|
- Label done(this);
|
||
|
- GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &done);
|
||
|
- CallRuntime(Runtime::kSetProperty, native_context, generator,
|
||
|
- LoadRoot(Heap::kgenerator_outer_promise_symbolRootIndex),
|
||
|
- outer_promise, SmiConstant(LanguageMode::kStrict));
|
||
|
- GotoIf(IsFalse(is_predicted_as_caught), &done);
|
||
|
- GotoIf(TaggedIsSmi(value), &done);
|
||
|
- GotoIfNot(IsJSPromise(value), &done);
|
||
|
- PromiseSetHandledHint(value);
|
||
|
- Goto(&done);
|
||
|
- BIND(&done);
|
||
|
-}
|
||
|
-
|
||
|
-void AsyncBuiltinsAssembler::Await(Node* context, Node* generator, Node* value,
|
||
|
- Node* outer_promise,
|
||
|
- Builtins::Name fulfill_builtin,
|
||
|
- Builtins::Name reject_builtin,
|
||
|
- bool is_predicted_as_caught) {
|
||
|
- return Await(context, generator, value, outer_promise, fulfill_builtin,
|
||
|
- reject_builtin, BooleanConstant(is_predicted_as_caught));
|
||
|
-}
|
||
|
-
|
||
|
namespace {
|
||
|
// Describe fields of Context associated with the AsyncIterator unwrap closure.
|
||
|
class ValueUnwrapContext {
|
||
|
@@ -74,6 +22,161 @@ class ValueUnwrapContext {
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
+Node* AsyncBuiltinsAssembler::Await(
|
||
|
+ 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);
|
||
|
+
|
||
|
+ static const int kWrappedPromiseOffset = FixedArray::SizeFor(context_length);
|
||
|
+ static const int kThrowawayPromiseOffset =
|
||
|
+ kWrappedPromiseOffset + JSPromise::kSizeWithEmbedderFields;
|
||
|
+ static const int kResolveClosureOffset =
|
||
|
+ kThrowawayPromiseOffset + JSPromise::kSizeWithEmbedderFields;
|
||
|
+ static const int kRejectClosureOffset =
|
||
|
+ kResolveClosureOffset + JSFunction::kSizeWithoutPrototype;
|
||
|
+ static const int kTotalSize =
|
||
|
+ kRejectClosureOffset + JSFunction::kSizeWithoutPrototype;
|
||
|
+
|
||
|
+ 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);
|
||
|
+ }
|
||
|
+
|
||
|
+ // Let promiseCapability be ! NewPromiseCapability(%Promise%).
|
||
|
+ Node* const promise_fun =
|
||
|
+ LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
|
||
|
+ CSA_ASSERT(this, IsFunctionWithPrototypeSlotMap(LoadMap(promise_fun)));
|
||
|
+ 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 wrapped_value = InnerAllocate(base, kWrappedPromiseOffset);
|
||
|
+ {
|
||
|
+ // Initialize Promise
|
||
|
+ StoreMapNoWriteBarrier(wrapped_value, promise_map);
|
||
|
+ InitializeJSObjectFromMap(
|
||
|
+ wrapped_value, promise_map,
|
||
|
+ IntPtrConstant(JSPromise::kSizeWithEmbedderFields));
|
||
|
+ PromiseInit(wrapped_value);
|
||
|
+ }
|
||
|
+
|
||
|
+ 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(IsPromiseHookEnabledOrDebugIsActive(), &next);
|
||
|
+ CallRuntime(Runtime::kPromiseHookInit, context, wrapped_value,
|
||
|
+ outer_promise);
|
||
|
+ CallRuntime(Runtime::kPromiseHookInit, context, throwaway, wrapped_value);
|
||
|
+ Goto(&next);
|
||
|
+ BIND(&next);
|
||
|
+ }
|
||
|
+
|
||
|
+ // Perform ! Call(promiseCapability.[[Resolve]], undefined, « promise »).
|
||
|
+ CallBuiltin(Builtins::kResolvePromise, context, wrapped_value, value);
|
||
|
+
|
||
|
+ // 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, context, wrapped_value,
|
||
|
+ on_resolve, on_reject, throwaway);
|
||
|
+}
|
||
|
+
|
||
|
+void AsyncBuiltinsAssembler::InitializeNativeClosure(Node* context,
|
||
|
+ Node* native_context,
|
||
|
+ Node* function,
|
||
|
+ Node* context_index) {
|
||
|
+ Node* const function_map = LoadContextElement(
|
||
|
+ native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
|
||
|
+ // Ensure that we don't have to initialize prototype_or_initial_map field of
|
||
|
+ // JSFunction.
|
||
|
+ CSA_ASSERT(this, WordEqual(LoadMapInstanceSizeInWords(function_map),
|
||
|
+ IntPtrConstant(JSFunction::kSizeWithoutPrototype /
|
||
|
+ kPointerSize)));
|
||
|
+ STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
|
||
|
+ StoreMapNoWriteBarrier(function, function_map);
|
||
|
+ StoreObjectFieldRoot(function, JSObject::kPropertiesOrHashOffset,
|
||
|
+ Heap::kEmptyFixedArrayRootIndex);
|
||
|
+ StoreObjectFieldRoot(function, JSObject::kElementsOffset,
|
||
|
+ Heap::kEmptyFixedArrayRootIndex);
|
||
|
+ StoreObjectFieldRoot(function, JSFunction::kFeedbackCellOffset,
|
||
|
+ Heap::kManyClosuresCellRootIndex);
|
||
|
+
|
||
|
+ Node* shared_info = LoadContextElement(native_context, context_index);
|
||
|
+ CSA_ASSERT(this, IsSharedFunctionInfo(shared_info));
|
||
|
+ StoreObjectFieldNoWriteBarrier(
|
||
|
+ function, JSFunction::kSharedFunctionInfoOffset, shared_info);
|
||
|
+ StoreObjectFieldNoWriteBarrier(function, JSFunction::kContextOffset, context);
|
||
|
+
|
||
|
+ Node* const code = GetSharedFunctionInfoCode(shared_info);
|
||
|
+ StoreObjectFieldNoWriteBarrier(function, JSFunction::kCodeOffset, code);
|
||
|
+}
|
||
|
+
|
||
|
Node* AsyncBuiltinsAssembler::CreateUnwrapClosure(Node* native_context,
|
||
|
Node* done) {
|
||
|
Node* const map = LoadContextElement(
|
||
|
diff --git a/src/builtins/builtins-async-gen.h b/src/builtins/builtins-async-gen.h
|
||
|
index 70f68a498b7..45d7c8689a9 100644
|
||
|
--- a/src/builtins/builtins-async-gen.h
|
||
|
+++ b/src/builtins/builtins-async-gen.h
|
||
|
@@ -16,23 +16,48 @@ class AsyncBuiltinsAssembler : public PromiseBuiltinsAssembler {
|
||
|
: PromiseBuiltinsAssembler(state) {}
|
||
|
|
||
|
protected:
|
||
|
- void Await(Node* context, Node* generator, Node* value, Node* outer_promise,
|
||
|
- Builtins::Name fulfill_builtin, Builtins::Name reject_builtin,
|
||
|
- Node* is_predicted_as_caught);
|
||
|
- void Await(Node* context, Node* generator, Node* value, Node* outer_promise,
|
||
|
- Builtins::Name fulfill_builtin, Builtins::Name reject_builtin,
|
||
|
- bool is_predicted_as_caught);
|
||
|
+ typedef std::function<void(Node*)> ContextInitializer;
|
||
|
+
|
||
|
+ // Perform steps to resume generator after `value` is resolved.
|
||
|
+ // `on_reject_context_index` is an index into the Native Context, which should
|
||
|
+ // point to a SharedFunctioninfo instance used to create the closure. The
|
||
|
+ // value following the reject index should be a similar value for the resolve
|
||
|
+ // closure. Returns the Promise-wrapped `value`.
|
||
|
+ Node* Await(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);
|
||
|
+ Node* Await(Node* context, Node* generator, Node* value, Node* outer_promise,
|
||
|
+ int context_length,
|
||
|
+ const ContextInitializer& init_closure_context,
|
||
|
+ int on_resolve_context_index, int on_reject_context_index,
|
||
|
+ Node* is_predicted_as_caught) {
|
||
|
+ return Await(context, generator, value, outer_promise, context_length,
|
||
|
+ init_closure_context, IntPtrConstant(on_resolve_context_index),
|
||
|
+ IntPtrConstant(on_reject_context_index),
|
||
|
+ is_predicted_as_caught);
|
||
|
+ }
|
||
|
+ Node* Await(Node* context, Node* generator, Node* value, Node* outer_promise,
|
||
|
+ int context_length,
|
||
|
+ const ContextInitializer& init_closure_context,
|
||
|
+ int on_resolve_context_index, int on_reject_context_index,
|
||
|
+ bool is_predicted_as_caught) {
|
||
|
+ return Await(context, generator, value, outer_promise, context_length,
|
||
|
+ init_closure_context, on_resolve_context_index,
|
||
|
+ on_reject_context_index,
|
||
|
+ BooleanConstant(is_predicted_as_caught));
|
||
|
+ }
|
||
|
|
||
|
// Return a new built-in function object as defined in
|
||
|
// Async Iterator Value Unwrap Functions
|
||
|
Node* CreateUnwrapClosure(Node* const native_context, Node* const done);
|
||
|
|
||
|
private:
|
||
|
+ void InitializeNativeClosure(Node* context, Node* native_context,
|
||
|
+ Node* function, Node* context_index);
|
||
|
Node* AllocateAsyncIteratorValueUnwrapContext(Node* native_context,
|
||
|
Node* done);
|
||
|
- Node* AllocateAwaitPromiseJobTask(Node* generator, Node* fulfill_handler,
|
||
|
- Node* reject_handler, Node* promise,
|
||
|
- Node* context);
|
||
|
};
|
||
|
|
||
|
} // namespace internal
|
||
|
diff --git a/src/builtins/builtins-async-generator-gen.cc b/src/builtins/builtins-async-generator-gen.cc
|
||
|
index 290252da624..dd6c6441964 100644
|
||
|
--- a/src/builtins/builtins-async-generator-gen.cc
|
||
|
+++ b/src/builtins/builtins-async-generator-gen.cc
|
||
|
@@ -140,8 +140,8 @@ class AsyncGeneratorBuiltinsAssembler : public AsyncBuiltinsAssembler {
|
||
|
// for AsyncGenerators.
|
||
|
template <typename Descriptor>
|
||
|
void AsyncGeneratorAwait(bool is_catchable);
|
||
|
- void AsyncGeneratorAwaitResume(
|
||
|
- Node* context, Node* generator, Node* argument,
|
||
|
+ void AsyncGeneratorAwaitResumeClosure(
|
||
|
+ Node* context, Node* value,
|
||
|
JSAsyncGeneratorObject::ResumeMode resume_mode);
|
||
|
};
|
||
|
|
||
|
@@ -219,9 +219,11 @@ Node* AsyncGeneratorBuiltinsAssembler::AllocateAsyncGeneratorRequest(
|
||
|
return request;
|
||
|
}
|
||
|
|
||
|
-void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResume(
|
||
|
- Node* context, Node* generator, Node* argument,
|
||
|
+void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResumeClosure(
|
||
|
+ Node* context, Node* value,
|
||
|
JSAsyncGeneratorObject::ResumeMode resume_mode) {
|
||
|
+ Node* const generator =
|
||
|
+ LoadContextElement(context, AwaitContext::kGeneratorSlot);
|
||
|
CSA_SLOW_ASSERT(this, TaggedIsAsyncGenerator(generator));
|
||
|
|
||
|
SetGeneratorNotAwaiting(generator);
|
||
|
@@ -233,30 +235,36 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResume(
|
||
|
JSGeneratorObject::kResumeModeOffset,
|
||
|
SmiConstant(resume_mode));
|
||
|
|
||
|
- CallStub(CodeFactory::ResumeGenerator(isolate()), context, argument,
|
||
|
- generator);
|
||
|
+ CallStub(CodeFactory::ResumeGenerator(isolate()), context, value, generator);
|
||
|
|
||
|
TailCallBuiltin(Builtins::kAsyncGeneratorResumeNext, context, generator);
|
||
|
}
|
||
|
|
||
|
template <typename Descriptor>
|
||
|
void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwait(bool is_catchable) {
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const value = Parameter(Descriptor::kValue);
|
||
|
- Node* const context = Parameter(Descriptor::kContext);
|
||
|
+ Node* generator = Parameter(Descriptor::kGenerator);
|
||
|
+ Node* value = Parameter(Descriptor::kAwaited);
|
||
|
+ Node* context = Parameter(Descriptor::kContext);
|
||
|
|
||
|
CSA_SLOW_ASSERT(this, TaggedIsAsyncGenerator(generator));
|
||
|
|
||
|
Node* const request = LoadFirstAsyncGeneratorRequestFromQueue(generator);
|
||
|
CSA_ASSERT(this, IsNotUndefined(request));
|
||
|
|
||
|
+ ContextInitializer init_closure_context = [&](Node* context) {
|
||
|
+ StoreContextElementNoWriteBarrier(context, AwaitContext::kGeneratorSlot,
|
||
|
+ generator);
|
||
|
+ };
|
||
|
+
|
||
|
Node* outer_promise =
|
||
|
LoadObjectField(request, AsyncGeneratorRequest::kPromiseOffset);
|
||
|
|
||
|
+ const int resolve_index = Context::ASYNC_GENERATOR_AWAIT_RESOLVE_SHARED_FUN;
|
||
|
+ const int reject_index = Context::ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN;
|
||
|
+
|
||
|
SetGeneratorAwaiting(generator);
|
||
|
- Await(context, generator, value, outer_promise,
|
||
|
- Builtins::kAsyncGeneratorAwaitFulfill,
|
||
|
- Builtins::kAsyncGeneratorAwaitReject, is_catchable);
|
||
|
+ Await(context, generator, value, outer_promise, AwaitContext::kLength,
|
||
|
+ init_closure_context, resolve_index, reject_index, is_catchable);
|
||
|
Return(UndefinedConstant());
|
||
|
}
|
||
|
|
||
|
@@ -367,20 +375,18 @@ TF_BUILTIN(AsyncGeneratorPrototypeThrow, AsyncGeneratorBuiltinsAssembler) {
|
||
|
"[AsyncGenerator].prototype.throw");
|
||
|
}
|
||
|
|
||
|
-TF_BUILTIN(AsyncGeneratorAwaitFulfill, AsyncGeneratorBuiltinsAssembler) {
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const argument = Parameter(Descriptor::kArgument);
|
||
|
- Node* const context = Parameter(Descriptor::kContext);
|
||
|
- AsyncGeneratorAwaitResume(context, generator, argument,
|
||
|
- JSAsyncGeneratorObject::kNext);
|
||
|
+TF_BUILTIN(AsyncGeneratorAwaitResolveClosure, AsyncGeneratorBuiltinsAssembler) {
|
||
|
+ Node* value = Parameter(Descriptor::kValue);
|
||
|
+ Node* context = Parameter(Descriptor::kContext);
|
||
|
+ AsyncGeneratorAwaitResumeClosure(context, value,
|
||
|
+ JSAsyncGeneratorObject::kNext);
|
||
|
}
|
||
|
|
||
|
-TF_BUILTIN(AsyncGeneratorAwaitReject, AsyncGeneratorBuiltinsAssembler) {
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const argument = Parameter(Descriptor::kArgument);
|
||
|
- Node* const context = Parameter(Descriptor::kContext);
|
||
|
- AsyncGeneratorAwaitResume(context, generator, argument,
|
||
|
- JSAsyncGeneratorObject::kThrow);
|
||
|
+TF_BUILTIN(AsyncGeneratorAwaitRejectClosure, AsyncGeneratorBuiltinsAssembler) {
|
||
|
+ Node* value = Parameter(Descriptor::kValue);
|
||
|
+ Node* context = Parameter(Descriptor::kContext);
|
||
|
+ AsyncGeneratorAwaitResumeClosure(context, value,
|
||
|
+ JSAsyncGeneratorObject::kThrow);
|
||
|
}
|
||
|
|
||
|
TF_BUILTIN(AsyncGeneratorAwaitUncaught, AsyncGeneratorBuiltinsAssembler) {
|
||
|
@@ -518,34 +524,11 @@ TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) {
|
||
|
done);
|
||
|
}
|
||
|
|
||
|
- // We know that {iter_result} itself doesn't have any "then" property and
|
||
|
- // we also know that the [[Prototype]] of {iter_result} is the intrinsic
|
||
|
- // %ObjectPrototype%. So we can skip the [[Resolve]] logic here completely
|
||
|
- // and directly call into the FulfillPromise operation if we can prove
|
||
|
- // that the %ObjectPrototype% also doesn't have any "then" property. This
|
||
|
- // is guarded by the Promise#then protector.
|
||
|
- Label if_fast(this), if_slow(this, Label::kDeferred), return_promise(this);
|
||
|
- GotoIfForceSlowPath(&if_slow);
|
||
|
- Branch(IsPromiseThenProtectorCellInvalid(), &if_slow, &if_fast);
|
||
|
-
|
||
|
- BIND(&if_fast);
|
||
|
- {
|
||
|
- // Skip the "then" on {iter_result} and directly fulfill the {promise}
|
||
|
- // with the {iter_result}.
|
||
|
- CallBuiltin(Builtins::kFulfillPromise, context, promise, iter_result);
|
||
|
- Goto(&return_promise);
|
||
|
- }
|
||
|
-
|
||
|
- BIND(&if_slow);
|
||
|
- {
|
||
|
- // Perform Call(promiseCapability.[[Resolve]], undefined, «iteratorResult»).
|
||
|
- CallBuiltin(Builtins::kResolvePromise, context, promise, iter_result);
|
||
|
- Goto(&return_promise);
|
||
|
- }
|
||
|
+ // Perform Call(promiseCapability.[[Resolve]], undefined, «iteratorResult»).
|
||
|
+ CallBuiltin(Builtins::kResolvePromise, context, promise, iter_result);
|
||
|
|
||
|
// Per spec, AsyncGeneratorResolve() returns undefined. However, for the
|
||
|
// benefit of %TraceExit(), return the Promise.
|
||
|
- BIND(&return_promise);
|
||
|
Return(promise);
|
||
|
}
|
||
|
|
||
|
@@ -571,54 +554,31 @@ TF_BUILTIN(AsyncGeneratorYield, AsyncGeneratorBuiltinsAssembler) {
|
||
|
Node* const request = LoadFirstAsyncGeneratorRequestFromQueue(generator);
|
||
|
Node* const outer_promise = LoadPromiseFromAsyncGeneratorRequest(request);
|
||
|
|
||
|
- // Mark the generator as "awaiting".
|
||
|
- SetGeneratorAwaiting(generator);
|
||
|
+ ContextInitializer init_closure_context = [&](Node* context) {
|
||
|
+ StoreContextElementNoWriteBarrier(context, AwaitContext::kGeneratorSlot,
|
||
|
+ generator);
|
||
|
+ };
|
||
|
|
||
|
- // We can skip the creation of a temporary promise and the whole
|
||
|
- // [[Resolve]] logic if we already know that the {value} that's
|
||
|
- // being yielded is a primitive, as in that case we would immediately
|
||
|
- // fulfill the temporary promise anyways and schedule a fulfill
|
||
|
- // reaction job. This gives a nice performance boost for async
|
||
|
- // generators that yield only primitives, e.g. numbers or strings.
|
||
|
- Label if_primitive(this), if_generic(this);
|
||
|
- GotoIfForceSlowPath(&if_generic);
|
||
|
- GotoIf(IsPromiseHookEnabledOrDebugIsActive(), &if_generic);
|
||
|
- GotoIf(TaggedIsSmi(value), &if_primitive);
|
||
|
- Branch(IsJSReceiver(value), &if_generic, &if_primitive);
|
||
|
-
|
||
|
- BIND(&if_generic);
|
||
|
- {
|
||
|
- Await(context, generator, value, outer_promise,
|
||
|
- Builtins::kAsyncGeneratorYieldFulfill,
|
||
|
- Builtins::kAsyncGeneratorAwaitReject, is_caught);
|
||
|
- Return(UndefinedConstant());
|
||
|
- }
|
||
|
+ const int on_resolve = Context::ASYNC_GENERATOR_YIELD_RESOLVE_SHARED_FUN;
|
||
|
+ const int on_reject = Context::ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN;
|
||
|
|
||
|
- BIND(&if_primitive);
|
||
|
- {
|
||
|
- // For primitive {value}s we can skip the allocation of the temporary
|
||
|
- // promise and the resolution of that, and directly allocate the fulfill
|
||
|
- // reaction job.
|
||
|
- Node* const microtask = AllocatePromiseReactionJobTask(
|
||
|
- Heap::kPromiseFulfillReactionJobTaskMapRootIndex, context, value,
|
||
|
- HeapConstant(Builtins::CallableFor(
|
||
|
- isolate(), Builtins::kAsyncGeneratorYieldFulfill)
|
||
|
- .code()),
|
||
|
- generator);
|
||
|
- TailCallBuiltin(Builtins::kEnqueueMicrotask, context, microtask);
|
||
|
- }
|
||
|
+ SetGeneratorAwaiting(generator);
|
||
|
+ Await(context, generator, value, outer_promise, AwaitContext::kLength,
|
||
|
+ init_closure_context, on_resolve, on_reject, is_caught);
|
||
|
+ Return(UndefinedConstant());
|
||
|
}
|
||
|
|
||
|
-TF_BUILTIN(AsyncGeneratorYieldFulfill, AsyncGeneratorBuiltinsAssembler) {
|
||
|
+TF_BUILTIN(AsyncGeneratorYieldResolveClosure, AsyncGeneratorBuiltinsAssembler) {
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const argument = Parameter(Descriptor::kArgument);
|
||
|
+ Node* const value = Parameter(Descriptor::kValue);
|
||
|
+ Node* const generator =
|
||
|
+ LoadContextElement(context, AwaitContext::kGeneratorSlot);
|
||
|
|
||
|
SetGeneratorNotAwaiting(generator);
|
||
|
|
||
|
// Per proposal-async-iteration/#sec-asyncgeneratoryield step 9
|
||
|
// Return ! AsyncGeneratorResolve(_F_.[[Generator]], _value_, *false*).
|
||
|
- CallBuiltin(Builtins::kAsyncGeneratorResolve, context, generator, argument,
|
||
|
+ CallBuiltin(Builtins::kAsyncGeneratorResolve, context, generator, value,
|
||
|
FalseConstant());
|
||
|
|
||
|
TailCallBuiltin(Builtins::kAsyncGeneratorResumeNext, context, generator);
|
||
|
@@ -644,33 +604,39 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
|
||
|
Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
Node* const value = Parameter(Descriptor::kValue);
|
||
|
Node* const is_caught = Parameter(Descriptor::kIsCaught);
|
||
|
- Node* const context = Parameter(Descriptor::kContext);
|
||
|
Node* const req = LoadFirstAsyncGeneratorRequestFromQueue(generator);
|
||
|
- Node* const outer_promise = LoadPromiseFromAsyncGeneratorRequest(req);
|
||
|
CSA_ASSERT(this, IsNotUndefined(req));
|
||
|
|
||
|
- Label if_closed(this, Label::kDeferred), if_not_closed(this), done(this);
|
||
|
+ Label perform_await(this);
|
||
|
+ VARIABLE(var_on_resolve, MachineType::PointerRepresentation(),
|
||
|
+ IntPtrConstant(
|
||
|
+ Context::ASYNC_GENERATOR_RETURN_CLOSED_RESOLVE_SHARED_FUN));
|
||
|
+ VARIABLE(
|
||
|
+ var_on_reject, MachineType::PointerRepresentation(),
|
||
|
+ IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_CLOSED_REJECT_SHARED_FUN));
|
||
|
+
|
||
|
Node* const state = LoadGeneratorState(generator);
|
||
|
- SetGeneratorAwaiting(generator);
|
||
|
- Branch(IsGeneratorStateClosed(state), &if_closed, &if_not_closed);
|
||
|
+ GotoIf(IsGeneratorStateClosed(state), &perform_await);
|
||
|
+ var_on_resolve.Bind(
|
||
|
+ IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_RESOLVE_SHARED_FUN));
|
||
|
+ var_on_reject.Bind(
|
||
|
+ IntPtrConstant(Context::ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN));
|
||
|
+ Goto(&perform_await);
|
||
|
|
||
|
- BIND(&if_closed);
|
||
|
- {
|
||
|
- Await(context, generator, value, outer_promise,
|
||
|
- Builtins::kAsyncGeneratorReturnClosedFulfill,
|
||
|
- Builtins::kAsyncGeneratorReturnClosedReject, is_caught);
|
||
|
- Goto(&done);
|
||
|
- }
|
||
|
+ BIND(&perform_await);
|
||
|
|
||
|
- BIND(&if_not_closed);
|
||
|
- {
|
||
|
- Await(context, generator, value, outer_promise,
|
||
|
- Builtins::kAsyncGeneratorReturnFulfill,
|
||
|
- Builtins::kAsyncGeneratorAwaitReject, is_caught);
|
||
|
- Goto(&done);
|
||
|
- }
|
||
|
+ ContextInitializer init_closure_context = [&](Node* context) {
|
||
|
+ StoreContextElementNoWriteBarrier(context, AwaitContext::kGeneratorSlot,
|
||
|
+ generator);
|
||
|
+ };
|
||
|
+
|
||
|
+ SetGeneratorAwaiting(generator);
|
||
|
+ Node* const context = Parameter(Descriptor::kContext);
|
||
|
+ Node* const outer_promise = LoadPromiseFromAsyncGeneratorRequest(req);
|
||
|
+ Await(context, generator, value, outer_promise, AwaitContext::kLength,
|
||
|
+ init_closure_context, var_on_resolve.value(), var_on_reject.value(),
|
||
|
+ is_caught);
|
||
|
|
||
|
- BIND(&done);
|
||
|
Return(UndefinedConstant());
|
||
|
}
|
||
|
|
||
|
@@ -678,44 +644,47 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
|
||
|
// Resume the generator with "return" resume_mode, and finally perform
|
||
|
// AsyncGeneratorResumeNext. Per
|
||
|
// proposal-async-iteration/#sec-asyncgeneratoryield step 8.e
|
||
|
-TF_BUILTIN(AsyncGeneratorReturnFulfill, AsyncGeneratorBuiltinsAssembler) {
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const argument = Parameter(Descriptor::kArgument);
|
||
|
+TF_BUILTIN(AsyncGeneratorReturnResolveClosure,
|
||
|
+ AsyncGeneratorBuiltinsAssembler) {
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
- AsyncGeneratorAwaitResume(context, generator, argument,
|
||
|
- JSGeneratorObject::kReturn);
|
||
|
+ Node* const value = Parameter(Descriptor::kValue);
|
||
|
+ AsyncGeneratorAwaitResumeClosure(context, value, JSGeneratorObject::kReturn);
|
||
|
}
|
||
|
|
||
|
// On-resolve closure for Await in AsyncGeneratorReturn
|
||
|
// Perform AsyncGeneratorResolve({awaited_value}, true) and finally perform
|
||
|
// AsyncGeneratorResumeNext.
|
||
|
-TF_BUILTIN(AsyncGeneratorReturnClosedFulfill, AsyncGeneratorBuiltinsAssembler) {
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const argument = Parameter(Descriptor::kArgument);
|
||
|
+TF_BUILTIN(AsyncGeneratorReturnClosedResolveClosure,
|
||
|
+ AsyncGeneratorBuiltinsAssembler) {
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
+ Node* const value = Parameter(Descriptor::kValue);
|
||
|
+ Node* const generator =
|
||
|
+ LoadContextElement(context, AwaitContext::kGeneratorSlot);
|
||
|
|
||
|
SetGeneratorNotAwaiting(generator);
|
||
|
|
||
|
// https://tc39.github.io/proposal-async-iteration/
|
||
|
// #async-generator-resume-next-return-processor-fulfilled step 2:
|
||
|
// Return ! AsyncGeneratorResolve(_F_.[[Generator]], _value_, *true*).
|
||
|
- CallBuiltin(Builtins::kAsyncGeneratorResolve, context, generator, argument,
|
||
|
+ CallBuiltin(Builtins::kAsyncGeneratorResolve, context, generator, value,
|
||
|
TrueConstant());
|
||
|
|
||
|
TailCallBuiltin(Builtins::kAsyncGeneratorResumeNext, context, generator);
|
||
|
}
|
||
|
|
||
|
-TF_BUILTIN(AsyncGeneratorReturnClosedReject, AsyncGeneratorBuiltinsAssembler) {
|
||
|
- Node* const generator = Parameter(Descriptor::kGenerator);
|
||
|
- Node* const argument = Parameter(Descriptor::kArgument);
|
||
|
+TF_BUILTIN(AsyncGeneratorReturnClosedRejectClosure,
|
||
|
+ AsyncGeneratorBuiltinsAssembler) {
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
+ Node* const value = Parameter(Descriptor::kValue);
|
||
|
+ Node* const generator =
|
||
|
+ LoadContextElement(context, AwaitContext::kGeneratorSlot);
|
||
|
|
||
|
SetGeneratorNotAwaiting(generator);
|
||
|
|
||
|
// https://tc39.github.io/proposal-async-iteration/
|
||
|
// #async-generator-resume-next-return-processor-rejected step 2:
|
||
|
// Return ! AsyncGeneratorReject(_F_.[[Generator]], _reason_).
|
||
|
- CallBuiltin(Builtins::kAsyncGeneratorReject, context, generator, argument);
|
||
|
+ CallBuiltin(Builtins::kAsyncGeneratorReject, context, generator, value);
|
||
|
|
||
|
TailCallBuiltin(Builtins::kAsyncGeneratorResumeNext, context, generator);
|
||
|
}
|
||
|
diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h
|
||
|
index 0f60dfd97e8..5f06abeceb0 100644
|
||
|
--- a/src/builtins/builtins-definitions.h
|
||
|
+++ b/src/builtins/builtins-definitions.h
|
||
|
@@ -381,10 +381,10 @@ namespace internal {
|
||
|
CPP(ArrayBufferPrototypeSlice) \
|
||
|
\
|
||
|
/* AsyncFunction */ \
|
||
|
- TFC(AsyncFunctionAwaitFulfill, PromiseReactionHandler, 1) \
|
||
|
- TFC(AsyncFunctionAwaitReject, PromiseReactionHandler, 1) \
|
||
|
- TFS(AsyncFunctionAwaitCaught, kGenerator, kValue, kOuterPromise) \
|
||
|
- TFS(AsyncFunctionAwaitUncaught, kGenerator, kValue, kOuterPromise) \
|
||
|
+ TFJ(AsyncFunctionAwaitCaught, 3, kGenerator, kAwaited, kOuterPromise) \
|
||
|
+ TFJ(AsyncFunctionAwaitUncaught, 3, kGenerator, kAwaited, kOuterPromise) \
|
||
|
+ TFJ(AsyncFunctionAwaitRejectClosure, 1, kSentError) \
|
||
|
+ TFJ(AsyncFunctionAwaitResolveClosure, 1, kSentValue) \
|
||
|
TFJ(AsyncFunctionPromiseCreate, 0) \
|
||
|
TFJ(AsyncFunctionPromiseRelease, 1, kPromise) \
|
||
|
\
|
||
|
@@ -838,8 +838,8 @@ namespace internal {
|
||
|
/* ES #sec-promise.prototype.catch */ \
|
||
|
TFJ(PromisePrototypeCatch, 1, kOnRejected) \
|
||
|
/* ES #sec-promisereactionjob */ \
|
||
|
- TFS(PromiseRejectReactionJob, kReason, kHandler, kPayload) \
|
||
|
- TFS(PromiseFulfillReactionJob, kValue, kHandler, kPayload) \
|
||
|
+ TFS(PromiseRejectReactionJob, kReason, kHandler, kPromiseOrCapability) \
|
||
|
+ TFS(PromiseFulfillReactionJob, kValue, kHandler, kPromiseOrCapability) \
|
||
|
/* ES #sec-promiseresolvethenablejob */ \
|
||
|
TFS(PromiseResolveThenableJob, kPromiseToResolve, kThenable, kThen) \
|
||
|
/* ES #sec-promise.resolve */ \
|
||
|
@@ -1203,17 +1203,6 @@ namespace internal {
|
||
|
\
|
||
|
/* AsyncGenerator */ \
|
||
|
\
|
||
|
- /* Await (proposal-async-iteration/#await), with resume behaviour */ \
|
||
|
- /* specific to Async Generators. Internal / Not exposed to JS code. */ \
|
||
|
- TFS(AsyncGeneratorAwaitCaught, kGenerator, kValue) \
|
||
|
- TFS(AsyncGeneratorAwaitUncaught, kGenerator, kValue) \
|
||
|
- TFC(AsyncGeneratorAwaitFulfill, PromiseReactionHandler, 1) \
|
||
|
- TFC(AsyncGeneratorAwaitReject, PromiseReactionHandler, 1) \
|
||
|
- TFC(AsyncGeneratorYieldFulfill, PromiseReactionHandler, 1) \
|
||
|
- TFC(AsyncGeneratorReturnClosedFulfill, PromiseReactionHandler, 1) \
|
||
|
- TFC(AsyncGeneratorReturnClosedReject, PromiseReactionHandler, 1) \
|
||
|
- TFC(AsyncGeneratorReturnFulfill, PromiseReactionHandler, 1) \
|
||
|
- \
|
||
|
TFS(AsyncGeneratorResolve, kGenerator, kValue, kDone) \
|
||
|
TFS(AsyncGeneratorReject, kGenerator, kValue) \
|
||
|
TFS(AsyncGeneratorYield, kGenerator, kValue, kIsCaught) \
|
||
|
@@ -1236,6 +1225,17 @@ namespace internal {
|
||
|
TFJ(AsyncGeneratorPrototypeThrow, \
|
||
|
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||
|
\
|
||
|
+ /* Await (proposal-async-iteration/#await), with resume behaviour */ \
|
||
|
+ /* specific to Async Generators. Internal / Not exposed to JS code. */ \
|
||
|
+ TFJ(AsyncGeneratorAwaitCaught, 2, kGenerator, kAwaited) \
|
||
|
+ TFJ(AsyncGeneratorAwaitUncaught, 2, kGenerator, kAwaited) \
|
||
|
+ TFJ(AsyncGeneratorAwaitResolveClosure, 1, kValue) \
|
||
|
+ TFJ(AsyncGeneratorAwaitRejectClosure, 1, kValue) \
|
||
|
+ TFJ(AsyncGeneratorYieldResolveClosure, 1, kValue) \
|
||
|
+ TFJ(AsyncGeneratorReturnClosedResolveClosure, 1, kValue) \
|
||
|
+ TFJ(AsyncGeneratorReturnClosedRejectClosure, 1, kValue) \
|
||
|
+ TFJ(AsyncGeneratorReturnResolveClosure, 1, kValue) \
|
||
|
+ \
|
||
|
/* Async-from-Sync Iterator */ \
|
||
|
\
|
||
|
/* %AsyncFromSyncIteratorPrototype% */ \
|
||
|
@@ -1284,7 +1284,11 @@ namespace internal {
|
||
|
V(AsyncFromSyncIteratorPrototypeNext) \
|
||
|
V(AsyncFromSyncIteratorPrototypeReturn) \
|
||
|
V(AsyncFromSyncIteratorPrototypeThrow) \
|
||
|
+ V(AsyncFunctionAwaitCaught) \
|
||
|
+ V(AsyncFunctionAwaitUncaught) \
|
||
|
V(AsyncGeneratorResolve) \
|
||
|
+ V(AsyncGeneratorAwaitCaught) \
|
||
|
+ V(AsyncGeneratorAwaitUncaught) \
|
||
|
V(PromiseAll) \
|
||
|
V(PromiseConstructor) \
|
||
|
V(PromiseConstructorLazyDeoptContinuation) \
|
||
|
diff --git a/src/builtins/builtins-internal-gen.cc b/src/builtins/builtins-internal-gen.cc
|
||
|
index e1f4aea4052..4e533ad1c4c 100644
|
||
|
--- a/src/builtins/builtins-internal-gen.cc
|
||
|
+++ b/src/builtins/builtins-internal-gen.cc
|
||
|
@@ -669,7 +669,7 @@ class InternalBuiltinsAssembler : public CodeStubAssembler {
|
||
|
void LeaveMicrotaskContext();
|
||
|
|
||
|
void RunPromiseHook(Runtime::FunctionId id, TNode<Context> context,
|
||
|
- SloppyTNode<HeapObject> payload);
|
||
|
+ SloppyTNode<HeapObject> promise_or_capability);
|
||
|
|
||
|
TNode<Object> GetPendingException() {
|
||
|
auto ref = ExternalReference(kPendingExceptionAddress, isolate());
|
||
|
@@ -790,12 +790,20 @@ void InternalBuiltinsAssembler::LeaveMicrotaskContext() {
|
||
|
|
||
|
void InternalBuiltinsAssembler::RunPromiseHook(
|
||
|
Runtime::FunctionId id, TNode<Context> context,
|
||
|
- SloppyTNode<HeapObject> payload) {
|
||
|
+ SloppyTNode<HeapObject> promise_or_capability) {
|
||
|
Label hook(this, Label::kDeferred), done_hook(this);
|
||
|
Branch(IsPromiseHookEnabledOrDebugIsActive(), &hook, &done_hook);
|
||
|
BIND(&hook);
|
||
|
{
|
||
|
- CallRuntime(id, context, payload);
|
||
|
+ // Get to the underlying JSPromise instance.
|
||
|
+ Node* const promise = Select<HeapObject>(
|
||
|
+ IsJSPromise(promise_or_capability),
|
||
|
+ [=] { return promise_or_capability; },
|
||
|
+ [=] {
|
||
|
+ return CAST(LoadObjectField(promise_or_capability,
|
||
|
+ PromiseCapability::kPromiseOffset));
|
||
|
+ });
|
||
|
+ CallRuntime(id, context, promise);
|
||
|
Goto(&done_hook);
|
||
|
}
|
||
|
BIND(&done_hook);
|
||
|
@@ -1008,19 +1016,21 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
|
||
|
LoadObjectField(microtask, PromiseReactionJobTask::kArgumentOffset);
|
||
|
Node* const handler =
|
||
|
LoadObjectField(microtask, PromiseReactionJobTask::kHandlerOffset);
|
||
|
- Node* const payload =
|
||
|
- LoadObjectField(microtask, PromiseReactionJobTask::kPayloadOffset);
|
||
|
+ Node* const promise_or_capability = LoadObjectField(
|
||
|
+ microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset);
|
||
|
|
||
|
// Run the promise before/debug hook if enabled.
|
||
|
- RunPromiseHook(Runtime::kPromiseHookBefore, microtask_context, payload);
|
||
|
+ RunPromiseHook(Runtime::kPromiseHookBefore, microtask_context,
|
||
|
+ promise_or_capability);
|
||
|
|
||
|
Node* const result =
|
||
|
CallBuiltin(Builtins::kPromiseFulfillReactionJob, microtask_context,
|
||
|
- argument, handler, payload);
|
||
|
+ argument, handler, promise_or_capability);
|
||
|
GotoIfException(result, &if_exception, &var_exception);
|
||
|
|
||
|
// Run the promise after/debug hook if enabled.
|
||
|
- RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context, payload);
|
||
|
+ RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context,
|
||
|
+ promise_or_capability);
|
||
|
|
||
|
LeaveMicrotaskContext();
|
||
|
SetCurrentContext(current_context);
|
||
|
@@ -1041,19 +1051,21 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
|
||
|
LoadObjectField(microtask, PromiseReactionJobTask::kArgumentOffset);
|
||
|
Node* const handler =
|
||
|
LoadObjectField(microtask, PromiseReactionJobTask::kHandlerOffset);
|
||
|
- Node* const payload =
|
||
|
- LoadObjectField(microtask, PromiseReactionJobTask::kPayloadOffset);
|
||
|
+ Node* const promise_or_capability = LoadObjectField(
|
||
|
+ microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset);
|
||
|
|
||
|
// Run the promise before/debug hook if enabled.
|
||
|
- RunPromiseHook(Runtime::kPromiseHookBefore, microtask_context, payload);
|
||
|
+ RunPromiseHook(Runtime::kPromiseHookBefore, microtask_context,
|
||
|
+ promise_or_capability);
|
||
|
|
||
|
Node* const result =
|
||
|
CallBuiltin(Builtins::kPromiseRejectReactionJob, microtask_context,
|
||
|
- argument, handler, payload);
|
||
|
+ argument, handler, promise_or_capability);
|
||
|
GotoIfException(result, &if_exception, &var_exception);
|
||
|
|
||
|
// Run the promise after/debug hook if enabled.
|
||
|
- RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context, payload);
|
||
|
+ RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context,
|
||
|
+ promise_or_capability);
|
||
|
|
||
|
LeaveMicrotaskContext();
|
||
|
SetCurrentContext(current_context);
|
||
|
diff --git a/src/builtins/builtins-promise-gen.cc b/src/builtins/builtins-promise-gen.cc
|
||
|
index dd38dbc5435..868b45a8316 100644
|
||
|
--- a/src/builtins/builtins-promise-gen.cc
|
||
|
+++ b/src/builtins/builtins-promise-gen.cc
|
||
|
@@ -391,15 +391,15 @@ TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) {
|
||
|
Return(result_promise);
|
||
|
}
|
||
|
|
||
|
-Node* PromiseBuiltinsAssembler::AllocatePromiseReaction(Node* next,
|
||
|
- Node* payload,
|
||
|
- Node* fulfill_handler,
|
||
|
- Node* reject_handler) {
|
||
|
+Node* PromiseBuiltinsAssembler::AllocatePromiseReaction(
|
||
|
+ Node* next, Node* promise_or_capability, Node* fulfill_handler,
|
||
|
+ Node* reject_handler) {
|
||
|
Node* const reaction = Allocate(PromiseReaction::kSize);
|
||
|
StoreMapNoWriteBarrier(reaction, Heap::kPromiseReactionMapRootIndex);
|
||
|
StoreObjectFieldNoWriteBarrier(reaction, PromiseReaction::kNextOffset, next);
|
||
|
- StoreObjectFieldNoWriteBarrier(reaction, PromiseReaction::kPayloadOffset,
|
||
|
- payload);
|
||
|
+ StoreObjectFieldNoWriteBarrier(reaction,
|
||
|
+ PromiseReaction::kPromiseOrCapabilityOffset,
|
||
|
+ promise_or_capability);
|
||
|
StoreObjectFieldNoWriteBarrier(
|
||
|
reaction, PromiseReaction::kFulfillHandlerOffset, fulfill_handler);
|
||
|
StoreObjectFieldNoWriteBarrier(
|
||
|
@@ -408,7 +408,8 @@ Node* PromiseBuiltinsAssembler::AllocatePromiseReaction(Node* next,
|
||
|
}
|
||
|
|
||
|
Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
|
||
|
- Node* map, Node* context, Node* argument, Node* handler, Node* payload) {
|
||
|
+ Node* map, Node* context, Node* argument, Node* handler,
|
||
|
+ Node* promise_or_capability) {
|
||
|
Node* const microtask = Allocate(PromiseReactionJobTask::kSize);
|
||
|
StoreMapNoWriteBarrier(microtask, map);
|
||
|
StoreObjectFieldNoWriteBarrier(
|
||
|
@@ -418,18 +419,19 @@ Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
|
||
|
StoreObjectFieldNoWriteBarrier(
|
||
|
microtask, PromiseReactionJobTask::kHandlerOffset, handler);
|
||
|
StoreObjectFieldNoWriteBarrier(
|
||
|
- microtask, PromiseReactionJobTask::kPayloadOffset, payload);
|
||
|
+ microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset,
|
||
|
+ promise_or_capability);
|
||
|
return microtask;
|
||
|
}
|
||
|
|
||
|
Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
|
||
|
Heap::RootListIndex map_root_index, Node* context, Node* argument,
|
||
|
- Node* handler, Node* payload) {
|
||
|
+ Node* handler, Node* promise_or_capability) {
|
||
|
DCHECK(map_root_index == Heap::kPromiseFulfillReactionJobTaskMapRootIndex ||
|
||
|
map_root_index == Heap::kPromiseRejectReactionJobTaskMapRootIndex);
|
||
|
Node* const map = LoadRoot(map_root_index);
|
||
|
return AllocatePromiseReactionJobTask(map, context, argument, handler,
|
||
|
- payload);
|
||
|
+ promise_or_capability);
|
||
|
}
|
||
|
|
||
|
Node* PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobTask(
|
||
|
@@ -502,8 +504,8 @@ Node* PromiseBuiltinsAssembler::TriggerPromiseReactions(
|
||
|
context);
|
||
|
STATIC_ASSERT(PromiseReaction::kFulfillHandlerOffset ==
|
||
|
PromiseReactionJobTask::kHandlerOffset);
|
||
|
- STATIC_ASSERT(PromiseReaction::kPayloadOffset ==
|
||
|
- PromiseReactionJobTask::kPayloadOffset);
|
||
|
+ STATIC_ASSERT(PromiseReaction::kPromiseOrCapabilityOffset ==
|
||
|
+ PromiseReactionJobTask::kPromiseOrCapabilityOffset);
|
||
|
} else {
|
||
|
Node* handler =
|
||
|
LoadObjectField(current, PromiseReaction::kRejectHandlerOffset);
|
||
|
@@ -515,8 +517,8 @@ Node* PromiseBuiltinsAssembler::TriggerPromiseReactions(
|
||
|
context);
|
||
|
StoreObjectField(current, PromiseReactionJobTask::kHandlerOffset,
|
||
|
handler);
|
||
|
- STATIC_ASSERT(PromiseReaction::kPayloadOffset ==
|
||
|
- PromiseReactionJobTask::kPayloadOffset);
|
||
|
+ STATIC_ASSERT(PromiseReaction::kPromiseOrCapabilityOffset ==
|
||
|
+ PromiseReactionJobTask::kPromiseOrCapabilityOffset);
|
||
|
}
|
||
|
CallBuiltin(Builtins::kEnqueueMicrotask, NoContextConstant(), current);
|
||
|
Goto(&loop);
|
||
|
@@ -1118,28 +1120,20 @@ TF_BUILTIN(PromiseResolveThenableJob, PromiseBuiltinsAssembler) {
|
||
|
|
||
|
// ES #sec-promisereactionjob
|
||
|
void PromiseBuiltinsAssembler::PromiseReactionJob(Node* context, Node* argument,
|
||
|
- Node* handler, Node* payload,
|
||
|
+ Node* handler,
|
||
|
+ Node* promise_or_capability,
|
||
|
PromiseReaction::Type type) {
|
||
|
CSA_ASSERT(this, TaggedIsNotSmi(handler));
|
||
|
- CSA_ASSERT(this, Word32Or(IsCallable(handler),
|
||
|
- Word32Or(IsCode(handler), IsUndefined(handler))));
|
||
|
- CSA_ASSERT(this, TaggedIsNotSmi(payload));
|
||
|
+ CSA_ASSERT(this, Word32Or(IsUndefined(handler), IsCallable(handler)));
|
||
|
+ CSA_ASSERT(this, TaggedIsNotSmi(promise_or_capability));
|
||
|
+ CSA_ASSERT(this, Word32Or(IsJSPromise(promise_or_capability),
|
||
|
+ IsPromiseCapability(promise_or_capability)));
|
||
|
|
||
|
VARIABLE(var_handler_result, MachineRepresentation::kTagged, argument);
|
||
|
- Label if_handler_callable(this), if_fulfill(this), if_reject(this),
|
||
|
- if_code_handler(this);
|
||
|
-
|
||
|
- GotoIf(IsUndefined(handler),
|
||
|
- type == PromiseReaction::kFulfill ? &if_fulfill : &if_reject);
|
||
|
- Branch(IsCode(handler), &if_code_handler, &if_handler_callable);
|
||
|
-
|
||
|
- BIND(&if_code_handler);
|
||
|
- {
|
||
|
- // The {handler} is a Code object that knows how to deal with
|
||
|
- // the {payload} and the {argument}.
|
||
|
- PromiseReactionHandlerDescriptor descriptor(isolate());
|
||
|
- TailCallStub(descriptor, handler, context, argument, payload);
|
||
|
- }
|
||
|
+ Label if_handler_callable(this), if_fulfill(this), if_reject(this);
|
||
|
+ Branch(IsUndefined(handler),
|
||
|
+ type == PromiseReaction::kFulfill ? &if_fulfill : &if_reject,
|
||
|
+ &if_handler_callable);
|
||
|
|
||
|
BIND(&if_handler_callable);
|
||
|
{
|
||
|
@@ -1155,22 +1149,24 @@ void PromiseBuiltinsAssembler::PromiseReactionJob(Node* context, Node* argument,
|
||
|
{
|
||
|
Label if_promise(this), if_promise_capability(this, Label::kDeferred);
|
||
|
Node* const value = var_handler_result.value();
|
||
|
- Branch(IsPromiseCapability(payload), &if_promise_capability, &if_promise);
|
||
|
+ Branch(IsPromiseCapability(promise_or_capability), &if_promise_capability,
|
||
|
+ &if_promise);
|
||
|
|
||
|
BIND(&if_promise);
|
||
|
{
|
||
|
// For fast native promises we can skip the indirection
|
||
|
// via the promiseCapability.[[Resolve]] function and
|
||
|
// run the resolve logic directly from here.
|
||
|
- TailCallBuiltin(Builtins::kResolvePromise, context, payload, value);
|
||
|
+ TailCallBuiltin(Builtins::kResolvePromise, context, promise_or_capability,
|
||
|
+ value);
|
||
|
}
|
||
|
|
||
|
BIND(&if_promise_capability);
|
||
|
{
|
||
|
// In the general case we need to call the (user provided)
|
||
|
// promiseCapability.[[Resolve]] function.
|
||
|
- Node* const resolve =
|
||
|
- LoadObjectField(payload, PromiseCapability::kResolveOffset);
|
||
|
+ Node* const resolve = LoadObjectField(promise_or_capability,
|
||
|
+ PromiseCapability::kResolveOffset);
|
||
|
Node* const result = CallJS(
|
||
|
CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
|
||
|
context, resolve, UndefinedConstant(), value);
|
||
|
@@ -1183,15 +1179,16 @@ void PromiseBuiltinsAssembler::PromiseReactionJob(Node* context, Node* argument,
|
||
|
if (type == PromiseReaction::kReject) {
|
||
|
Label if_promise(this), if_promise_capability(this, Label::kDeferred);
|
||
|
Node* const reason = var_handler_result.value();
|
||
|
- Branch(IsPromiseCapability(payload), &if_promise_capability, &if_promise);
|
||
|
+ Branch(IsPromiseCapability(promise_or_capability), &if_promise_capability,
|
||
|
+ &if_promise);
|
||
|
|
||
|
BIND(&if_promise);
|
||
|
{
|
||
|
// For fast native promises we can skip the indirection
|
||
|
// via the promiseCapability.[[Reject]] function and
|
||
|
// run the resolve logic directly from here.
|
||
|
- TailCallBuiltin(Builtins::kRejectPromise, context, payload, reason,
|
||
|
- FalseConstant());
|
||
|
+ TailCallBuiltin(Builtins::kRejectPromise, context, promise_or_capability,
|
||
|
+ reason, FalseConstant());
|
||
|
}
|
||
|
|
||
|
BIND(&if_promise_capability);
|
||
|
@@ -1201,8 +1198,8 @@ void PromiseBuiltinsAssembler::PromiseReactionJob(Node* context, Node* argument,
|
||
|
Label if_exception(this, Label::kDeferred);
|
||
|
VARIABLE(var_exception, MachineRepresentation::kTagged,
|
||
|
TheHoleConstant());
|
||
|
- Node* const reject =
|
||
|
- LoadObjectField(payload, PromiseCapability::kRejectOffset);
|
||
|
+ Node* const reject = LoadObjectField(promise_or_capability,
|
||
|
+ PromiseCapability::kRejectOffset);
|
||
|
Node* const result = CallJS(
|
||
|
CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
|
||
|
context, reject, UndefinedConstant(), reason);
|
||
|
@@ -1219,7 +1216,8 @@ void PromiseBuiltinsAssembler::PromiseReactionJob(Node* context, Node* argument,
|
||
|
// predictions in the debugger will be wrong, which just walks the stack
|
||
|
// and checks for certain builtins.
|
||
|
TailCallBuiltin(Builtins::kPromiseRejectReactionJob, context,
|
||
|
- var_handler_result.value(), UndefinedConstant(), payload);
|
||
|
+ var_handler_result.value(), UndefinedConstant(),
|
||
|
+ promise_or_capability);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -1228,9 +1226,10 @@ TF_BUILTIN(PromiseFulfillReactionJob, PromiseBuiltinsAssembler) {
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
Node* const value = Parameter(Descriptor::kValue);
|
||
|
Node* const handler = Parameter(Descriptor::kHandler);
|
||
|
- Node* const payload = Parameter(Descriptor::kPayload);
|
||
|
+ Node* const promise_or_capability =
|
||
|
+ Parameter(Descriptor::kPromiseOrCapability);
|
||
|
|
||
|
- PromiseReactionJob(context, value, handler, payload,
|
||
|
+ PromiseReactionJob(context, value, handler, promise_or_capability,
|
||
|
PromiseReaction::kFulfill);
|
||
|
}
|
||
|
|
||
|
@@ -1239,9 +1238,10 @@ TF_BUILTIN(PromiseRejectReactionJob, PromiseBuiltinsAssembler) {
|
||
|
Node* const context = Parameter(Descriptor::kContext);
|
||
|
Node* const reason = Parameter(Descriptor::kReason);
|
||
|
Node* const handler = Parameter(Descriptor::kHandler);
|
||
|
- Node* const payload = Parameter(Descriptor::kPayload);
|
||
|
+ Node* const promise_or_capability =
|
||
|
+ Parameter(Descriptor::kPromiseOrCapability);
|
||
|
|
||
|
- PromiseReactionJob(context, reason, handler, payload,
|
||
|
+ PromiseReactionJob(context, reason, handler, promise_or_capability,
|
||
|
PromiseReaction::kReject);
|
||
|
}
|
||
|
|
||
|
@@ -1717,23 +1717,21 @@ TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) {
|
||
|
|
||
|
// 7. If Type(resolution) is not Object, then
|
||
|
GotoIf(TaggedIsSmi(resolution), &if_fulfill);
|
||
|
- Node* const resolution_map = LoadMap(resolution);
|
||
|
- GotoIfNot(IsJSReceiverMap(resolution_map), &if_fulfill);
|
||
|
+ Node* const result_map = LoadMap(resolution);
|
||
|
+ GotoIfNot(IsJSReceiverMap(result_map), &if_fulfill);
|
||
|
|
||
|
// We can skip the "then" lookup on {resolution} if its [[Prototype]]
|
||
|
// is the (initial) Promise.prototype and the Promise#then protector
|
||
|
// is intact, as that guards the lookup path for the "then" property
|
||
|
// on JSPromise instances which have the (initial) %PromisePrototype%.
|
||
|
- Label if_fast(this), if_generic(this), if_slow(this, Label::kDeferred);
|
||
|
+ Label if_fast(this), if_slow(this, Label::kDeferred);
|
||
|
Node* const native_context = LoadNativeContext(context);
|
||
|
- GotoIfForceSlowPath(&if_slow);
|
||
|
- GotoIf(IsPromiseThenProtectorCellInvalid(), &if_slow);
|
||
|
- GotoIfNot(IsJSPromiseMap(resolution_map), &if_generic);
|
||
|
- Node* const promise_prototype =
|
||
|
- LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
|
||
|
- Branch(WordEqual(LoadMapPrototype(resolution_map), promise_prototype),
|
||
|
- &if_fast, &if_slow);
|
||
|
+ BranchIfPromiseThenLookupChainIntact(native_context, result_map, &if_fast,
|
||
|
+ &if_slow);
|
||
|
|
||
|
+ // Resolution is a native promise and if it's already resolved or
|
||
|
+ // rejected, shortcircuit the resolution procedure by directly
|
||
|
+ // reusing the value from the promise.
|
||
|
BIND(&if_fast);
|
||
|
{
|
||
|
Node* const then =
|
||
|
@@ -1742,21 +1740,6 @@ TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) {
|
||
|
Goto(&do_enqueue);
|
||
|
}
|
||
|
|
||
|
- BIND(&if_generic);
|
||
|
- {
|
||
|
- // We can skip the lookup of "then" if the {resolution} is a (newly
|
||
|
- // created) IterResultObject, as the Promise#then protector also
|
||
|
- // ensures that the intrinsic %ObjectPrototype% doesn't contain any
|
||
|
- // "then" property. This helps to avoid negative lookups on iterator
|
||
|
- // results from async generators.
|
||
|
- CSA_ASSERT(this, IsJSReceiverMap(resolution_map));
|
||
|
- CSA_ASSERT(this, Word32BinaryNot(IsPromiseThenProtectorCellInvalid()));
|
||
|
- Node* const iterator_result_map =
|
||
|
- LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
|
||
|
- Branch(WordEqual(resolution_map, iterator_result_map), &if_fulfill,
|
||
|
- &if_slow);
|
||
|
- }
|
||
|
-
|
||
|
BIND(&if_slow);
|
||
|
{
|
||
|
// 8. Let then be Get(resolution, "then").
|
||
|
diff --git a/src/builtins/builtins-promise-gen.h b/src/builtins/builtins-promise-gen.h
|
||
|
index f21d86a141a..694cea28c06 100644
|
||
|
--- a/src/builtins/builtins-promise-gen.h
|
||
|
+++ b/src/builtins/builtins-promise-gen.h
|
||
|
@@ -85,14 +85,16 @@ class PromiseBuiltinsAssembler : public CodeStubAssembler {
|
||
|
Node* AllocateAndSetJSPromise(Node* context, v8::Promise::PromiseState status,
|
||
|
Node* result);
|
||
|
|
||
|
- Node* AllocatePromiseReaction(Node* next, Node* payload,
|
||
|
+ Node* AllocatePromiseReaction(Node* next, Node* promise_or_capability,
|
||
|
Node* fulfill_handler, Node* reject_handler);
|
||
|
|
||
|
Node* AllocatePromiseReactionJobTask(Heap::RootListIndex map_root_index,
|
||
|
Node* context, Node* argument,
|
||
|
- Node* handler, Node* payload);
|
||
|
+ Node* handler,
|
||
|
+ Node* promise_or_capability);
|
||
|
Node* AllocatePromiseReactionJobTask(Node* map, Node* context, Node* argument,
|
||
|
- Node* handler, Node* payload);
|
||
|
+ Node* handler,
|
||
|
+ Node* promise_or_capability);
|
||
|
Node* AllocatePromiseResolveThenableJobTask(Node* promise_to_resolve,
|
||
|
Node* then, Node* thenable,
|
||
|
Node* context);
|
||
|
@@ -192,7 +194,8 @@ class PromiseBuiltinsAssembler : public CodeStubAssembler {
|
||
|
Node* PromiseStatus(Node* promise);
|
||
|
|
||
|
void PromiseReactionJob(Node* context, Node* argument, Node* handler,
|
||
|
- Node* payload, PromiseReaction::Type type);
|
||
|
+ Node* promise_or_capability,
|
||
|
+ PromiseReaction::Type type);
|
||
|
|
||
|
Node* IsPromiseStatus(Node* actual, v8::Promise::PromiseState expected);
|
||
|
void PromiseSetStatus(Node* promise, v8::Promise::PromiseState status);
|
||
|
diff --git a/src/builtins/builtins.cc b/src/builtins/builtins.cc
|
||
|
index c348248fffb..7e6a0459a7d 100644
|
||
|
--- a/src/builtins/builtins.cc
|
||
|
+++ b/src/builtins/builtins.cc
|
||
|
@@ -364,17 +364,12 @@ bool Builtins::IsIsolateIndependent(int index) {
|
||
|
case kAsyncFromSyncIteratorPrototypeNext:
|
||
|
case kAsyncFromSyncIteratorPrototypeReturn:
|
||
|
case kAsyncFromSyncIteratorPrototypeThrow:
|
||
|
- case kAsyncFunctionAwaitFulfill:
|
||
|
- case kAsyncFunctionAwaitReject:
|
||
|
+ case kAsyncFunctionAwaitCaught:
|
||
|
case kAsyncFunctionPromiseCreate:
|
||
|
case kAsyncFunctionPromiseRelease:
|
||
|
- case kAsyncGeneratorAwaitFulfill:
|
||
|
- case kAsyncGeneratorAwaitReject:
|
||
|
case kAsyncGeneratorResumeNext:
|
||
|
- case kAsyncGeneratorReturnClosedFulfill:
|
||
|
- case kAsyncGeneratorReturnClosedReject:
|
||
|
- case kAsyncGeneratorReturnFulfill:
|
||
|
- case kAsyncGeneratorYieldFulfill:
|
||
|
+ case kAsyncGeneratorReturnClosedRejectClosure:
|
||
|
+ case kAsyncGeneratorReturn:
|
||
|
case kAsyncIteratorValueUnwrap:
|
||
|
case kBitwiseNot:
|
||
|
case kBooleanPrototypeToString:
|
||
|
diff --git a/src/compiler/js-intrinsic-lowering.cc b/src/compiler/js-intrinsic-lowering.cc
|
||
|
index c570a1f8ddc..d9742e47d9f 100644
|
||
|
--- a/src/compiler/js-intrinsic-lowering.cc
|
||
|
+++ b/src/compiler/js-intrinsic-lowering.cc
|
||
|
@@ -41,14 +41,6 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
|
||
|
return ReduceCreateJSGeneratorObject(node);
|
||
|
case Runtime::kInlineGeneratorGetInputOrDebugPos:
|
||
|
return ReduceGeneratorGetInputOrDebugPos(node);
|
||
|
- case Runtime::kInlineAsyncFunctionAwaitCaught:
|
||
|
- return ReduceAsyncFunctionAwaitCaught(node);
|
||
|
- case Runtime::kInlineAsyncFunctionAwaitUncaught:
|
||
|
- return ReduceAsyncFunctionAwaitUncaught(node);
|
||
|
- case Runtime::kInlineAsyncGeneratorAwaitCaught:
|
||
|
- return ReduceAsyncGeneratorAwaitCaught(node);
|
||
|
- case Runtime::kInlineAsyncGeneratorAwaitUncaught:
|
||
|
- return ReduceAsyncGeneratorAwaitUncaught(node);
|
||
|
case Runtime::kInlineAsyncGeneratorReject:
|
||
|
return ReduceAsyncGeneratorReject(node);
|
||
|
case Runtime::kInlineAsyncGeneratorResolve:
|
||
|
@@ -185,33 +177,6 @@ Reduction JSIntrinsicLowering::ReduceGeneratorGetInputOrDebugPos(Node* node) {
|
||
|
return Change(node, op, generator, effect, control);
|
||
|
}
|
||
|
|
||
|
-Reduction JSIntrinsicLowering::ReduceAsyncFunctionAwaitCaught(Node* node) {
|
||
|
- return Change(
|
||
|
- node,
|
||
|
- Builtins::CallableFor(isolate(), Builtins::kAsyncFunctionAwaitCaught), 0);
|
||
|
-}
|
||
|
-
|
||
|
-Reduction JSIntrinsicLowering::ReduceAsyncFunctionAwaitUncaught(Node* node) {
|
||
|
- return Change(
|
||
|
- node,
|
||
|
- Builtins::CallableFor(isolate(), Builtins::kAsyncFunctionAwaitUncaught),
|
||
|
- 0);
|
||
|
-}
|
||
|
-
|
||
|
-Reduction JSIntrinsicLowering::ReduceAsyncGeneratorAwaitCaught(Node* node) {
|
||
|
- return Change(
|
||
|
- node,
|
||
|
- Builtins::CallableFor(isolate(), Builtins::kAsyncGeneratorAwaitCaught),
|
||
|
- 0);
|
||
|
-}
|
||
|
-
|
||
|
-Reduction JSIntrinsicLowering::ReduceAsyncGeneratorAwaitUncaught(Node* node) {
|
||
|
- return Change(
|
||
|
- node,
|
||
|
- Builtins::CallableFor(isolate(), Builtins::kAsyncGeneratorAwaitUncaught),
|
||
|
- 0);
|
||
|
-}
|
||
|
-
|
||
|
Reduction JSIntrinsicLowering::ReduceAsyncGeneratorReject(Node* node) {
|
||
|
return Change(
|
||
|
node, Builtins::CallableFor(isolate(), Builtins::kAsyncGeneratorReject),
|
||
|
diff --git a/src/compiler/js-intrinsic-lowering.h b/src/compiler/js-intrinsic-lowering.h
|
||
|
index fb745986a60..18fe1248c7a 100644
|
||
|
--- a/src/compiler/js-intrinsic-lowering.h
|
||
|
+++ b/src/compiler/js-intrinsic-lowering.h
|
||
|
@@ -45,10 +45,6 @@ class V8_EXPORT_PRIVATE JSIntrinsicLowering final
|
||
|
Reduction ReduceCreateJSGeneratorObject(Node* node);
|
||
|
Reduction ReduceGeneratorClose(Node* node);
|
||
|
Reduction ReduceGeneratorGetInputOrDebugPos(Node* node);
|
||
|
- Reduction ReduceAsyncFunctionAwaitCaught(Node* node);
|
||
|
- Reduction ReduceAsyncFunctionAwaitUncaught(Node* node);
|
||
|
- Reduction ReduceAsyncGeneratorAwaitCaught(Node* node);
|
||
|
- Reduction ReduceAsyncGeneratorAwaitUncaught(Node* node);
|
||
|
Reduction ReduceAsyncGeneratorReject(Node* node);
|
||
|
Reduction ReduceAsyncGeneratorResolve(Node* node);
|
||
|
Reduction ReduceAsyncGeneratorYield(Node* node);
|
||
|
diff --git a/src/contexts.h b/src/contexts.h
|
||
|
index 6fc6f2d1c32..fcfeccdc44e 100644
|
||
|
--- a/src/contexts.h
|
||
|
+++ b/src/contexts.h
|
||
|
@@ -32,37 +32,44 @@ enum ContextLookupFlags {
|
||
|
// must always be allocated via Heap::AllocateContext() or
|
||
|
// Factory::NewContext.
|
||
|
|
||
|
-#define NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
|
||
|
- V(ASYNC_FUNCTION_PROMISE_CREATE_INDEX, JSFunction, \
|
||
|
- async_function_promise_create) \
|
||
|
- V(ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, JSFunction, \
|
||
|
- async_function_promise_release) \
|
||
|
- V(IS_ARRAYLIKE, JSFunction, is_arraylike) \
|
||
|
- V(GENERATOR_NEXT_INTERNAL, JSFunction, generator_next_internal) \
|
||
|
- V(MAKE_ERROR_INDEX, JSFunction, make_error) \
|
||
|
- V(MAKE_RANGE_ERROR_INDEX, JSFunction, make_range_error) \
|
||
|
- V(MAKE_SYNTAX_ERROR_INDEX, JSFunction, make_syntax_error) \
|
||
|
- V(MAKE_TYPE_ERROR_INDEX, JSFunction, make_type_error) \
|
||
|
- V(MAKE_URI_ERROR_INDEX, JSFunction, make_uri_error) \
|
||
|
- V(OBJECT_CREATE, JSFunction, object_create) \
|
||
|
- V(OBJECT_DEFINE_PROPERTIES, JSFunction, object_define_properties) \
|
||
|
- V(OBJECT_DEFINE_PROPERTY, JSFunction, object_define_property) \
|
||
|
- V(OBJECT_GET_PROTOTYPE_OF, JSFunction, object_get_prototype_of) \
|
||
|
- V(OBJECT_IS_EXTENSIBLE, JSFunction, object_is_extensible) \
|
||
|
- V(OBJECT_IS_FROZEN, JSFunction, object_is_frozen) \
|
||
|
- V(OBJECT_IS_SEALED, JSFunction, object_is_sealed) \
|
||
|
- V(OBJECT_KEYS, JSFunction, object_keys) \
|
||
|
- V(REGEXP_INTERNAL_MATCH, JSFunction, regexp_internal_match) \
|
||
|
- V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \
|
||
|
- V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
|
||
|
- V(REFLECT_DEFINE_PROPERTY_INDEX, JSFunction, reflect_define_property) \
|
||
|
- V(REFLECT_DELETE_PROPERTY_INDEX, JSFunction, reflect_delete_property) \
|
||
|
- V(MATH_FLOOR_INDEX, JSFunction, math_floor) \
|
||
|
- V(MATH_POW_INDEX, JSFunction, math_pow) \
|
||
|
- V(PROMISE_INTERNAL_CONSTRUCTOR_INDEX, JSFunction, \
|
||
|
- promise_internal_constructor) \
|
||
|
- V(IS_PROMISE_INDEX, JSFunction, is_promise) \
|
||
|
- V(PROMISE_THEN_INDEX, JSFunction, promise_then)
|
||
|
+#define NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
|
||
|
+ V(ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, JSFunction, \
|
||
|
+ async_function_await_caught) \
|
||
|
+ V(ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX, JSFunction, \
|
||
|
+ async_function_await_uncaught) \
|
||
|
+ V(ASYNC_FUNCTION_PROMISE_CREATE_INDEX, JSFunction, \
|
||
|
+ async_function_promise_create) \
|
||
|
+ V(ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, JSFunction, \
|
||
|
+ async_function_promise_release) \
|
||
|
+ V(IS_ARRAYLIKE, JSFunction, is_arraylike) \
|
||
|
+ V(GENERATOR_NEXT_INTERNAL, JSFunction, generator_next_internal) \
|
||
|
+ V(MAKE_ERROR_INDEX, JSFunction, make_error) \
|
||
|
+ V(MAKE_RANGE_ERROR_INDEX, JSFunction, make_range_error) \
|
||
|
+ V(MAKE_SYNTAX_ERROR_INDEX, JSFunction, make_syntax_error) \
|
||
|
+ V(MAKE_TYPE_ERROR_INDEX, JSFunction, make_type_error) \
|
||
|
+ V(MAKE_URI_ERROR_INDEX, JSFunction, make_uri_error) \
|
||
|
+ V(OBJECT_CREATE, JSFunction, object_create) \
|
||
|
+ V(OBJECT_DEFINE_PROPERTIES, JSFunction, object_define_properties) \
|
||
|
+ V(OBJECT_DEFINE_PROPERTY, JSFunction, object_define_property) \
|
||
|
+ V(OBJECT_GET_PROTOTYPE_OF, JSFunction, object_get_prototype_of) \
|
||
|
+ V(OBJECT_IS_EXTENSIBLE, JSFunction, object_is_extensible) \
|
||
|
+ V(OBJECT_IS_FROZEN, JSFunction, object_is_frozen) \
|
||
|
+ V(OBJECT_IS_SEALED, JSFunction, object_is_sealed) \
|
||
|
+ V(OBJECT_KEYS, JSFunction, object_keys) \
|
||
|
+ V(REGEXP_INTERNAL_MATCH, JSFunction, regexp_internal_match) \
|
||
|
+ V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \
|
||
|
+ V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
|
||
|
+ V(REFLECT_DEFINE_PROPERTY_INDEX, JSFunction, reflect_define_property) \
|
||
|
+ V(REFLECT_DELETE_PROPERTY_INDEX, JSFunction, reflect_delete_property) \
|
||
|
+ V(MATH_FLOOR_INDEX, JSFunction, math_floor) \
|
||
|
+ V(MATH_POW_INDEX, JSFunction, math_pow) \
|
||
|
+ V(NEW_PROMISE_CAPABILITY_INDEX, JSFunction, new_promise_capability) \
|
||
|
+ V(PROMISE_INTERNAL_CONSTRUCTOR_INDEX, JSFunction, \
|
||
|
+ promise_internal_constructor) \
|
||
|
+ V(IS_PROMISE_INDEX, JSFunction, is_promise) \
|
||
|
+ V(PROMISE_THEN_INDEX, JSFunction, promise_then) \
|
||
|
+ V(ASYNC_GENERATOR_AWAIT_CAUGHT, JSFunction, async_generator_await_caught) \
|
||
|
+ V(ASYNC_GENERATOR_AWAIT_UNCAUGHT, JSFunction, async_generator_await_uncaught)
|
||
|
|
||
|
#define NATIVE_CONTEXT_IMPORTED_FIELDS(V) \
|
||
|
V(ARRAY_POP_INDEX, JSFunction, array_pop) \
|
||
|
@@ -116,11 +123,27 @@ enum ContextLookupFlags {
|
||
|
V(ARRAY_BUFFER_NOINIT_FUN_INDEX, JSFunction, array_buffer_noinit_fun) \
|
||
|
V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
|
||
|
V(ASYNC_FROM_SYNC_ITERATOR_MAP_INDEX, Map, async_from_sync_iterator_map) \
|
||
|
+ V(ASYNC_FUNCTION_AWAIT_REJECT_SHARED_FUN, SharedFunctionInfo, \
|
||
|
+ async_function_await_reject_shared_fun) \
|
||
|
+ V(ASYNC_FUNCTION_AWAIT_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
|
||
|
+ async_function_await_resolve_shared_fun) \
|
||
|
V(ASYNC_FUNCTION_FUNCTION_INDEX, JSFunction, async_function_constructor) \
|
||
|
V(ASYNC_GENERATOR_FUNCTION_FUNCTION_INDEX, JSFunction, \
|
||
|
async_generator_function_function) \
|
||
|
V(ASYNC_ITERATOR_VALUE_UNWRAP_SHARED_FUN, SharedFunctionInfo, \
|
||
|
async_iterator_value_unwrap_shared_fun) \
|
||
|
+ V(ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN, SharedFunctionInfo, \
|
||
|
+ async_generator_await_reject_shared_fun) \
|
||
|
+ V(ASYNC_GENERATOR_AWAIT_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
|
||
|
+ async_generator_await_resolve_shared_fun) \
|
||
|
+ V(ASYNC_GENERATOR_YIELD_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
|
||
|
+ async_generator_yield_resolve_shared_fun) \
|
||
|
+ V(ASYNC_GENERATOR_RETURN_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
|
||
|
+ async_generator_return_resolve_shared_fun) \
|
||
|
+ V(ASYNC_GENERATOR_RETURN_CLOSED_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
|
||
|
+ async_generator_return_closed_resolve_shared_fun) \
|
||
|
+ V(ASYNC_GENERATOR_RETURN_CLOSED_REJECT_SHARED_FUN, SharedFunctionInfo, \
|
||
|
+ async_generator_return_closed_reject_shared_fun) \
|
||
|
V(ATOMICS_OBJECT, JSObject, atomics_object) \
|
||
|
V(BIGINT_FUNCTION_INDEX, JSFunction, bigint_function) \
|
||
|
V(BIGINT64_ARRAY_FUN_INDEX, JSFunction, bigint64_array_fun) \
|
||
|
diff --git a/src/heap-symbols.h b/src/heap-symbols.h
|
||
|
index 82ecd766575..c15aa9ba138 100644
|
||
|
--- a/src/heap-symbols.h
|
||
|
+++ b/src/heap-symbols.h
|
||
|
@@ -237,7 +237,6 @@
|
||
|
V(error_script_symbol) \
|
||
|
V(error_start_pos_symbol) \
|
||
|
V(frozen_symbol) \
|
||
|
- V(generator_outer_promise_symbol) \
|
||
|
V(generic_symbol) \
|
||
|
V(home_object_symbol) \
|
||
|
V(intl_initialized_marker_symbol) \
|
||
|
diff --git a/src/interface-descriptors.h b/src/interface-descriptors.h
|
||
|
index 61da0c3f4ea..8375ea11971 100644
|
||
|
--- a/src/interface-descriptors.h
|
||
|
+++ b/src/interface-descriptors.h
|
||
|
@@ -81,7 +81,6 @@ class PlatformInterfaceDescriptor;
|
||
|
V(FrameDropperTrampoline) \
|
||
|
V(WasmRuntimeCall) \
|
||
|
V(RunMicrotasks) \
|
||
|
- V(PromiseReactionHandler) \
|
||
|
BUILTIN_LIST_TFS(V)
|
||
|
|
||
|
class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
|
||
|
@@ -889,13 +888,6 @@ class RunMicrotasksDescriptor final : public CallInterfaceDescriptor {
|
||
|
0)
|
||
|
};
|
||
|
|
||
|
-class PromiseReactionHandlerDescriptor final : public CallInterfaceDescriptor {
|
||
|
- public:
|
||
|
- DEFINE_PARAMETERS(kArgument, kGenerator)
|
||
|
- DECLARE_DEFAULT_DESCRIPTOR(PromiseReactionHandlerDescriptor,
|
||
|
- CallInterfaceDescriptor, 2)
|
||
|
-};
|
||
|
-
|
||
|
#define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, ...) \
|
||
|
class Name##Descriptor : public CallInterfaceDescriptor { \
|
||
|
public: \
|
||
|
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
||
|
index 29ad2c2a82f..744c6614f7a 100644
|
||
|
--- a/src/interpreter/bytecode-generator.cc
|
||
|
+++ b/src/interpreter/bytecode-generator.cc
|
||
|
@@ -3239,20 +3239,22 @@ void BytecodeGenerator::BuildAwait(Expression* await_expr) {
|
||
|
// Await(operand) and suspend.
|
||
|
RegisterAllocationScope register_scope(this);
|
||
|
|
||
|
- Runtime::FunctionId id;
|
||
|
+ int await_builtin_context_index;
|
||
|
RegisterList args;
|
||
|
if (IsAsyncGeneratorFunction(function_kind())) {
|
||
|
- id = catch_prediction() == HandlerTable::ASYNC_AWAIT
|
||
|
- ? Runtime::kInlineAsyncGeneratorAwaitUncaught
|
||
|
- : Runtime::kInlineAsyncGeneratorAwaitCaught;
|
||
|
+ await_builtin_context_index =
|
||
|
+ catch_prediction() == HandlerTable::ASYNC_AWAIT
|
||
|
+ ? Context::ASYNC_GENERATOR_AWAIT_UNCAUGHT
|
||
|
+ : Context::ASYNC_GENERATOR_AWAIT_CAUGHT;
|
||
|
args = register_allocator()->NewRegisterList(2);
|
||
|
builder()
|
||
|
->MoveRegister(generator_object(), args[0])
|
||
|
.StoreAccumulatorInRegister(args[1]);
|
||
|
} else {
|
||
|
- id = catch_prediction() == HandlerTable::ASYNC_AWAIT
|
||
|
- ? Runtime::kInlineAsyncFunctionAwaitUncaught
|
||
|
- : Runtime::kInlineAsyncFunctionAwaitCaught;
|
||
|
+ await_builtin_context_index =
|
||
|
+ catch_prediction() == HandlerTable::ASYNC_AWAIT
|
||
|
+ ? Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX
|
||
|
+ : Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX;
|
||
|
args = register_allocator()->NewRegisterList(3);
|
||
|
builder()
|
||
|
->MoveRegister(generator_object(), args[0])
|
||
|
@@ -3265,7 +3267,7 @@ void BytecodeGenerator::BuildAwait(Expression* await_expr) {
|
||
|
builder()->StoreAccumulatorInRegister(args[2]);
|
||
|
}
|
||
|
|
||
|
- builder()->CallRuntime(id, args);
|
||
|
+ builder()->CallJSRuntime(await_builtin_context_index, args);
|
||
|
}
|
||
|
|
||
|
BuildSuspendPoint(await_expr);
|
||
|
diff --git a/src/interpreter/interpreter-intrinsics-generator.cc b/src/interpreter/interpreter-intrinsics-generator.cc
|
||
|
index 675a8bcccc7..0480dec6cc6 100644
|
||
|
--- a/src/interpreter/interpreter-intrinsics-generator.cc
|
||
|
+++ b/src/interpreter/interpreter-intrinsics-generator.cc
|
||
|
@@ -402,30 +402,6 @@ Node* IntrinsicsGenerator::GetImportMetaObject(
|
||
|
return return_value.value();
|
||
|
}
|
||
|
|
||
|
-Node* IntrinsicsGenerator::AsyncFunctionAwaitCaught(
|
||
|
- const InterpreterAssembler::RegListNodePair& args, Node* context) {
|
||
|
- return IntrinsicAsBuiltinCall(args, context,
|
||
|
- Builtins::kAsyncFunctionAwaitCaught);
|
||
|
-}
|
||
|
-
|
||
|
-Node* IntrinsicsGenerator::AsyncFunctionAwaitUncaught(
|
||
|
- const InterpreterAssembler::RegListNodePair& args, Node* context) {
|
||
|
- return IntrinsicAsBuiltinCall(args, context,
|
||
|
- Builtins::kAsyncFunctionAwaitUncaught);
|
||
|
-}
|
||
|
-
|
||
|
-Node* IntrinsicsGenerator::AsyncGeneratorAwaitCaught(
|
||
|
- const InterpreterAssembler::RegListNodePair& args, Node* context) {
|
||
|
- return IntrinsicAsBuiltinCall(args, context,
|
||
|
- Builtins::kAsyncGeneratorAwaitCaught);
|
||
|
-}
|
||
|
-
|
||
|
-Node* IntrinsicsGenerator::AsyncGeneratorAwaitUncaught(
|
||
|
- const InterpreterAssembler::RegListNodePair& args, Node* context) {
|
||
|
- return IntrinsicAsBuiltinCall(args, context,
|
||
|
- Builtins::kAsyncGeneratorAwaitUncaught);
|
||
|
-}
|
||
|
-
|
||
|
Node* IntrinsicsGenerator::AsyncGeneratorReject(
|
||
|
const InterpreterAssembler::RegListNodePair& args, Node* context) {
|
||
|
return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncGeneratorReject);
|
||
|
diff --git a/src/interpreter/interpreter-intrinsics.h b/src/interpreter/interpreter-intrinsics.h
|
||
|
index 6cdfec2d04f..3016183c0b9 100644
|
||
|
--- a/src/interpreter/interpreter-intrinsics.h
|
||
|
+++ b/src/interpreter/interpreter-intrinsics.h
|
||
|
@@ -14,10 +14,6 @@ namespace interpreter {
|
||
|
// List of supported intrisics, with upper case name, lower case name and
|
||
|
// expected number of arguments (-1 denoting argument count is variable).
|
||
|
#define INTRINSICS_LIST(V) \
|
||
|
- V(AsyncFunctionAwaitCaught, async_function_await_caught, 3) \
|
||
|
- V(AsyncFunctionAwaitUncaught, async_function_await_uncaught, 3) \
|
||
|
- V(AsyncGeneratorAwaitCaught, async_generator_await_caught, 2) \
|
||
|
- V(AsyncGeneratorAwaitUncaught, async_generator_await_uncaught, 2) \
|
||
|
V(AsyncGeneratorReject, async_generator_reject, 2) \
|
||
|
V(AsyncGeneratorResolve, async_generator_resolve, 3) \
|
||
|
V(AsyncGeneratorYield, async_generator_yield, 3) \
|
||
|
diff --git a/src/isolate.cc b/src/isolate.cc
|
||
|
index adb30b12ace..2c4e22726d7 100644
|
||
|
--- a/src/isolate.cc
|
||
|
+++ b/src/isolate.cc
|
||
|
@@ -2048,7 +2048,6 @@ void Isolate::PopPromise() {
|
||
|
}
|
||
|
|
||
|
namespace {
|
||
|
-
|
||
|
bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate,
|
||
|
Handle<JSPromise> promise);
|
||
|
|
||
|
@@ -2095,27 +2094,29 @@ bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate,
|
||
|
}
|
||
|
|
||
|
if (promise->status() == Promise::kPending) {
|
||
|
- Handle<Object> current(promise->reactions(), isolate);
|
||
|
- while (!current->IsSmi()) {
|
||
|
- Handle<PromiseReaction> current_reaction =
|
||
|
- Handle<PromiseReaction>::cast(current);
|
||
|
- Handle<HeapObject> payload(current_reaction->payload(), isolate);
|
||
|
- Handle<JSPromise> current_promise;
|
||
|
- if (JSPromise::From(payload).ToHandle(¤t_promise)) {
|
||
|
- if (current_reaction->reject_handler()->IsCallable()) {
|
||
|
- Handle<JSReceiver> current_handler(
|
||
|
- JSReceiver::cast(current_reaction->reject_handler()), isolate);
|
||
|
- if (PromiseHandlerCheck(isolate, current_handler, current_promise)) {
|
||
|
- return true;
|
||
|
- }
|
||
|
- } else {
|
||
|
- if (InternalPromiseHasUserDefinedRejectHandler(isolate,
|
||
|
- current_promise)) {
|
||
|
- return true;
|
||
|
- }
|
||
|
+ for (Handle<Object> current(promise->reactions(), isolate);
|
||
|
+ !current->IsSmi();) {
|
||
|
+ Handle<PromiseReaction> reaction = Handle<PromiseReaction>::cast(current);
|
||
|
+ Handle<HeapObject> promise_or_capability(
|
||
|
+ reaction->promise_or_capability(), isolate);
|
||
|
+ Handle<JSPromise> promise = Handle<JSPromise>::cast(
|
||
|
+ promise_or_capability->IsJSPromise()
|
||
|
+ ? promise_or_capability
|
||
|
+ : handle(Handle<PromiseCapability>::cast(promise_or_capability)
|
||
|
+ ->promise(),
|
||
|
+ isolate));
|
||
|
+ if (reaction->reject_handler()->IsUndefined(isolate)) {
|
||
|
+ if (InternalPromiseHasUserDefinedRejectHandler(isolate, promise)) {
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ Handle<JSReceiver> current_handler(
|
||
|
+ JSReceiver::cast(reaction->reject_handler()), isolate);
|
||
|
+ if (PromiseHandlerCheck(isolate, current_handler, promise)) {
|
||
|
+ return true;
|
||
|
}
|
||
|
}
|
||
|
- current = handle(current_reaction->next(), isolate);
|
||
|
+ current = handle(reaction->next(), isolate);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/src/isolate.h b/src/isolate.h
|
||
|
index 75b447f1629..82d33033737 100644
|
||
|
--- a/src/isolate.h
|
||
|
+++ b/src/isolate.h
|
||
|
@@ -1096,10 +1096,7 @@ class Isolate {
|
||
|
bool IsPromiseResolveLookupChainIntact();
|
||
|
|
||
|
// Make sure a lookup of "then" on any JSPromise whose [[Prototype]] is the
|
||
|
- // initial %PromisePrototype% yields the initial method. In addition this
|
||
|
- // protector also guards the negative lookup of "then" on the intrinsic
|
||
|
- // %ObjectPrototype%, meaning that such lookups are guaranteed to yield
|
||
|
- // undefined without triggering any side-effects.
|
||
|
+ // initial %PromisePrototype% yields the initial method.
|
||
|
bool IsPromiseThenLookupChainIntact();
|
||
|
bool IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver);
|
||
|
|
||
|
diff --git a/src/lookup.cc b/src/lookup.cc
|
||
|
index 20501149947..a4cca33d6c3 100644
|
||
|
--- a/src/lookup.cc
|
||
|
+++ b/src/lookup.cc
|
||
|
@@ -364,14 +364,7 @@ void LookupIterator::InternalUpdateProtector() {
|
||
|
if (!isolate_->IsPromiseThenLookupChainIntact()) return;
|
||
|
// Setting the "then" property on any JSPromise instance or on the
|
||
|
// initial %PromisePrototype% invalidates the Promise#then protector.
|
||
|
- // Also setting the "then" property on the initial %ObjectPrototype%
|
||
|
- // invalidates the Promise#then protector, since we use this protector
|
||
|
- // to guard the fast-path in AsyncGeneratorResolve, where we can skip
|
||
|
- // the ResolvePromise step and go directly to FulfillPromise if we
|
||
|
- // know that the Object.prototype doesn't contain a "then" method.
|
||
|
if (holder_->IsJSPromise() ||
|
||
|
- isolate_->IsInAnyContext(*holder_,
|
||
|
- Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ||
|
||
|
isolate_->IsInAnyContext(*holder_, Context::PROMISE_PROTOTYPE_INDEX)) {
|
||
|
isolate_->InvalidatePromiseThenProtector();
|
||
|
}
|
||
|
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
|
||
|
index c735cc0813c..086078bb251 100644
|
||
|
--- a/src/objects-debug.cc
|
||
|
+++ b/src/objects-debug.cc
|
||
|
@@ -1172,13 +1172,10 @@ void PromiseReactionJobTask::PromiseReactionJobTaskVerify() {
|
||
|
VerifyHeapPointer(context());
|
||
|
CHECK(context()->IsContext());
|
||
|
VerifyHeapPointer(handler());
|
||
|
- VerifyHeapPointer(payload());
|
||
|
- if (handler()->IsCode()) {
|
||
|
- CHECK(payload()->IsJSReceiver());
|
||
|
- } else {
|
||
|
- CHECK(handler()->IsUndefined(isolate) || handler()->IsCallable());
|
||
|
- CHECK(payload()->IsJSPromise() || payload()->IsPromiseCapability());
|
||
|
- }
|
||
|
+ CHECK(handler()->IsUndefined(isolate) || handler()->IsCallable());
|
||
|
+ VerifyHeapPointer(promise_or_capability());
|
||
|
+ CHECK(promise_or_capability()->IsJSPromise() ||
|
||
|
+ promise_or_capability()->IsPromiseCapability());
|
||
|
}
|
||
|
|
||
|
void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskVerify() {
|
||
|
@@ -1220,18 +1217,14 @@ void PromiseReaction::PromiseReactionVerify() {
|
||
|
VerifyPointer(next());
|
||
|
CHECK(next()->IsSmi() || next()->IsPromiseReaction());
|
||
|
VerifyHeapPointer(reject_handler());
|
||
|
+ CHECK(reject_handler()->IsUndefined(isolate) ||
|
||
|
+ reject_handler()->IsCallable());
|
||
|
VerifyHeapPointer(fulfill_handler());
|
||
|
- VerifyHeapPointer(payload());
|
||
|
- if (reject_handler()->IsCode()) {
|
||
|
- CHECK(fulfill_handler()->IsCode());
|
||
|
- CHECK(payload()->IsJSReceiver());
|
||
|
- } else {
|
||
|
- CHECK(reject_handler()->IsUndefined(isolate) ||
|
||
|
- reject_handler()->IsCallable());
|
||
|
- CHECK(fulfill_handler()->IsUndefined(isolate) ||
|
||
|
- fulfill_handler()->IsCallable());
|
||
|
- CHECK(payload()->IsJSPromise() || payload()->IsPromiseCapability());
|
||
|
- }
|
||
|
+ CHECK(fulfill_handler()->IsUndefined(isolate) ||
|
||
|
+ fulfill_handler()->IsCallable());
|
||
|
+ VerifyHeapPointer(promise_or_capability());
|
||
|
+ CHECK(promise_or_capability()->IsJSPromise() ||
|
||
|
+ promise_or_capability()->IsPromiseCapability());
|
||
|
}
|
||
|
|
||
|
void JSPromise::JSPromiseVerify() {
|
||
|
diff --git a/src/objects-inl.h b/src/objects-inl.h
|
||
|
index bda031e0637..297e9fc836d 100644
|
||
|
--- a/src/objects-inl.h
|
||
|
+++ b/src/objects-inl.h
|
||
|
@@ -2278,7 +2278,7 @@ ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
|
||
|
ACCESSORS(AccessorInfo, name, Name, kNameOffset)
|
||
|
SMI_ACCESSORS(AccessorInfo, flags, kFlagsOffset)
|
||
|
ACCESSORS(AccessorInfo, expected_receiver_type, Object,
|
||
|
- kExpectedReceiverTypeOffset)
|
||
|
+ kExpectedReceiverTypeOffset)
|
||
|
|
||
|
ACCESSORS_CHECKED2(AccessorInfo, getter, Object, kGetterOffset, true,
|
||
|
Foreign::IsNormalized(value))
|
||
|
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
|
||
|
index 942b9de0ba2..8d20279b2f1 100644
|
||
|
--- a/src/objects-printer.cc
|
||
|
+++ b/src/objects-printer.cc
|
||
|
@@ -1441,7 +1441,7 @@ void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskPrint(
|
||
|
os << "\n - argument: " << Brief(argument());
|
||
|
os << "\n - context: " << Brief(context());
|
||
|
os << "\n - handler: " << Brief(handler());
|
||
|
- os << "\n - payload: " << Brief(payload());
|
||
|
+ os << "\n - promise_or_capability: " << Brief(promise_or_capability());
|
||
|
os << "\n";
|
||
|
}
|
||
|
|
||
|
@@ -1451,7 +1451,7 @@ void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskPrint(
|
||
|
os << "\n - argument: " << Brief(argument());
|
||
|
os << "\n - context: " << Brief(context());
|
||
|
os << "\n - handler: " << Brief(handler());
|
||
|
- os << "\n - payload: " << Brief(payload());
|
||
|
+ os << "\n - promise_or_capability: " << Brief(promise_or_capability());
|
||
|
os << "\n";
|
||
|
}
|
||
|
|
||
|
@@ -1478,7 +1478,7 @@ void PromiseReaction::PromiseReactionPrint(std::ostream& os) { // NOLINT
|
||
|
os << "\n - next: " << Brief(next());
|
||
|
os << "\n - reject_handler: " << Brief(reject_handler());
|
||
|
os << "\n - fulfill_handler: " << Brief(fulfill_handler());
|
||
|
- os << "\n - payload: " << Brief(payload());
|
||
|
+ os << "\n - promise_or_capability: " << Brief(promise_or_capability());
|
||
|
os << "\n";
|
||
|
}
|
||
|
|
||
|
diff --git a/src/objects.cc b/src/objects.cc
|
||
|
index 8057cb837b1..6565910fd3f 100644
|
||
|
--- a/src/objects.cc
|
||
|
+++ b/src/objects.cc
|
||
|
@@ -16054,27 +16054,6 @@ MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise,
|
||
|
return isolate->factory()->undefined_value();
|
||
|
}
|
||
|
|
||
|
-// static
|
||
|
-MaybeHandle<JSPromise> JSPromise::From(Handle<HeapObject> object) {
|
||
|
- Isolate* const isolate = object->GetIsolate();
|
||
|
- if (object->IsJSPromise()) {
|
||
|
- return Handle<JSPromise>::cast(object);
|
||
|
- } else if (object->IsPromiseCapability()) {
|
||
|
- Handle<PromiseCapability> capability =
|
||
|
- Handle<PromiseCapability>::cast(object);
|
||
|
- if (capability->promise()->IsJSPromise()) {
|
||
|
- return handle(JSPromise::cast(capability->promise()), isolate);
|
||
|
- }
|
||
|
- } else if (object->IsJSGeneratorObject()) {
|
||
|
- Handle<JSGeneratorObject> generator =
|
||
|
- Handle<JSGeneratorObject>::cast(object);
|
||
|
- Handle<Object> handled_by = JSObject::GetDataProperty(
|
||
|
- generator, isolate->factory()->generator_outer_promise_symbol());
|
||
|
- if (handled_by->IsJSPromise()) return Handle<JSPromise>::cast(handled_by);
|
||
|
- }
|
||
|
- return MaybeHandle<JSPromise>();
|
||
|
-}
|
||
|
-
|
||
|
// static
|
||
|
Handle<Object> JSPromise::TriggerPromiseReactions(Isolate* isolate,
|
||
|
Handle<Object> reactions,
|
||
|
@@ -16114,8 +16093,8 @@ Handle<Object> JSPromise::TriggerPromiseReactions(Isolate* isolate,
|
||
|
*isolate->native_context());
|
||
|
STATIC_ASSERT(PromiseReaction::kFulfillHandlerOffset ==
|
||
|
PromiseFulfillReactionJobTask::kHandlerOffset);
|
||
|
- STATIC_ASSERT(PromiseReaction::kPayloadOffset ==
|
||
|
- PromiseFulfillReactionJobTask::kPayloadOffset);
|
||
|
+ STATIC_ASSERT(PromiseReaction::kPromiseOrCapabilityOffset ==
|
||
|
+ PromiseFulfillReactionJobTask::kPromiseOrCapabilityOffset);
|
||
|
} else {
|
||
|
DisallowHeapAllocation no_gc;
|
||
|
HeapObject* handler = reaction->reject_handler();
|
||
|
@@ -16125,8 +16104,8 @@ Handle<Object> JSPromise::TriggerPromiseReactions(Isolate* isolate,
|
||
|
Handle<PromiseRejectReactionJobTask>::cast(task)->set_context(
|
||
|
*isolate->native_context());
|
||
|
Handle<PromiseRejectReactionJobTask>::cast(task)->set_handler(handler);
|
||
|
- STATIC_ASSERT(PromiseReaction::kPayloadOffset ==
|
||
|
- PromiseRejectReactionJobTask::kPayloadOffset);
|
||
|
+ STATIC_ASSERT(PromiseReaction::kPromiseOrCapabilityOffset ==
|
||
|
+ PromiseRejectReactionJobTask::kPromiseOrCapabilityOffset);
|
||
|
}
|
||
|
|
||
|
isolate->EnqueueMicrotask(Handle<PromiseReactionJobTask>::cast(task));
|
||
|
diff --git a/src/objects/js-promise.h b/src/objects/js-promise.h
|
||
|
index 20a0a90131a..434bae89338 100644
|
||
|
--- a/src/objects/js-promise.h
|
||
|
+++ b/src/objects/js-promise.h
|
||
|
@@ -59,12 +59,6 @@ class JSPromise : public JSObject {
|
||
|
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Resolve(
|
||
|
Handle<JSPromise> promise, Handle<Object> resolution);
|
||
|
|
||
|
- // This is a helper that extracts the JSPromise from the input
|
||
|
- // {object}, which is used as a payload for PromiseReaction and
|
||
|
- // PromiseReactionJobTask.
|
||
|
- V8_WARN_UNUSED_RESULT static MaybeHandle<JSPromise> From(
|
||
|
- Handle<HeapObject> object);
|
||
|
-
|
||
|
DECL_CAST(JSPromise)
|
||
|
|
||
|
// Dispatched behavior.
|
||
|
diff --git a/src/objects/promise-inl.h b/src/objects/promise-inl.h
|
||
|
index 4283f0aa194..f9fb6110f34 100644
|
||
|
--- a/src/objects/promise-inl.h
|
||
|
+++ b/src/objects/promise-inl.h
|
||
|
@@ -23,7 +23,8 @@ CAST_ACCESSOR(PromiseResolveThenableJobTask)
|
||
|
ACCESSORS(PromiseReaction, next, Object, kNextOffset)
|
||
|
ACCESSORS(PromiseReaction, reject_handler, HeapObject, kRejectHandlerOffset)
|
||
|
ACCESSORS(PromiseReaction, fulfill_handler, HeapObject, kFulfillHandlerOffset)
|
||
|
-ACCESSORS(PromiseReaction, payload, HeapObject, kPayloadOffset)
|
||
|
+ACCESSORS(PromiseReaction, promise_or_capability, HeapObject,
|
||
|
+ kPromiseOrCapabilityOffset)
|
||
|
|
||
|
ACCESSORS(PromiseResolveThenableJobTask, context, Context, kContextOffset)
|
||
|
ACCESSORS(PromiseResolveThenableJobTask, promise_to_resolve, JSPromise,
|
||
|
@@ -34,7 +35,8 @@ ACCESSORS(PromiseResolveThenableJobTask, thenable, JSReceiver, kThenableOffset)
|
||
|
ACCESSORS(PromiseReactionJobTask, context, Context, kContextOffset)
|
||
|
ACCESSORS(PromiseReactionJobTask, argument, Object, kArgumentOffset);
|
||
|
ACCESSORS(PromiseReactionJobTask, handler, HeapObject, kHandlerOffset);
|
||
|
-ACCESSORS(PromiseReactionJobTask, payload, HeapObject, kPayloadOffset);
|
||
|
+ACCESSORS(PromiseReactionJobTask, promise_or_capability, HeapObject,
|
||
|
+ kPromiseOrCapabilityOffset);
|
||
|
|
||
|
ACCESSORS(PromiseCapability, promise, HeapObject, kPromiseOffset)
|
||
|
ACCESSORS(PromiseCapability, resolve, Object, kResolveOffset)
|
||
|
diff --git a/src/objects/promise.h b/src/objects/promise.h
|
||
|
index 36ef4afe1d6..5ff5dac6f37 100644
|
||
|
--- a/src/objects/promise.h
|
||
|
+++ b/src/objects/promise.h
|
||
|
@@ -26,16 +26,15 @@ class PromiseReactionJobTask : public Microtask {
|
||
|
public:
|
||
|
DECL_ACCESSORS(argument, Object)
|
||
|
DECL_ACCESSORS(context, Context)
|
||
|
- // [handler]: This is either a Code object, a Callable or Undefined.
|
||
|
DECL_ACCESSORS(handler, HeapObject)
|
||
|
- // [payload]: Usually a JSPromise or a PromiseCapability.
|
||
|
- DECL_ACCESSORS(payload, HeapObject)
|
||
|
+ // [promise_or_capability]: Either a JSPromise or a PromiseCapability.
|
||
|
+ DECL_ACCESSORS(promise_or_capability, HeapObject)
|
||
|
|
||
|
static const int kArgumentOffset = Microtask::kHeaderSize;
|
||
|
static const int kContextOffset = kArgumentOffset + kPointerSize;
|
||
|
static const int kHandlerOffset = kContextOffset + kPointerSize;
|
||
|
- static const int kPayloadOffset = kHandlerOffset + kPointerSize;
|
||
|
- static const int kSize = kPayloadOffset + kPointerSize;
|
||
|
+ static const int kPromiseOrCapabilityOffset = kHandlerOffset + kPointerSize;
|
||
|
+ static const int kSize = kPromiseOrCapabilityOffset + kPointerSize;
|
||
|
|
||
|
// Dispatched behavior.
|
||
|
DECL_CAST(PromiseReactionJobTask)
|
||
|
@@ -121,10 +120,9 @@ class PromiseCapability : public Struct {
|
||
|
// of microtasks. So the size of PromiseReaction and the size of the
|
||
|
// PromiseReactionJobTask has to be same for this to work.
|
||
|
//
|
||
|
-// The PromiseReaction::payload field usually holds a JSPromise
|
||
|
-// instance (in the fast case of a native promise) or a PromiseCapability
|
||
|
-// in case of a custom promise. For await we store the JSGeneratorObject
|
||
|
-// here and use custom Code handlers.
|
||
|
+// The PromiseReaction::promise_or_capability field can either hold a JSPromise
|
||
|
+// instance (in the fast case of a native promise) or a PromiseCapability in
|
||
|
+// case of a Promise subclass.
|
||
|
//
|
||
|
// We need to keep the context in the PromiseReaction so that we can run
|
||
|
// the default handlers (in case they are undefined) in the proper context.
|
||
|
@@ -138,18 +136,16 @@ class PromiseReaction : public Struct {
|
||
|
enum Type { kFulfill, kReject };
|
||
|
|
||
|
DECL_ACCESSORS(next, Object)
|
||
|
- // [reject_handler]: This is either a Code object, a Callable or Undefined.
|
||
|
DECL_ACCESSORS(reject_handler, HeapObject)
|
||
|
- // [fulfill_handler]: This is either a Code object, a Callable or Undefined.
|
||
|
DECL_ACCESSORS(fulfill_handler, HeapObject)
|
||
|
- // [payload]: Usually a JSPromise or a PromiseCapability.
|
||
|
- DECL_ACCESSORS(payload, HeapObject)
|
||
|
+ DECL_ACCESSORS(promise_or_capability, HeapObject)
|
||
|
|
||
|
static const int kNextOffset = Struct::kHeaderSize;
|
||
|
static const int kRejectHandlerOffset = kNextOffset + kPointerSize;
|
||
|
static const int kFulfillHandlerOffset = kRejectHandlerOffset + kPointerSize;
|
||
|
- static const int kPayloadOffset = kFulfillHandlerOffset + kPointerSize;
|
||
|
- static const int kSize = kPayloadOffset + kPointerSize;
|
||
|
+ static const int kPromiseOrCapabilityOffset =
|
||
|
+ kFulfillHandlerOffset + kPointerSize;
|
||
|
+ static const int kSize = kPromiseOrCapabilityOffset + kPointerSize;
|
||
|
|
||
|
// Dispatched behavior.
|
||
|
DECL_CAST(PromiseReaction)
|
||
|
diff --git a/src/runtime/runtime-generator.cc b/src/runtime/runtime-generator.cc
|
||
|
index e69d3340426..3c7c808c30b 100644
|
||
|
--- a/src/runtime/runtime-generator.cc
|
||
|
+++ b/src/runtime/runtime-generator.cc
|
||
|
@@ -70,30 +70,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetInputOrDebugPos) {
|
||
|
UNREACHABLE();
|
||
|
}
|
||
|
|
||
|
-RUNTIME_FUNCTION(Runtime_AsyncFunctionAwaitCaught) {
|
||
|
- // Runtime call is implemented in InterpreterIntrinsics and lowered in
|
||
|
- // JSIntrinsicLowering
|
||
|
- UNREACHABLE();
|
||
|
-}
|
||
|
-
|
||
|
-RUNTIME_FUNCTION(Runtime_AsyncFunctionAwaitUncaught) {
|
||
|
- // Runtime call is implemented in InterpreterIntrinsics and lowered in
|
||
|
- // JSIntrinsicLowering
|
||
|
- UNREACHABLE();
|
||
|
-}
|
||
|
-
|
||
|
-RUNTIME_FUNCTION(Runtime_AsyncGeneratorAwaitCaught) {
|
||
|
- // Runtime call is implemented in InterpreterIntrinsics and lowered in
|
||
|
- // JSIntrinsicLowering
|
||
|
- UNREACHABLE();
|
||
|
-}
|
||
|
-
|
||
|
-RUNTIME_FUNCTION(Runtime_AsyncGeneratorAwaitUncaught) {
|
||
|
- // Runtime call is implemented in InterpreterIntrinsics and lowered in
|
||
|
- // JSIntrinsicLowering
|
||
|
- UNREACHABLE();
|
||
|
-}
|
||
|
-
|
||
|
RUNTIME_FUNCTION(Runtime_AsyncGeneratorResolve) {
|
||
|
// Runtime call is implemented in InterpreterIntrinsics and lowered in
|
||
|
// JSIntrinsicLowering
|
||
|
diff --git a/src/runtime/runtime-promise.cc b/src/runtime/runtime-promise.cc
|
||
|
index b2a7e8bae1b..f5b9db3c028 100644
|
||
|
--- a/src/runtime/runtime-promise.cc
|
||
|
+++ b/src/runtime/runtime-promise.cc
|
||
|
@@ -114,14 +114,13 @@ RUNTIME_FUNCTION(Runtime_PromiseHookInit) {
|
||
|
RUNTIME_FUNCTION(Runtime_PromiseHookBefore) {
|
||
|
HandleScope scope(isolate);
|
||
|
DCHECK_EQ(1, args.length());
|
||
|
- CONVERT_ARG_HANDLE_CHECKED(HeapObject, payload, 0);
|
||
|
- Handle<JSPromise> promise;
|
||
|
- if (JSPromise::From(payload).ToHandle(&promise)) {
|
||
|
- if (isolate->debug()->is_active()) isolate->PushPromise(promise);
|
||
|
- if (promise->IsJSPromise()) {
|
||
|
- isolate->RunPromiseHook(PromiseHookType::kBefore, promise,
|
||
|
- isolate->factory()->undefined_value());
|
||
|
- }
|
||
|
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, maybe_promise, 0);
|
||
|
+ if (!maybe_promise->IsJSPromise()) return isolate->heap()->undefined_value();
|
||
|
+ Handle<JSPromise> promise = Handle<JSPromise>::cast(maybe_promise);
|
||
|
+ if (isolate->debug()->is_active()) isolate->PushPromise(promise);
|
||
|
+ if (promise->IsJSPromise()) {
|
||
|
+ isolate->RunPromiseHook(PromiseHookType::kBefore, promise,
|
||
|
+ isolate->factory()->undefined_value());
|
||
|
}
|
||
|
return isolate->heap()->undefined_value();
|
||
|
}
|
||
|
@@ -129,14 +128,13 @@ RUNTIME_FUNCTION(Runtime_PromiseHookBefore) {
|
||
|
RUNTIME_FUNCTION(Runtime_PromiseHookAfter) {
|
||
|
HandleScope scope(isolate);
|
||
|
DCHECK_EQ(1, args.length());
|
||
|
- CONVERT_ARG_HANDLE_CHECKED(HeapObject, payload, 0);
|
||
|
- Handle<JSPromise> promise;
|
||
|
- if (JSPromise::From(payload).ToHandle(&promise)) {
|
||
|
- if (isolate->debug()->is_active()) isolate->PopPromise();
|
||
|
- if (promise->IsJSPromise()) {
|
||
|
- isolate->RunPromiseHook(PromiseHookType::kAfter, promise,
|
||
|
- isolate->factory()->undefined_value());
|
||
|
- }
|
||
|
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, maybe_promise, 0);
|
||
|
+ if (!maybe_promise->IsJSPromise()) return isolate->heap()->undefined_value();
|
||
|
+ Handle<JSPromise> promise = Handle<JSPromise>::cast(maybe_promise);
|
||
|
+ if (isolate->debug()->is_active()) isolate->PopPromise();
|
||
|
+ if (promise->IsJSPromise()) {
|
||
|
+ isolate->RunPromiseHook(PromiseHookType::kAfter, promise,
|
||
|
+ isolate->factory()->undefined_value());
|
||
|
}
|
||
|
return isolate->heap()->undefined_value();
|
||
|
}
|
||
|
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
|
||
|
index 48a63d500da..37ce74e8250 100644
|
||
|
--- a/src/runtime/runtime.h
|
||
|
+++ b/src/runtime/runtime.h
|
||
|
@@ -222,10 +222,6 @@ namespace internal {
|
||
|
F(SetNativeFlag, 1, 1)
|
||
|
|
||
|
#define FOR_EACH_INTRINSIC_GENERATOR(F) \
|
||
|
- F(AsyncFunctionAwaitCaught, 3, 1) \
|
||
|
- F(AsyncFunctionAwaitUncaught, 3, 1) \
|
||
|
- F(AsyncGeneratorAwaitCaught, 2, 1) \
|
||
|
- F(AsyncGeneratorAwaitUncaught, 2, 1) \
|
||
|
F(AsyncGeneratorHasCatchHandlerForPC, 1, 1) \
|
||
|
F(AsyncGeneratorReject, 2, 1) \
|
||
|
F(AsyncGeneratorResolve, 3, 1) \
|
||
|
diff --git a/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden b/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden
|
||
|
index df6b3723586..2b4eb6b2cc5 100644
|
||
|
--- a/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden
|
||
|
+++ b/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden
|
||
|
@@ -39,7 +39,7 @@ bytecodes: [
|
||
|
B(LdaUndefined),
|
||
|
B(Star), R(6),
|
||
|
B(Mov), R(0), R(5),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorAwaitUncaught), R(5), U8(2),
|
||
|
+ B(CallJSRuntime), U8(%async_generator_await_uncaught), R(5), U8(2),
|
||
|
B(SuspendGenerator), R(0), R(0), U8(5), U8(1),
|
||
|
B(ResumeGenerator), R(0), R(0), U8(5),
|
||
|
B(Star), R(5),
|
||
|
@@ -166,7 +166,7 @@ bytecodes: [
|
||
|
B(LdaUndefined),
|
||
|
B(Star), R(6),
|
||
|
B(Mov), R(0), R(5),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorAwaitUncaught), R(5), U8(2),
|
||
|
+ B(CallJSRuntime), U8(%async_generator_await_uncaught), R(5), U8(2),
|
||
|
B(SuspendGenerator), R(0), R(0), U8(5), U8(2),
|
||
|
B(ResumeGenerator), R(0), R(0), U8(5),
|
||
|
B(Star), R(5),
|
||
|
@@ -404,7 +404,7 @@ bytecodes: [
|
||
|
B(LdaUndefined),
|
||
|
B(Star), R(16),
|
||
|
B(Mov), R(2), R(15),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorAwaitUncaught), R(15), U8(2),
|
||
|
+ B(CallJSRuntime), U8(%async_generator_await_uncaught), R(15), U8(2),
|
||
|
B(SuspendGenerator), R(2), R(0), U8(15), U8(2),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(15),
|
||
|
B(Star), R(15),
|
||
|
@@ -580,7 +580,7 @@ bytecodes: [
|
||
|
B(Jump), U8(2),
|
||
|
B(Star), R(13),
|
||
|
B(Mov), R(0), R(12),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorAwaitUncaught), R(12), U8(2),
|
||
|
+ B(CallJSRuntime), U8(%async_generator_await_uncaught), R(12), U8(2),
|
||
|
/* 49 E> */ B(SuspendGenerator), R(0), R(0), U8(12), U8(1),
|
||
|
B(ResumeGenerator), R(0), R(0), U8(12),
|
||
|
B(Star), R(12),
|
||
|
@@ -598,7 +598,7 @@ bytecodes: [
|
||
|
B(CallRuntime), U16(Runtime::kThrowThrowMethodMissing), R(0), U8(0),
|
||
|
B(Star), R(13),
|
||
|
B(Mov), R(0), R(12),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorAwaitUncaught), R(12), U8(2),
|
||
|
+ B(CallJSRuntime), U8(%async_generator_await_uncaught), R(12), U8(2),
|
||
|
/* 49 E> */ B(SuspendGenerator), R(0), R(0), U8(12), U8(2),
|
||
|
B(ResumeGenerator), R(0), R(0), U8(12),
|
||
|
B(Star), R(12),
|
||
|
@@ -639,7 +639,7 @@ bytecodes: [
|
||
|
B(LdaUndefined),
|
||
|
B(Star), R(6),
|
||
|
B(Mov), R(0), R(5),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorAwaitUncaught), R(5), U8(2),
|
||
|
+ B(CallJSRuntime), U8(%async_generator_await_uncaught), R(5), U8(2),
|
||
|
B(SuspendGenerator), R(0), R(0), U8(5), U8(4),
|
||
|
B(ResumeGenerator), R(0), R(0), U8(5),
|
||
|
B(Star), R(5),
|
||
|
diff --git a/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden b/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden
|
||
|
index 95400dacf80..4d36315f027 100644
|
||
|
--- a/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden
|
||
|
+++ b/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden
|
||
|
@@ -53,7 +53,7 @@ bytecodes: [
|
||
|
B(Star), R(21),
|
||
|
B(Mov), R(2), R(20),
|
||
|
B(Mov), R(11), R(22),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(20), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_uncaught), R(20), U8(3),
|
||
|
/* 40 E> */ B(SuspendGenerator), R(2), R(0), U8(20), U8(0),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(20),
|
||
|
B(Star), R(20),
|
||
|
@@ -137,7 +137,7 @@ bytecodes: [
|
||
|
B(Star), R(21),
|
||
|
B(Mov), R(2), R(20),
|
||
|
B(Mov), R(11), R(22),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitCaught), R(20), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_caught), R(20), U8(3),
|
||
|
B(SuspendGenerator), R(2), R(0), U8(20), U8(1),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(20),
|
||
|
B(Star), R(20),
|
||
|
@@ -160,7 +160,7 @@ bytecodes: [
|
||
|
B(Star), R(20),
|
||
|
B(Mov), R(2), R(19),
|
||
|
B(Mov), R(11), R(21),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(19), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_uncaught), R(19), U8(3),
|
||
|
B(SuspendGenerator), R(2), R(0), U8(19), U8(2),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(19),
|
||
|
B(Star), R(19),
|
||
|
@@ -306,7 +306,7 @@ bytecodes: [
|
||
|
B(Star), R(21),
|
||
|
B(Mov), R(2), R(20),
|
||
|
B(Mov), R(11), R(22),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(20), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_uncaught), R(20), U8(3),
|
||
|
/* 40 E> */ B(SuspendGenerator), R(2), R(0), U8(20), U8(0),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(20),
|
||
|
B(Star), R(20),
|
||
|
@@ -391,7 +391,7 @@ bytecodes: [
|
||
|
B(Star), R(21),
|
||
|
B(Mov), R(2), R(20),
|
||
|
B(Mov), R(11), R(22),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitCaught), R(20), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_caught), R(20), U8(3),
|
||
|
B(SuspendGenerator), R(2), R(0), U8(20), U8(1),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(20),
|
||
|
B(Star), R(20),
|
||
|
@@ -414,7 +414,7 @@ bytecodes: [
|
||
|
B(Star), R(20),
|
||
|
B(Mov), R(2), R(19),
|
||
|
B(Mov), R(11), R(21),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(19), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_uncaught), R(19), U8(3),
|
||
|
B(SuspendGenerator), R(2), R(0), U8(19), U8(2),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(19),
|
||
|
B(Star), R(19),
|
||
|
@@ -575,7 +575,7 @@ bytecodes: [
|
||
|
B(Star), R(21),
|
||
|
B(Mov), R(2), R(20),
|
||
|
B(Mov), R(11), R(22),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(20), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_uncaught), R(20), U8(3),
|
||
|
/* 40 E> */ B(SuspendGenerator), R(2), R(0), U8(20), U8(0),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(20),
|
||
|
B(Star), R(20),
|
||
|
@@ -667,7 +667,7 @@ bytecodes: [
|
||
|
B(Star), R(21),
|
||
|
B(Mov), R(2), R(20),
|
||
|
B(Mov), R(11), R(22),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitCaught), R(20), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_caught), R(20), U8(3),
|
||
|
B(SuspendGenerator), R(2), R(0), U8(20), U8(1),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(20),
|
||
|
B(Star), R(20),
|
||
|
@@ -690,7 +690,7 @@ bytecodes: [
|
||
|
B(Star), R(20),
|
||
|
B(Mov), R(2), R(19),
|
||
|
B(Mov), R(11), R(21),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(19), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_uncaught), R(19), U8(3),
|
||
|
B(SuspendGenerator), R(2), R(0), U8(19), U8(2),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(19),
|
||
|
B(Star), R(19),
|
||
|
diff --git a/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden b/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden
|
||
|
index 1a0155da79c..f92076e6e65 100644
|
||
|
--- a/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden
|
||
|
+++ b/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden
|
||
|
@@ -1196,7 +1196,7 @@ bytecodes: [
|
||
|
/* 45 S> */ B(Mov), R(2), R(21),
|
||
|
B(Mov), R(0), R(22),
|
||
|
B(Mov), R(11), R(23),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(21), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_uncaught), R(21), U8(3),
|
||
|
/* 45 E> */ B(SuspendGenerator), R(2), R(0), U8(21), U8(0),
|
||
|
B(ResumeGenerator), R(2), R(0), U8(21),
|
||
|
B(Star), R(21),
|
||
|
diff --git a/test/cctest/interpreter/bytecode_expectations/StandardForLoop.golden b/test/cctest/interpreter/bytecode_expectations/StandardForLoop.golden
|
||
|
index 80609db7b80..7edf446ce33 100644
|
||
|
--- a/test/cctest/interpreter/bytecode_expectations/StandardForLoop.golden
|
||
|
+++ b/test/cctest/interpreter/bytecode_expectations/StandardForLoop.golden
|
||
|
@@ -493,7 +493,7 @@ bytecodes: [
|
||
|
/* 52 S> */ B(Mov), R(1), R(7),
|
||
|
B(Mov), R(0), R(8),
|
||
|
B(Mov), R(2), R(9),
|
||
|
- B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(7), U8(3),
|
||
|
+ B(CallJSRuntime), U8(%async_function_await_uncaught), R(7), U8(3),
|
||
|
/* 52 E> */ B(SuspendGenerator), R(1), R(0), U8(7), U8(0),
|
||
|
B(ResumeGenerator), R(1), R(0), U8(7),
|
||
|
B(Star), R(7),
|
||
|
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
||
|
index 2f552a9d9d9..8b93944d933 100644
|
||
|
--- a/test/cctest/test-api.cc
|
||
|
+++ b/test/cctest/test-api.cc
|
||
|
@@ -18358,12 +18358,6 @@ TEST(PromiseHook) {
|
||
|
CHECK_EQ(v8::Promise::kFulfilled, GetPromise("p")->State());
|
||
|
CHECK_EQ(9, promise_hook_data->promise_hook_count);
|
||
|
|
||
|
- promise_hook_data->Reset();
|
||
|
- source = "(async() => await p)();\n";
|
||
|
-
|
||
|
- CompileRun(source);
|
||
|
- CHECK_EQ(11, promise_hook_data->promise_hook_count);
|
||
|
-
|
||
|
delete promise_hook_data;
|
||
|
isolate->SetPromiseHook(nullptr);
|
||
|
}
|
||
|
diff --git a/tools/v8heapconst.py b/tools/v8heapconst.py
|
||
|
index 1e57ce64a9e..e3b29f82042 100644
|
||
|
--- a/tools/v8heapconst.py
|
||
|
+++ b/tools/v8heapconst.py
|
||
|
@@ -263,12 +263,12 @@
|
||
|
("MAP_SPACE", 0x04511): (173, "Tuple2Map"),
|
||
|
("MAP_SPACE", 0x04569): (171, "ScriptMap"),
|
||
|
("MAP_SPACE", 0x045c1): (163, "InterceptorInfoMap"),
|
||
|
- ("MAP_SPACE", 0x04619): (154, "AccessorInfoMap"),
|
||
|
- ("MAP_SPACE", 0x04671): (153, "AccessCheckInfoMap"),
|
||
|
- ("MAP_SPACE", 0x046c9): (155, "AccessorPairMap"),
|
||
|
- ("MAP_SPACE", 0x04721): (156, "AliasedArgumentsEntryMap"),
|
||
|
- ("MAP_SPACE", 0x04779): (157, "AllocationMementoMap"),
|
||
|
- ("MAP_SPACE", 0x047d1): (158, "AllocationSiteMap"),
|
||
|
+ ("MAP_SPACE", 0x04619): (158, "AllocationSiteMap"),
|
||
|
+ ("MAP_SPACE", 0x04671): (154, "AccessorInfoMap"),
|
||
|
+ ("MAP_SPACE", 0x046c9): (153, "AccessCheckInfoMap"),
|
||
|
+ ("MAP_SPACE", 0x04721): (155, "AccessorPairMap"),
|
||
|
+ ("MAP_SPACE", 0x04779): (156, "AliasedArgumentsEntryMap"),
|
||
|
+ ("MAP_SPACE", 0x047d1): (157, "AllocationMementoMap"),
|
||
|
("MAP_SPACE", 0x04829): (159, "AsyncGeneratorRequestMap"),
|
||
|
("MAP_SPACE", 0x04881): (160, "ContextExtensionMap"),
|
||
|
("MAP_SPACE", 0x048d9): (161, "DebugInfoMap"),
|
||
|
@@ -366,4 +366,4 @@
|
||
|
"NATIVE",
|
||
|
)
|
||
|
|
||
|
-# This set of constants is generated from a shipping build.
|
||
|
+# This set of constants is generated from a non-shipping build.
|