Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Conversation

@pepyakin
Copy link
Contributor

@pepyakin pepyakin commented Jan 20, 2020

Fixes #4599

This PR is basically a refactoring that migrates the code from wasmtime-runtime, wasmtime-jit et al to the now stable wasmtime crate. The crate is now sprinkled with comments. Hopefully, one now doesn't have to have a black belt in unsafejitsu to deal with this crate.

Note that this PR relies on some fixes on the wasmtime side, hence the git reference.

This PR should not introduce any significant functional changes and should have the same behavior.


TODO:

  • Verify that it syncs on Kusama.
  • Provide a companion PR for Polkadot
  • Update to upstream version of wasmtime

@pepyakin pepyakin added the A3-in_progress Pull request is in progress. No review needed at this stage. label Jan 20, 2020
@pepyakin pepyakin requested review from bkchr and tomusdrw January 20, 2020 14:18
This may solve a problem with segfaults.
Copy link
Contributor

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My WASM / wasmtime / low level knowledge is pretty limited, but it looks reasonable. I like the unsafe abstractions introduced and the docs are very convincing that everything is correct :)

// available in substrate.
//
// This, however, cannot happen since the signature of this function is created from
// a `dyn Function` signature of which cannot have a non substrate value by definition.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the values that we support change over time? Would the documentation above still be valid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess no. But I am not sure what would be a better way?

pub fn extract_heap_base(&self) -> Result<u32> {
let heap_base_export = self
.instance
.get_export("__heap_base")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should stuff like __heap_base rather be declared as some constants? Usually I prefer that over random strings sprinkled all over, at least you can maintain some convention, even if the constant is only used in one place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would also give a place to leave some docs!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be a good idea to address this in a follow-up PR!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with me!

Copy link
Contributor

@Demi-Marie Demi-Marie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still many places where code could be made safer. I don’t see any explicit unsoundness, but I also am not convinced that the code is safe either.

/// # Safety
///
/// This wrapper requires exclusive ownership over the given instance and all its components.
/// Since `Instance` is a `Clone` we cannot use typesystem to prevent this, hence unsafe.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can (and should) use RefCell or Mutex for this.

Copy link
Contributor Author

@pepyakin pepyakin Feb 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if I agree: how would they help from violating the invariant? It would still be possible to clone the memory instance from within this module and create aliases, right?

///
/// Wasmtime doesn't provide comprehensive documentation about the exact behavior of the data
/// pointer. If a dynamic style heap is used the base pointer of the heap can change. Since
/// growing, we cannot guarantee the lifetime of the returned slice reference.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better approach would be for this to be a function taking a callback, such that the reference cannot escape the callback.

/// See `[memory_as_slice]`. In addition to those requirements, since a mutable reference is
/// returned it must be ensured that only one mutable and no shared references to memory exists
/// at the same time.
unsafe fn memory_as_slice_mut(&self) -> &mut [u8] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

@pepyakin pepyakin added A0-please_review Pull request needs code review. and removed A1-onice labels Feb 12, 2020
@pepyakin pepyakin requested a review from bkchr February 12, 2020 14:05
Copy link
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


let resolved = match import_ty.name() {
"memory" => {
memory_import_index = Some(externs.len());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we error when a second memory instance is requested?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure!

First, it won't be possible atm, since if the module has 2 memory imports then it is a not valid module. Second, as soon as multiple memories are supported then it is OK (although useless) to import the same memory twice.

@bkchr bkchr merged commit 0b2ae97 into master Feb 13, 2020
@bkchr bkchr deleted the ser-wasmtime-api branch February 13, 2020 13:54
General-Beck pushed a commit to General-Beck/substrate that referenced this pull request Feb 18, 2020
* Migrate wasmtime backend to wasmtime-api

* Port to a newer version of wasmtime

* Update to the latest changes.

* Rejig the sandbox module a bit

* Materialze

* Fixes.

* executor wasm_runtime fix

* Refactor everything

* More refactoring

* Even more refactorings

* More cleaning.

* Update to the latest wasmtime

* Reformat

* Renames

* Refactoring and comments.

* Docs

* Rename FunctionExecutor to host.

* Imrpove docs.

* fmt

* Remove panic

* Assert the number of arguments are equal between wasmtime and hostfunc.

* Comment a possible panic if there is no corresponding value variant.

* Check signature of the entrypoint.

* Use git version of wasmtime

* Refine and doc the sandbox code.

* Comment RefCells.

* Update wasmtime to the latest-ish master.

This may solve a problem with segfaults.

* Apply suggestions from code review

Co-Authored-By: Tomasz Drwięga <[email protected]>

* Use full SHA1 hash of wasmtime commit.

* Add a panic message.

* Add some documentation

* Update wasmtime version to include SIGSEGV fix

* Update to crates.io version of wasmtime

* Make it work.

* Move the creation of memory into `InstanceWrapper::new`

* Make `InstanceWrapper` !Send & !Sync

* Avoid using `take_mut`

* Update client/executor/wasmtime/Cargo.toml

Co-Authored-By: Bastian Köcher <[email protected]>

* Limit maximum size of memory.

* Rename `init_state` to `with_initialized_state`

Co-authored-by: Tomasz Drwięga <[email protected]>
Co-authored-by: Bastian Köcher <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

A0-please_review Pull request needs code review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wasmtime implementation violates aliasing requirements

5 participants