1/*
2 * Copyright (C) 2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "JSDOMPromise.h"
28
29#include "DOMWindow.h"
30#include "JSDOMWindow.h"
31#include <JavaScriptCore/BuiltinNames.h>
32#include <JavaScriptCore/CatchScope.h>
33#include <JavaScriptCore/Exception.h>
34#include <JavaScriptCore/JSNativeStdFunction.h>
35#include <JavaScriptCore/JSPromiseConstructor.h>
36
37using namespace JSC;
38
39namespace WebCore {
40
41static inline JSC::JSValue callFunction(JSC::ExecState& state, JSC::JSValue jsFunction, JSC::JSValue thisValue, const JSC::ArgList& arguments)
42{
43 VM& vm = state.vm();
44 auto scope = DECLARE_THROW_SCOPE(vm);
45 JSC::CallData callData;
46 auto callType = JSC::getCallData(vm, jsFunction, callData);
47 ASSERT(callType != JSC::CallType::None);
48 auto result = call(&state, jsFunction, callType, callData, thisValue, arguments);
49
50 EXCEPTION_ASSERT_UNUSED(scope, !scope.exception() || isTerminatedExecutionException(state.vm(), scope.exception()));
51
52 return result;
53}
54
55void DOMPromise::whenSettled(std::function<void()>&& callback)
56{
57 whenPromiseIsSettled(globalObject(), promise(), WTFMove(callback));
58}
59
60void DOMPromise::whenPromiseIsSettled(JSDOMGlobalObject* globalObject, JSC::JSObject* promise, std::function<void()>&& callback)
61{
62 auto& state = *globalObject->globalExec();
63 auto& vm = state.vm();
64 JSLockHolder lock(vm);
65 auto* handler = JSC::JSNativeStdFunction::create(vm, globalObject, 1, String { }, [callback = WTFMove(callback)] (ExecState*) mutable {
66 callback();
67 return JSC::JSValue::encode(JSC::jsUndefined());
68 });
69
70 const JSC::Identifier& privateName = vm.propertyNames->builtinNames().thenPrivateName();
71 auto thenFunction = promise->get(&state, privateName);
72 ASSERT(thenFunction.isFunction(vm));
73
74 JSC::MarkedArgumentBuffer arguments;
75 arguments.append(handler);
76 arguments.append(handler);
77 callFunction(state, thenFunction, promise, arguments);
78}
79
80JSC::JSValue DOMPromise::result() const
81{
82 return promise()->result(m_globalObject->globalExec()->vm());
83}
84
85DOMPromise::Status DOMPromise::status() const
86{
87 switch (promise()->status(m_globalObject->globalExec()->vm())) {
88 case JSC::JSPromise::Status::Pending:
89 return Status::Pending;
90 case JSC::JSPromise::Status::Fulfilled:
91 return Status::Fulfilled;
92 case JSC::JSPromise::Status::Rejected:
93 return Status::Rejected;
94 };
95 ASSERT_NOT_REACHED();
96 return Status::Rejected;
97}
98
99}
100