UniFFI.webidl (5448B)
1 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 // Interface for making UniFFI scaffolding calls 7 // 8 // Gecko uses UniFFI to generate privileged JS bindings for Rust components. 9 // UniFFI defines a C-ABI FFI layer for calling into Rust, called the 10 // scaffolding. This interface is a bridge that allows the JS code to make 11 // scaffolding calls 12 // 13 // See https://mozilla.github.io/uniffi-rs/ for details. 14 15 // Define some ID types to identify various parts of the UDL interfaces. Using 16 // these IDs, allow this .webidl file to remain static, but support new 17 // interfaces. Using IDs is that the C++ and JS code need to agree on their 18 // meaning, which is handled by 19 // toolkit/components/uniffi-bindgen-gecko-js/src/ci_list.rs. 20 21 // Identifies a scaffolding function. 22 typedef unsigned long long UniFFIFunctionId; 23 24 // Identifies a pointer type 25 typedef unsigned long long UniFFIPointerId; 26 27 // Identifies a callback interface 28 typedef unsigned long UniFFICallbackInterfaceId; 29 30 // Handle for a callback interface instance 31 typedef unsigned long long UniFFICallbackObjectHandle; 32 33 // Opaque type used to represent a pointer from Rust 34 [ChromeOnly, Exposed=Window] 35 interface UniFFIPointer { }; 36 37 // Types that can be passed or returned from scaffolding functions 38 // 39 // - double is used for all numeric types and types which the JS code coerces 40 // to an int including Boolean and CallbackInterface. 41 // - ArrayBuffer is used for RustBuffer 42 // - UniFFIPointer is used for Arc pointers 43 typedef (double or ArrayBuffer or UniFFIPointer) UniFFIScaffoldingValue; 44 45 // The result of a call into UniFFI scaffolding call 46 enum UniFFIScaffoldingCallCode { 47 "success", // Successful return 48 "error", // Rust Err return 49 "internal-error", // Internal/unexpected error 50 }; 51 52 dictionary UniFFIScaffoldingCallResult { 53 required UniFFIScaffoldingCallCode code; 54 // For success, this will be the return value for non-void returns 55 // For error, this will be an ArrayBuffer storing the serialized error value 56 UniFFIScaffoldingValue data; 57 }; 58 59 // JS handler for a callback interface 60 // 61 // These are responsible for invoking callback interface calls. Internally, these map handles to 62 // objects that implement the callback interface. 63 // 64 // Before the JS code returns a callback-interface-implementing object Rust, it first sends the 65 // object to a UniFFICallbackHandler, which adds an entry in the map. The handle is then what's 66 // sent to Rust. 67 // 68 // When the Rust code wants to invoke a method, it calls into the C++ layer and passes the handle 69 // along with all arguments. The C++ layer then calls `UniFFICallbackHandler.call()` which then 70 // looks up the object in the map and invokes the actual method. 71 // 72 // Finally, when the Rust code frees the object, it calls into the C++ layer, which then calls 73 // `UniFFICallbackHandler.release()` to remove the entry in the map. 74 [Exposed=Window] 75 callback interface UniFFICallbackHandler { 76 Promise<UniFFIScaffoldingCallResult> callAsync(UniFFICallbackObjectHandle objectHandle, unsigned long methodIndex, UniFFIScaffoldingValue... args); 77 UniFFIScaffoldingCallResult callSync(UniFFICallbackObjectHandle objectHandle, unsigned long methodIndex, UniFFIScaffoldingValue... args); 78 undefined destroy(UniFFICallbackObjectHandle objectHandle); 79 }; 80 81 // Functions to facilitate UniFFI scaffolding calls 82 [ChromeOnly, Exposed=Window] 83 namespace UniFFIScaffolding { 84 // Call a sync Rust function 85 // 86 // id is a unique identifier for the function, known to both the C++ and JS code 87 [Throws] 88 UniFFIScaffoldingCallResult callSync(UniFFIFunctionId id, UniFFIScaffoldingValue... args); 89 90 // Call an async Rust function 91 // 92 // id is a unique identifier for the function, known to both the C++ and JS code 93 [Throws] 94 Promise<UniFFIScaffoldingCallResult> callAsync(UniFFIFunctionId id, UniFFIScaffoldingValue... args); 95 96 // Call a sync Rust function, but wrap it to so that it behaves in JS as an async function 97 // 98 // id is a unique identifier for the function, known to both the C++ and JS code 99 [Throws] 100 Promise<UniFFIScaffoldingCallResult> callAsyncWrapper(UniFFIFunctionId id, UniFFIScaffoldingValue... args); 101 102 103 // Read a UniFFIPointer from an ArrayBuffer 104 // 105 // id is a unique identifier for the pointer type, known to both the C++ and JS code 106 [Throws] 107 UniFFIPointer readPointer(UniFFIPointerId id, ArrayBuffer buff, long position); 108 109 // Write a UniFFIPointer to an ArrayBuffer 110 // 111 // id is a unique identifier for the pointer type, known to both the C++ and JS code 112 [Throws] 113 undefined writePointer(UniFFIPointerId id, UniFFIPointer ptr, ArrayBuffer buff, long position); 114 115 // Register the global calblack handler 116 // 117 // This will be used to invoke all calls for a CallbackInterface. 118 // interfaceId is a unique identifier for the callback interface, known to both the C++ and JS code 119 [Throws] 120 undefined registerCallbackHandler(UniFFICallbackInterfaceId interfaceId, UniFFICallbackHandler handler); 121 122 // Deregister the global calblack handler 123 // 124 // This is called at shutdown to clear out the reference to the JS function. 125 [Throws] 126 undefined deregisterCallbackHandler(UniFFICallbackInterfaceId interfaceId); 127 };