You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/abi.md
+25-15
Original file line number
Diff line number
Diff line change
@@ -13,11 +13,18 @@ linking external libraries.
13
13
14
14
r[abi.compatibility]
15
15
16
-
r[abi.compatibility.type]
17
-
Two types, `T`and `U`, can be *abi compatible*.
16
+
r[abi.compatibility.intro]
17
+
Function calls pass parameters and return values between the caller and the callee function. This requires the caller and callee to agree on an ABI for those parameters and return values. This is typically only guaranteed when the same type is used in both the call site and the definition site of the callee, but certain other types may be *abi compatible*. This can appear when transmuting a [function pointer] or using an [`extern` block] to call a function. When the parameters or return types differ between the call site and def site, assuming they are *abi compatible*, the parameters or return types are transmuted to the type at the def site or call site respectively.
18
18
19
19
> [!NOTE]
20
-
> *abi compatible* types can be used in place of each other in signatures when calling via [function pointer] at runtime (via pointer, or [`extern` block]).
20
+
> This can include calls to functions defined outside of rust, or built using a different Rust compiler version.
21
+
> Additional guarantees will apply in this case for "FFI Safe" types, which match up with the platform C ABI in well-defined ways.
22
+
> These are not fully documented here currently.
23
+
24
+
> [!WARNING]
25
+
> Two types that are ABI Compatible may not allow the same set of values (e.g. [`*const T`] and [`core::ptr::NonNull<T>`]).
26
+
> If an invalid value is passed as a parameter or returned from a function, the result is immediate undefined behaviour, even if the parameter or return value is never used.
27
+
> For example, passing a null pointer to a function that accepts a `NonNull<i32>` parameter via `fn(*const i32)` function pointer caused undefined behaviour.
21
28
22
29
r[abi.compatibility.equivalence]
23
30
Two types `T` and `U` are *abi compatible* if:
@@ -27,12 +34,16 @@ Two types `T` and `U` are *abi compatible* if:
27
34
28
35
> [!NOTE]
29
36
> These properties are respectively called "reflexivity", "symmetry", and "transitivity". They ensure that *abi compatibility* is an equivalence relation.
37
+
> ABI compatibility is a pairwise relation between two types. With Transivity and Symmetry, however, it can be well-defined to refer to several types being ABI compatible
30
38
31
39
r[abi.compatibility.integer]
32
-
Two [integer types] are *abi compatible* if they have the same size and the same signedness.
40
+
Two [integer types] are *abi compatible* if they have the same width and the same signedness.
41
+
42
+
> [!NOTE]
43
+
> The width of an integer type is the number of bits, e.g. `u8` has a width of 8, and `i128` has a width of 128.
33
44
34
45
> [!NOTE]
35
-
> In particular, `usize` is *abi compatible* with `uN`, and `isize` is *abi compatible* with `iN` where `N` is the target_pointer_width.
46
+
> In particular, [`usize`] is *abi compatible* with `uN`, and `isize` is *abi compatible* with `iN` where `N` is the target_pointer_width.
36
47
> Two integer types with different signedness, such as `u8` and `i8` are not *abi compatible*.
37
48
38
49
```rust
@@ -124,7 +135,6 @@ Two types, `T` and `U`, are *abi compatible* if both have size 0 and alignment 1
124
135
r[abi.compatibility.option]
125
136
If `T` is a type listed in [layout.enum.option](https://doc.rust-lang.org/stable/core/option/index.html#representation), then given `S` is a type with size 0 and alignment 1, `T` is *abi compatible* with the types [`core::option::Option<T>`], [`core::result::Result<T,S>`], and [`core::result::Result<S,T>`].
126
137
127
-
128
138
r[abi.compatibility.fn-ptr]
129
139
An [function pointer] type `T` is *abi compatible* with an [function pointer] type `U` if `T` and `U` have *abi compatible* tags.
130
140
@@ -147,22 +157,24 @@ Two function signatures are compatible if:
147
157
> A signature is compatible with itself.
148
158
149
159
r[abi.compatibility.simd-abi]
150
-
A type has *simd abi requirements* if:
160
+
Certain types have *simd abi requirements*, which can impose additional constraints on calls with a parameter or return value of that type. A type has *simd abi requirements* if:
151
161
* It is a type declared with the standard-library repr-attribute `simd`, or
152
162
* It is a aggregate type[^aggregate], which has a type with *simd abi requirements* as a field.
153
163
154
164
> [!NOTE]
155
165
> Types with *simd abi requirements* may be passed using special registers that aren't always available to code.
156
166
157
167
> [!NOTE]
158
-
> Notably References and pointers to types with *simd abi requirements* do not have *simd abi requirements*.
168
+
> Notably References and pointers to types with *simd abi requirements* do not have *simd abi requirements*.
169
+
> Only direct parameters and return values are affected by *simd abi requirements*.
159
170
160
171
> [!NOTE]
161
-
> The `repr(simd)` attribute cannot be used by Rust code, only by the standard library.
172
+
> The `repr(simd)` attribute cannot be used by Rust code, only by the standard library. The name used here is for *exposition only*.
162
173
163
174
r[abi.compatibility.simd-target-feature]
164
175
A type with *simd abi requirements* may have one or more [*salient target features*][target_feature] . In the case of an aggregate type, the set of [*salient target features*][target_feature] is the union of the set of [*salient target features*][target_feature] of each field with *simd abi requirements*.
165
176
177
+
r[abi.compatibility.simd-target-feature-x86]
166
178
> [!TARGET-SPECIFIC]
167
179
> On x86 and x86-64, the [*salient target features*][target_feature] of the `simd` types are:
168
180
> *[`__m128`], [`__m128i`], [`__m128f`], and [`__m128d`] (128-bit vector types): `sse`
@@ -176,8 +188,6 @@ A call to a function `f` via a function item or function pointer with a given si
176
188
177
189
The behavior of a call that is not valid is undefined.
178
190
179
-
> [!NOTE]
180
-
> When parameter or return types do not exactly match, they are converted as though by calling [`core::mem::transmute`]. The representation and validity requirements of the type in the definition or return site still apply. For example, passing `0` to a function pointer `fn(u32)` that points to a function declared as `fn foo(x: NonZeroU32)` is undefined behavior.
181
191
182
192
> [!NOTE]
183
193
> The ABI tag `extern "Rust"` is the default when the `extern` keyword is not used (either to declare the function within an [`extern` block], or as a [function qualifier][extern functions]). Thus it is safe to call most functions that use simd types.
@@ -270,8 +280,7 @@ $ nm -C foo.o
270
280
271
281
r[abi.symbol-name]
272
282
273
-
274
-
The `no_mangle` and `export_name` attributes allow you to control which symbols are exported from rust code under provided symbol names.
283
+
The `no_mangle` and `export_name` attributes allow you to control which symbols are exported from rust code under provided symbol names.
275
284
276
285
> **<sup>Attribute Syntax</sup>**\
277
286
> _MetaItemNoMangle_ :\
@@ -304,7 +313,6 @@ extern "C" {
304
313
> [!NOTE]
305
314
> They may be applied to an associated `fn` of an `impl` block.
306
315
307
-
308
316
r[abi.symbol-name.exported]
309
317
An item with either the *`no_mangle` attribute* or the *`export_name` attribute* is an *exported item*.
310
318
@@ -361,7 +369,7 @@ extern "C" fn foo() {}
361
369
362
370
r[abi.link_section]
363
371
364
-
The `link_section` attribute allows a program to control the section that certain items are placed into.
372
+
The `link_section` attribute allows a program to control the section that certain items are placed into.
0 commit comments