Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/cranelift/src/func_environ/stack_switching/control_effect.rs
1693 views
1
use cranelift_codegen::ir;
2
use cranelift_codegen::ir::InstBuilder;
3
use cranelift_codegen::ir::types::{I32, I64};
4
use cranelift_frontend::FunctionBuilder;
5
6
/// Universal control effect. This structure encodes return signal,
7
/// resume signal, suspension signal, and handler index into a
8
/// u64 value. This instance is used at compile time. There is a runtime
9
/// counterpart in `continuations/src/lib.rs`.
10
/// We convert to and from u64 as follows: The low 32 bits of the u64 are the
11
/// discriminant, the high 32 bits are the handler_index (if `Suspend`)
12
#[derive(Clone, Copy)]
13
pub struct ControlEffect(ir::Value);
14
15
impl ControlEffect {
16
// Returns the discriminant
17
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
/// Returns the payload of the `Suspend` variant
62
pub fn handler_index(self, builder: &mut FunctionBuilder) -> ir::Value {
63
builder.ins().ireduce(I32, self.0)
64
}
65
}
66
67