// Copyright 2016 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_BUILTINS_BUILTINS_PROMISE_H_ #define V8_BUILTINS_BUILTINS_PROMISE_H_ #include "src/code-stub-assembler.h" #include "src/contexts.h" namespace v8 { namespace internal { typedef compiler::Node Node; typedef CodeStubAssembler::ParameterMode ParameterMode; typedef compiler::CodeAssemblerState CodeAssemblerState; class PromiseBuiltinsAssembler : public CodeStubAssembler { public: enum PromiseResolvingFunctionContextSlot { // Whether the resolve/reject callback was already called. kAlreadyVisitedSlot = Context::MIN_CONTEXT_SLOTS, // The promise which resolve/reject callbacks fulfill. kPromiseSlot, // Whether to trigger a debug event or not. Used in catch // prediction. kDebugEventSlot, kPromiseContextLength, }; enum FunctionContextSlot { kCapabilitySlot = Context::MIN_CONTEXT_SLOTS, kCapabilitiesContextLength, }; // This is used by the PromiseThenFinally and PromiseCatchFinally // builtins to store the onFinally in the onFinallySlot. // // This is also used by the PromiseValueThunkFinally to store the // value in the onFinallySlot and PromiseThrowerFinally to store the // reason in the onFinallySlot. enum PromiseFinallyContextSlot { kOnFinallySlot = Context::MIN_CONTEXT_SLOTS, kOnFinallyContextLength, }; explicit PromiseBuiltinsAssembler(CodeAssemblerState* state) : CodeStubAssembler(state) {} // These allocate and initialize a promise with pending state and // undefined fields. // // This uses undefined as the parent promise for the promise init // hook. Node* AllocateAndInitJSPromise(Node* context); // This uses the given parent as the parent promise for the promise // init hook. Node* AllocateAndInitJSPromise(Node* context, Node* parent); // This allocates and initializes a promise with the given state and // fields. Node* AllocateAndSetJSPromise(Node* context, Node* status, Node* result); Node* AllocatePromiseResolveThenableJobInfo(Node* result, Node* then, Node* resolve, Node* reject, Node* context); std::pair<Node*, Node*> CreatePromiseResolvingFunctions( Node* promise, Node* native_context, Node* promise_context); Node* PromiseHasHandler(Node* promise); Node* CreatePromiseResolvingFunctionsContext(Node* promise, Node* debug_event, Node* native_context); Node* CreatePromiseGetCapabilitiesExecutorContext(Node* native_context, Node* promise_capability); Node* NewPromiseCapability(Node* context, Node* constructor, Node* debug_event = nullptr); protected: void PromiseInit(Node* promise); Node* ThrowIfNotJSReceiver(Node* context, Node* value, MessageTemplate::Template msg_template, const char* method_name = nullptr); Node* SpeciesConstructor(Node* context, Node* object, Node* default_constructor); void PromiseSetHasHandler(Node* promise); void PromiseSetHandledHint(Node* promise); void AppendPromiseCallback(int offset, compiler::Node* promise, compiler::Node* value); Node* InternalPromiseThen(Node* context, Node* promise, Node* on_resolve, Node* on_reject); Node* InternalPerformPromiseThen(Node* context, Node* promise, Node* on_resolve, Node* on_reject, Node* deferred_promise, Node* deferred_on_resolve, Node* deferred_on_reject); void InternalResolvePromise(Node* context, Node* promise, Node* result); void BranchIfFastPath(Node* context, Node* promise, Label* if_isunmodified, Label* if_ismodified); void BranchIfFastPath(Node* native_context, Node* promise_fun, Node* promise, Label* if_isunmodified, Label* if_ismodified); Node* CreatePromiseContext(Node* native_context, int slots); void PromiseFulfill(Node* context, Node* promise, Node* result, v8::Promise::PromiseState status); void BranchIfAccessCheckFailed(Node* context, Node* native_context, Node* promise_constructor, Node* executor, Label* if_noaccess); void InternalPromiseReject(Node* context, Node* promise, Node* value, bool debug_event); void InternalPromiseReject(Node* context, Node* promise, Node* value, Node* debug_event); std::pair<Node*, Node*> CreatePromiseFinallyFunctions(Node* on_finally, Node* native_context); Node* CreatePromiseFinallyContext(Node* on_finally, Node* native_context); Node* CreateValueThunkFunction(Node* value, Node* native_context); Node* CreateValueThunkFunctionContext(Node* value, Node* native_context); Node* CreateThrowerFunctionContext(Node* reason, Node* native_context); Node* CreateThrowerFunction(Node* reason, Node* native_context); private: Node* AllocateJSPromise(Node* context); }; } // namespace internal } // namespace v8 #endif // V8_BUILTINS_BUILTINS_PROMISE_H_