Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/cranelift/src/func_environ/stack_switching/fatpointer.rs
1693 views
1
use cranelift_codegen::ir;
2
use cranelift_codegen::ir::InstBuilder;
3
4
/// Returns the Cranelift type used to represent all of the following:
5
/// - wasm values of type `(ref null $ct)` and `(ref $ct)`
6
/// - equivalently: runtime values of type `Option<VMContObj>` and `VMContObj`
7
/// Note that a `VMContObj` is a fat pointer consisting of a pointer to
8
/// `VMContRef` and a pointer-sized revision counter. We represent this as 2 words
9
/// (pointer and usize).
10
pub fn fatpointer_type(env: &crate::func_environ::FuncEnvironment) -> ir::Type {
11
let ptr_bits = env.pointer_type().bits();
12
ir::Type::int((2 * ptr_bits).try_into().unwrap()).unwrap()
13
}
14
15
/// Turns a (possibly null) reference to a continuation object into a tuple
16
/// (revision, contref_ptr). If `contobj` denotes a wasm null reference, the
17
/// contref_ptr part will be a null pointer.
18
pub(crate) fn deconstruct<'a>(
19
env: &mut crate::func_environ::FuncEnvironment<'a>,
20
pos: &mut cranelift_codegen::cursor::FuncCursor,
21
contobj: ir::Value,
22
) -> (ir::Value, ir::Value) {
23
debug_assert_eq!(pos.func.dfg.value_type(contobj), fatpointer_type(env));
24
let ptr_ty = env.pointer_type();
25
let ptr_bits = ptr_ty.bits();
26
27
let contref = pos.ins().ireduce(ptr_ty, contobj);
28
let shifted = pos.ins().ushr_imm(contobj, i64::from(ptr_bits));
29
let revision_counter = pos.ins().ireduce(ptr_ty, shifted);
30
31
(revision_counter, contref)
32
}
33
34
/// Constructs a continuation object from a given contref and revision pointer.
35
/// The contref_addr may be 0, to indicate that we want to build a wasm null reference.
36
pub(crate) fn construct<'a>(
37
env: &mut crate::func_environ::FuncEnvironment<'a>,
38
pos: &mut cranelift_codegen::cursor::FuncCursor,
39
revision_counter: ir::Value,
40
contref_addr: ir::Value,
41
) -> ir::Value {
42
let ptr_ty = env.pointer_type();
43
let ptr_bits = ptr_ty.bits();
44
let fat_ptr_ty = fatpointer_type(env);
45
46
debug_assert_eq!(pos.func.dfg.value_type(contref_addr), ptr_ty);
47
debug_assert_eq!(pos.func.dfg.value_type(revision_counter), ptr_ty);
48
49
let contref_addr = pos.ins().uextend(fat_ptr_ty, contref_addr);
50
let revision_counter = pos.ins().uextend(fat_ptr_ty, revision_counter);
51
let shifted_counter = pos.ins().ishl_imm(revision_counter, i64::from(ptr_bits));
52
let contobj = pos.ins().bor(shifted_counter, contref_addr);
53
54
contobj
55
}
56
57