|
1 | 1 | #include "jsb_jsc_object.h"
|
2 | 2 | #include "jsb_jsc_isolate.h"
|
| 3 | +#include "jsb_jsc_context.h" |
3 | 4 | #include "jsb_jsc_function_interop.h"
|
4 | 5 |
|
5 | 6 | namespace v8
|
@@ -262,4 +263,95 @@ namespace v8
|
262 | 263 | return MaybeLocal<Array>();
|
263 | 264 | }
|
264 | 265 |
|
| 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 | + } |
265 | 357 | }
|
0 commit comments