Skip to content

Commit

Permalink
Get tests working for globals and shims
Browse files Browse the repository at this point in the history
  • Loading branch information
captbaritone committed Apr 2, 2021
1 parent 4313624 commit 74099ad
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 170 deletions.
3 changes: 2 additions & 1 deletion compiler-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ wee_alloc = { version = "0.4.5", optional = true }


[dev-dependencies]
wasmi = "0.8.0"
# https://github.com/paritytech/wasmi/issues/252
wasmi = { git = "https://github.com/paritytech/wasmi", branch = "master" }
wabt = "0.9.0"
wasm-bindgen-test = "0.3.13"
wasmprinter = "0.2.0"
Expand Down
10 changes: 8 additions & 2 deletions compiler-rs/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ impl Emitter {
imports.push(make_import_entry(self.current_pool.clone(), global.clone()));
}

let (function_exports, function_bodies, funcs) = self.emit_programs(programs)?;
self.shims.get(Shim::Sin);

let (function_exports, function_bodies, funcs) = self.emit_programs(programs, 1)?;

for shim in self.shims.keys() {
let type_index = self.function_types.get(shim.get_type());
Expand Down Expand Up @@ -143,13 +145,17 @@ impl Emitter {
fn emit_programs(
&mut self,
programs: Vec<(String, Program, String)>,
offset: u32,
) -> EmitterResult<(Vec<ExportEntry>, Vec<FuncBody>, Vec<Func>)> {
let mut exports = Vec::new();
let mut function_bodies = Vec::new();
let mut function_definitions = Vec::new();
for (i, (name, program, pool_name)) in programs.into_iter().enumerate() {
self.current_pool = pool_name;
exports.push(ExportEntry::new(name, Internal::Function(i as u32)));
exports.push(ExportEntry::new(
name,
Internal::Function(i as u32 + offset),
));
let locals = Vec::new();
function_bodies.push(FuncBody::new(locals, self.emit_program(program)?));

Expand Down
15 changes: 15 additions & 0 deletions compiler-rs/src/index_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,18 @@ impl<T: Eq + Hash> IndexStore<T> {
self.map.keys().collect()
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::EelFunctionType;
#[test]
fn tuple() {
let mut function_types: IndexStore<EelFunctionType> = IndexStore::new();
let one_arg_one_return = function_types.get((1, 1));
let no_arg_one_return = function_types.get((0, 1));

assert_eq!(one_arg_one_return, 0);
assert_eq!(no_arg_one_return, 1);
}
}
75 changes: 75 additions & 0 deletions compiler-rs/tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
extern crate eel_wasm;

use wasmi::nan_preserving_float::F64;
use wasmi::RuntimeValue;
use wasmi::{
Error as WasmiError, Externals, FuncInstance, FuncRef, GlobalDescriptor, GlobalInstance,
GlobalRef, ModuleImportResolver, RuntimeArgs, Signature, Trap, ValueType,
};

pub struct GlobalPool {}

impl GlobalPool {
fn check_signature(&self, index: usize, signature: &Signature) -> bool {
let (params, ret_ty): (&[ValueType], Option<ValueType>) = match index {
SIN_FUNC_INDEX => (&[ValueType::F64], Some(ValueType::F64)),
_ => return false,
};
signature.params() == params && signature.return_type() == ret_ty
}
}

impl ModuleImportResolver for GlobalPool {
fn resolve_global(
&self,
_field_name: &str,
_global_type: &GlobalDescriptor,
) -> Result<GlobalRef, WasmiError> {
let global = GlobalInstance::alloc(RuntimeValue::F64(F64::from_float(0.0)), true);
Ok(global)
}
fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, WasmiError> {
let index = match field_name {
"sin" => SIN_FUNC_INDEX,
_ => {
return Err(WasmiError::Instantiation(format!(
"Export {} not found",
field_name
)))
}
};

if !self.check_signature(index, signature) {
return Err(WasmiError::Instantiation(format!(
"Export {} has a bad signature",
field_name
)));
}

Ok(FuncInstance::alloc_host(
Signature::new(&[ValueType::F64][..], Some(ValueType::F64)),
index,
))
}
}

const SIN_FUNC_INDEX: usize = 0;

impl Externals for GlobalPool {
fn invoke_index(
&mut self,
index: usize,
args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
match index {
SIN_FUNC_INDEX => {
let a: F64 = args.nth_checked(0)?;

let result = a.to_float().sin();

Ok(Some(RuntimeValue::F64(F64::from(result))))
}
_ => panic!("Unimplemented function at {}", index),
}
}
}
17 changes: 13 additions & 4 deletions compiler-rs/tests/compatibility_test.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
use common::GlobalPool;
use eel_wasm::compile;
use wasmi::{ImportsBuilder, ModuleInstance, NopExternals, RuntimeValue};
use wasmi::{ImportsBuilder, ModuleInstance, RuntimeValue};
mod common;

fn run(body: &[u8]) -> Result<f64, String> {
let wasm_binary = body;
let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm");
let instance = ModuleInstance::new(&module, &ImportsBuilder::default())
let mut global_imports = GlobalPool {};
let mut imports = ImportsBuilder::default();
imports.push_resolver("pool", &global_imports);
imports.push_resolver("shims", &global_imports);
let instance = ModuleInstance::new(&module, &imports)
.expect("failed to instantiate wasm module")
.assert_no_start();

// Finally, invoke the exported function "test" with no parameters
// and empty external function executor.
match instance
.invoke_export("test", &[], &mut NopExternals)
.invoke_export("test", &[], &mut global_imports)
.expect("failed to execute export")
{
Some(RuntimeValue::F64(val)) => Ok(val.into()),
Expand Down Expand Up @@ -540,7 +546,10 @@ fn compatibility_tests() {
];

for (name, code, expected) in test_cases {
match compile(vec![("test".to_string(), code, "pool".to_string())], vec![]) {
match compile(
vec![("test".to_string(), code, "pool".to_string())],
vec![("pool".to_string(), "g".to_string())],
) {
Ok(binary) => {
if expected_failing.contains(name) {
panic!(format!("Expected {} to fail, but it passed!", name));
Expand Down
6 changes: 4 additions & 2 deletions compiler-rs/tests/fixtures/wat/one_plus_one.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
========================================================================
(module
(type (;0;) (func (result f64)))
(func (;0;) (type 0) (result f64)
(type (;1;) (func (param f64) (result f64)))
(import "shims" "sin" (func (;0;) (type 1)))
(func (;1;) (type 0) (result f64)
f64.const 0x1p+0 (;=1;)
f64.const 0x1p+0 (;=1;)
f64.add)
(export "test" (func 0)))
(export "test" (func 1)))
6 changes: 4 additions & 2 deletions compiler-rs/tests/fixtures/wat/reg.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ reg00=10
========================================================================
(module
(type (;0;) (func (result f64)))
(func (;0;) (type 0) (result f64)
(type (;1;) (func (param f64) (result f64)))
(import "shims" "sin" (func (;0;) (type 1)))
(func (;1;) (type 0) (result f64)
f64.const 0x1.4p+3 (;=10;)
global.set 0
global.get 0)
(global (;0;) (mut f64) (f64.const 0x0p+0 (;=0;)))
(export "test" (func 0)))
(export "test" (func 1)))
2 changes: 1 addition & 1 deletion compiler-rs/tests/fixtures/wat/sin.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ sin(100)
(func (;1;) (type 0) (result f64)
f64.const 0x1.9p+6 (;=100;)
call 0)
(export "test" (func 0)))
(export "test" (func 1)))
Loading

0 comments on commit 74099ad

Please sign in to comment.