Coverage Report

Created: 2026-05-29 13:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/build/source/src/execution/interpreter_loop/variable.rs
Line
Count
Source
1
use core::ops::ControlFlow;
2
3
use crate::{
4
    assert_validated::UnwrapValidatedExt,
5
    core::{
6
        indices::{GlobalIdx, LocalIdx},
7
        reader::types::opcode,
8
    },
9
    execution::interpreter_loop::{define_instruction_fn, Args},
10
};
11
12
define_instruction_fn! {
13
    local_get,
14
    fuel_check = flat(opcode::LOCAL_GET),
15
    |Args {
16
         resumable, wasm, ..
17
5.71M
     }| {
18
        // SAFETY: Validation guarantees there to be a valid local index
19
        // next.
20
5.71M
        let local_idx = unsafe { LocalIdx::read_unchecked(wasm) };
21
5.71M
        let value = *resumable.stack.get_local(local_idx);
22
5.71M
        resumable.stack.push_value(value)
?0
;
23
5.71M
        trace!("Instruction: local.get {} [] -> [t]", local_idx);
24
5.71M
        Ok(ControlFlow::Continue(()))
25
5.71M
    }
26
}
27
28
define_instruction_fn! {
29
    local_set,
30
    fuel_check = flat(opcode::LOCAL_SET),
31
    |Args {
32
         resumable, wasm, ..
33
1.31M
     }| {
34
        // SAFETY: Validation guarantees there to be a valid local index
35
        // next.
36
1.31M
        let local_idx = unsafe { LocalIdx::read_unchecked(wasm) };
37
1.31M
        let value = resumable.stack.pop_value();
38
1.31M
        *resumable.stack.get_local_mut(local_idx) = value;
39
1.31M
        trace!("Instruction: local.set {} [t] -> []", local_idx);
40
1.31M
        Ok(ControlFlow::Continue(()))
41
1.31M
    }
42
}
43
44
define_instruction_fn! {
45
    local_tee,
46
    fuel_check = flat(opcode::LOCAL_TEE),
47
    |Args {
48
         resumable, wasm, ..
49
1.91k
     }| {
50
        // SAFETY: Validation guarantees there to be a valid local index
51
        // next.
52
1.91k
        let local_idx = unsafe { LocalIdx::read_unchecked(wasm) };
53
1.91k
        let value = resumable.stack.peek_value().unwrap_validated();
54
1.91k
        *resumable.stack.get_local_mut(local_idx) = value;
55
1.91k
        trace!("Instruction: local.tee {} [t] -> [t]", local_idx);
56
1.91k
        Ok(ControlFlow::Continue(()))
57
1.91k
    }
58
}
59
60
define_instruction_fn! {
61
    global_get,
62
    fuel_check = flat(opcode::GLOBAL_GET),
63
    |Args {
64
         store_inner,
65
         modules,
66
         resumable,
67
         wasm,
68
         current_module,
69
         ..
70
235
     }| {
71
        // SAFETY: Validation guarantees there to be a valid global
72
        // index next.
73
235
        let global_idx = unsafe { GlobalIdx::read_unchecked(wasm) };
74
        // SAFETY: The current module address must come from the current
75
        // store, because it is the only parameter to this function that
76
        // can contain module addresses. All stores guarantee all
77
        // addresses in them to be valid within themselves.
78
235
        let module = unsafe { modules.get(*current_module) };
79
80
        // SAFETY: Validation guarantees the global index to be valid in
81
        // the current module.
82
235
        let global_addr = *unsafe { module.global_addrs.get(global_idx) };
83
        // SAFETY: This global address was just read from the current
84
        // store. Therefore, it is valid in the current store.
85
235
        let global = unsafe { store_inner.globals.get(global_addr) };
86
87
235
        resumable.stack.push_value(global.value)
?0
;
88
89
235
        trace!(
90
            "Instruction: global.get '{}' [<GLOBAL>] -> [{:?}]",
91
            global_idx,
92
            global.value
93
        );
94
235
        Ok(ControlFlow::Continue(()))
95
235
    }
96
}
97
98
define_instruction_fn! {
99
    global_set,
100
    fuel_check = flat(opcode::GLOBAL_SET),
101
    |Args {
102
         store_inner,
103
         modules,
104
         resumable,
105
         wasm,
106
         current_module,
107
         ..
108
59
     }| {
109
        // SAFETY: Validation guarantees there to be a valid global
110
        // index next.
111
59
        let global_idx = unsafe { GlobalIdx::read_unchecked(wasm) };
112
        // SAFETY: The current module address must come from the current
113
        // store, because it is the only parameter to this function that
114
        // can contain module addresses. All stores guarantee all
115
        // addresses in them to be valid within themselves.
116
59
        let module = unsafe { modules.get(*current_module) };
117
        // SAFETY: Validation guarantees the global index to be valid in
118
        // the current module.
119
59
        let global_addr = *unsafe { module.global_addrs.get(global_idx) };
120
        // SAFETY: This global address was just read from the current
121
        // store. Therefore, it is valid in the current store.
122
59
        let global = unsafe { store_inner.globals.get_mut(global_addr) };
123
124
59
        global.value = resumable.stack.pop_value();
125
59
        trace!("Instruction: GLOBAL_SET");
126
59
        Ok(ControlFlow::Continue(()))
127
59
    }
128
}