Skip to content

Commit

Permalink
Bump polkavm version
Browse files Browse the repository at this point in the history
Signed-off-by: Jarkko Sakkinen <[email protected]>
  • Loading branch information
jarkkojs committed Nov 19, 2024
1 parent b71bd53 commit 3abb4c5
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 45 deletions.
40 changes: 39 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion substrate/client/executor/polkavm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
log = { workspace = true }
polkavm = { workspace = true }
polkavm = { version = "0.16.0", default-features = false }

sc-executor-common = { workspace = true, default-features = true }
sp-wasm-interface = { workspace = true, default-features = true }
62 changes: 19 additions & 43 deletions substrate/client/executor/polkavm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ pub struct Instance(polkavm::Instance<()>);

impl WasmModule for InstancePre {
fn new_instance(&self) -> Result<Box<dyn WasmInstance>, Error> {
Ok(Box::new(Instance(self.0.instantiate()?)))
// FIXME: Does not return `sc_executor_common::error::Error`.
Ok(Box::new(Instance(self.0.instantiate().unwrap())))
}
}

Expand All @@ -43,38 +44,18 @@ impl WasmInstance for Instance {
name: &str,
raw_data: &[u8],
) -> (Result<Vec<u8>, Error>, Option<AllocationStats>) {
let Some(method_index) = self.0.module().lookup_export(name) else {
return (
Err(format!("cannot call into the runtime: export not found: '{name}'").into()),
None,
);
};

let Ok(raw_data_length) = u32::try_from(raw_data.len()) else {
return (
Err(format!("cannot call runtime method '{name}': input payload is too big").into()),
None,
);
};

// TODO: This will leak guest memory; find a better solution.
let mut state_args = polkavm::StateArgs::new();

// Make sure the memory is cleared...
state_args.reset_memory(true);
// ...and allocate space for the input payload.
state_args.sbrk(raw_data_length);
self.0.reset_memory().unwrap();

match self.0.update_state(state_args) {
Ok(()) => {},
Err(polkavm::ExecutionError::Trap(trap)) => {
return (Err(format!("call into the runtime method '{name}' failed: failed to prepare the guest's memory: {trap}").into()), None);
},
Err(polkavm::ExecutionError::Error(error)) => {
return (Err(format!("call into the runtime method '{name}' failed: failed to prepare the guest's memory: {error}").into()), None);
},
Err(polkavm::ExecutionError::OutOfGas) => unreachable!("gas metering is never enabled"),
}
// ...and allocate space for the input payload.
self.0.sbrk(raw_data_length).unwrap();

// Grab the address of where the guest's heap starts; that's where we've just allocated
// the memory for the input payload.
Expand All @@ -84,30 +65,21 @@ impl WasmInstance for Instance {
return (Err(format!("call into the runtime method '{name}': failed to write the input payload into guest memory: {error}").into()), None);
}

let mut state = ();
let mut call_args = polkavm::CallArgs::new(&mut state, method_index);
call_args.args_untyped(&[data_pointer, raw_data_length]);

match self.0.call(Default::default(), call_args) {
Ok(()) => {},
Err(polkavm::ExecutionError::Trap(trap)) => {
return (
Err(format!("call into the runtime method '{name}' failed: {trap}").into()),
None,
);
},
Err(polkavm::ExecutionError::Error(error)) => {
match self.0.call_typed(&mut (), name, (data_pointer, raw_data_length)) {
Ok(()) => (),
Err(polkavm::CallError::Trap) => (),
Err(polkavm::CallError::Error(error)) => {
return (
Err(format!("call into the runtime method '{name}' failed: {error}").into()),
None,
);
},
Err(polkavm::ExecutionError::OutOfGas) => unreachable!("gas metering is never enabled"),
Err(polkavm::CallError::NotEnoughGas) => unreachable!("gas metering is never enabled"),
}

let result_pointer = self.0.get_reg(Reg::A0);
let result_length = self.0.get_reg(Reg::A1);
let output = match self.0.read_memory_into_vec(result_pointer, result_length) {
let result_pointer = self.0.reg(Reg::A0);
let result_length = self.0.reg(Reg::A1);
let output = match self.0.read_memory(result_pointer as u32, result_length as u32) {
Ok(output) => output,
Err(error) => {
return (Err(format!("call into the runtime method '{name}' failed: failed to read the return payload: {error}").into()), None)
Expand All @@ -127,13 +99,17 @@ impl<'r, 'a> FunctionContext for Context<'r, 'a> {
dest: &mut [u8],
) -> sp_wasm_interface::Result<()> {
self.0
.read_memory_into_slice(u32::from(address), dest)
.instance
.read_memory_into(u32::from(address), dest)
.map_err(|error| error.to_string())
.map(|_| ())
}

fn write_memory(&mut self, address: Pointer<u8>, data: &[u8]) -> sp_wasm_interface::Result<()> {
self.0.write_memory(u32::from(address), data).map_err(|error| error.to_string())
self.0
.instance
.write_memory(u32::from(address), data)
.map_err(|error| error.to_string())
}

fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result<Pointer<u8>> {
Expand Down

0 comments on commit 3abb4c5

Please sign in to comment.