Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ethexe): remove to_vec and mem::transmute from ethexe #4419

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ethexe/processor/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,13 @@ pub enum LocalOutcome {

Transition(StateTransition),
}

pub fn unpack_i64(packed: i64) -> (i32, i32) {
let high = (packed >> 32) as i32; // Shift right and cast
let low = (packed & 0xFFFFFFFF) as i32; // Mask and cast
(high, low)
}

pub fn pack_i64(high: i32, low: i32) -> i64 {
((high as i64) << 32) | (low as i64 & 0xFFFFFFFF)
}
26 changes: 17 additions & 9 deletions ethexe/processor/src/host/api/lazy_pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,27 @@ fn pre_process_memory_accesses(

let memory = MemoryWrap(caller.data().memory());

let reads = memory.slice_by_val(&caller, reads).to_vec();
let reads = memory.slice_by_val(&caller, reads);

let writes = memory.slice_by_val(&caller, writes).to_vec();
let writes = memory.slice_by_val(&caller, writes);

// 8 len bytes of u64 counter.
// TODO: why gas_bytes is &mut [u8; 8] and not &mut u64 (?).
let gas_bytes = memory
// read gas_bytes into `mut` variable because `pre_process_memory_accesses` updates
// it, then write updated slice to memory. Can't use `slice_mut` here without using `.to_vec()`
// on `writes` and `reads`.
let mut gas_counter: u64 = u64::from_le_bytes(
memory
.slice(&caller, gas_bytes as usize, 8)
.try_into()
.unwrap(),
);

let res =
lazy_pages_detail::pre_process_memory_accesses(reads, writes, &mut gas_counter) as i32;

memory
.slice_mut(&mut caller, gas_bytes as usize, 8)
.try_into()
.unwrap();

let res = lazy_pages_detail::pre_process_memory_accesses(&reads, &writes, gas_bytes) as i32;

.copy_from_slice(&gas_counter.to_le_bytes());
log::trace!(target: "host_call", "pre_process_memory_accesses(..) -> {res:?}");

res
Expand Down
7 changes: 4 additions & 3 deletions ethexe/processor/src/host/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::common::{pack_i64, unpack_i64};

use super::context::HostContext;
use parity_scale_codec::{Decode, Encode};
use sp_wasm_interface::{FunctionContext as _, IntoValue as _, StoreData};
use std::mem;
use wasmtime::{Caller, Memory, StoreContext, StoreContextMut};

pub mod allocator;
Expand Down Expand Up @@ -58,7 +59,7 @@ impl MemoryWrap {
store: impl Into<StoreContext<'a, T>>,
ptr_len: i64,
) -> &'a [u8] {
let [ptr, len]: [i32; 2] = unsafe { mem::transmute(ptr_len) };
let (ptr, len) = unpack_i64(ptr_len);
playX18 marked this conversation as resolved.
Show resolved Hide resolved

self.slice(store, ptr as usize, len as usize)
}
Expand Down Expand Up @@ -119,7 +120,7 @@ pub fn allocate_and_write_raw(

memory.write(&mut caller, ptr as usize, data).unwrap();

let res = unsafe { mem::transmute::<[i32; 2], i64>([ptr, len as i32]) };
let res = pack_i64(ptr, len as i32);

(caller, res)
}
8 changes: 5 additions & 3 deletions ethexe/processor/src/host/api/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

// TODO (breathx): remove cloning of slices from wasm memory.

use crate::host::{api::MemoryWrap, context::HostContext};
use crate::{
common::pack_i64,
host::{api::MemoryWrap, context::HostContext},
};
use anyhow::Result;
use core::mem;
use gear_runtime_interface::{sandbox_detail, Instantiate};
use parity_scale_codec::Encode;
use sp_wasm_interface::{FunctionContext as _, IntoValue as _, Pointer, StoreData};
Expand Down Expand Up @@ -102,7 +104,7 @@ fn get_global_val(caller: Caller<'_, StoreData>, instance_idx: i32, name: i64) -

memory.write(&mut caller, ptr as usize, &res).unwrap();

let res = unsafe { mem::transmute::<[i32; 2], i64>([ptr, res_len]) };
let res = pack_i64(ptr, res_len);

log::trace!(target: "host_call", "get_global_val(..) -> {res:?}");

Expand Down
7 changes: 3 additions & 4 deletions ethexe/processor/src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::{common::unpack_i64, Database};
use anyhow::{anyhow, Result};
use core_processor::common::JournalNote;
use gear_core::{code::InstrumentedCode, ids::ProgramId};
use gprimitives::{CodeId, H256};
use parity_scale_codec::{Decode, Encode};
use sp_allocator::{AllocationStats, FreeingBumpHeapAllocator};
use sp_wasm_interface::{HostState, IntoValue, MemoryWrapper, StoreData};
use std::{mem, sync::Arc};

use crate::Database;
use std::sync::Arc;

pub mod api;
pub mod runtime;
Expand Down Expand Up @@ -200,7 +199,7 @@ impl InstanceWrapper {
}

fn get_call_output<D: Decode>(&mut self, ptr_len: i64) -> Result<D> {
let [ptr, len]: [i32; 2] = unsafe { mem::transmute(ptr_len) };
let (ptr, len) = unpack_i64(ptr_len);

// TODO: check range.
let memory = self.memory()?;
Expand Down
2 changes: 1 addition & 1 deletion ethexe/runtime/src/wasm/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ fn return_val(val: impl Encode) -> i64 {
let len = encoded.len() as i32;
let ptr = Box::leak(Box::new(encoded)).as_ptr() as i32;

unsafe { core::mem::transmute([ptr, len]) }
((ptr as i64) << 32) | (len as i64 & 0xFFFFFFFF)
}
4 changes: 2 additions & 2 deletions ethexe/runtime/src/wasm/interface/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::wasm::interface;
use core::{mem, slice};
use core::slice;
use gprimitives::H256;
use parity_scale_codec::{Decode, Encode, Error as CodecError};

Expand All @@ -43,7 +43,7 @@ pub fn read_raw(hash: &H256) -> Option<&[u8]> {
let ptr_len = sys::ext_database_read_by_hash_version_1(hash.as_ptr() as _);

(ptr_len != 0).then(|| {
let [ptr, len]: [i32; 2] = mem::transmute(ptr_len);
let (ptr, len) = ((ptr_len >> 32) as i32, (ptr_len & 0xFFFFFFFF) as i32);
slice::from_raw_parts(ptr as _, len as usize)
})
}
Expand Down
2 changes: 1 addition & 1 deletion ethexe/runtime/src/wasm/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub(crate) mod utils {
let ptr = slice.as_ptr() as i32;
let len = slice.len() as i32;

unsafe { core::mem::transmute([ptr, len]) }
((ptr as i64) << 32) | (len as i64 & 0xFFFFFFFF)
}
}

Expand Down
20 changes: 8 additions & 12 deletions runtime-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

extern crate alloc;

use byteorder::{ByteOrder, LittleEndian};
use codec::{Decode, Encode};
use gear_core::{
gas::GasLeft,
Expand Down Expand Up @@ -153,7 +152,10 @@ pub enum ProcessAccessErrorVer1 {
pub trait GearRI {
#[version(2)]
fn pre_process_memory_accesses(reads: &[u8], writes: &[u8], gas_bytes: &mut [u8; 8]) -> u8 {
lazy_pages_detail::pre_process_memory_accesses(reads, writes, gas_bytes)
let mut gas_counter = u64::from_le_bytes(*gas_bytes);
let res = lazy_pages_detail::pre_process_memory_accesses(reads, writes, &mut gas_counter);
gas_bytes.copy_from_slice(&gas_counter.to_le_bytes());
res
}

fn lazy_pages_status() -> (Status,) {
Expand Down Expand Up @@ -224,7 +226,7 @@ pub trait GearRI {
pub mod lazy_pages_detail {
use super::*;

pub fn pre_process_memory_accesses(reads: &[u8], writes: &[u8], gas_bytes: &mut [u8; 8]) -> u8 {
pub fn pre_process_memory_accesses(reads: &[u8], writes: &[u8], gas_counter: &mut u64) -> u8 {
let mem_interval_size = size_of::<MemoryInterval>();
let reads_len = reads.len();
let writes_len = writes.len();
Expand All @@ -234,20 +236,14 @@ pub mod lazy_pages_detail {
let mut writes_intervals = Vec::with_capacity(writes_len / mem_interval_size);
deserialize_mem_intervals(writes, &mut writes_intervals);

let mut gas_counter = LittleEndian::read_u64(gas_bytes);

let res = match gear_lazy_pages::pre_process_memory_accesses(
match gear_lazy_pages::pre_process_memory_accesses(
playX18 marked this conversation as resolved.
Show resolved Hide resolved
&reads_intervals,
&writes_intervals,
&mut gas_counter,
gas_counter,
) {
Ok(_) => 0,
Err(err) => err.into(),
};

LittleEndian::write_u64(gas_bytes, gas_counter);

res
}
}

pub fn lazy_pages_status() -> (Status,) {
Expand Down
Loading