Skip to content

Commit c32c7c7

Browse files
committed
properly use and encode copy_span_{asc,des}
1 parent 44c8850 commit c32c7c7

File tree

4 files changed

+45
-9
lines changed

4 files changed

+45
-9
lines changed

crates/wasmi/src/engine/executor/handler/dispatch.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,8 @@ pub fn op_code_to_handler(code: OpCode) -> Handler {
347347
OpCode::Copy => exec::copy,
348348
OpCode::Copy32 => exec::copy32,
349349
OpCode::Copy64 => exec::copy64,
350-
OpCode::CopySpan => exec::copy_span,
350+
OpCode::CopySpanAsc => exec::copy_span_asc,
351+
OpCode::CopySpanDes => exec::copy_span_des,
351352
// global
352353
OpCode::GlobalGet => exec::global_get,
353354
OpCode::GlobalSet => exec::global_set,

crates/wasmi/src/engine/executor/handler/exec.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use crate::{
1818
executor::handler::{
1919
state::DoneReason,
2020
utils::{
21-
exec_copy_span,
21+
exec_copy_span_asc,
22+
exec_copy_span_des,
2223
resolve_global,
2324
resolve_indirect_func,
2425
set_global,
@@ -80,7 +81,7 @@ pub fn consume_fuel(
8081
dispatch!(state, ip, sp, mem0, mem0_len, instance)
8182
}
8283

83-
pub fn copy_span(
84+
pub fn copy_span_asc(
8485
state: &mut VmState,
8586
ip: Ip,
8687
sp: Sp,
@@ -90,13 +91,35 @@ pub fn copy_span(
9091
) -> Done {
9192
let (
9293
ip,
93-
crate::ir::decode::CopySpan {
94+
crate::ir::decode::CopySpanAsc {
9495
results,
9596
values,
9697
len,
9798
},
9899
) = unsafe { decode_op(ip) };
99-
exec_copy_span(sp, results, values, len);
100+
debug_assert!(results.head() <= values.head());
101+
exec_copy_span_asc(sp, results, values, len);
102+
dispatch!(state, ip, sp, mem0, mem0_len, instance)
103+
}
104+
105+
pub fn copy_span_des(
106+
state: &mut VmState,
107+
ip: Ip,
108+
sp: Sp,
109+
mem0: *mut u8,
110+
mem0_len: usize,
111+
instance: NonNull<InstanceEntity>,
112+
) -> Done {
113+
let (
114+
ip,
115+
crate::ir::decode::CopySpanDes {
116+
results,
117+
values,
118+
len,
119+
},
120+
) = unsafe { decode_op(ip) };
121+
debug_assert!(results.head() >= values.head());
122+
exec_copy_span_des(sp, results, values, len);
100123
dispatch!(state, ip, sp, mem0, mem0_len, instance)
101124
}
102125

@@ -311,7 +334,7 @@ pub fn return_span(
311334
let dst = SlotSpan::new(Slot::from(0));
312335
let src = values.span();
313336
let len = values.len();
314-
exec_copy_span(sp, dst, src, len);
337+
exec_copy_span_asc(sp, dst, src, len);
315338
exec_return!(state, sp, mem0, mem0_len, instance)
316339
}
317340

crates/wasmi/src/engine/executor/handler/utils.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ macro_rules! exec_return {
141141
}};
142142
}
143143

144-
pub fn exec_copy_span(sp: Sp, dst: SlotSpan, src: SlotSpan, len: u16) {
144+
pub fn exec_copy_span_asc(sp: Sp, dst: SlotSpan, src: SlotSpan, len: u16) {
145145
let dst = dst.iter(len);
146146
let src = src.iter(len);
147147
for (dst, src) in dst.into_iter().zip(src.into_iter()) {
@@ -150,6 +150,15 @@ pub fn exec_copy_span(sp: Sp, dst: SlotSpan, src: SlotSpan, len: u16) {
150150
}
151151
}
152152

153+
pub fn exec_copy_span_des(sp: Sp, dst: SlotSpan, src: SlotSpan, len: u16) {
154+
let dst = dst.iter(len);
155+
let src = src.iter(len);
156+
for (dst, src) in dst.into_iter().zip(src.into_iter()).rev() {
157+
let value: u64 = get_value(src, sp);
158+
set_value(sp, dst, value);
159+
}
160+
}
161+
153162
pub fn extract_mem0(
154163
store: &mut PrunedStore,
155164
instance: NonNull<InstanceEntity>,

crates/wasmi/src/engine/translator/func/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,9 +495,12 @@ impl FuncTranslator {
495495
// Case: results and values are equal and therefore the copy is a no-op
496496
return Ok(());
497497
}
498-
debug_assert!(!SlotSpan::has_overlapping_copies(results, values, len));
498+
let copy_span = match results.head() > values.head() {
499+
true => Op::copy_span_des,
500+
false => Op::copy_span_asc,
501+
};
499502
self.instrs.encode(
500-
Op::copy_span(results, values, len),
503+
copy_span(results, values, len),
501504
consume_fuel_instr,
502505
|costs: &FuelCostsProvider| costs.fuel_for_copying_values(u64::from(len)),
503506
)?;

0 commit comments

Comments
 (0)