wasmer icon indicating copy to clipboard operation
wasmer copied to clipboard

Why I was getting "Incompatible("The provided bytes are not wasmer-universal")" Err

Open canewsin opened this issue 1 year ago • 8 comments

Summary

I was testing wasmer to run rust lib compiled to wasm.

Additional details

use std::path::PathBuf;

use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen]
pub fn use_block_storage() -> bool {
    true
}

#[wasm_bindgen]
pub fn get_block_storage_path(data_path: &str) -> String {
    let data_path = PathBuf::from(data_path);
    data_path.join("blockstorage").display().to_string()
}

#[wasm_bindgen]
pub fn get_block_file_path(data_path: &str, block_id: &str) -> String {
    let data_path = PathBuf::from(data_path);
    data_path
        .join("blockstorage")
        .join(block_id)
        .display()
        .to_string()
}

using

cargo build --lib --release --target wasm32-unknown-unknown

i got lib.wasm

Trying to load wasm file with wasmer

crate

wasmer = {version = "3.0.0-beta", features = ["cranelift"]}

use wasmer::{imports, EngineBuilder, Instance, Module, Store, Value};

fn main() {
    let bytes = include_bytes!("../blockstorage.wasm");
    let engine = EngineBuilder::headless();
    let mut store = Store::new(engine);
    let module = unsafe { Module::deserialize(&store, bytes) }.unwrap();
    let import_object = imports! {};
    let instance = Instance::new(&mut store, &module, &import_object).unwrap();
    let sum = instance.exports.get_function("sum").unwrap();
    let results = sum
        .call(&mut store, &[Value::I32(1), Value::I32(2)])
        .unwrap();

    println!("Results: {:?}", results);
    assert_eq!(results.to_vec(), vec![Value::I32(3)]);
}

Error:

Could not deserialize as static object: Feature static load is not compiled in is not yet supported thread 'main' panicked at 'called Result::unwrap() on an Err value: Incompatible("The provided bytes are not wasmer-universal")', src\main.rs:7:64

canewsin avatar Aug 09 '22 07:08 canewsin

loading module using new() gives error

Codegen("The Engine is not compiled in.") @epilys

canewsin avatar Aug 09 '22 08:08 canewsin

Is there any inbuilt compiler to build rust code instead of wasm text ?

Yes, I was following examples in the repo. But all those are restricted to raw wat, which most don't write by bear hand. We should include other lang examples, at least rust example as engine is written in rust.

I was following this example's code snippet to import my module https://github.com/wasmerio/wasmer/blob/master/examples/engine_headless.rs

canewsin avatar Aug 09 '22 08:08 canewsin

@epilys

let engine = Cranelift::default(); recognized wasm format , thus no error.

But,

let import_object = imports! {}; let instance = Instance::new(&mut store, &module, &import_object).unwrap();

now gives

Link(Import("wbindgen_placeholder", "__wbindgen_describe", UnknownImport(Function(FunctionType { params: [I32], results: [] }))))'

See the attached wat file and wasm file blockstorage.wasm.txt

blockstorage.wat.txt

canewsin avatar Aug 09 '22 08:08 canewsin

Consider sharing your working branch, if related assigned changes is started.

and what do you think about the error

Link(Import("wbindgen_placeholder", "__wbindgen_describe", UnknownImport(Function(FunctionType { params: [I32], results: [] }))))'

I see that those declarations are from wasm_bindgen generated binary, but are these gen libraries half baked ?

canewsin avatar Aug 09 '22 16:08 canewsin

I do had an alternative impl, which is

use std::ffi::{c_char, CString};
use std::path::PathBuf;

#[no_mangle]
pub extern "C" fn use_block_storage() -> bool {
    true
}

#[no_mangle]
pub extern "C" fn get_block_storage_path(data_path: *const c_char) -> *const c_char {
    let data_path = unsafe { CString::from_raw(data_path as *mut _) };
    let data_path = PathBuf::from(data_path.to_str().unwrap());
    let path = data_path.join("blockstorage").display().to_string();
    let path = CString::new(path).unwrap();
    path.as_ptr()
}

#[no_mangle]
pub extern "C" fn get_block_file_path(
    data_path: *const c_char,
    block_id: *const c_char,
) -> *const c_char {
    let data_path = unsafe { CString::from_raw(data_path as *mut _) };
    let data_path = PathBuf::from(data_path.to_str().unwrap());
    let block_id = unsafe { CString::from_raw(block_id as *mut _) };
    let path = data_path
        .join("blockstorage")
        .join(block_id.to_str().unwrap())
        .display()
        .to_string();
    let path = CString::new(path).unwrap();
    path.as_ptr()
}

which works, but all those attr should be manually added to fns.

I see a fork of wit-bindgen here https://github.com/wasmerio/wit-bindgen Is wit-bindgen fork usable ? 'cause using that crate gives me, may be due to wasmer dep being used there seems to git dep with features def turned off.

error[E0599]: no method named `data_unchecked` found for reference `&wasmer::Memory` in the current scope
   --> C:\Users\PramUkesh\.cargo\git\checkouts\wit-bindgen-828ec3d74a4dee1a\75c0c14\crates\wasmer\src\lib.rs:122:18
    |
122 |                 .data_unchecked(store)
    |                  ^^^^^^^^^^^^^^ method not found in `&wasmer::Memory`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `wit-bindgen-wasmer` due to previous error

canewsin avatar Aug 09 '22 20:08 canewsin

Is wit-bindgen fork usable ?

Yeah, our fork should be fully usable!

The issue that we are seeing is that we are precompiling the Wasm module in the server (using wasmer-sys), and we want to deserialize in wasmer-js. However, precompilation doesn't work cross-VMs since the browser don't support loading assembly function into memory code.

Cross-compilation and deserialization works only when the same "wasmer" API is used (as commented, wasmer-js and wasmer-sys return different serialization and deserialization bytes... and they will never be compatible because how Wasm in the browser works)

Closing the issue!

syrusakbary avatar Sep 06 '22 15:09 syrusakbary