wasmtime_internal_cranelift/func_environ/stack_switching/
control_effect.rs1use cranelift_codegen::ir;
2use cranelift_codegen::ir::InstBuilder;
3use cranelift_codegen::ir::types::{I32, I64};
4use cranelift_frontend::FunctionBuilder;
5
6#[derive(Clone, Copy)]
13pub struct ControlEffect(ir::Value);
14
15impl ControlEffect {
16 pub fn signal(&self, builder: &mut FunctionBuilder) -> ir::Value {
18 builder.ins().ushr_imm(self.0, 32)
19 }
20
21 pub fn from_u64(val: ir::Value) -> Self {
22 Self(val)
23 }
24
25 pub fn to_u64(&self) -> ir::Value {
26 self.0
27 }
28
29 pub fn encode_resume(builder: &mut FunctionBuilder) -> Self {
30 let discriminant = builder.ins().iconst(
31 I64,
32 i64::from(wasmtime_environ::CONTROL_EFFECT_RESUME_DISCRIMINANT),
33 );
34 let val = builder.ins().ishl_imm(discriminant, 32);
35
36 Self(val)
37 }
38
39 pub fn encode_switch(builder: &mut FunctionBuilder) -> Self {
40 let discriminant = builder.ins().iconst(
41 I64,
42 i64::from(wasmtime_environ::CONTROL_EFFECT_SWITCH_DISCRIMINANT),
43 );
44 let val = builder.ins().ishl_imm(discriminant, 32);
45
46 Self(val)
47 }
48
49 pub fn encode_suspend(builder: &mut FunctionBuilder, handler_index: ir::Value) -> Self {
50 let discriminant = builder.ins().iconst(
51 I64,
52 i64::from(wasmtime_environ::CONTROL_EFFECT_SUSPEND_DISCRIMINANT),
53 );
54 let val = builder.ins().ishl_imm(discriminant, 32);
55 let handler_index = builder.ins().uextend(I64, handler_index);
56 let val = builder.ins().bor(val, handler_index);
57
58 Self(val)
59 }
60
61 pub fn handler_index(self, builder: &mut FunctionBuilder) -> ir::Value {
63 builder.ins().ireduce(I32, self.0)
64 }
65}