Skip to content

Commit 319256d

Browse files
committed
[1.9>master] [MERGE #5131 @kfarnung] New APIs for getting Promise state and result
Merge pull request #5131 from kfarnung:promises
2 parents 8821afb + 1c76177 commit 319256d

File tree

4 files changed

+176
-2
lines changed

4 files changed

+176
-2
lines changed

bin/ChakraCore/ChakraCore.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ JsLessThan
6363
JsLessThanOrEqual
6464

6565
JsCreateEnhancedFunction
66-
6766
JsSetHostPromiseRejectionTracker
68-
6967
JsGetProxyProperties
7068
JsSerializeParserState
7169
JsRunScriptWithParserState
70+
JsGetPromiseState
71+
JsGetPromiseResult

bin/NativeTests/JsRTApiTest.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//-------------------------------------------------------------------------------------------------------
55
#include "stdafx.h"
66
#include "catch.hpp"
7+
#include <array>
78
#include <process.h>
89

910
#pragma warning(disable:4100) // unreferenced formal parameter
@@ -2747,4 +2748,74 @@ namespace JsRTApiTest
27472748
{
27482749
JsRTApiTest::RunWithAttributes(JsRTApiTest::ApiTest_JsSerializeParseErrorTest);
27492750
}
2751+
2752+
void JsCreatePromiseTest(JsRuntimeAttributes attributes, JsRuntimeHandle runtime)
2753+
{
2754+
JsValueRef result = JS_INVALID_REFERENCE;
2755+
2756+
JsValueRef promise = JS_INVALID_REFERENCE;
2757+
JsValueRef resolve = JS_INVALID_REFERENCE;
2758+
JsValueRef reject = JS_INVALID_REFERENCE;
2759+
2760+
// Create resolvable promise
2761+
REQUIRE(JsCreatePromise(&promise, &resolve, &reject) == JsNoError);
2762+
2763+
JsPromiseState state = JsPromiseState_Pending;
2764+
REQUIRE(JsGetPromiseState(promise, &state) == JsNoError);
2765+
CHECK(state == JsPromiseState_Pending);
2766+
2767+
result = JS_INVALID_REFERENCE;
2768+
CHECK(JsGetPromiseResult(promise, &result) == JsErrorInvalidArgument);
2769+
CHECK(result == JS_INVALID_REFERENCE);
2770+
2771+
JsValueRef num = JS_INVALID_REFERENCE;
2772+
REQUIRE(JsIntToNumber(42, &num) == JsNoError);
2773+
2774+
std::array<JsValueRef, 2> args{ GetUndefined(), num };
2775+
REQUIRE(JsCallFunction(resolve, args.data(), static_cast<unsigned short>(args.size()), &result) == JsNoError);
2776+
2777+
state = JsPromiseState_Pending;
2778+
REQUIRE(JsGetPromiseState(promise, &state) == JsNoError);
2779+
CHECK(state == JsPromiseState_Fulfilled);
2780+
2781+
result = JS_INVALID_REFERENCE;
2782+
REQUIRE(JsGetPromiseResult(promise, &result) == JsNoError);
2783+
2784+
int resultNum = 0;
2785+
REQUIRE(JsNumberToInt(result, &resultNum) == JsNoError);
2786+
CHECK(resultNum == 42);
2787+
2788+
// Create rejectable promise
2789+
REQUIRE(JsCreatePromise(&promise, &resolve, &reject) == JsNoError);
2790+
2791+
state = JsPromiseState_Pending;
2792+
REQUIRE(JsGetPromiseState(promise, &state) == JsNoError);
2793+
CHECK(state == JsPromiseState_Pending);
2794+
2795+
result = JS_INVALID_REFERENCE;
2796+
CHECK(JsGetPromiseResult(promise, &result) == JsErrorInvalidArgument);
2797+
CHECK(result == JS_INVALID_REFERENCE);
2798+
2799+
num = JS_INVALID_REFERENCE;
2800+
REQUIRE(JsIntToNumber(43, &num) == JsNoError);
2801+
2802+
args = { GetUndefined(), num };
2803+
REQUIRE(JsCallFunction(reject, args.data(), static_cast<unsigned short>(args.size()), &result) == JsNoError);
2804+
2805+
state = JsPromiseState_Pending;
2806+
REQUIRE(JsGetPromiseState(promise, &state) == JsNoError);
2807+
CHECK(state == JsPromiseState_Rejected);
2808+
2809+
result = JS_INVALID_REFERENCE;
2810+
REQUIRE(JsGetPromiseResult(promise, &result) == JsNoError);
2811+
2812+
resultNum = 0;
2813+
REQUIRE(JsNumberToInt(result, &resultNum) == JsNoError);
2814+
CHECK(resultNum == 43);
2815+
}
2816+
2817+
TEST_CASE("ApiTest_JsCreatePromiseTest", "[ApiTest]")
2818+
{
2819+
JsRTApiTest::RunWithAttributes(JsRTApiTest::JsCreatePromiseTest);
2820+
}
27502821
}

lib/Jsrt/ChakraCore.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,16 @@ typedef enum JsModuleHostInfoKind
9797
JsModuleHostInfo_Url = 0x6
9898
} JsModuleHostInfoKind;
9999

100+
/// <summary>
101+
/// The possible states for a Promise object.
102+
/// </summary>
103+
typedef enum _JsPromiseState
104+
{
105+
JsPromiseState_Pending = 0x0,
106+
JsPromiseState_Fulfilled = 0x1,
107+
JsPromiseState_Rejected = 0x2
108+
} JsPromiseState;
109+
100110
/// <summary>
101111
/// User implemented callback to fetch additional imported modules in ES modules.
102112
/// </summary>
@@ -709,6 +719,38 @@ CHAKRA_API
709719
_In_ JsValueRef sourceUrl,
710720
_Out_ JsValueRef *result);
711721

722+
/// <summary>
723+
/// Gets the state of a given Promise object.
724+
/// </summary>
725+
/// <remarks>
726+
/// Requires an active script context.
727+
/// </remarks>
728+
/// <param name="promise">The Promise object.</param>
729+
/// <param name="state">The current state of the Promise.</param>
730+
/// <returns>
731+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
732+
/// </returns>
733+
CHAKRA_API
734+
JsGetPromiseState(
735+
_In_ JsValueRef promise,
736+
_Out_ JsPromiseState *state);
737+
738+
/// <summary>
739+
/// Gets the result of a given Promise object.
740+
/// </summary>
741+
/// <remarks>
742+
/// Requires an active script context.
743+
/// </remarks>
744+
/// <param name="promise">The Promise object.</param>
745+
/// <param name="result">The result of the Promise.</param>
746+
/// <returns>
747+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
748+
/// </returns>
749+
CHAKRA_API
750+
JsGetPromiseResult(
751+
_In_ JsValueRef promise,
752+
_Out_ JsValueRef *result);
753+
712754
/// <summary>
713755
/// Creates a new JavaScript Promise object.
714756
/// </summary>

lib/Jsrt/Jsrt.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5161,6 +5161,67 @@ CHAKRA_API JsCreatePromise(_Out_ JsValueRef *promise, _Out_ JsValueRef *resolve,
51615161
});
51625162
}
51635163

5164+
CHAKRA_API JsGetPromiseState(_In_ JsValueRef promise, _Out_ JsPromiseState *state)
5165+
{
5166+
return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&](Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
5167+
PERFORM_JSRT_TTD_RECORD_ACTION_NOT_IMPLEMENTED(scriptContext);
5168+
5169+
VALIDATE_INCOMING_REFERENCE(promise, scriptContext);
5170+
PARAM_NOT_NULL(state);
5171+
5172+
*state = JsPromiseState_Pending;
5173+
5174+
if (!Js::JavascriptPromise::Is(promise))
5175+
{
5176+
return JsErrorInvalidArgument;
5177+
}
5178+
5179+
Js::JavascriptPromise *jsPromise = Js::JavascriptPromise::FromVar(promise);
5180+
Js::JavascriptPromise::PromiseStatus status = jsPromise->GetStatus();
5181+
5182+
switch (status)
5183+
{
5184+
case Js::JavascriptPromise::PromiseStatus::PromiseStatusCode_HasRejection:
5185+
*state = JsPromiseState_Rejected;
5186+
break;
5187+
5188+
case Js::JavascriptPromise::PromiseStatus::PromiseStatusCode_HasResolution:
5189+
*state = JsPromiseState_Fulfilled;
5190+
break;
5191+
}
5192+
5193+
return JsNoError;
5194+
});
5195+
}
5196+
5197+
CHAKRA_API JsGetPromiseResult(_In_ JsValueRef promise, _Out_ JsValueRef *result)
5198+
{
5199+
return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&](Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
5200+
PERFORM_JSRT_TTD_RECORD_ACTION_NOT_IMPLEMENTED(scriptContext);
5201+
5202+
VALIDATE_INCOMING_REFERENCE(promise, scriptContext);
5203+
PARAM_NOT_NULL(result);
5204+
5205+
*result = JS_INVALID_REFERENCE;
5206+
5207+
if (!Js::JavascriptPromise::Is(promise))
5208+
{
5209+
return JsErrorInvalidArgument;
5210+
}
5211+
5212+
Js::JavascriptPromise *jsPromise = Js::JavascriptPromise::FromVar(promise);
5213+
Js::Var jsResult = jsPromise->GetResult();
5214+
5215+
if (jsResult == nullptr)
5216+
{
5217+
return JsErrorInvalidArgument;
5218+
}
5219+
5220+
*result = (JsValueRef)jsResult;
5221+
return JsNoError;
5222+
});
5223+
}
5224+
51645225
CHAKRA_API JsCreateWeakReference(
51655226
_In_ JsValueRef value,
51665227
_Out_ JsWeakRef* weakRef)

0 commit comments

Comments
 (0)