@@ -9,6 +9,7 @@ use crate::{
9
9
masm:: { IntCmpKind , MacroAssembler , OperandSize , RegImm , TrapCode } ,
10
10
stack:: TypedReg ,
11
11
} ;
12
+ use anyhow:: Result ;
12
13
use wasmtime_environ:: Signed ;
13
14
14
15
/// A newtype to represent an immediate offset argument for a heap access.
@@ -86,30 +87,33 @@ pub(crate) fn load_dynamic_heap_bounds<M>(
86
87
masm : & mut M ,
87
88
heap : & HeapData ,
88
89
ptr_size : OperandSize ,
89
- ) -> Bounds
90
+ ) -> Result < Bounds >
90
91
where
91
92
M : MacroAssembler ,
92
93
{
93
- let dst = context. any_gpr ( masm) ;
94
+ let dst = context. any_gpr ( masm) ? ;
94
95
match heap. memory . static_heap_size ( ) {
95
96
// Constant size, no need to perform a load.
96
- Some ( size) => masm. mov ( writable ! ( dst) , RegImm :: i64 ( size. signed ( ) ) , ptr_size) ,
97
+ Some ( size) => masm. mov ( writable ! ( dst) , RegImm :: i64 ( size. signed ( ) ) , ptr_size) ? ,
97
98
98
99
None => {
99
100
let scratch = scratch ! ( M ) ;
100
101
let base = if let Some ( offset) = heap. import_from {
101
- let addr = masm. address_at_vmctx ( offset) ;
102
- masm. load_ptr ( addr, writable ! ( scratch) ) ;
102
+ let addr = masm. address_at_vmctx ( offset) ? ;
103
+ masm. load_ptr ( addr, writable ! ( scratch) ) ? ;
103
104
scratch
104
105
} else {
105
106
vmctx ! ( M )
106
107
} ;
107
- let addr = masm. address_at_reg ( base, heap. current_length_offset ) ;
108
- masm. load_ptr ( addr, writable ! ( dst) ) ;
108
+ let addr = masm. address_at_reg ( base, heap. current_length_offset ) ? ;
109
+ masm. load_ptr ( addr, writable ! ( dst) ) ? ;
109
110
}
110
111
}
111
112
112
- Bounds :: from_typed_reg ( TypedReg :: new ( heap. index_type ( ) , dst) )
113
+ Ok ( Bounds :: from_typed_reg ( TypedReg :: new (
114
+ heap. index_type ( ) ,
115
+ dst,
116
+ ) ) )
113
117
}
114
118
115
119
/// This function ensures the following:
@@ -125,10 +129,10 @@ pub(crate) fn ensure_index_and_offset<M: MacroAssembler>(
125
129
index : Index ,
126
130
offset : u64 ,
127
131
heap_ty_size : OperandSize ,
128
- ) -> ImmOffset {
132
+ ) -> Result < ImmOffset > {
129
133
match u32:: try_from ( offset) {
130
134
// If the immediate offset fits in a u32, then we simply return.
131
- Ok ( offs) => ImmOffset :: from_u32 ( offs) ,
135
+ Ok ( offs) => Ok ( ImmOffset :: from_u32 ( offs) ) ,
132
136
// Else we adjust the index to be index = index + offset, including an
133
137
// overflow check, and return 0 as the offset.
134
138
Err ( _) => {
@@ -138,9 +142,9 @@ pub(crate) fn ensure_index_and_offset<M: MacroAssembler>(
138
142
RegImm :: i64 ( offset as i64 ) ,
139
143
heap_ty_size,
140
144
TrapCode :: HEAP_OUT_OF_BOUNDS ,
141
- ) ;
145
+ ) ? ;
142
146
143
- ImmOffset :: from_u32 ( 0 )
147
+ Ok ( ImmOffset :: from_u32 ( 0 ) )
144
148
}
145
149
}
146
150
}
@@ -157,28 +161,28 @@ pub(crate) fn load_heap_addr_checked<M, F>(
157
161
index : Index ,
158
162
offset : ImmOffset ,
159
163
mut emit_check_condition : F ,
160
- ) -> Reg
164
+ ) -> Result < Reg >
161
165
where
162
166
M : MacroAssembler ,
163
- F : FnMut ( & mut M , Bounds , Index ) -> IntCmpKind ,
167
+ F : FnMut ( & mut M , Bounds , Index ) -> Result < IntCmpKind > ,
164
168
{
165
- let cmp_kind = emit_check_condition ( masm, bounds, index) ;
169
+ let cmp_kind = emit_check_condition ( masm, bounds, index) ? ;
166
170
167
- masm. trapif ( cmp_kind, TrapCode :: HEAP_OUT_OF_BOUNDS ) ;
168
- let addr = context. any_gpr ( masm) ;
171
+ masm. trapif ( cmp_kind, TrapCode :: HEAP_OUT_OF_BOUNDS ) ? ;
172
+ let addr = context. any_gpr ( masm) ? ;
169
173
170
- load_heap_addr_unchecked ( masm, heap, index, offset, addr, ptr_size) ;
174
+ load_heap_addr_unchecked ( masm, heap, index, offset, addr, ptr_size) ? ;
171
175
if !enable_spectre_mitigation {
172
- addr
176
+ Ok ( addr)
173
177
} else {
174
178
// Conditionally assign 0 to the register holding the base address if
175
179
// the comparison kind is met.
176
- let tmp = context. any_gpr ( masm) ;
177
- masm. mov ( writable ! ( tmp) , RegImm :: i64 ( 0 ) , ptr_size) ;
178
- let cmp_kind = emit_check_condition ( masm, bounds, index) ;
179
- masm. cmov ( writable ! ( addr) , tmp, cmp_kind, ptr_size) ;
180
+ let tmp = context. any_gpr ( masm) ? ;
181
+ masm. mov ( writable ! ( tmp) , RegImm :: i64 ( 0 ) , ptr_size) ? ;
182
+ let cmp_kind = emit_check_condition ( masm, bounds, index) ? ;
183
+ masm. cmov ( writable ! ( addr) , tmp, cmp_kind, ptr_size) ? ;
180
184
context. free_reg ( tmp) ;
181
- addr
185
+ Ok ( addr)
182
186
}
183
187
}
184
188
@@ -192,14 +196,15 @@ pub(crate) fn load_heap_addr_unchecked<M>(
192
196
offset : ImmOffset ,
193
197
dst : Reg ,
194
198
ptr_size : OperandSize ,
195
- ) where
199
+ ) -> Result < ( ) >
200
+ where
196
201
M : MacroAssembler ,
197
202
{
198
203
let base = if let Some ( offset) = heap. import_from {
199
204
// If the WebAssembly memory is imported, load the address into
200
205
// the scratch register.
201
206
let scratch = scratch ! ( M ) ;
202
- masm. load_ptr ( masm. address_at_vmctx ( offset) , writable ! ( scratch) ) ;
207
+ masm. load_ptr ( masm. address_at_vmctx ( offset) ? , writable ! ( scratch) ) ? ;
203
208
scratch
204
209
} else {
205
210
// Else if the WebAssembly memory is defined in the current module,
@@ -208,17 +213,18 @@ pub(crate) fn load_heap_addr_unchecked<M>(
208
213
} ;
209
214
210
215
// Load the base of the memory into the `addr` register.
211
- masm. load_ptr ( masm. address_at_reg ( base, heap. offset ) , writable ! ( dst) ) ;
216
+ masm. load_ptr ( masm. address_at_reg ( base, heap. offset ) ? , writable ! ( dst) ) ? ;
212
217
// Start by adding the index to the heap base addr.
213
218
let index_reg = index. as_typed_reg ( ) . reg ;
214
- masm. add ( writable ! ( dst) , dst, index_reg. into ( ) , ptr_size) ;
219
+ masm. add ( writable ! ( dst) , dst, index_reg. into ( ) , ptr_size) ? ;
215
220
216
221
if offset. as_u32 ( ) > 0 {
217
222
masm. add (
218
223
writable ! ( dst) ,
219
224
dst,
220
225
RegImm :: i64 ( offset. as_u32 ( ) as i64 ) ,
221
226
ptr_size,
222
- ) ;
227
+ ) ? ;
223
228
}
229
+ Ok ( ( ) )
224
230
}
0 commit comments