Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/toolkit/crashreporter/client/app/src/ui/macos/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 7 kB image not shown  

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


//! Objective-C bindings and helpers.

// Forward all exports from the `objc` crate.
pub use objc::*;

/// An objc class instance which contains rust data `T`.
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct Objc<T> {
    pub instance: cocoa::id,
    _phantom: std::marker::PhantomData<*mut T>,
}

impl<T> Objc<T> {
    pub fn new(instance: cocoa::id) -> Self {
        Objc {
            instance,
            _phantom: std::marker::PhantomData,
        }
    }

    pub fn data(&self) -> &T {
        let data = *unsafe { (*self.instance).get_ivar::<usize>("rust_self") } as *mut T;
        unsafe { &*data }
    }

    pub fn data_mut(&mut self) -> &mut T {
        let data = *unsafe { (*self.instance).get_ivar::<usize>("rust_self") } as *mut T;
        unsafe { &mut *data }
    }
}

impl<T> std::ops::Deref for Objc<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        self.data()
    }
}

impl<T> std::ops::DerefMut for Objc<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.data_mut()
    }
}

unsafe impl<T> Encode for Objc<T> {
    fn encode() -> Encoding {
        cocoa::id::encode()
    }
}

/// Wrapper to provide `Encode` for bindgen-generated types (bindgen should do this in the future).
#[repr(transparent)]
pub struct Ptr<T>(pub T);

unsafe impl<T> Encode for Ptr<T> {
    fn encode() -> Encoding {
        cocoa::id::encode()
    }
}

/// A strong objective-c reference to `T`.
#[repr(transparent)]
pub struct StrongRef<T> {
    ptr: rc::StrongPtr,
    _phantom: std::marker::PhantomData<T>,
}

impl<T> Clone for StrongRef<T> {
    fn clone(&self) -> Self {
        StrongRef {
            ptr: self.ptr.clone(),
            _phantom: self._phantom,
        }
    }
}

impl<T> std::ops::Deref for StrongRef<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        let obj: &cocoa::id = &*self.ptr;
        unsafe { std::mem::transmute(obj) }
    }
}

impl<T> StrongRef<T> {
    /// Assume the given pointer-wrapper is an already-retained strong reference.
    ///
    /// # Safety
    /// The type _must_ be the same size as cocoa::id and contain only a cocoa::id.
    pub unsafe fn new(v: T) -> Self {
        std::mem::transmute_copy(&v)
    }

    /// Retain the given pointer-wrapper.
    ///
    /// # Safety
    /// The type _must_ be the same size as cocoa::id and contain only a cocoa::id.
    #[allow(dead_code)]
    pub unsafe fn retain(v: T) -> Self {
        let obj: cocoa::id = std::mem::transmute_copy(&v);
        StrongRef {
            ptr: rc::StrongPtr::retain(obj),
            _phantom: std::marker::PhantomData,
        }
    }

    pub fn autorelease(self) -> T {
        let obj = self.ptr.autorelease();
        unsafe { std::mem::transmute_copy(&obj) }
    }

    pub fn weak(&self) -> WeakRef<T> {
        WeakRef {
            ptr: self.ptr.weak(),
            _phantom: std::marker::PhantomData,
        }
    }

    /// Unwrap the StrongRef value without affecting reference counts.
    ///
    /// This is the opposite of `new`.
    #[allow(dead_code)]
    pub fn unwrap(selfSelf) -> T {
        let v = unsafe { std::mem::transmute_copy(&self) };
        std::mem::forget(self);
        v
    }

    /// Cast to a base class.
    ///
    /// Bindgen pointer-wrappers have trival `From<Derived> for Base` implementations.
    pub fn cast<U: From<T>>(self) -> StrongRef<U> {
        StrongRef {
            ptr: self.ptr,
            _phantom: std::marker::PhantomData,
        }
    }
}

/// A weak objective-c reference to `T`.
#[derive(Clone)]
#[repr(transparent)]
pub struct WeakRef<T> {
    ptr: rc::WeakPtr,
    _phantom: std::marker::PhantomData<T>,
}

impl<T> WeakRef<T> {
    pub fn lock(&self) -> Option<StrongRef<T>> {
        let ptr = self.ptr.load();
        if ptr.is_null() {
            None
        } else {
            Some(StrongRef {
                ptr,
                _phantom: std::marker::PhantomData,
            })
        }
    }
}

/// A macro for creating an objc class.
///
/// Classes _must_ be registered before use (`Objc<T>::register()`).
///
/// Example:
/// ```
/// struct Foo(u8);
///
/// objc_class! {
///     impl Foo: NSObject {
///         #[sel(mySelector:)]
///         fn my_selector(&mut self, arg: u8) -> u8 {
///             self.0 + arg
///         }
///     }
/// }
///
/// fn make_foo() -> StrongRef<Objc<Foo>> {
///     Foo(42).into_object()
/// }
/// ```
///
/// Call `T::into_object()` to create the objective-c class instance.
macro_rules! objc_class {
    ( impl $name:ident : $base:ident $(<$($protocol:ident),+>)? {
        $(
            #[sel($($sel:tt)+)]
            fn $mname:ident (&mut $self:ident $(, $argname:ident : $argtype:ty )*) $(-> $rettype:ty)? $body:block
        )*
    }) => {
        impl Objc<$name> {
            pub fn register() {
                let mut decl = declare::ClassDecl::new(concat!("CR", stringify!($name)), class!($base)).expect(concat!("failed to declare ", stringify!($name), " class"));
                $($(decl.add_protocol(runtime::Protocol::get(stringify!($protocol)).expect(concat!("failed to find ",stringify!($protocol)," protocol")));)+)?
                decl.add_ivar::<usize>("rust_self");
                $({
                    extern "C" fn method_impl(obj: &mut runtime::Object, _: runtime::Sel $(, $argname: $argtype )*) $(-> $rettype)? {
                        Objc::<$name>::new(obj).$mname($($argname),*)
                    }
                    unsafe {
                        decl.add_method(sel!($($sel)+), method_impl as extern "C" fn(&mut runtime::Object, runtime::Sel $(, $argname: $argtype )*) $(-> $rettype)?);
                    }
                })*
                {
                    extern "C" fn dealloc_impl(obj: &runtime::Object, _: runtime::Sel) {
                        drop(unsafe { Box::from_raw(*obj.get_ivar::<usize>("rust_self"as *mut $name) });
                        unsafe {
                            let _: () = msg_send![super(obj, class!(NSObject)), dealloc];
                        }
                    }
                    unsafe {
                        decl.add_method(sel!(dealloc), dealloc_impl as extern "C" fn(&runtime::Object, runtime::Sel));
                    }
                }
                decl.register();
            }

            pub fn class() -> &'static runtime::Class {
                runtime::Class::get(concat!("CR", stringify!($name))).expect("class not registered")
            }

            $(fn $mname (&mut $self $(, $argname : $argtype )*) $(-> $rettype)? $body)*
        }

        impl $name {
            pub fn into_object(self) -> StrongRef<Objc<$name>> {
                let obj: *mut runtime::Object = unsafe { msg_send![Objc::<Self>::class(), alloc] };
                unsafe { (*obj).set_ivar("rust_self"Box::into_raw(Box::new(self)) as usize) };
                let obj: *mut runtime::Object = unsafe { msg_send![obj, init] };
                unsafe { StrongRef::new(Objc::new(obj)) }
            }
        }
    }
}

pub(crateuse objc_class;

Messung V0.5 in Prozent
C=82 H=78 G=79

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-08-26) ¤

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