-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Write some very basic codegen using
walrus
- Loading branch information
Showing
12 changed files
with
193 additions
and
1,116 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,4 @@ edition = "2021" | |
|
||
[dependencies] | ||
rose = { path = "../core" } | ||
|
||
[dev-dependencies] | ||
wasmtime = "9" | ||
walrus = "0.20" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,90 @@ | ||
#[cfg(test)] | ||
mod tests { | ||
use wasmtime::{Caller, Engine, Func, Instance, Module, Store}; | ||
use walrus::{ir::BinaryOp, FunctionBuilder, LocalId, Module, ModuleConfig, ValType}; | ||
|
||
// https://docs.rs/wasmtime/9.0.2/wasmtime/ | ||
#[test] | ||
fn test_foo() -> wasmtime::Result<()> { | ||
// Modules can be compiled through either the text or binary format | ||
let engine = Engine::default(); | ||
let wat = r#" | ||
(module | ||
(import "host" "host_func" (func $host_hello (param i32))) | ||
pub const EXPORT_NAME: &str = ""; | ||
|
||
(func (export "hello") | ||
i32.const 3 | ||
call $host_hello) | ||
) | ||
"#; | ||
let module = Module::new(&engine, wat)?; | ||
|
||
// All wasm objects operate within the context of a "store". Each | ||
// `Store` has a type parameter to store host-specific data, which in | ||
// this case we're using `4` for. | ||
let mut store = Store::new(&engine, 4); | ||
let host_func = Func::wrap(&mut store, |caller: Caller<'_, u32>, param: i32| { | ||
println!("Got {} from WebAssembly", param); | ||
println!("my host state is: {}", caller.data()); | ||
}); | ||
|
||
// Instantiation of a module requires specifying its imports and then | ||
// afterwards we can fetch exports by name, as well as asserting the | ||
// type signature of the function with `get_typed_func`. | ||
let instance = Instance::new(&mut store, &module, &[host_func.into()])?; | ||
let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?; | ||
|
||
// And finally we can call the wasm! | ||
hello.call(&mut store, ())?; | ||
fn type_to_wasm(t: rose::Type) -> ValType { | ||
match t { | ||
rose::Type::Bool => ValType::I32, | ||
rose::Type::Int => ValType::I32, | ||
rose::Type::Real => ValType::F64, | ||
rose::Type::Size { val: _ } => todo!(), | ||
rose::Type::Nat { bound: _ } => todo!(), | ||
rose::Type::Var { id: _ } => todo!(), | ||
} | ||
} | ||
|
||
Ok(()) | ||
pub fn compile(f: &rose::Def<rose::Function>, _generics: &[usize]) -> Vec<u8> { | ||
let config = ModuleConfig::new(); | ||
let mut module = Module::with_config(config); | ||
let params: Vec<ValType> = f.def.params.iter().map(|&t| type_to_wasm(t)).collect(); | ||
let results: Vec<ValType> = f.def.ret.iter().map(|&t| type_to_wasm(t)).collect(); | ||
let mut func = FunctionBuilder::new(&mut module.types, ¶ms, &results); | ||
let params: Vec<LocalId> = params.into_iter().map(|t| module.locals.add(t)).collect(); | ||
let mut body = func.func_body(); | ||
for &id in params.iter() { | ||
body.local_get(id); | ||
} | ||
let locals: Vec<LocalId> = f | ||
.def | ||
.locals | ||
.iter() | ||
.map(|&t| module.locals.add(type_to_wasm(t))) | ||
.collect(); | ||
for &instr in &f.def.body { | ||
match instr { | ||
rose::Instr::Generic { id: _ } => todo!(), | ||
rose::Instr::Get { id } => { | ||
body.local_get(locals[id.0]); | ||
} | ||
rose::Instr::Set { id } => { | ||
body.local_set(locals[id.0]); | ||
} | ||
rose::Instr::Bool { val: _ } => todo!(), | ||
rose::Instr::Int { val: _ } => todo!(), | ||
rose::Instr::Real { val: _ } => todo!(), | ||
rose::Instr::Vector { id: _ } => todo!(), | ||
rose::Instr::Tuple { id: _ } => todo!(), | ||
rose::Instr::Index => todo!(), | ||
rose::Instr::Member { id: _ } => todo!(), | ||
rose::Instr::Call { id: _ } => todo!(), | ||
rose::Instr::Unary { op: _ } => todo!(), | ||
rose::Instr::Binary { op } => match op { | ||
rose::Binop::And => todo!(), | ||
rose::Binop::Or => todo!(), | ||
rose::Binop::EqBool => todo!(), | ||
rose::Binop::NeqBool => todo!(), | ||
rose::Binop::NeqInt => todo!(), | ||
rose::Binop::LtInt => todo!(), | ||
rose::Binop::LeqInt => todo!(), | ||
rose::Binop::EqInt => todo!(), | ||
rose::Binop::GtInt => todo!(), | ||
rose::Binop::GeqInt => todo!(), | ||
rose::Binop::NeqReal => todo!(), | ||
rose::Binop::LtReal => todo!(), | ||
rose::Binop::LeqReal => todo!(), | ||
rose::Binop::EqReal => todo!(), | ||
rose::Binop::GtReal => todo!(), | ||
rose::Binop::GeqReal => todo!(), | ||
rose::Binop::AddInt => todo!(), | ||
rose::Binop::SubInt => todo!(), | ||
rose::Binop::MulInt => todo!(), | ||
rose::Binop::DivInt => todo!(), | ||
rose::Binop::Mod => todo!(), | ||
rose::Binop::AddReal => { | ||
body.binop(BinaryOp::F64Add); | ||
} | ||
rose::Binop::SubReal => todo!(), | ||
rose::Binop::MulReal => todo!(), | ||
rose::Binop::DivReal => todo!(), | ||
}, | ||
rose::Instr::If => todo!(), | ||
rose::Instr::Else => todo!(), | ||
rose::Instr::End => todo!(), | ||
rose::Instr::For { limit: _ } => todo!(), | ||
} | ||
} | ||
module | ||
.exports | ||
.add(EXPORT_NAME, func.finish(params, &mut module.funcs)); | ||
module.emit_wasm() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import * as ffi from "./ffi.js"; | ||
import { Fn, ToJs } from "./fn.js"; | ||
import { Real } from "./real.js"; | ||
|
||
/** | ||
* Converts an abstract function into a concrete function using the interpreter. | ||
*/ | ||
export const compile = async <const T extends readonly Real[]>( | ||
f: Fn & ((...args: T) => Real), | ||
generics: number[] | ||
): Promise<(...args: ToJs<T>) => number> => { | ||
const bytes = ffi.compile(f.f, generics); | ||
console.log(bytes); | ||
const instance = await WebAssembly.instantiate( | ||
await WebAssembly.compile(bytes) | ||
); | ||
return instance.exports[ffi.wasmExportName] as any; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters