void Promise::AppendNativeHandler(PromiseNativeHandler* aRunnable) { NS_ASSERT_OWNINGTHREAD(Promise); AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(mGlobal))) { // Our API doesn't allow us to return a useful error. Not like this should // happen anyway. return; } // The self-hosted promise js may keep the object we pass to it alive // for quite a while depending on when GC runs. Therefore, pass a shim // object instead. The shim will free its inner PromiseNativeHandler // after the promise has settled just like our previous c++ promises did. RefPtr<PromiseNativeHandlerShim> shim = new PromiseNativeHandlerShim(aRunnable); JSContext* cx = jsapi.cx(); JS::Rooted<JSObject*> handlerWrapper(cx); // Note: PromiseNativeHandler is NOT wrappercached. So we can't use // ToJSValue here, because it will try to do XPConnect wrapping on it, sadly. if (NS_WARN_IF(!shim->WrapObject(cx, nullptr, &handlerWrapper))) { // Again, no way to report errors. jsapi.ClearException(); return; } JS::Rooted<JSObject*> resolveFunc(cx); resolveFunc = CreateNativeHandlerFunction(cx, handlerWrapper, NativeHandlerTask::Resolve); if (NS_WARN_IF(!resolveFunc)) { jsapi.ClearException(); return; } JS::Rooted<JSObject*> rejectFunc(cx); rejectFunc = CreateNativeHandlerFunction(cx, handlerWrapper, NativeHandlerTask::Reject); if (NS_WARN_IF(!rejectFunc)) { jsapi.ClearException(); return; } JS::Rooted<JSObject*> promiseObj(cx, PromiseObj()); if (NS_WARN_IF(!JS::AddPromiseReactions(cx, promiseObj, resolveFunc, rejectFunc))) { jsapi.ClearException(); return; } }
static int elektraResolveFilename (Key * parentKey, ElektraResolveTempfile tmpFile) { int rc = 0; void * handle = elektraInvokeOpen ("resolver", 0, 0); if (!handle) { rc = -1; goto RESOLVE_FAILED; } ElektraResolved * resolved = NULL; typedef ElektraResolved * (*resolveFileFunc) (elektraNamespace, const char *, ElektraResolveTempfile, Key *); resolveFileFunc resolveFunc = *(resolveFileFunc *) elektraInvokeGetFunction (handle, "filename"); if (!resolveFunc) { rc = -1; goto RESOLVE_FAILED; } typedef void (*freeHandleFunc) (ElektraResolved *); freeHandleFunc freeHandle = *(freeHandleFunc *) elektraInvokeGetFunction (handle, "freeHandle"); if (!freeHandle) { rc = -1; goto RESOLVE_FAILED; } resolved = resolveFunc (keyGetNamespace (parentKey), keyString (parentKey), tmpFile, parentKey); if (!resolved) { rc = -1; goto RESOLVE_FAILED; } else { keySetString (parentKey, resolved->fullPath); freeHandle (resolved); } RESOLVE_FAILED: elektraInvokeClose (handle, 0); return rc; }