forked from mirrors/gecko-dev
		
	 1c2fbc9d73
			
		
	
	
		1c2fbc9d73
		
	
	
	
	
		
			
			Update:
  - Glean to v53.1.0
  - UniFFI to v0.24.1
  - application-services to a recent nightly that uses the above
    versions
- Updated `rusqlite` in toolkit/library/rust/shared/Cargo.toml
- Updated `uniffi-bindgen-gecko-js` to work with the new UniFFI.  Also
  updated it's askama version.
- Vetted new cargo dependencies
Ran `mach uniffi generate` to regenerate the code.
Differential Revision: https://phabricator.services.mozilla.com/D181872
		
	
			
		
			
				
	
	
		
			164 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim:set ts=2 sw=2 sts=2 et cindent: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "nsPrintfCString.h"
 | |
| #include "nsString.h"
 | |
| #include "nsThreadUtils.h"
 | |
| #include "mozilla/dom/OwnedRustBuffer.h"
 | |
| #include "mozilla/dom/RootedDictionary.h"
 | |
| #include "mozilla/dom/UniFFIBinding.h"
 | |
| #include "mozilla/dom/UniFFICallbacks.h"
 | |
| #include "mozilla/Maybe.h"
 | |
| #include "mozilla/Logging.h"
 | |
| #include "mozilla/RefPtr.h"
 | |
| #include "mozilla/UniquePtr.h"
 | |
| 
 | |
| static mozilla::LazyLogModule UNIFFI_INVOKE_CALLBACK_LOGGER("uniffi");
 | |
| 
 | |
| namespace mozilla::uniffi {
 | |
| 
 | |
| using dom::ArrayBuffer;
 | |
| using dom::RootedDictionary;
 | |
| using dom::UniFFICallbackHandler;
 | |
| using dom::UniFFIScaffoldingCallCode;
 | |
| 
 | |
| static Maybe<CallbackInterfaceInfo> GetCallbackInterfaceInfo(
 | |
|     uint64_t aInterfaceId) {
 | |
|   const Maybe<CallbackInterfaceInfo> cbiInfo =
 | |
|       UniFFIGetCallbackInterfaceInfo(aInterfaceId);
 | |
| #ifdef MOZ_UNIFFI_FIXTURES
 | |
|   if (!cbiInfo) {
 | |
|     return UniFFIFixturesGetCallbackInterfaceInfo(aInterfaceId);
 | |
|   }
 | |
| #endif
 | |
|   return cbiInfo;
 | |
| }
 | |
| 
 | |
| void RegisterCallbackHandler(uint64_t aInterfaceId,
 | |
|                              UniFFICallbackHandler& aCallbackHandler,
 | |
|                              ErrorResult& aError) {
 | |
|   // We should only be mutating mHandler on the main thread
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| 
 | |
|   Maybe<CallbackInterfaceInfo> cbiInfo = GetCallbackInterfaceInfo(aInterfaceId);
 | |
|   if (!cbiInfo.isSome()) {
 | |
|     aError.ThrowUnknownError(
 | |
|         nsPrintfCString("Unknown interface id: %" PRIu64, aInterfaceId));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (*cbiInfo->mHandler) {
 | |
|     MOZ_LOG(UNIFFI_INVOKE_CALLBACK_LOGGER, LogLevel::Error,
 | |
|             ("[UniFFI] Callback handler already registered for %s",
 | |
|              cbiInfo->mName));
 | |
|     return;
 | |
|   }
 | |
|   *cbiInfo->mHandler = &aCallbackHandler;
 | |
|   RustCallStatus status = {0};
 | |
|   cbiInfo->mInitForeignCallback(cbiInfo->mForeignCallback, &status);
 | |
|   // Just use MOZ_DIAGNOSTIC_ASSERT to check the status, since the call should
 | |
|   // always succeed. The RustCallStatus out param only exists because UniFFI
 | |
|   // adds it to all FFI calls.
 | |
|   MOZ_DIAGNOSTIC_ASSERT(status.code == RUST_CALL_SUCCESS);
 | |
| }
 | |
| 
 | |
| void DeregisterCallbackHandler(uint64_t aInterfaceId, ErrorResult& aError) {
 | |
|   // We should only be mutating mHandler on the main thread
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| 
 | |
|   Maybe<CallbackInterfaceInfo> cbiInfo = GetCallbackInterfaceInfo(aInterfaceId);
 | |
|   if (!cbiInfo.isSome()) {
 | |
|     aError.ThrowUnknownError(
 | |
|         nsPrintfCString("Unknown interface id: %" PRIu64, aInterfaceId));
 | |
|     return;
 | |
|   }
 | |
|   *cbiInfo->mHandler = nullptr;
 | |
| }
 | |
| 
 | |
| MOZ_CAN_RUN_SCRIPT
 | |
| static void QueueCallbackInner(uint64_t aInterfaceId, uint64_t aHandle,
 | |
|                                uint32_t aMethod,
 | |
|                                UniquePtr<uint8_t[], JS::FreePolicy>&& aArgsData,
 | |
|                                int32_t aArgsLen) {
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| 
 | |
|   Maybe<CallbackInterfaceInfo> cbiInfo = GetCallbackInterfaceInfo(aInterfaceId);
 | |
|   if (!cbiInfo.isSome()) {
 | |
|     MOZ_LOG(UNIFFI_INVOKE_CALLBACK_LOGGER, LogLevel::Error,
 | |
|             ("[UniFFI] Unknown inferface id: %" PRIu64, aInterfaceId));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // Take our own reference to the callback handler to ensure that it stays
 | |
|   // alive for the duration of this call
 | |
|   RefPtr<UniFFICallbackHandler> ihandler = *cbiInfo->mHandler;
 | |
| 
 | |
|   if (!ihandler) {
 | |
|     MOZ_LOG(UNIFFI_INVOKE_CALLBACK_LOGGER, LogLevel::Error,
 | |
|             ("[UniFFI] JS handler for %s not registered", cbiInfo->mName));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   JSObject* global = ihandler->CallbackGlobalOrNull();
 | |
|   if (!global) {
 | |
|     MOZ_LOG(UNIFFI_INVOKE_CALLBACK_LOGGER, LogLevel::Error,
 | |
|             ("[UniFFI] JS handler for %s has null global", cbiInfo->mName));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   dom::AutoEntryScript aes(global, cbiInfo->mName);
 | |
| 
 | |
|   JS::Rooted<JSObject*> args(
 | |
|       aes.cx(),
 | |
|       JS::NewArrayBufferWithContents(aes.cx(), aArgsLen, std::move(aArgsData)));
 | |
|   if (!args) {
 | |
|     MOZ_LOG(UNIFFI_INVOKE_CALLBACK_LOGGER, LogLevel::Error,
 | |
|             ("[UniFFI] Failed to allocate buffer for arguments"));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   IgnoredErrorResult error;
 | |
|   ihandler->Call(aHandle, aMethod, args, error);
 | |
| 
 | |
|   if (error.Failed()) {
 | |
|     MOZ_LOG(UNIFFI_INVOKE_CALLBACK_LOGGER, LogLevel::Error,
 | |
|             ("[UniFFI] Error invoking JS handler for %s", cbiInfo->mName));
 | |
|     return;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void QueueCallback(uint64_t aInterfaceId, uint64_t aHandle, uint32_t aMethod,
 | |
|                    const uint8_t* aArgsData, int32_t aArgsLen) {
 | |
|   // Make a copy of aArgsData to be deserialized asynchronously on
 | |
|   // the main thread.
 | |
|   //
 | |
|   // This copy will be allocated in the ArrayBufferContentsArena, as
 | |
|   // ownership will be passed to an ArrayBuffer for deserialization.
 | |
|   UniquePtr<uint8_t[], JS::FreePolicy> argsDataOwned(
 | |
|       js_pod_arena_malloc<uint8_t>(js::ArrayBufferContentsArena, aArgsLen));
 | |
|   if (!argsDataOwned) {
 | |
|     MOZ_LOG(UNIFFI_INVOKE_CALLBACK_LOGGER, LogLevel::Error,
 | |
|             ("[UniFFI] Error allocating memory for arguments"));
 | |
|     return;
 | |
|   }
 | |
|   memcpy(argsDataOwned.get(), aArgsData, aArgsLen);
 | |
| 
 | |
|   nsresult dispatchResult =
 | |
|       GetMainThreadSerialEventTarget()->Dispatch(NS_NewRunnableFunction(
 | |
|           "UniFFI callback", [=, argsDataOwned = std::move(argsDataOwned)]()
 | |
|                                  MOZ_CAN_RUN_SCRIPT_BOUNDARY mutable {
 | |
|                                    QueueCallbackInner(
 | |
|                                        aInterfaceId, aHandle, aMethod,
 | |
|                                        std::move(argsDataOwned), aArgsLen);
 | |
|                                  }));
 | |
| 
 | |
|   if (NS_FAILED(dispatchResult)) {
 | |
|     MOZ_LOG(UNIFFI_INVOKE_CALLBACK_LOGGER, LogLevel::Error,
 | |
|             ("[UniFFI] Error dispatching UniFFI callback task"));
 | |
|   }
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla::uniffi
 |