| cache.rs |
|
3664 |
| class.rs |
|
3235 |
| common_selectors.rs |
Common selectors.
These are put here to deduplicate the cached selector, and when using
`unstable-static-sel`, the statics.
Note that our assembly tests of `unstable-static-sel-inlined` output a GOT
entry for such accesses, but that is just a limitation of our tests - the
actual assembly is as one would expect. |
3939 |
| convert.rs |
|
8702 |
| define_class.rs |
|
13437 |
| defined_ivars.rs |
# Supporting code for instance variables on defined classes.
Adding instance variables to Objective-C classes is fairly simple, it can
be done using `ClassBuilder::add_ivar`.
However, things become more complicated once we have to handle `Drop`,
deallocation and unwind safety; remember, `dealloc` may be called even on
newly, non-initialized instances.
Note that Swift [doesn't handle this][swift-deinit-unsound], but that
doesn't mean we can simply stick our heads in the sand.
Basically, instead of storing the ivars directly, we store it as the
following tagged enum:
```
#[repr(u8)]
enum ActualIvar<T: objc2::DefinedClass> {
Allocated = 0,
PartialInit(T::Ivars),
Finalized(T::Ivars),
}
```
For performance reasons, we unfortunately can't write it that cleanly: we
want the data and the drop flag as two separate ivars instead of combining
them into one, since that will give the layout algorithm in the
Objective-C runtime more information to work with, and it allows us to
selectively omit the drop flag or the data storage when either is not
needed.
Ideally, we'd be able to somehow statically detect when the ivars have a
zero niche, which would allow us to know if the type is safe to drop when
zero-initialized:
```ignore
None::<T::Ivars>.is_all_zeroes_bitpattern()
```
However, detecting if the `None` is all zeroes requires reading the bytes,
which is [unsound for types that may have padding][unsound-read-padding],
since that padding is uninitialized.
So this is an optimization that we don't yet do, but that may be possible
in the future using something like `bytemuck::ZeroableInOption`.
[swift-deinit-unsound]: https://github.com/apple/swift/issues/68734
[unsound-read-padding]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ea068e8d9e55801aa9520ea914eb2822 |
31662 |
| image_info.rs |
|
1598 |
| method_family.rs |
|
11878 |
| mod.rs |
|
3774 |
| module_info.rs |
|
747 |
| msg_send_retained.rs |
|
35364 |
| null_error.rs |
|
4648 |
| os_version |
|
|
| os_version.rs |
Utilities for checking the runtime availability of APIs.
TODO: Upstream some of this to `std`? |
11513 |
| retain_semantics.rs |
|
22378 |
| sync_unsafe_cell.rs |
|
693 |
| writeback.rs |
Support for passing "out"-parameters to `msg_send!` and family.
See clang's documentation:
<https://clang.llvm.org/docs/AutomaticReferenceCounting.html#passing-to-an-out-parameter-by-writeback>
Note: We differ from that in that we do not create a temporary, whose
address we then work on; instead, we directly reuse the pointer that the
user provides (since, if it's a mutable pointer, we know that it's not
shared elsewhere in the program, and hence it is safe to modify directly).
Another important consideration is unwinding; I haven't researched how
Clang handles that, but the correct thing is to do the writeback
retain/release dance regardless of whether the function unwinded or not.
We ensure this by doing it in `Drop`. |
16208 |