mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-19 06:40:20 +03:00
repl_test: write Rust replacements for JS functions
This commit is contained in:
parent
ef97ad69ae
commit
a75aa52b91
49
Cargo.lock
generated
49
Cargo.lock
generated
@ -1193,6 +1193,32 @@ version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
|
||||
|
||||
[[package]]
|
||||
name = "dynasm"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b1801e630bd336d0bbbdbf814de6cc749c9a400c7e3d995e6adfd455d0c83c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"lazy_static",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dynasmrt"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d428afc93ad288f6dffc1fa5f4a78201ad2eec33c5a522e51c181009eb09061"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"dynasm",
|
||||
"memmap2 0.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
@ -3192,9 +3218,10 @@ dependencies = [
|
||||
"indoc",
|
||||
"roc_cli",
|
||||
"roc_repl_cli",
|
||||
"roc_repl_wasm",
|
||||
"roc_test_utils",
|
||||
"strip-ansi-escapes",
|
||||
"wasmer",
|
||||
"wasmer-wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4748,6 +4775,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"wasmer-compiler",
|
||||
"wasmer-compiler-cranelift",
|
||||
"wasmer-compiler-singlepass",
|
||||
"wasmer-derive",
|
||||
"wasmer-engine",
|
||||
"wasmer-engine-dylib",
|
||||
@ -4796,6 +4824,25 @@ dependencies = [
|
||||
"wasmer-vm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-compiler-singlepass"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9429b9f7708c582d855b1787f09c7029ff23fb692550d4a1cc351c8ea84c3014"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"dynasm",
|
||||
"dynasmrt",
|
||||
"lazy_static",
|
||||
"loupe",
|
||||
"more-asserts",
|
||||
"rayon",
|
||||
"smallvec",
|
||||
"wasmer-compiler",
|
||||
"wasmer-types",
|
||||
"wasmer-vm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-derive"
|
||||
version = "2.0.0"
|
||||
|
@ -39,7 +39,7 @@ libc = "0.2.106"
|
||||
inkwell = { path = "../../vendor/inkwell" }
|
||||
target-lexicon = "0.12.2"
|
||||
libloading = "0.7.1"
|
||||
wasmer = { version = "2.0.0", default-features = false, features = ["default-cranelift", "default-universal"] }
|
||||
wasmer = { version = "2.0.0", default-features = false, features = ["default-singlepass", "default-universal"] }
|
||||
wasmer-wasi = "2.0.0"
|
||||
tempfile = "3.2.0"
|
||||
indoc = "1.0.3"
|
||||
|
@ -12,13 +12,12 @@ roc_cli = {path = "../cli"}
|
||||
|
||||
[dev-dependencies]
|
||||
indoc = "1.0.3"
|
||||
roc_test_utils = {path = "../test_utils"}
|
||||
strip-ansi-escapes = "0.1.1"
|
||||
wasmer = {version = "2.0.0", default-features = false, features = ["default-singlepass", "default-universal"]}
|
||||
wasmer-wasi = "2.0.0"
|
||||
|
||||
roc_repl_cli = {path = "../repl_cli"}
|
||||
# roc_repl_wasm = {path = "../repl_wasm"}
|
||||
roc_test_utils = {path = "../test_utils"}
|
||||
|
||||
[features]
|
||||
default = ["cli"]
|
||||
cli = []
|
||||
wasm = []
|
||||
|
@ -1,10 +1,15 @@
|
||||
use indoc::indoc;
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
mod cli;
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
use crate::cli::{expect_failure, expect_success};
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
mod wasm;
|
||||
#[cfg(feature = "wasm")]
|
||||
use crate::wasm::{expect_failure, expect_success};
|
||||
|
||||
#[test]
|
||||
fn literal_0() {
|
||||
expect_success("0", "0 : Num *");
|
||||
|
129
repl_test/src/wasm.rs
Normal file
129
repl_test/src/wasm.rs
Normal file
@ -0,0 +1,129 @@
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
ops::{Deref, DerefMut},
|
||||
thread_local,
|
||||
};
|
||||
use wasmer::Instance;
|
||||
|
||||
thread_local! {
|
||||
static REPL_STATE: RefCell<Option<ReplState>> = RefCell::new(None)
|
||||
}
|
||||
|
||||
struct ReplState {
|
||||
compiler: Instance,
|
||||
app: Option<Instance>,
|
||||
result_addr: Option<u32>,
|
||||
}
|
||||
|
||||
fn instantiate_compiler(wasm_module_bytes: &[u8]) {
|
||||
use wasmer::{Module, Store};
|
||||
use wasmer_wasi::WasiState;
|
||||
|
||||
let store = Store::default();
|
||||
let wasmer_module = Module::new(&store, &wasm_module_bytes).unwrap();
|
||||
|
||||
// First, we create the `WasiEnv`
|
||||
let mut wasi_env = WasiState::new("hello").finalize().unwrap();
|
||||
|
||||
// Then, we get the import object related to our WASI
|
||||
// and attach it to the Wasm instance.
|
||||
let import_object = wasi_env
|
||||
.import_object(&wasmer_module)
|
||||
.unwrap_or_else(|_| wasmer::imports!());
|
||||
|
||||
let instance = wasmer::Instance::new(&wasmer_module, &import_object).unwrap();
|
||||
REPL_STATE.with(|f| {
|
||||
if let Some(state) = f.borrow_mut().deref_mut() {
|
||||
state.app = Some(instance)
|
||||
} else {
|
||||
panic!("REPL state not found")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn wasmer_create_app(wasm_module_bytes: &[u8]) {
|
||||
use wasmer::{Module, Store};
|
||||
use wasmer_wasi::WasiState;
|
||||
|
||||
let store = Store::default();
|
||||
let wasmer_module = Module::new(&store, &wasm_module_bytes).unwrap();
|
||||
|
||||
// First, we create the `WasiEnv`
|
||||
let mut wasi_env = WasiState::new("hello").finalize().unwrap();
|
||||
|
||||
// Then, we get the import object related to our WASI
|
||||
// and attach it to the Wasm instance.
|
||||
let import_object = wasi_env
|
||||
.import_object(&wasmer_module)
|
||||
.unwrap_or_else(|_| wasmer::imports!());
|
||||
|
||||
let instance = wasmer::Instance::new(&wasmer_module, &import_object).unwrap();
|
||||
REPL_STATE.with(|f| {
|
||||
if let Some(state) = f.borrow_mut().deref_mut() {
|
||||
state.app = Some(instance)
|
||||
} else {
|
||||
panic!("REPL state not found")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn wasmer_run_app() -> u32 {
|
||||
REPL_STATE.with(|f| {
|
||||
if let Some(state) = f.borrow_mut().deref_mut() {
|
||||
if let Some(app) = &state.app {
|
||||
let wrapper = app.exports.get_function("wrapper").unwrap();
|
||||
|
||||
let result_addr: i32 = match wrapper.call(&[]) {
|
||||
Err(e) => panic!("{:?}", e),
|
||||
Ok(result) => match result[0] {
|
||||
wasmer::Value::I32(a) => a,
|
||||
_ => panic!("Expected an i32 address, got {:?}", result),
|
||||
},
|
||||
};
|
||||
state.result_addr = Some(result_addr as u32);
|
||||
|
||||
let memory = app.exports.get_memory("memory").unwrap();
|
||||
memory.size().bytes().0 as u32
|
||||
} else {
|
||||
panic!("App not found")
|
||||
}
|
||||
} else {
|
||||
panic!("REPL state not found")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn wasmer_get_result_and_memory(buffer_alloc_addr: u32) -> u32 {
|
||||
REPL_STATE.with(|f| {
|
||||
if let Some(state) = f.borrow().deref() {
|
||||
if let Some(app) = &state.app {
|
||||
let app_memory = app.exports.get_memory("memory").unwrap();
|
||||
let compiler_memory = state.compiler.exports.get_memory("memory").unwrap();
|
||||
let result_addr = state.result_addr.unwrap();
|
||||
|
||||
let compiler_memory_bytes: &mut [u8] =
|
||||
unsafe { compiler_memory.data_unchecked_mut() };
|
||||
|
||||
let app_memory_bytes: &[u8] = unsafe { app_memory.data_unchecked() };
|
||||
|
||||
let buf_addr = buffer_alloc_addr as usize;
|
||||
let len = app_memory_bytes.len();
|
||||
compiler_memory_bytes[buf_addr..][..len].copy_from_slice(app_memory_bytes);
|
||||
|
||||
result_addr
|
||||
} else {
|
||||
panic!("REPL app not found")
|
||||
}
|
||||
} else {
|
||||
panic!("REPL state not found")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expect_success(input: &str, expected: &str) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn expect_failure(input: &str, expected: &str) {
|
||||
todo!()
|
||||
}
|
Loading…
Reference in New Issue
Block a user