Inserts instructions necessary for checking the stack limit into the prologue. This function will generate instructions necessary for perform a stack check at the header of a function. The stack check is intended to trap if the stack pointer goes below a particular threshold, preventing stack overflow in wasm or other code. The `stack_limit` argument here is the register which holds the threshold
(
&self,
stack_limit: Reg,
stack_size: u32,
insts: &mut SmallInstVec<M::I>,
)
| 1350 | /// because we just need to perform a stack check before progressing with |
| 1351 | /// the rest of the function. |
| 1352 | fn insert_stack_check( |
| 1353 | &self, |
| 1354 | stack_limit: Reg, |
| 1355 | stack_size: u32, |
| 1356 | insts: &mut SmallInstVec<M::I>, |
| 1357 | ) { |
| 1358 | // With no explicit stack allocated we can just emit the simple check of |
| 1359 | // the stack registers against the stack limit register, and trap if |
| 1360 | // it's out of bounds. |
| 1361 | if stack_size == 0 { |
| 1362 | insts.extend(M::gen_stack_lower_bound_trap(stack_limit)); |
| 1363 | return; |
| 1364 | } |
| 1365 | |
| 1366 | // Note that the 32k stack size here is pretty special. See the |
| 1367 | // documentation in x86/abi.rs for why this is here. The general idea is |
| 1368 | // that we're protecting against overflow in the addition that happens |
| 1369 | // below. |
| 1370 | if stack_size >= 32 * 1024 { |
| 1371 | insts.extend(M::gen_stack_lower_bound_trap(stack_limit)); |
| 1372 | } |
| 1373 | |
| 1374 | // Add the `stack_size` to `stack_limit`, placing the result in |
| 1375 | // `scratch`. |
| 1376 | // |
| 1377 | // Note though that `stack_limit`'s register may be the same as |
| 1378 | // `scratch`. If our stack size doesn't fit into an immediate this |
| 1379 | // means we need a second scratch register for loading the stack size |
| 1380 | // into a register. |
| 1381 | let scratch = Writable::from_reg(M::get_stacklimit_reg(self.call_conv)); |
| 1382 | insts.extend(M::gen_add_imm( |
| 1383 | self.call_conv, |
| 1384 | scratch, |
| 1385 | stack_limit, |
| 1386 | stack_size, |
| 1387 | )); |
| 1388 | insts.extend(M::gen_stack_lower_bound_trap(scratch.to_reg())); |
| 1389 | } |
| 1390 | } |
| 1391 | |
| 1392 | /// Generates the instructions necessary for the `gv` to be materialized into a |
no test coverage detected