I am using rust and webassembly. I am getting this error message operation not supported on wasm yet
. So either one of two things is happening, and I was curious if anyone knew the answer. So either my filepath is not correct and this is the least helpful error message, or wasm doesn't support loading files.
#[wasm_bindgen]
#[macro_use]
pub fn file() -> () {
let mut data: Vec<u8> = Vec::new();
///I would load the png with the same path in my javascript.
let opened = File::open("./png/A_SingleCell.png");
let unwraped = match opened {
Ok(a) => log(&format!("opened {}", "worked")),
Err(e) => log(&format!("{}", e)),
};
// .read_to_end(&mut data)
// .unwrap();
return ();
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(msg: &str);
}
and the javascript call is merely just file()
.
Is there a different directory path I need to use to get the png or can you truly not load a file?
Edit Adding my index.js to show that webpack has already loaded the png.
import { memory } from "break-game/break_game_bg";
import A from './png/A_SingleCell.png';
import { alloc, fill, decode, file } from "break-game";
file();
wasm : Create a new XMLHttpRequest() instance, and use its open() method to open a request, setting the request method to GET , and declaring the path to the file we want to fetch. The key part of this is to set the response type to 'arraybuffer' using the responseType property.
Briefly, the steps to get your WASM WebApp working are: Compile C/C++ code with Emscripten, to obtain a WASM binary. Bind your WASM binary to your page using a JavaScript "glue code". Run your app and let the browser to instantiate your WASM module, the memory and the table of references.
The WASM files can be decompiled using the WebAssembly-to-C decompiler.
The WebAssembly VM provides a sandbox to ensure application safety. However, this sandbox is also a very limited “computer” that has no concept of file system, network, or even a clock or timer. That is very limiting for the Rust programs running inside WebAssembly.
Loading a file from the filesystem doesn't work with the Rust standard library and the wasm32-unknown-unknown
target. This error is, consequently, an expected runtime error for using File::open
.
The Rust standard library currently provides a uniform API surface area for all targets, regardless of whether the target actually supports the functionality or not. It turns out that almost all platforms implement basically all of the stable surface area of the standard library, but the wasm32-unknown-unknown
target in specific is a bit of an odd-one-out. On this wasm target the standard library notably has no way to implement functions in modules like std::net
or std::fs
, so the functions unconditionally return an error. What you're seeing here is that File::open
unconditionally returns an error on the wasm32-unknown-unknown
target.
Speaking specifically about the wasm32-unknown-unknown
target, this target is used to represent the "base layer of compatibility for Rust and wasm". On this target the standard library can only assume the WebAssembly instruction set, nothing else. Because WebAssembly provides no means of doing I/O or loading files, it means that these stubs are left to return errors in the standard library.
Note that an alternative way for us to provide the standard library on the wasm32-unknown-unknown
target is to simply not provide these functions at all, causing a compile time error when they're attempted to be used. We chose to not take this route, for better or worse, to remain consistent across targets in Rust. It's hoped that something like the proposed portability lint can change the calculus of this story, but Rust isn't quite there yet!
In the meantime, though, you probably still want to get this done! The wasm-bindgen
project has a few guides about the wasm32-unknown-unknown
target which may help you make some progress here:
Notably the web platform doesn't currently provide the ability to load files from the filesystem, so there's no great way to implement File::open
as an API in Rust for the wasm32-unknown-unknown
target, even if JS is used. If you're using Node.js, though, I'd recommend reading about JS interop as well as checking out the wasm-bindgen
guide for importing Node.js functions to implement this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With