|
104 | 104 | //! }
|
105 | 105 | //!
|
106 | 106 | //! #[custom_mir(dialect = "runtime", phase = "optimized")]
|
| 107 | +#![cfg_attr(bootstrap, doc = "#[cfg(any())]")] // disable the following function in doctests when `bootstrap` is set |
107 | 108 | //! fn push_and_pop<T>(v: &mut Vec<T>, value: T) {
|
108 | 109 | //! mir!(
|
109 | 110 | //! let _unused;
|
110 | 111 | //! let popped;
|
111 | 112 | //!
|
112 | 113 | //! {
|
113 |
| -//! Call(_unused = Vec::push(v, value), pop, UnwindContinue()) |
| 114 | +//! Call(_unused = Vec::push(v, value), ReturnTo(pop), UnwindContinue()) |
114 | 115 | //! }
|
115 | 116 | //!
|
116 | 117 | //! pop = {
|
117 |
| -//! Call(popped = Vec::pop(v), drop, UnwindContinue()) |
| 118 | +//! Call(popped = Vec::pop(v), ReturnTo(drop), UnwindContinue()) |
118 | 119 | //! }
|
119 | 120 | //!
|
120 | 121 | //! drop = {
|
121 |
| -//! Drop(popped, ret, UnwindContinue()) |
| 122 | +//! Drop(popped, ReturnTo(ret), UnwindContinue()) |
122 | 123 | //! }
|
123 | 124 | //!
|
124 | 125 | //! ret = {
|
|
242 | 243 | //! - `match some_int_operand` becomes a `SwitchInt`. Each arm should be `literal => basic_block`
|
243 | 244 | //! - The exception is the last arm, which must be `_ => basic_block` and corresponds to the
|
244 | 245 | //! otherwise branch.
|
245 |
| -//! - [`Call`] has an associated function as well. The third argument of this function is a normal |
246 |
| -//! function call expression, for example `my_other_function(a, 5)`. |
247 |
| -//! |
| 246 | +//! - [`Call`] has an associated function as well, with special syntax: |
| 247 | +//! `Call(ret_val = function(arg1, arg2, ...), ReturnTo(next_block), UnwindContinue())`. |
248 | 248 |
|
249 | 249 | #![unstable(
|
250 | 250 | feature = "custom_mir",
|
@@ -287,35 +287,68 @@ macro_rules! define {
|
287 | 287 | }
|
288 | 288 |
|
289 | 289 | // Unwind actions
|
| 290 | +pub struct UnwindActionArg; |
290 | 291 | define!(
|
291 | 292 | "mir_unwind_continue",
|
292 | 293 | /// An unwind action that continues unwinding.
|
293 |
| - fn UnwindContinue() |
| 294 | + fn UnwindContinue() -> UnwindActionArg |
294 | 295 | );
|
295 | 296 | define!(
|
296 | 297 | "mir_unwind_unreachable",
|
297 | 298 | /// An unwind action that triggers undefined behaviour.
|
298 |
| - fn UnwindUnreachable() -> BasicBlock |
| 299 | + fn UnwindUnreachable() -> UnwindActionArg |
299 | 300 | );
|
300 | 301 | define!(
|
301 | 302 | "mir_unwind_terminate",
|
302 | 303 | /// An unwind action that terminates the execution.
|
303 | 304 | ///
|
304 | 305 | /// `UnwindTerminate` can also be used as a terminator.
|
305 |
| - fn UnwindTerminate(reason: UnwindTerminateReason) |
| 306 | + fn UnwindTerminate(reason: UnwindTerminateReason) -> UnwindActionArg |
306 | 307 | );
|
307 | 308 | define!(
|
308 | 309 | "mir_unwind_cleanup",
|
309 | 310 | /// An unwind action that continues execution in a given basic blok.
|
310 |
| - fn UnwindCleanup(goto: BasicBlock) |
| 311 | + fn UnwindCleanup(goto: BasicBlock) -> UnwindActionArg |
311 | 312 | );
|
312 | 313 |
|
| 314 | +// Return destination for `Call` |
| 315 | +pub struct ReturnToArg; |
| 316 | +define!("mir_return_to", fn ReturnTo(goto: BasicBlock) -> ReturnToArg); |
| 317 | + |
313 | 318 | // Terminators
|
314 | 319 | define!("mir_return", fn Return() -> BasicBlock);
|
315 | 320 | define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock);
|
316 | 321 | define!("mir_unreachable", fn Unreachable() -> BasicBlock);
|
317 |
| -define!("mir_drop", fn Drop<T, U>(place: T, goto: BasicBlock, unwind_action: U)); |
318 |
| -define!("mir_call", fn Call<U>(call: (), goto: BasicBlock, unwind_action: U)); |
| 322 | +define!("mir_drop", |
| 323 | + /// Drop the contents of a place. |
| 324 | + /// |
| 325 | + /// The first argument must be a place. |
| 326 | + /// |
| 327 | + /// The second argument must be of the form `ReturnTo(bb)`, where `bb` is the basic block that |
| 328 | + /// will be jumped to after the destructor returns. |
| 329 | + /// |
| 330 | + /// The third argument describes what happens on unwind. It can be one of: |
| 331 | + /// - [`UnwindContinue`] |
| 332 | + /// - [`UnwindUnreachable`] |
| 333 | + /// - [`UnwindTerminate`] |
| 334 | + /// - [`UnwindCleanup`] |
| 335 | + fn Drop<T>(place: T, goto: ReturnToArg, unwind_action: UnwindActionArg) |
| 336 | +); |
| 337 | +define!("mir_call", |
| 338 | + /// Call a function. |
| 339 | + /// |
| 340 | + /// The first argument must be of the form `ret_val = fun(arg1, arg2, ...)`. |
| 341 | + /// |
| 342 | + /// The second argument must be of the form `ReturnTo(bb)`, where `bb` is the basic block that |
| 343 | + /// will be jumped to after the function returns. |
| 344 | + /// |
| 345 | + /// The third argument describes what happens on unwind. It can be one of: |
| 346 | + /// - [`UnwindContinue`] |
| 347 | + /// - [`UnwindUnreachable`] |
| 348 | + /// - [`UnwindTerminate`] |
| 349 | + /// - [`UnwindCleanup`] |
| 350 | + fn Call(call: (), goto: ReturnToArg, unwind_action: UnwindActionArg) |
| 351 | +); |
319 | 352 | define!("mir_unwind_resume",
|
320 | 353 | /// A terminator that resumes the unwinding.
|
321 | 354 | fn UnwindResume()
|
|
0 commit comments