1
//! Boxing an i32-repr value for a `$pair` car or an anyref slot. An index boxes
2
//! through the range-checked `box_index`; a bool is i31 0/1 in a bool-typed
3
//! cell, but `nil`-as-null in an anyref slot, where `null?` tests
4
//! `ref.is_null`.
5

            
6
use crate::ast::{PairElement, WasmType};
7
use crate::compiler::context::CompileContext;
8
use crate::compiler::emit::FunctionEmitter;
9

            
10
/// Boxes a value of type `ty` (on the stack) into an anyref slot. References are
11
/// anyref subtypes already.
12
13363
pub(in crate::compiler) fn emit_box_anyref(
13
13363
    ctx: &CompileContext,
14
13363
    emit: &mut FunctionEmitter,
15
13363
    ty: WasmType,
16
13363
) {
17
13363
    match ty {
18
3735
        WasmType::I32 => emit.call(ctx.ids.box_index),
19
6308
        WasmType::Bool => emit.call(ctx.ids.box_bool),
20
3320
        _ => {}
21
    }
22
13363
}
23

            
24
/// Boxes a car of element `value` (on the stack) for a chain whose cells are
25
/// `slot`.
26
25398
pub(in crate::compiler) fn emit_box_cell(
27
25398
    ctx: &CompileContext,
28
25398
    emit: &mut FunctionEmitter,
29
25398
    value: PairElement,
30
25398
    slot: PairElement,
31
25398
) {
32
25398
    match (slot, value) {
33
415
        (PairElement::AnyRef, _) => emit_box_anyref(ctx, emit, value.as_wasm_type()),
34
12035
        (_, PairElement::I32) => emit.call(ctx.ids.box_index),
35
2241
        (_, PairElement::Bool) => emit.ref_i31(),
36
10707
        _ => {}
37
    }
38
25398
}
39

            
40
/// Retypes a `from` chain (on the stack) as a `to` chain. Only a bool chain's
41
/// cells (i31 0 nils) differ from their anyref form, so it alone is rebuilt;
42
/// every other cell is already a valid anyref car.
43
3320
pub(in crate::compiler) fn emit_relabel_chain(
44
3320
    ctx: &CompileContext,
45
3320
    emit: &mut FunctionEmitter,
46
3320
    from: PairElement,
47
3320
    to: PairElement,
48
3320
) {
49
3320
    if from == PairElement::Bool && to == PairElement::AnyRef {
50
249
        emit.call(ctx.ids.bool_chain_to_anyref);
51
3071
    }
52
3320
}