// 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_