-
Notifications
You must be signed in to change notification settings - Fork 10
Add attempt for better module configuration #161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0a9530e
8c9f0c6
227163e
a63b3ec
e826c58
6d325a2
af8bfb1
124093c
6d58db3
858da62
2933c35
e539a95
93eb346
26ca1be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
use std::collections::HashMap; | ||
|
||
use parity_wasm::elements::Module; | ||
|
||
use super::{ChiselModule, ModuleError, ModuleKind, ModuleValidator}; | ||
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModuleValidator}; | ||
|
||
/// Struct on which ModuleValidator is implemented. | ||
pub struct CheckStartFunc { | ||
|
@@ -31,6 +33,23 @@ impl<'a> ChiselModule<'a> for CheckStartFunc { | |
} | ||
} | ||
|
||
impl ModuleConfig for CheckStartFunc { | ||
fn with_defaults() -> Result<Self, ModuleError> { | ||
Err(ModuleError::NotSupported) | ||
} | ||
|
||
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could also split this into two (and that would remove the need for default):
e.g.
and then There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think key-val configuration should be fine for now. No need to further complicate things with the config string, and we can definitely just implement the config string as a specified key There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, but the downside is the terrible syntax needed for creating a hashmap and passing it. So for simple modules a string is much more simple. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps the config string method could just wrap that logic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean by wrap? Define a way to encode hashmaps? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
let require_start = if let Some(value) = config.get("require_start") { | ||
value == "true" | ||
} else { | ||
false | ||
}; | ||
Ok(CheckStartFunc { | ||
start_required: require_start, | ||
}) | ||
} | ||
} | ||
|
||
impl ModuleValidator for CheckStartFunc { | ||
fn validate(&self, module: &Module) -> Result<bool, ModuleError> { | ||
Ok(module.start_section().is_some() == self.start_required) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,12 @@ | ||
use std::collections::HashMap; | ||
use std::error::Error; | ||
|
||
use parity_wasm::elements::{Module, Section}; | ||
|
||
use super::{ChiselModule, ModuleError, ModuleKind, ModuleTranslator}; | ||
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModuleTranslator}; | ||
|
||
/// Enum on which ModuleTranslator is implemented. | ||
#[derive(Debug)] | ||
pub enum DropSection { | ||
NamesSection, | ||
/// Name of the custom section. | ||
|
@@ -29,6 +33,58 @@ impl<'a> ChiselModule<'a> for DropSection { | |
} | ||
} | ||
|
||
impl From<std::num::ParseIntError> for ModuleError { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could make this more generic, and support all kinds of errors:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, though I was considering here to wrap it with some text or use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apparently this is unstable: rust-lang/rust#52662 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could have this blanket impl and then have specialized impls for specific errors |
||
fn from(error: std::num::ParseIntError) -> Self { | ||
ModuleError::Custom(error.description().to_string()) | ||
} | ||
} | ||
|
||
impl ModuleConfig for DropSection { | ||
fn with_defaults() -> Result<Self, ModuleError> { | ||
Err(ModuleError::NotSupported) | ||
} | ||
|
||
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> { | ||
// Query all possible modes | ||
let modes: [(&'static str, Option<&String>); 4] = [ | ||
("names", config.get("names".into())), | ||
("custom_by_name", config.get("custom_by_name".into())), | ||
("custom_by_index", config.get("custom_by_index".into())), | ||
("unknown_by_index", config.get("unknown_by_index".into())), | ||
]; | ||
|
||
// Filter out modes which were provided. | ||
let mut matches: Vec<(&'static str, &String)> = modes | ||
.iter() | ||
.filter_map(|(k, v)| { | ||
if let Some(v) = v { | ||
Some((*k, *v)) | ||
} else { | ||
None | ||
} | ||
}) | ||
.collect(); | ||
|
||
// Reject multiple modes | ||
if matches.len() != 1 { | ||
return Err(ModuleError::Custom( | ||
"Only one mode allowed at a time".to_string(), | ||
)); | ||
} | ||
|
||
let (mode, val) = matches.pop().expect("Verified that one match is present"); | ||
match mode { | ||
"names" => Ok(DropSection::NamesSection), | ||
"custom_by_name" => Ok(DropSection::CustomSectionByName(val.clone())), | ||
"custom_by_index" => Ok(DropSection::CustomSectionByIndex(str::parse::<usize>(val)?)), | ||
"unknown_by_index" => Ok(DropSection::UnknownSectionByIndex(str::parse::<usize>( | ||
val, | ||
)?)), | ||
_ => panic!("Only one of the above was present in the array"), | ||
} | ||
} | ||
} | ||
|
||
// TODO: consider upstreaming this | ||
fn custom_section_index_for(module: &Module, name: &str) -> Option<usize> { | ||
module.sections().iter().position(|e| match e { | ||
|
@@ -258,4 +314,17 @@ mod tests { | |
assert!(custom_section_index_for(&module, "name").is_none()); | ||
assert!(custom_section_index_for(&module1, "name").is_none()); | ||
} | ||
|
||
#[test] | ||
fn with_config_multiple_modes() { | ||
let mut conf = HashMap::new(); | ||
conf.insert("names".to_string(), "".to_string()); | ||
conf.insert("custom_by_name".to_string(), "name".to_string()); | ||
|
||
let module = DropSection::with_config(&conf); | ||
assert_eq!( | ||
module.unwrap_err(), | ||
ModuleError::Custom("Only one mode allowed at a time".to_string()) | ||
); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.