#include "config.h"
#include "JSDOMPromise.h"
#include "DOMWindow.h"
#include "JSDOMWindow.h"
#include <JavaScriptCore/BuiltinNames.h>
#include <JavaScriptCore/CatchScope.h>
#include <JavaScriptCore/Exception.h>
#include <JavaScriptCore/JSNativeStdFunction.h>
#include <JavaScriptCore/JSPromiseConstructor.h>
using namespace JSC;
namespace WebCore {
static inline JSC::JSValue callFunction(JSC::ExecState& state, JSC::JSValue jsFunction, JSC::JSValue thisValue, const JSC::ArgList& arguments)
{
VM& vm = state.vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSC::CallData callData;
auto callType = JSC::getCallData(vm, jsFunction, callData);
ASSERT(callType != JSC::CallType::None);
auto result = call(&state, jsFunction, callType, callData, thisValue, arguments);
EXCEPTION_ASSERT_UNUSED(scope, !scope.exception() || isTerminatedExecutionException(state.vm(), scope.exception()));
return result;
}
void DOMPromise::whenSettled(std::function<void()>&& callback)
{
whenPromiseIsSettled(globalObject(), promise(), WTFMove(callback));
}
void DOMPromise::whenPromiseIsSettled(JSDOMGlobalObject* globalObject, JSC::JSObject* promise, std::function<void()>&& callback)
{
auto& state = *globalObject->globalExec();
auto& vm = state.vm();
JSLockHolder lock(vm);
auto* handler = JSC::JSNativeStdFunction::create(vm, globalObject, 1, String { }, [callback = WTFMove(callback)] (ExecState*) mutable {
callback();
return JSC::JSValue::encode(JSC::jsUndefined());
});
const JSC::Identifier& privateName = vm.propertyNames->builtinNames().thenPrivateName();
auto thenFunction = promise->get(&state, privateName);
ASSERT(thenFunction.isFunction(vm));
JSC::MarkedArgumentBuffer arguments;
arguments.append(handler);
arguments.append(handler);
callFunction(state, thenFunction, promise, arguments);
}
JSC::JSValue DOMPromise::result() const
{
return promise()->result(m_globalObject->globalExec()->vm());
}
DOMPromise::Status DOMPromise::status() const
{
switch (promise()->status(m_globalObject->globalExec()->vm())) {
case JSC::JSPromise::Status::Pending:
return Status::Pending;
case JSC::JSPromise::Status::Fulfilled:
return Status::Fulfilled;
case JSC::JSPromise::Status::Rejected:
return Status::Rejected;
};
ASSERT_NOT_REACHED();
return Status::Rejected;
}
}