Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading a file From Wasm?

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();
like image 365
christopher clark Avatar asked Nov 14 '18 16:11

christopher clark


People also ask

How do I load a Wasm file in HTML?

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.

How do I run a Wasm file?

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.

Can WebAssembly be decompiled?

The WASM files can be decompiled using the WebAssembly-to-C decompiler.

Can WebAssembly access file system?

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.


1 Answers

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:

  • Which crates will work off the shelf with WebAssembly?
  • How to add WebAssembly support to a general purpose crate

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.

like image 186
alexcrichton Avatar answered Sep 22 '22 00:09

alexcrichton