Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/uniffi_macros/src/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 8 kB image not shown  

Quelle  setup_scaffolding.rs

  Sprache: Rust
 

/* 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/. */


use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use syn::Result;

use crate::util::mod_path;
use uniffi_meta::UNIFFI_CONTRACT_VERSION;

pub fn setup_scaffolding(namespace: String) -> Result<TokenStream> {
    let module_path = mod_path()?;
    let normalized_module_path = module_path.replace("::""__");
    let ffi_contract_version_ident =
        format_ident!("ffi_{normalized_module_path}_uniffi_contract_version");
    let namespace_upper = namespace.to_ascii_uppercase();
    let namespace_const_ident = format_ident!("UNIFFI_META_CONST_NAMESPACE_{namespace_upper}");
    let namespace_static_ident = format_ident!("UNIFFI_META_NAMESPACE_{namespace_upper}");
    let ffi_rustbuffer_alloc_ident = format_ident!("ffi_{normalized_module_path}_rustbuffer_alloc");
    let ffi_rustbuffer_from_bytes_ident =
        format_ident!("ffi_{normalized_module_path}_rustbuffer_from_bytes");
    let ffi_rustbuffer_free_ident = format_ident!("ffi_{normalized_module_path}_rustbuffer_free");
    let ffi_rustbuffer_reserve_ident =
        format_ident!("ffi_{normalized_module_path}_rustbuffer_reserve");
    let reexport_hack_ident = format_ident!("{normalized_module_path}_uniffi_reexport_hack");
    let ffi_rust_future_scaffolding_fns = rust_future_scaffolding_fns(&normalized_module_path);

    Ok(quote! {
        // Unit struct to parameterize the FfiConverter trait.
        //
        // We use FfiConverter<UniFfiTag> to handle lowering/lifting/serializing types for this crate.  See
        // https://mozilla.github.io/uniffi-rs/internals/lifting_and_lowering.html#code-generation-and-the-fficonverter-trait
        // for details.
        //
        // This is pub, since we need to access it to support external types
        #[doc(hidden)]
        pub struct UniFfiTag;

        #[allow(clippy::missing_safety_doc, missing_docs)]
        #[doc(hidden)]
        #[unsafe(no_mangle)]
        pub extern "C" fn #ffi_contract_version_ident() -> ::std::primitive::u32 {
            #UNIFFI_CONTRACT_VERSION
        }


        /// Export namespace metadata.
        ///
        /// See `uniffi_bindgen::macro_metadata` for how this is used.

        const #namespace_const_ident: ::uniffi::MetadataBuffer =
            ::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::NAMESPACE)
                .concat_str(#module_path)
                .concat_str(#namespace);

        #[doc(hidden)]
        #[unsafe(no_mangle)]
        pub static #namespace_static_ident: [::std::primitive::u8; #namespace_const_ident.size] =
            #namespace_const_ident.into_array();

        // Everybody gets basic buffer support, since it's needed for passing complex types over the FFI.
        //
        // See `uniffi/src/ffi/rustbuffer.rs` for documentation on these functions

        #[allow(clippy::missing_safety_doc, missing_docs)]
        #[doc(hidden)]
        #[unsafe(no_mangle)]
        pub extern "C" fn #ffi_rustbuffer_alloc_ident(
            size: ::std::primitive::u64,
            call_status: &mut ::uniffi::RustCallStatus,
        ) -> ::uniffi::RustBuffer {
            ::uniffi::ffi::uniffi_rustbuffer_alloc(size, call_status)
        }

        #[allow(clippy::missing_safety_doc, missing_docs)]
        #[doc(hidden)]
        #[unsafe(no_mangle)]
        pub unsafe extern "C" fn #ffi_rustbuffer_from_bytes_ident(
            bytes: ::uniffi::ForeignBytes,
            call_status: &mut ::uniffi::RustCallStatus,
        ) -> ::uniffi::RustBuffer {
            ::uniffi::ffi::uniffi_rustbuffer_from_bytes(bytes, call_status)
        }

        #[allow(clippy::missing_safety_doc, missing_docs)]
        #[doc(hidden)]
        #[unsafe(no_mangle)]
        pub unsafe extern "C" fn #ffi_rustbuffer_free_ident(
            buf: ::uniffi::RustBuffer,
            call_status: &mut ::uniffi::RustCallStatus,
        ) {
            ::uniffi::ffi::uniffi_rustbuffer_free(buf, call_status);
        }

        #[allow(clippy::missing_safety_doc, missing_docs)]
        #[doc(hidden)]
        #[unsafe(no_mangle)]
        pub unsafe extern "C" fn #ffi_rustbuffer_reserve_ident(
            buf: ::uniffi::RustBuffer,
            additional: ::std::primitive::u64,
            call_status: &mut ::uniffi::RustCallStatus,
        ) -> ::uniffi::RustBuffer {
            ::uniffi::ffi::uniffi_rustbuffer_reserve(buf, additional, call_status)
        }

        #ffi_rust_future_scaffolding_fns

        // Code to re-export the UniFFI scaffolding functions.
        //
        // Some build environments won't always re-export the functions from dependencies.
        // Originally attributed to [rust-lang#50007](https://github.com/rust-lang/rust/issues/50007),
        // it's still needed in mozilla-central with that resolved.
        //
        // A workaround for this is to have the dependent crate reference a function from its dependency in
        // an extern "C" function.
        //
        // The main way we use this macro is for libraries which contain multiple UniFFI components (libxul,
        // megazord).  This library has a cargo dependency for each component and calls
        // uniffi_reexport_scaffolding!() in each one.

        #[allow(missing_docs)]
        #[doc(hidden)]
        pub const fn uniffi_reexport_hack() {}

        #[doc(hidden)]
        #[macro_export]
        macro_rules! uniffi_reexport_scaffolding {
            () => {
                #[doc(hidden)]
                #[unsafe(no_mangle)]
                pub extern "C" fn #reexport_hack_ident() {
                    $crate::uniffi_reexport_hack()
                }
            };
        }
    })
}

/// Generates the rust_future_* functions
///
/// The foreign side uses a type-erased `Handle` to interact with futures, which presents
/// a problem when creating scaffolding functions.  What is the `ReturnType` parameter of `RustFutureFfi`?
///
/// Handle this by using some brute-force monomorphization.  For each possible ffi type, we
/// generate a set of scaffolding functions.  The bindings code is responsible for calling the one
/// corresponds the scaffolding function that created the `Handle`.
///
/// This introduces safety issues, but we do get some type checking.  If the bindings code calls
/// the wrong rust_future_complete function, they should get an unexpected return type, which
/// hopefully will result in a compile-time error.
fn rust_future_scaffolding_fns(module_path: &str) -> TokenStream {
    let fn_info = [
        (quote! { u8 }, "u8"),
        (quote! { i8 }, "i8"),
        (quote! { u16 }, "u16"),
        (quote! { i16 }, "i16"),
        (quote! { u32 }, "u32"),
        (quote! { i32 }, "i32"),
        (quote! { u64 }, "u64"),
        (quote! { i64 }, "i64"),
        (quote! { f32 }, "f32"),
        (quote! { f64 }, "f64"),
        (quote! { ::uniffi::RustBuffer }, "rust_buffer"),
        (quote! { () }, "void"),
    ];
    fn_info.iter()
    .map(|(return_type, fn_suffix)| {
        let ffi_rust_future_poll = format_ident!("ffi_{module_path}_rust_future_poll_{fn_suffix}");
        let ffi_rust_future_cancel = format_ident!("ffi_{module_path}_rust_future_cancel_{fn_suffix}");
        let ffi_rust_future_complete = format_ident!("ffi_{module_path}_rust_future_complete_{fn_suffix}");
        let ffi_rust_future_free = format_ident!("ffi_{module_path}_rust_future_free_{fn_suffix}");

        quote! {
            #[allow(clippy::missing_safety_doc, missing_docs)]
            #[doc(hidden)]
            #[unsafe(no_mangle)]
            pub unsafe extern "C" fn #ffi_rust_future_poll(handle: ::uniffi::Handle, callback: ::uniffi::RustFutureContinuationCallback, data: u64) {
                ::uniffi::ffi::rust_future_poll::<#return_type>(handle, callback, data);
            }

            #[allow(clippy::missing_safety_doc, missing_docs)]
            #[doc(hidden)]
            #[unsafe(no_mangle)]
            pub unsafe extern "C" fn #ffi_rust_future_cancel(handle: ::uniffi::Handle) {
                ::uniffi::ffi::rust_future_cancel::<#return_type>(handle)
            }

            #[allow(clippy::missing_safety_doc, missing_docs)]
            #[doc(hidden)]
            #[unsafe(no_mangle)]
            pub unsafe extern "C" fn #ffi_rust_future_complete(
                handle: ::uniffi::Handle,
                out_status: &mut ::uniffi::RustCallStatus
            ) -> #return_type {
                ::uniffi::ffi::rust_future_complete::<#return_type>(handle, out_status)
            }

            #[allow(clippy::missing_safety_doc, missing_docs)]
            #[doc(hidden)]
            #[unsafe(no_mangle)]
            pub unsafe extern "C" fn #ffi_rust_future_free(handle: ::uniffi::Handle) {
                ::uniffi::ffi::rust_future_free::<#return_type>(handle)
            }
        }
    })
    .collect()
}

Messung V0.5 in Prozent
C=74 H=95 G=84

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.