|
| 1 | +//! Uniform chisel module handling abstraction. |
| 2 | +//! This module implements get_module_delegate, an API function which takes a string and returns a closure |
| 3 | +//! executing the module with the provided binary and configuration. |
| 4 | +
|
1 | 5 | use std::collections::HashMap; |
2 | 6 |
|
3 | | -use crate::checkfloat::CheckFloat; |
4 | 7 | use crate::Module; |
5 | 8 | use crate::ModuleError; |
6 | 9 | use crate::ModuleKind; |
7 | | -use crate::ModuleValidator; |
8 | 10 |
|
| 11 | +/// The delegate type signature. |
9 | 12 | type ChiselDelegate = dyn Fn(&mut Module, &HashMap<String, String>) -> Result<bool, ModuleError>; |
10 | 13 |
|
11 | | -// Primitive module server, relies on huge matcher |
12 | | -pub fn get_module_delegate(name: &str) -> Result<&'static ChiselDelegate, ModuleError> { |
13 | | - match name { |
14 | | - "checkfloat" => Ok(&|wasm, _config| { |
15 | | - let module = CheckFloat::new(); |
16 | | - module.validate(&wasm) |
17 | | - }), |
18 | | - _ => Err(ModuleError::NotFound), |
| 14 | +/// Create a matcher for get_module_delegate with the provided delegates. |
| 15 | +/// NOTE: There must be a delegate of the same name declared in the delegates module. |
| 16 | +macro_rules! delegate_matcher { |
| 17 | + ($name:ident; $( $module:ident ),*) => { |
| 18 | + match $name { |
| 19 | + $(stringify!($module) => Some(&crate::moduledelegate::delegates::$module)),*, |
| 20 | + _ => None, |
| 21 | + } |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +/// Look up the module name and return the appropriate delegate function. |
| 26 | +pub fn get_module_delegate(name: &str) -> Option<&'static ChiselDelegate> { |
| 27 | + delegate_matcher!(name; checkfloat, remapstart) |
| 28 | +} |
| 29 | + |
| 30 | +/// Delegate functions |
| 31 | +mod delegates { |
| 32 | + #![allow(non_upper_case_globals)] |
| 33 | + use super::*; |
| 34 | + |
| 35 | + use crate::ModuleCreator; |
| 36 | + use crate::ModuleTranslator; |
| 37 | + use crate::ModuleValidator; |
| 38 | + |
| 39 | + /// Generate a delegate for a module with no config, which calls $method on the module. |
| 40 | + /// NOTE: currently only works with translate_inplace and validate |
| 41 | + macro_rules! __delegate_noconfig { |
| 42 | + ($delegate_name:ident, $module:ty, $method:ident) => { |
| 43 | + pub const $delegate_name: &'static ChiselDelegate = &|mut wasm, _| { |
| 44 | + let module = <$module>::new(); |
| 45 | + module.$method(&mut wasm) |
| 46 | + }; |
| 47 | + }; |
19 | 48 | } |
| 49 | + |
| 50 | + // TODO: integrate config api |
| 51 | + // TODO: accomodate functional-style validate() |
| 52 | + |
| 53 | + __delegate_noconfig!(checkfloat, crate::checkfloat::CheckFloat, validate); |
| 54 | + __delegate_noconfig!(remapstart, crate::remapstart::RemapStart, translate_inplace); |
| 55 | + |
20 | 56 | } |
21 | 57 |
|
22 | 58 | #[cfg(test)] |
23 | 59 | mod tests { |
24 | 60 | use super::*; |
| 61 | + use rustc_hex::FromHex; |
25 | 62 |
|
26 | 63 | #[test] |
27 | | - fn get_checkfloat() { |
| 64 | + fn get_validator() { |
28 | 65 | let delegate = get_module_delegate("checkfloat").expect("Cannot fail"); |
29 | 66 |
|
30 | 67 | let wasm: Vec<u8> = vec![ |
31 | 68 | 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, 0x02, 0x7c, |
32 | 69 | 0x7c, 0x01, 0x7c, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01, 0x03, 0x61, 0x64, 0x64, |
33 | 70 | 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0xa0, 0x0b, |
34 | 71 | ]; |
| 72 | + |
35 | 73 | let mut module = Module::from_bytes(&wasm).unwrap(); |
36 | 74 |
|
37 | 75 | let result = delegate(&mut module, &HashMap::new()); |
38 | 76 |
|
39 | 77 | assert_eq!(result.expect("Cannot fail"), false); |
40 | 78 | } |
| 79 | + |
| 80 | + #[test] |
| 81 | + fn get_translator() { |
| 82 | + let delegate = get_module_delegate("remapstart").expect("Cannot fail"); |
| 83 | + |
| 84 | + let wasm: Vec<u8> = FromHex::from_hex( |
| 85 | + "0061736d0100000001080260017e0060 |
| 86 | +000002170103656e760f657468657265756d5f75736547617300000303020101050301000107110 |
| 87 | +2046d61696e0001066d656d6f727902000801020a070202000b02000b0020046e616d65010e0201 |
| 88 | +046d61696e02056d61696e320209030001000001000200", |
| 89 | + ) |
| 90 | + .unwrap(); |
| 91 | + |
| 92 | + let mut module = Module::from_bytes(&wasm).unwrap(); |
| 93 | + let result = delegate(&mut module, &HashMap::new()); |
| 94 | + assert_eq!(result.expect("Cannot fail"), true); |
| 95 | + } |
41 | 96 | } |
0 commit comments