1
- - Feature Name: ` "C unwind" ABI `
1
+ - Feature Name: ` "C- unwind" ABI `
2
2
- Start Date: 2019-04-03
3
3
- RFC PR: [ rust-lang/rfcs #0000 ] ( https://github.com/rust-lang/rfcs/pull/0000 )
4
4
- Rust Issue: [ rust-lang/rust #0000 ] ( https://github.com/rust-lang/rust/issues/0000 )
9
9
# Summary
10
10
[ summary ] : #summary
11
11
12
- We introduce a new ABI string, ` "C unwind" ` , to enable unwinding from other
12
+ We introduce a new ABI string, ` "C- unwind" ` , to enable unwinding from other
13
13
languages (such as C++) into Rust frames and from Rust into other languages.
14
14
15
15
Additionally, we define the behavior for a limited number of
16
16
previously-undefined cases when an unwind operation reaches a Rust function
17
- boundary with a non-` "Rust" ` , non-` "C unwind" ` ABI.
17
+ boundary with a non-` "Rust" ` , non-` "C- unwind" ` ABI.
18
18
19
19
As part of this specification, we introduce the term [ "Plain Old Frame"
20
20
(POF)] [ POF-definition ] . These are frames that have no pending destructors and
@@ -96,42 +96,42 @@ how well the current design satisfies these constraints.
96
96
[ guide-level-explanation ] : #guide-level-explanation
97
97
98
98
When declaring an external function that may unwind, such as an entrypoint to a
99
- C++ library, use ` extern "C unwind" ` instead of ` extern "C" ` :
99
+ C++ library, use ` extern "C- unwind" ` instead of ` extern "C" ` :
100
100
101
101
```
102
- extern "C unwind" {
102
+ extern "C- unwind" {
103
103
fn may_throw();
104
104
}
105
105
```
106
106
107
107
Rust functions that call a possibly-unwinding external function should either
108
108
use the default Rust ABI (which can be made explicit with ` extern "Rust" ` ) or
109
- the ` "C unwind" ` ABI:
109
+ the ` "C- unwind" ` ABI:
110
110
111
111
```
112
- extern "C unwind" fn can_unwind() {
112
+ extern "C- unwind" fn can_unwind() {
113
113
may_throw();
114
114
}
115
115
```
116
116
117
- Using the ` "C unwind" ` ABI to "sandwich" Rust frames between frames from
117
+ Using the ` "C- unwind" ` ABI to "sandwich" Rust frames between frames from
118
118
another language (such as C++) allows an exception initiated in a callee frame
119
119
in the other language to traverse the intermediate Rust frames before being
120
120
caught in the caller frames. I.e., a C++ exception may be thrown,
121
- cross into Rust via an ` extern "C unwind" ` function declaration, safely unwind
121
+ cross into Rust via an ` extern "C- unwind" ` function declaration, safely unwind
122
122
the Rust frames, and cross back into C++ (where it may be caught) via a Rust
123
- ` "C unwind" ` function definition.
123
+ ` "C- unwind" ` function definition.
124
124
125
125
Conversely, languages that support the native unwinding mechanism, such as C++,
126
126
may be "sandwiched" between Rust frames, so that Rust ` panic ` s may safely
127
127
unwind the C++ frames, if the Rust code declares both the C++ entrypoint and
128
- the Rust entrypoint using ` "C unwind" ` .
128
+ the Rust entrypoint using ` "C- unwind" ` .
129
129
130
130
## Other ` unwind ` ABI strings
131
131
132
132
Because the ` C ` ABI is not appropriate for all use cases, we also introduce
133
133
these ` unwind ` ABI strings, which will only differ from their non-` unwind `
134
- variants by permitting unwinding, with the same semantics as ` "C unwind" ` :
134
+ variants by permitting unwinding, with the same semantics as ` "C- unwind" ` :
135
135
136
136
* ` "system unwind" ` - available on all platforms
137
137
* ` "stdcall unwind" ` and ` "thiscall unwind" ` - available only on platforms
@@ -178,7 +178,7 @@ types). In other words, a forced unwind operation on one platform will simply
178
178
deallocate Rust frames without true unwinding on other platforms.
179
179
180
180
This RFC specifies that, regardless of the platform or the ABI string (` "C" ` or
181
- ` "C unwind" ` ), any platform features that may rely on forced unwinding will
181
+ ` "C- unwind" ` ), any platform features that may rely on forced unwinding will
182
182
always be considered undefined behavior if they cross
183
183
non-[ POFs] [ POF-definition ] . Crossing only POFs is necessary but not sufficient,
184
184
however, to make forced unwinding safe, and for now we do not specify any safe
@@ -229,9 +229,9 @@ behavior. `"C"`-like ABIs are `"C"` itself but also related ABIs such as
229
229
230
230
| panic runtime | ABI | ` panic ` -unwind | Unforced foreign unwind |
231
231
| -------------- | ------------ | ------------------------------------- | ----------------------- |
232
- | ` panic=unwind ` | ` "C unwind" ` | unwind | unwind |
232
+ | ` panic=unwind ` | ` "C- unwind" ` | unwind | unwind |
233
233
| ` panic=unwind ` | ` "C" ` -like | abort | UB |
234
- | ` panic=abort ` | ` "C unwind" ` | ` panic! ` aborts | abort |
234
+ | ` panic=abort ` | ` "C- unwind" ` | ` panic! ` aborts | abort |
235
235
| ` panic=abort ` | ` "C" ` -like | ` panic! ` aborts (no unwinding occurs) | UB |
236
236
237
237
In debug mode, the compiler could insert code to catch unwind attempts at
@@ -257,7 +257,7 @@ In order to limit the scope of this RFC, the following limitations are imposed:
257
257
258
258
* No subtype relationship is defined between functions or function pointers
259
259
using different ABIs.
260
- * Coercions are not defined between ` "C" ` and ` "C unwind" ` .
260
+ * Coercions are not defined between ` "C" ` and ` "C- unwind" ` .
261
261
* As noted in the [ summary] [ summary ] , if a Rust frame containing a pending
262
262
` catch_unwind ` call is unwound by a foreign exception, the behavior is
263
263
undefined for now.
@@ -277,7 +277,7 @@ inconsistent across platforms, which is not desirable.
277
277
This design imposes some burden on existing codebases (mentioned
278
278
[ above] [ motivation ] ) to change their ` extern ` annotations to use the new ABI.
279
279
280
- Having separate ABIs for ` "C" ` and ` "C unwind" ` may make interface design more
280
+ Having separate ABIs for ` "C" ` and ` "C- unwind" ` may make interface design more
281
281
difficult, especially since this RFC [ postpones] [ unresolved-questions ]
282
282
introducing coercions between function types using different ABIs. Conversely,
283
283
a single ABI that "just works" with C++ (or any other language that may throw
@@ -304,13 +304,13 @@ explained in [this Inside Rust blog post][inside-rust-proposals]. The design in
304
304
RFC is referred to as "option 2" in that post.
305
305
306
306
"Option 1" in that blog post only differs from the current proposal in the
307
- behavior of a forced unwind across a ` "C unwind" ` boundary under ` panic=abort ` .
307
+ behavior of a forced unwind across a ` "C- unwind" ` boundary under ` panic=abort ` .
308
308
Under the current proposal, this type of unwind is permitted, allowing
309
309
` longjmp ` and ` pthread_exit ` to behave "normally" with both the ` "C" ` and the
310
- ` "C unwind" ` ABI across all platforms regardless of panic runtime. If
310
+ ` "C- unwind" ` ABI across all platforms regardless of panic runtime. If
311
311
[ non-POFs] [ POF-definition ] are unwound, this results in undefined behavior.
312
312
Under "option 1", however, all foreign unwinding, forced or unforced, is caught
313
- at ` "C unwind" ` boundaries under ` panic=abort ` , and the process is aborted.
313
+ at ` "C- unwind" ` boundaries under ` panic=abort ` , and the process is aborted.
314
314
This gives ` longjmp ` and ` pthread_exit ` surprising behavior on some platforms,
315
315
but avoids that cause of undefined behavior in the current proposal.
316
316
@@ -327,7 +327,7 @@ Our reasons for preferring the current proposal are:
327
327
328
328
* Introducing a new ABI makes reliance on cross-language exception handling
329
329
more explicit.
330
- * ` panic=abort ` can be safely used with ` extern "C unwind" ` (there is no
330
+ * ` panic=abort ` can be safely used with ` extern "C- unwind" ` (there is no
331
331
undefined behavior except with improperly used forced unwinding), but `extern
332
332
"C"` has more optimization potential (eliding landing pads). Having two ABIs
333
333
puts this choice in the hands of users.
@@ -344,7 +344,7 @@ Our reasons for preferring the current proposal are:
344
344
* This design has simpler forward compatibility with alternate ` panic! `
345
345
implementations. Any well-defined cross-language unwinding will require shims
346
346
to translate between the Rust unwinding mechanism and the natively provided
347
- mechanism. In this proposal, only ` "C unwind" ` boundaries would require shims.
347
+ mechanism. In this proposal, only ` "C- unwind" ` boundaries would require shims.
348
348
349
349
## Analysis of key design goals
350
350
[ analysis-of-design-goals ] : #analysis-of-design-goals
@@ -358,17 +358,17 @@ This constraint is met:
358
358
359
359
* Unwinding across a "C" boundary is UB regardless
360
360
of whether one is using ` panic=unwind ` or ` panic=abort ` .
361
- * Unwinding across a "C unwind" boundary is always defined,
361
+ * Unwinding across a "C- unwind" boundary is always defined,
362
362
though it is defined to abort if ` panic=abort ` is used.
363
363
* Forced exceptions behave the same regardless of panic mode.
364
364
365
365
### Optimization with panic=abort
366
366
367
367
Using this proposal, the compiler is ** almost always** able to reduce
368
368
overhead related to unwinding when using panic=abort. The one
369
- exception is that invoking a "C unwind" ABI still requires some kind
369
+ exception is that invoking a "C- unwind" ABI still requires some kind
370
370
of minimal landing pad to trigger an abort. The expectation is that
371
- very few functions will use the "C unwind" boundary unless they truly
371
+ very few functions will use the "C- unwind" boundary unless they truly
372
372
intend to unwind -- and, in that case, those functions are likely
373
373
using panic=unwind anyway, so this is not expected to make much
374
374
difference in practice.
@@ -378,7 +378,7 @@ difference in practice.
378
378
This constraint is met. If we were to change Rust panics to a
379
379
different mechanism from the mechanism used by the native ABI,
380
380
however, there would have to be a conversion step that interconverts
381
- between Rust panics and foreign exceptions at "C unwind" ABI
381
+ between Rust panics and foreign exceptions at "C- unwind" ABI
382
382
boundaries.
383
383
384
384
### Enable Rust panics to traverse through foreign frames
@@ -418,7 +418,7 @@ similar to how Rust's `panic=unwind` and `panic=abort` work for `panic!`
418
418
unwinds, and under the "option 3" proposal, the behavior would be similar for
419
419
foreign exceptions as well. In the current proposal, though, such foreign
420
420
exception support is not enabled by default with ` panic=unwind ` but requires
421
- the new ` "C unwind" ` ABI.
421
+ the new ` "C- unwind" ` ABI.
422
422
423
423
## Attributes on nightly Rust and prior RFCs
424
424
[ nightly-attributes ] : #attributes-on-nightly-rust-and-prior-rfcs
@@ -511,7 +511,7 @@ and rethrow them from another thread. Such a mechanism may either be
511
511
incorporated into the functionality of ` catch_unwind ` or provided as a separate
512
512
language or standard library feature.
513
513
514
- Coercions between ` "C unwind" ` function types (such as function pointers) and
514
+ Coercions between ` "C- unwind" ` function types (such as function pointers) and
515
515
the other ABIs are not part of this RFC. However, they will probably be
516
516
indispensible for API design, so we plan to provide them in a future RFC.
517
517
0 commit comments