Skip to content

Commit

Permalink
fix(wasm-gen): Include value into argument of invocable syscalls with…
Browse files Browse the repository at this point in the history
… destination param (#3484)
  • Loading branch information
techraed authored Nov 9, 2023
1 parent 35c1234 commit c910fe8
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
11 changes: 9 additions & 2 deletions utils/wasm-gen/src/generator/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ impl InvocableSysCall {
})
}

/// Returns the index of the destination param.
fn has_destination_param(&self) -> Option<usize> {
/// Returns the index of the destination param if a syscall has it.
fn destination_param_idx(&self) -> Option<usize> {
use InvocableSysCall::*;
use SysCallName::*;

Expand All @@ -206,6 +206,13 @@ impl InvocableSysCall {
}
}

/// Returns `true` for every syscall which has a destination param idx and that is not `gr_exit` syscall,
/// as it only has destination param.
fn has_destination_param_with_value(&self) -> bool {
self.destination_param_idx().is_some()
&& !matches!(self, InvocableSysCall::Loose(SysCallName::Exit))
}

// If syscall changes from fallible into infallible or vice versa in future,
// we'll see it by analyzing code coverage stats produced by fuzzer.
pub(crate) fn is_fallible(&self) -> bool {
Expand Down
30 changes: 24 additions & 6 deletions utils/wasm-gen/src/generator/syscalls/invocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ use gear_wasm_instrument::{
parity_wasm::elements::{BlockType, Instruction, Internal, ValueType},
syscalls::{ParamType, PtrInfo, PtrType, SysCallName, SysCallSignature},
};
use gsys::Hash;
use std::{
collections::{btree_map::Entry, BTreeMap, BinaryHeap, HashSet},
iter,
iter, mem,
num::NonZeroU32,
};

Expand Down Expand Up @@ -321,7 +322,7 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> {
self.unstructured.len()
);

if let Some(argument_index) = invocable.has_destination_param() {
if let Some(argument_index) = invocable.destination_param_idx() {
log::trace!(
" -- Building call instructions for a `{}` syscall with destination",
invocable.to_str()
Expand Down Expand Up @@ -376,13 +377,30 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> {
let upper_limit = mem_size.saturating_sub(100);
let offset = self.unstructured.int_in_range(0..=upper_limit)?;

vec![
// call `gsys::gr_source` with a memory offset
// 3 instructions for invoking `gsys::gr_source` and possibly 3 more
// for defining value param so HashWithValue will be constructed.
let mut ret = Vec::with_capacity(6);
ret.extend_from_slice(&[
// call `gsys::gr_source` storing actor id and some `offset` pointer.
Instruction::I32Const(offset as i32),
Instruction::Call(gr_source_call_indexes_handle),
// pass the offset as the first argument to the send-call
Instruction::I32Const(offset as i32),
]
]);

if invocable.has_destination_param_with_value() {
// We have to skip actor id bytes to define the following value param.
let skip_bytes = mem::size_of::<Hash>();
ret.extend_from_slice(&[
// Define 0 value for HashWithValue
Instruction::I32Const(0),
// Store value on the offset + skip_bytes. That will form HashWithValue.
Instruction::I32Store(2, skip_bytes as u32),
// Pass the offset as the first argument to the syscall with destination.
Instruction::I32Const(offset as i32),
]);
}

ret
} else {
let address_offset = match self.offsets.as_mut() {
Some(offsets) => {
Expand Down

0 comments on commit c910fe8

Please sign in to comment.