Commit feb545ce authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[async-generators] Also avoid throwaway promise here.

This extends the previously introduced logic for implementing await
without having to allocate the throwaway promise and the additional
closures and context, to also cover await and yield inside of async
generators.

Bug: v8:7253
Change-Id: I011583a7714bbd148c54e5f204e2076630008db0
Reviewed-on: https://chromium-review.googlesource.com/924003
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51361}
parent 4a90e486
...@@ -1615,38 +1615,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, ...@@ -1615,38 +1615,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
SimpleCreateFunction(isolate, factory->empty_string(), SimpleCreateFunction(isolate, factory->empty_string(),
Builtins::kAsyncGeneratorAwaitUncaught, 1, false); Builtins::kAsyncGeneratorAwaitUncaught, 1, false);
native_context()->set_async_generator_await_uncaught(*await_uncaught); 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 --- { // --- A r r a y ---
......
...@@ -88,39 +88,9 @@ void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait( ...@@ -88,39 +88,9 @@ void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait(
CSA_SLOW_ASSERT(this, IsJSGeneratorObject(generator)); CSA_SLOW_ASSERT(this, IsJSGeneratorObject(generator));
CSA_SLOW_ASSERT(this, IsJSPromise(outer_promise)); CSA_SLOW_ASSERT(this, IsJSPromise(outer_promise));
Node* const native_context = LoadNativeContext(context); Await(context, generator, awaited, outer_promise,
Node* const promise = AllocateAndInitJSPromise(native_context); Builtins::kAsyncFunctionAwaitFulfill,
Builtins::kAsyncFunctionAwaitReject, is_predicted_as_caught);
Node* const promise_reactions =
LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
Node* const fulfill_handler = HeapConstant(
Builtins::CallableFor(isolate(), Builtins::kAsyncFunctionAwaitFulfill)
.code());
Node* const reject_handler = HeapConstant(
Builtins::CallableFor(isolate(), Builtins::kAsyncFunctionAwaitReject)
.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, awaited);
{
Label done(this);
GotoIfNot(IsDebugActive(), &done);
CallRuntime(Runtime::kSetProperty, native_context, generator,
LoadRoot(Heap::kgenerator_outer_promise_symbolRootIndex),
outer_promise, SmiConstant(LanguageMode::kStrict));
if (is_predicted_as_caught) {
GotoIf(TaggedIsSmi(awaited), &done);
GotoIfNot(IsJSPromise(awaited), &done);
PromiseSetHandledHint(awaited);
}
Goto(&done);
BIND(&done);
}
// Return outer promise to avoid adding an load of the outer promise before // Return outer promise to avoid adding an load of the outer promise before
// suspending in BytecodeGenerator. // suspending in BytecodeGenerator.
......
...@@ -13,6 +13,58 @@ namespace internal { ...@@ -13,6 +13,58 @@ namespace internal {
using compiler::Node; 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(IsDebugActive(), &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 { namespace {
// Describe fields of Context associated with the AsyncIterator unwrap closure. // Describe fields of Context associated with the AsyncIterator unwrap closure.
class ValueUnwrapContext { class ValueUnwrapContext {
...@@ -22,162 +74,6 @@ class ValueUnwrapContext { ...@@ -22,162 +74,6 @@ class ValueUnwrapContext {
} // namespace } // 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::kFeedbackVectorOffset,
Heap::kUndefinedCellRootIndex);
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 =
LoadObjectField(shared_info, SharedFunctionInfo::kCodeOffset);
StoreObjectFieldNoWriteBarrier(function, JSFunction::kCodeOffset, code);
}
Node* AsyncBuiltinsAssembler::CreateUnwrapClosure(Node* native_context, Node* AsyncBuiltinsAssembler::CreateUnwrapClosure(Node* native_context,
Node* done) { Node* done) {
Node* const map = LoadContextElement( Node* const map = LoadContextElement(
......
...@@ -16,48 +16,23 @@ class AsyncBuiltinsAssembler : public PromiseBuiltinsAssembler { ...@@ -16,48 +16,23 @@ class AsyncBuiltinsAssembler : public PromiseBuiltinsAssembler {
: PromiseBuiltinsAssembler(state) {} : PromiseBuiltinsAssembler(state) {}
protected: protected:
typedef std::function<void(Node*)> ContextInitializer; void Await(Node* context, Node* generator, Node* value, Node* outer_promise,
Builtins::Name fulfill_builtin, Builtins::Name reject_builtin,
// Perform steps to resume generator after `value` is resolved. Node* is_predicted_as_caught);
// `on_reject_context_index` is an index into the Native Context, which should void Await(Node* context, Node* generator, Node* value, Node* outer_promise,
// point to a SharedFunctioninfo instance used to create the closure. The Builtins::Name fulfill_builtin, Builtins::Name reject_builtin,
// value following the reject index should be a similar value for the resolve bool is_predicted_as_caught);
// 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 // Return a new built-in function object as defined in
// Async Iterator Value Unwrap Functions // Async Iterator Value Unwrap Functions
Node* CreateUnwrapClosure(Node* const native_context, Node* const done); Node* CreateUnwrapClosure(Node* const native_context, Node* const done);
private: private:
void InitializeNativeClosure(Node* context, Node* native_context,
Node* function, Node* context_index);
Node* AllocateAsyncIteratorValueUnwrapContext(Node* native_context, Node* AllocateAsyncIteratorValueUnwrapContext(Node* native_context,
Node* done); Node* done);
Node* AllocateAwaitPromiseJobTask(Node* generator, Node* fulfill_handler,
Node* reject_handler, Node* promise,
Node* context);
}; };
} // namespace internal } // namespace internal
......
...@@ -1173,6 +1173,17 @@ namespace internal { ...@@ -1173,6 +1173,17 @@ namespace internal {
\ \
/* AsyncGenerator */ \ /* AsyncGenerator */ \
\ \
/* 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) \
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(AsyncGeneratorResolve, kGenerator, kValue, kDone) \
TFS(AsyncGeneratorReject, kGenerator, kValue) \ TFS(AsyncGeneratorReject, kGenerator, kValue) \
TFS(AsyncGeneratorYield, kGenerator, kValue, kIsCaught) \ TFS(AsyncGeneratorYield, kGenerator, kValue, kIsCaught) \
...@@ -1195,17 +1206,6 @@ namespace internal { ...@@ -1195,17 +1206,6 @@ namespace internal {
TFJ(AsyncGeneratorPrototypeThrow, \ TFJ(AsyncGeneratorPrototypeThrow, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ 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 */ \ /* Async-from-Sync Iterator */ \
\ \
/* %AsyncFromSyncIteratorPrototype% */ \ /* %AsyncFromSyncIteratorPrototype% */ \
......
...@@ -235,6 +235,8 @@ bool Builtins::IsLazy(int index) { ...@@ -235,6 +235,8 @@ bool Builtins::IsLazy(int index) {
case kArrayReduceRightLoopLazyDeoptContinuation: case kArrayReduceRightLoopLazyDeoptContinuation:
case kArraySomeLoopEagerDeoptContinuation: // https://crbug.com/v8/6786. case kArraySomeLoopEagerDeoptContinuation: // https://crbug.com/v8/6786.
case kArraySomeLoopLazyDeoptContinuation: // https://crbug.com/v8/6786. case kArraySomeLoopLazyDeoptContinuation: // https://crbug.com/v8/6786.
case kAsyncGeneratorAwaitCaught: // https://crbug.com/v8/6786.
case kAsyncGeneratorAwaitUncaught: // https://crbug.com/v8/6786.
case kCheckOptimizationMarker: case kCheckOptimizationMarker:
case kCompileLazy: case kCompileLazy:
case kDeserializeLazy: case kDeserializeLazy:
......
...@@ -4561,6 +4561,10 @@ Node* CodeStubAssembler::IsJSArrayMap(Node* map) { ...@@ -4561,6 +4561,10 @@ Node* CodeStubAssembler::IsJSArrayMap(Node* map) {
return IsJSArrayInstanceType(LoadMapInstanceType(map)); return IsJSArrayInstanceType(LoadMapInstanceType(map));
} }
Node* CodeStubAssembler::IsJSAsyncGeneratorObject(Node* object) {
return HasInstanceType(object, JS_ASYNC_GENERATOR_OBJECT_TYPE);
}
Node* CodeStubAssembler::IsFixedArray(Node* object) { Node* CodeStubAssembler::IsFixedArray(Node* object) {
return HasInstanceType(object, FIXED_ARRAY_TYPE); return HasInstanceType(object, FIXED_ARRAY_TYPE);
} }
......
...@@ -1121,6 +1121,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -1121,6 +1121,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* IsJSArrayInstanceType(Node* instance_type); Node* IsJSArrayInstanceType(Node* instance_type);
Node* IsJSArrayMap(Node* object); Node* IsJSArrayMap(Node* object);
Node* IsJSArray(Node* object); Node* IsJSArray(Node* object);
Node* IsJSAsyncGeneratorObject(Node* object);
Node* IsJSFunctionInstanceType(Node* instance_type); Node* IsJSFunctionInstanceType(Node* instance_type);
Node* IsJSFunctionMap(Node* object); Node* IsJSFunctionMap(Node* object);
Node* IsJSFunction(Node* object); Node* IsJSFunction(Node* object);
......
...@@ -211,18 +211,6 @@ enum ContextLookupFlags { ...@@ -211,18 +211,6 @@ enum ContextLookupFlags {
async_generator_function_function) \ async_generator_function_function) \
V(ASYNC_ITERATOR_VALUE_UNWRAP_SHARED_FUN, SharedFunctionInfo, \ V(ASYNC_ITERATOR_VALUE_UNWRAP_SHARED_FUN, SharedFunctionInfo, \
async_iterator_value_unwrap_shared_fun) \ 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(ATOMICS_OBJECT, JSObject, atomics_object) \
V(BIGINT_FUNCTION_INDEX, JSFunction, bigint_function) \ V(BIGINT_FUNCTION_INDEX, JSFunction, bigint_function) \
V(BIGINT64_ARRAY_FUN_INDEX, JSFunction, bigint64_array_fun) \ V(BIGINT64_ARRAY_FUN_INDEX, JSFunction, bigint64_array_fun) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment