ruka_codegen_wasm/memory_and_release/
string_ops.rs

1use super::*;
2
3pub(crate) fn emit_string_release(
4    body: &mut walrus::InstrSeqBuilder,
5    runtime: &RuntimeFunctions,
6    memory_id: MemoryId,
7    string_local: LocalId,
8    scratch_ptr_local: LocalId,
9    scratch_header_local: LocalId,
10    scratch_len_local: LocalId,
11) -> Result<(), LowerError> {
12    let free = runtime_function(runtime, wasm_api::RT_FREE_BYTES_SYMBOL)?;
13    emit_string_release_with_free(
14        body,
15        memory_id,
16        string_local,
17        scratch_ptr_local,
18        scratch_header_local,
19        scratch_len_local,
20        free.function_id,
21    );
22    Ok(())
23}
24
25pub(crate) fn emit_string_release_with_free(
26    body: &mut walrus::InstrSeqBuilder,
27    memory_id: MemoryId,
28    string_local: LocalId,
29    scratch_ptr_local: LocalId,
30    scratch_header_local: LocalId,
31    scratch_len_local: LocalId,
32    free_id: FunctionId,
33) {
34    body.local_get(string_local)
35        .local_set(scratch_ptr_local)
36        .local_get(scratch_ptr_local)
37        .i32_const(0)
38        .binop(BinaryOp::I32Ne)
39        .if_else(
40            None,
41            |then_| {
42                then_
43                    .local_get(scratch_ptr_local)
44                    .instr(Load {
45                        memory: memory_id,
46                        kind: LoadKind::I32 { atomic: false },
47                        arg: MemArg {
48                            align: 4,
49                            offset: STRING_HEADER_OFFSET,
50                        },
51                    })
52                    .local_set(scratch_header_local)
53                    .local_get(scratch_header_local)
54                    .i32_const(0)
55                    .binop(BinaryOp::I32Eq)
56                    .if_else(
57                        None,
58                        |_static_literal| {},
59                        |heap_string| {
60                            heap_string
61                                .local_get(scratch_ptr_local)
62                                .instr(Load {
63                                    memory: memory_id,
64                                    kind: LoadKind::I32 { atomic: false },
65                                    arg: MemArg {
66                                        align: 4,
67                                        offset: STRING_LEN_OFFSET,
68                                    },
69                                })
70                                .local_set(scratch_len_local)
71                                .local_get(scratch_ptr_local)
72                                .local_get(scratch_len_local)
73                                .i32_const(STRING_DATA_OFFSET as i32)
74                                .binop(BinaryOp::I32Add)
75                                .call(free_id);
76                        },
77                    );
78            },
79            |_else_| {},
80        );
81}