Fully Working WebAssembly Loading!
This commit is contained in:
parent
581e06bf8b
commit
db4d6b6eb5
3 changed files with 122 additions and 70 deletions
101
Cargo.lock
generated
101
Cargo.lock
generated
|
|
@ -110,7 +110,7 @@ dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"object 0.22.0",
|
"object",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -329,7 +329,7 @@ dependencies = [
|
||||||
"const_fn",
|
"const_fn",
|
||||||
"crossbeam-utils 0.8.0",
|
"crossbeam-utils 0.8.0",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"memoffset",
|
"memoffset 0.5.6",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -832,6 +832,15 @@ version = "2.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memmap2"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e73be3b7d04a0123e933fea1d50d126cc7196bbc0362c0ce426694f777194eee"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.5.6"
|
version = "0.5.6"
|
||||||
|
|
@ -841,6 +850,15 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
|
@ -915,20 +933,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.21.1"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693"
|
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "object"
|
|
||||||
version = "0.22.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
|
@ -1678,8 +1690,9 @@ checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer"
|
name = "wasmer"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffe7fb8734c3e522aea0bed12315115e4c5d684c3d312db5f3ef6a8a312b1b47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
|
@ -1688,6 +1701,7 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmer-compiler",
|
"wasmer-compiler",
|
||||||
"wasmer-compiler-cranelift",
|
"wasmer-compiler-cranelift",
|
||||||
|
"wasmer-derive",
|
||||||
"wasmer-engine",
|
"wasmer-engine",
|
||||||
"wasmer-engine-jit",
|
"wasmer-engine-jit",
|
||||||
"wasmer-engine-native",
|
"wasmer-engine-native",
|
||||||
|
|
@ -1699,8 +1713,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler"
|
name = "wasmer-compiler"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97789fdc5968ea3d29528648dc2422e0c795ca195b88a59c30a56f0e52805690"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"enumset",
|
"enumset",
|
||||||
"raw-cpuid",
|
"raw-cpuid",
|
||||||
|
|
@ -1716,8 +1731,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler-cranelift"
|
name = "wasmer-compiler-cranelift"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e80c86796019ef6d4519e1a66f2b99ab73b937a4e43e723772956b3e8c8df23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"cranelift-frontend",
|
"cranelift-frontend",
|
||||||
|
|
@ -1732,14 +1748,28 @@ dependencies = [
|
||||||
"wasmer-vm",
|
"wasmer-vm",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmer-derive"
|
||||||
|
version = "1.0.0-rc1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c74a84dc4ba0d60e9419f335734fa807097caf4938b2b44bc0703688a42b467"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine"
|
name = "wasmer-engine"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e787fb8e42b5ad32c1c8dcf105e42d2919dfb3ea4b8e286de3e43f306ae1457b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bincode",
|
"bincode",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"memmap2",
|
||||||
"more-asserts",
|
"more-asserts",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -1753,8 +1783,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine-jit"
|
name = "wasmer-engine-jit"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "552f4252f8d7984279c55df0970ca1d42b1e4c63d918e7af1cd004e427e5008c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
|
|
@ -1770,8 +1801,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine-native"
|
name = "wasmer-engine-native"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5264031a9b398a071fa128fe89fb55bc75f9c0ac5eaa7f1f9ef9efcee08afa1c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
|
|
@ -1790,10 +1822,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-object"
|
name = "wasmer-object"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e22ccf03052d73b3588bd30de94db9ee949957a543d0c317122f2b87b7d1f309"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"object 0.21.1",
|
"object",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmer-compiler",
|
"wasmer-compiler",
|
||||||
"wasmer-types",
|
"wasmer-types",
|
||||||
|
|
@ -1801,24 +1834,27 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-types"
|
name = "wasmer-types"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c3ea5b135db86baf39ce45f6cf98cc97d6e4234d3f75ac56a026f94bd8b68b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
"serde",
|
"serde",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-vm"
|
name = "wasmer-vm"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88d766b8db150b7e524c83b244e14a1180bf919b4f8bea6f063bae9a8e8d4156"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"libc",
|
"libc",
|
||||||
"memoffset",
|
"memoffset 0.6.1",
|
||||||
"more-asserts",
|
"more-asserts",
|
||||||
"region",
|
"region",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -1829,8 +1865,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-wasi"
|
name = "wasmer-wasi"
|
||||||
version = "1.0.0-alpha5"
|
version = "1.0.0-rc1"
|
||||||
source = "git+https://github.com/wasmerio/wasmer.git#5e2dc65463a49b08c14bf9fb48eb45fa7d79d4c2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28b9e383c0a20fb697080b8e87613a0bb2e901a9f06ca710030b4a521ebcc398"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ version = "1.3.0"
|
||||||
features = ["unstable"]
|
features = ["unstable"]
|
||||||
|
|
||||||
[dependencies.wasmer]
|
[dependencies.wasmer]
|
||||||
git = "https://github.com/wasmerio/wasmer.git"
|
version = "1.0.0-rc"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.wasmer-wasi]
|
[dependencies.wasmer-wasi]
|
||||||
git = "https://github.com/wasmerio/wasmer.git"
|
version = "1.0.0-rc"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
||||||
87
src/main.rs
87
src/main.rs
|
|
@ -387,52 +387,48 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
// TODO: Clone shared state here
|
// TODO: Clone shared state here
|
||||||
move || -> Result<(), Box<dyn std::error::Error>> {
|
move || -> Result<(), Box<dyn std::error::Error>> {
|
||||||
use std::io;
|
use std::{
|
||||||
use std::sync::{Arc, Mutex};
|
io,
|
||||||
|
process::{Command, Stdio},
|
||||||
|
};
|
||||||
use wasmer::{Exports, Function, Instance, Module, Store, Value};
|
use wasmer::{Exports, Function, Instance, Module, Store, Value};
|
||||||
use wasmer_wasi::WasiState;
|
use wasmer_wasi::{Pipe, WasiEnv, WasiState};
|
||||||
|
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
|
|
||||||
println!("Compiling module...");
|
println!("Compiling module...");
|
||||||
// FIXME: Switch to a higher performance compiler (`Store::default()`) and cache this on disk
|
// FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that
|
||||||
// I could use `(de)serialize_to_file()` for that
|
|
||||||
let module = if let Ok(m) = Module::from_file(&store, "strider.wasm") {
|
let module = if let Ok(m) = Module::from_file(&store, "strider.wasm") {
|
||||||
m
|
m
|
||||||
} else {
|
} else {
|
||||||
return Ok(()); // Just abort this thread quietly if the WASM isn't found
|
return Ok(()); // Just abort this thread quietly if the WASM isn't found
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Upstream the `Pipe` struct
|
let output = Pipe::new();
|
||||||
//let output = fluff::Pipe::new();
|
let input = Pipe::new();
|
||||||
//let input = fluff::Pipe::new();
|
|
||||||
let mut wasi_env = WasiState::new("mosaic")
|
let mut wasi_env = WasiState::new("mosaic")
|
||||||
.env("CLICOLOR_FORCE", "1")
|
.env("CLICOLOR_FORCE", "1")
|
||||||
.preopen(|p| {
|
.preopen(|p| {
|
||||||
p.directory(".") // TODO: Change this to a more meaningful dir
|
p.directory(".") // FIXME: Change this to a more meaningful dir
|
||||||
.alias(".")
|
.alias(".")
|
||||||
.read(true)
|
.read(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
})?
|
})?
|
||||||
//.stdin(Box::new(input))
|
.stdin(Box::new(input))
|
||||||
//.stdout(Box::new(output))
|
.stdout(Box::new(output))
|
||||||
.finalize()?;
|
.finalize()?;
|
||||||
|
|
||||||
let mut import_object = wasi_env.import_object(&module)?;
|
let mut import_object = wasi_env.import_object(&module)?;
|
||||||
// FIXME: Upstream an `ImportObject` merge method
|
// FIXME: Upstream an `ImportObject` merge method
|
||||||
let mut host_exports = Exports::new();
|
let mut host_exports = Exports::new();
|
||||||
/* host_exports.insert(
|
host_exports.insert(
|
||||||
"host_open_file",
|
"host_open_file",
|
||||||
Function::new_native_with_env(&store, Arc::clone(&wasi_env.state), host_open_file),
|
Function::new_native_with_env(&store, wasi_env.clone(), host_open_file),
|
||||||
); */
|
);
|
||||||
fn noop() {}
|
|
||||||
host_exports.insert("host_open_file", Function::new_native(&store, noop));
|
|
||||||
import_object.register("mosaic", host_exports);
|
import_object.register("mosaic", host_exports);
|
||||||
let instance = Instance::new(&module, &import_object)?;
|
let instance = Instance::new(&module, &import_object)?;
|
||||||
|
|
||||||
// WASI requires to explicitly set the memory for the `WasiEnv`
|
|
||||||
wasi_env.set_memory(instance.exports.get_memory("memory")?.clone());
|
|
||||||
|
|
||||||
let start = instance.exports.get_function("_start")?;
|
let start = instance.exports.get_function("_start")?;
|
||||||
let handle_key = instance.exports.get_function("handle_key")?;
|
let handle_key = instance.exports.get_function("handle_key")?;
|
||||||
let draw = instance.exports.get_function("draw")?;
|
let draw = instance.exports.get_function("draw")?;
|
||||||
|
|
@ -442,40 +438,59 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
||||||
|
|
||||||
#[warn(clippy::never_loop)]
|
#[warn(clippy::never_loop)]
|
||||||
loop {
|
loop {
|
||||||
break;
|
let (cols, rows) = (80, 24); //terminal::size()?;
|
||||||
//let (cols, rows) = terminal::size()?;
|
draw.call(&[Value::I32(rows), Value::I32(cols)])?;
|
||||||
//draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)])?;
|
|
||||||
|
|
||||||
// FIXME: This downcasting mess needs to be abstracted away
|
|
||||||
/* let mut state = wasi_env.state();
|
|
||||||
let wasi_file = state.fs.stdout_mut()?.as_mut().unwrap();
|
|
||||||
let output: &mut fluff::Pipe = wasi_file.downcast_mut().unwrap();
|
|
||||||
// Needed because raw mode doesn't implicitly return to the start of the line
|
// Needed because raw mode doesn't implicitly return to the start of the line
|
||||||
write!(
|
write!(
|
||||||
io::stdout(),
|
io::stdout(),
|
||||||
"{}\n\r",
|
"{}\n\r",
|
||||||
output.to_string().lines().collect::<Vec<_>>().join("\n\r")
|
wasi_stdout(&wasi_env)
|
||||||
|
.lines()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n\r")
|
||||||
)?;
|
)?;
|
||||||
output.clear();
|
|
||||||
|
|
||||||
let wasi_file = state.fs.stdin_mut()?.as_mut().unwrap();
|
/* match event::read().unwrap() {
|
||||||
let input: &mut fluff::Pipe = wasi_file.downcast_mut().unwrap();
|
|
||||||
input.clear(); */
|
|
||||||
|
|
||||||
/* match event::read()? {
|
|
||||||
Event::Key(KeyEvent {
|
Event::Key(KeyEvent {
|
||||||
code: KeyCode::Char('q'),
|
code: KeyCode::Char('q'),
|
||||||
..
|
..
|
||||||
}) => break,
|
}) => break,
|
||||||
Event::Key(e) => {
|
Event::Key(e) => {
|
||||||
writeln!(input, "{}\r", serde_json::to_string(&e)?)?;
|
wasi_write_string(&wasi_env, serde_json::to_string(&e).unwrap());
|
||||||
drop(state);
|
|
||||||
// Need to release the implicit `state` mutex or I deadlock!
|
|
||||||
handle_key.call(&[])?;
|
handle_key.call(&[])?;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
} */
|
} */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn host_open_file(wasi_env: &WasiEnv) {
|
||||||
|
Command::new("xdg-open")
|
||||||
|
.arg(format!(
|
||||||
|
"./{}",
|
||||||
|
wasi_stdout(wasi_env).lines().next().unwrap()
|
||||||
|
))
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Unwrap city
|
||||||
|
fn wasi_stdout(wasi_env: &WasiEnv) -> String {
|
||||||
|
let mut state = wasi_env.state();
|
||||||
|
let wasi_file = state.fs.stdout_mut().unwrap().as_mut().unwrap();
|
||||||
|
let mut buf = String::new();
|
||||||
|
wasi_file.read_to_string(&mut buf).unwrap();
|
||||||
|
buf
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _wasi_write_string(wasi_env: &WasiEnv, buf: &str) {
|
||||||
|
let mut state = wasi_env.state();
|
||||||
|
let wasi_file = state.fs.stdin_mut().unwrap().as_mut().unwrap();
|
||||||
|
writeln!(wasi_file, "{}\r", buf).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
debug_log_to_file("WASM module loaded and exited cleanly :)".to_string())?;
|
debug_log_to_file("WASM module loaded and exited cleanly :)".to_string())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue