Skip to content

Commit 55e591c

Browse files
committed
feat: add Promise::Resolver to jsc.impl
1 parent 2761031 commit 55e591c

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

impl/jsc/jsb_jsc_object.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "jsb_jsc_object.h"
22
#include "jsb_jsc_isolate.h"
3+
#include "jsb_jsc_context.h"
34
#include "jsb_jsc_function_interop.h"
45

56
namespace v8
@@ -262,4 +263,95 @@ namespace v8
262263
return MaybeLocal<Array>();
263264
}
264265

266+
MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context)
267+
{
268+
Isolate* isolate = context->GetIsolate();
269+
const JSContextRef ctx = isolate->ctx();
270+
JSObjectRef resolve, reject;
271+
JSValueRef error;
272+
const JSObjectRef promise = JSObjectMakeDeferredPromise(ctx, &resolve, &reject, &error);
273+
if (error)
274+
{
275+
isolate->_ThrowError(error);
276+
return MaybeLocal<Promise::Resolver>();
277+
}
278+
279+
const JSValueRef args[] = { resolve, reject, promise };
280+
const JSObjectRef holder = JSObjectMakeArray(ctx, 3, args, &error);
281+
if (error)
282+
{
283+
isolate->_ThrowError(error);
284+
return MaybeLocal<Promise::Resolver>();
285+
}
286+
287+
JSObjectSetPropertyAtIndex(ctx, holder, kHolderIndexResolve, args[0], &error);
288+
jsb_ensure(!error);
289+
JSObjectSetPropertyAtIndex(ctx, holder, kHolderIndexReject, args[1], &error);
290+
jsb_ensure(!error);
291+
JSObjectSetPropertyAtIndex(ctx, holder, kHolderIndexPromise, args[2], &error);
292+
jsb_ensure(!error);
293+
return MaybeLocal<Array>(Data(isolate, isolate->push_copy(holder)));
294+
}
295+
296+
Local<Promise> Promise::Resolver::GetPromise()
297+
{
298+
const JSContextRef ctx = isolate_->ctx();
299+
jsb_check(JSValueIsArray(ctx, (JSValueRef) *this));
300+
const JSObjectRef holder = jsb::impl::JavaScriptCore::AsObject(ctx, (JSValueRef) *this);
301+
JSValueRef error;
302+
const JSValueRef rval = JSObjectGetPropertyAtIndex(ctx, holder, kHolderIndexPromise, &error);
303+
304+
// or, just loosely check `!JSValueIsObject(ctx, rval)`
305+
if (error || !isolate_->_IsPromise(rval))
306+
{
307+
jsb::impl::JavaScriptCore::MarkExceptionAsTrivial(ctx, error);
308+
return Local<Promise>();
309+
}
310+
return Local<Promise>(Data(isolate_, isolate_->push_copy(rval)));
311+
}
312+
313+
namespace
314+
{
315+
template <uint32_t kHolderIndex>
316+
Maybe<bool> InvokePromise(Local<Context> context, Data* this_, Local<Value> value)
317+
{
318+
Isolate* isolate = context->GetIsolate();
319+
const JSContextRef ctx = isolate->ctx();
320+
jsb_check(JSValueIsArray(ctx, (JSValueRef) *this_));
321+
const JSObjectRef holder = jsb::impl::JavaScriptCore::AsObject(ctx, (JSValueRef) *this_);
322+
JSValueRef error;
323+
const JSValueRef holderValue = JSObjectGetPropertyAtIndex(ctx, holder, kHolderIndex, &error);
324+
if (error)
325+
{
326+
isolate->_ThrowError(error);
327+
return Maybe<bool>();
328+
}
329+
const JSObjectRef func = jsb::impl::JavaScriptCore::AsObject(ctx, holderValue);
330+
jsb_check(func && JSObjectIsFunction(ctx, func));
331+
const JSObjectRef thisObj = jsb::impl::JavaScriptCore::AsObject(ctx, isolate->stack_val(jsb::impl::StackPos::Undefined));
332+
const JSValueRef args[] = { (JSValueRef) value };
333+
const JSValueRef rval = JSObjectCallAsFunction(ctx,
334+
/* func */ func,
335+
/* this */ thisObj,
336+
/* args */ std::size(args), args,
337+
&error);
338+
if (error)
339+
{
340+
isolate->_ThrowError(error);
341+
return Maybe<bool>();
342+
}
343+
jsb_check(JSValueIsUndefined(ctx, rval));
344+
return Maybe<bool>(true);
345+
}
346+
}
347+
348+
Maybe<bool> Promise::Resolver::Resolve(Local<Context> context, Local<Value> value)
349+
{
350+
return InvokePromise<kHolderIndexResolve>(context, this, value);
351+
}
352+
353+
Maybe<bool> Promise::Resolver::Reject(Local<Context> context, Local<Value> value)
354+
{
355+
return InvokePromise<kHolderIndexReject>(context, this, value);
356+
}
265357
}

impl/jsc/jsb_jsc_object.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ namespace v8
5555
class Promise : public Object
5656
{
5757
public:
58+
class Resolver : public Object
59+
{
60+
enum : uint32_t { kHolderIndexResolve, kHolderIndexReject, kHolderIndexPromise, kHolderIndexCount };
61+
62+
public:
63+
static MaybeLocal<Resolver> New(Local<Context> context);
64+
65+
Local<Promise> GetPromise();
66+
67+
Maybe<bool> Resolve(Local<Context> context, Local<Value> value);
68+
69+
Maybe<bool> Reject(Local<Context> context, Local<Value> value);
70+
};
5871
};
5972

6073
}

jsb.config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@
6363
#define JSB_SUPPORT_RELOAD 1
6464

6565
// EXPERIMENTAL, LIMITED SUPPORT
66-
// only implemented in v8.impl and quickjs.impl, temporarily.
66+
// only implemented in v8.impl, jsc.impl and quickjs.impl, temporarily.
6767
// ---
6868
//
6969
// module 'godot-jsb':
7070
// - set_async_module_loader
7171
// - $import
72-
#define JSB_SUPPORT_ASYNC_MODULE_LOADER JSB_WITH_V8 || JSB_WITH_QUICKJS
72+
#define JSB_SUPPORT_ASYNC_MODULE_LOADER JSB_WITH_V8 || JSB_WITH_QUICKJS || JSB_WITH_JAVASCRIPTCORE
7373

7474
// translate the js source stacktrace with source map (currently, the `.map` file must locate at the same filename & directory of the js source)
7575
#define JSB_WITH_SOURCEMAP 1

0 commit comments

Comments
 (0)