Skip to content

Commit 35bbe00

Browse files
authored
Merge pull request #161 from wasmx/module-config
Add attempt for better module configuration
2 parents 2148aea + 26ca1be commit 35bbe00

14 files changed

+293
-13
lines changed

libchisel/src/binaryenopt.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use std::collections::HashMap;
2+
13
use parity_wasm::elements::Module;
24

3-
use super::{ChiselModule, ModuleError, ModuleKind, ModulePreset, ModuleTranslator};
5+
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModulePreset, ModuleTranslator};
46

57
// FIXME: change level names
68
pub enum BinaryenOptimiser {
@@ -29,6 +31,20 @@ impl<'a> ChiselModule<'a> for BinaryenOptimiser {
2931
}
3032
}
3133

34+
impl ModuleConfig for BinaryenOptimiser {
35+
fn with_defaults() -> Result<Self, ModuleError> {
36+
Ok(BinaryenOptimiser::O2)
37+
}
38+
39+
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> {
40+
if let Some(preset) = config.get("preset") {
41+
BinaryenOptimiser::with_preset(preset)
42+
} else {
43+
Err(ModuleError::NotSupported)
44+
}
45+
}
46+
}
47+
3248
impl ModulePreset for BinaryenOptimiser {
3349
fn with_preset(preset: &str) -> Result<Self, ModuleError> {
3450
match preset {

libchisel/src/checkfloat.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use std::collections::HashMap;
2+
13
use parity_wasm::elements::{Instruction, Module};
24

3-
use super::{ChiselModule, ModuleError, ModuleKind, ModuleValidator};
5+
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModuleValidator};
46

57
/// Struct on which ModuleValidator is implemented.
68
pub struct CheckFloat {}
@@ -21,6 +23,16 @@ impl<'a> ChiselModule<'a> for CheckFloat {
2123
}
2224
}
2325

26+
impl ModuleConfig for CheckFloat {
27+
fn with_defaults() -> Result<Self, ModuleError> {
28+
Ok(CheckFloat {})
29+
}
30+
31+
fn with_config(_config: &HashMap<String, String>) -> Result<Self, ModuleError> {
32+
Err(ModuleError::NotSupported)
33+
}
34+
}
35+
2436
impl CheckFloat {
2537
pub fn new() -> Self {
2638
CheckFloat {}

libchisel/src/checkstartfunc.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use std::collections::HashMap;
2+
13
use parity_wasm::elements::Module;
24

3-
use super::{ChiselModule, ModuleError, ModuleKind, ModuleValidator};
5+
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModuleValidator};
46

57
/// Struct on which ModuleValidator is implemented.
68
pub struct CheckStartFunc {
@@ -31,6 +33,23 @@ impl<'a> ChiselModule<'a> for CheckStartFunc {
3133
}
3234
}
3335

36+
impl ModuleConfig for CheckStartFunc {
37+
fn with_defaults() -> Result<Self, ModuleError> {
38+
Err(ModuleError::NotSupported)
39+
}
40+
41+
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> {
42+
let require_start = if let Some(value) = config.get("require_start") {
43+
value == "true"
44+
} else {
45+
false
46+
};
47+
Ok(CheckStartFunc {
48+
start_required: require_start,
49+
})
50+
}
51+
}
52+
3453
impl ModuleValidator for CheckStartFunc {
3554
fn validate(&self, module: &Module) -> Result<bool, ModuleError> {
3655
Ok(module.start_section().is_some() == self.start_required)

libchisel/src/deployer.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use std::collections::HashMap;
2+
13
use parity_wasm::builder;
24
use parity_wasm::elements::{CustomSection, Module};
35

4-
use super::{ChiselModule, ModuleError, ModuleKind, ModulePreset, ModuleTranslator};
6+
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModulePreset, ModuleTranslator};
57

68
/// Enum on which ModuleTranslator is implemented.
79
pub enum Deployer {
@@ -25,6 +27,20 @@ impl<'a> ChiselModule<'a> for Deployer {
2527
}
2628
}
2729

30+
impl ModuleConfig for Deployer {
31+
fn with_defaults() -> Result<Self, ModuleError> {
32+
Err(ModuleError::NotSupported)
33+
}
34+
35+
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> {
36+
if let Some(preset) = config.get("preset") {
37+
Deployer::with_preset(preset)
38+
} else {
39+
Err(ModuleError::NotSupported)
40+
}
41+
}
42+
}
43+
2844
impl ModulePreset for Deployer {
2945
fn with_preset(preset: &str) -> Result<Self, ModuleError> {
3046
match preset {

libchisel/src/dropsection.rs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
use std::collections::HashMap;
2+
use std::error::Error;
3+
14
use parity_wasm::elements::{Module, Section};
25

3-
use super::{ChiselModule, ModuleError, ModuleKind, ModuleTranslator};
6+
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModuleTranslator};
47

58
/// Enum on which ModuleTranslator is implemented.
9+
#[derive(Debug)]
610
pub enum DropSection {
711
NamesSection,
812
/// Name of the custom section.
@@ -29,6 +33,58 @@ impl<'a> ChiselModule<'a> for DropSection {
2933
}
3034
}
3135

36+
impl From<std::num::ParseIntError> for ModuleError {
37+
fn from(error: std::num::ParseIntError) -> Self {
38+
ModuleError::Custom(error.description().to_string())
39+
}
40+
}
41+
42+
impl ModuleConfig for DropSection {
43+
fn with_defaults() -> Result<Self, ModuleError> {
44+
Err(ModuleError::NotSupported)
45+
}
46+
47+
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> {
48+
// Query all possible modes
49+
let modes: [(&'static str, Option<&String>); 4] = [
50+
("names", config.get("names".into())),
51+
("custom_by_name", config.get("custom_by_name".into())),
52+
("custom_by_index", config.get("custom_by_index".into())),
53+
("unknown_by_index", config.get("unknown_by_index".into())),
54+
];
55+
56+
// Filter out modes which were provided.
57+
let mut matches: Vec<(&'static str, &String)> = modes
58+
.iter()
59+
.filter_map(|(k, v)| {
60+
if let Some(v) = v {
61+
Some((*k, *v))
62+
} else {
63+
None
64+
}
65+
})
66+
.collect();
67+
68+
// Reject multiple modes
69+
if matches.len() != 1 {
70+
return Err(ModuleError::Custom(
71+
"Only one mode allowed at a time".to_string(),
72+
));
73+
}
74+
75+
let (mode, val) = matches.pop().expect("Verified that one match is present");
76+
match mode {
77+
"names" => Ok(DropSection::NamesSection),
78+
"custom_by_name" => Ok(DropSection::CustomSectionByName(val.clone())),
79+
"custom_by_index" => Ok(DropSection::CustomSectionByIndex(str::parse::<usize>(val)?)),
80+
"unknown_by_index" => Ok(DropSection::UnknownSectionByIndex(str::parse::<usize>(
81+
val,
82+
)?)),
83+
_ => panic!("Only one of the above was present in the array"),
84+
}
85+
}
86+
}
87+
3288
// TODO: consider upstreaming this
3389
fn custom_section_index_for(module: &Module, name: &str) -> Option<usize> {
3490
module.sections().iter().position(|e| match e {
@@ -258,4 +314,17 @@ mod tests {
258314
assert!(custom_section_index_for(&module, "name").is_none());
259315
assert!(custom_section_index_for(&module1, "name").is_none());
260316
}
317+
318+
#[test]
319+
fn with_config_multiple_modes() {
320+
let mut conf = HashMap::new();
321+
conf.insert("names".to_string(), "".to_string());
322+
conf.insert("custom_by_name".to_string(), "name".to_string());
323+
324+
let module = DropSection::with_config(&conf);
325+
assert_eq!(
326+
module.unwrap_err(),
327+
ModuleError::Custom("Only one mode allowed at a time".to_string())
328+
);
329+
}
261330
}

libchisel/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub use parity_wasm::elements::Module;
22

3+
use std::collections::HashMap;
34
use std::{error, fmt};
45

56
pub mod imports;
@@ -71,6 +72,17 @@ pub trait ModulePreset {
7172
Self: std::marker::Sized;
7273
}
7374

75+
// TODO: move this to be part of ChiselModule and retire ModulePreset
76+
pub trait ModuleConfig {
77+
fn with_defaults() -> Result<Self, ModuleError>
78+
where
79+
Self: std::marker::Sized;
80+
81+
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError>
82+
where
83+
Self: std::marker::Sized;
84+
}
85+
7486
impl From<String> for ModuleError {
7587
fn from(error: String) -> Self {
7688
ModuleError::Custom(error)

libchisel/src/remapimports.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
use std::collections::HashMap;
2+
13
use parity_wasm::elements::{ImportEntry, ImportSection, Module};
24

35
use super::{
4-
imports::ImportList, ChiselModule, ModuleError, ModuleKind, ModulePreset, ModuleTranslator,
6+
imports::ImportList, ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModulePreset,
7+
ModuleTranslator,
58
};
69

710
pub struct RemapImports<'a> {
@@ -29,6 +32,20 @@ impl<'a> ChiselModule<'a> for RemapImports<'a> {
2932
}
3033
}
3134

35+
impl<'a> ModuleConfig for RemapImports<'a> {
36+
fn with_defaults() -> Result<Self, ModuleError> {
37+
Err(ModuleError::NotSupported)
38+
}
39+
40+
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> {
41+
if let Some(preset) = config.get("preset") {
42+
RemapImports::with_preset(preset)
43+
} else {
44+
Err(ModuleError::NotSupported)
45+
}
46+
}
47+
}
48+
3249
impl<'a> ModulePreset for RemapImports<'a> {
3350
fn with_preset(preset: &str) -> Result<Self, ModuleError> {
3451
let mut interface_set: Vec<ImportInterface> = Vec::new();

libchisel/src/remapstart.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use std::collections::HashMap;
2+
13
use parity_wasm::elements::{ExportEntry, ExportSection, Internal, Module, Section};
24

3-
use super::{ChiselModule, ModuleError, ModuleKind, ModulePreset, ModuleTranslator};
5+
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModulePreset, ModuleTranslator};
46

57
pub struct RemapStart;
68

@@ -30,6 +32,21 @@ impl<'a> ChiselModule<'a> for RemapStart {
3032
}
3133
}
3234

35+
impl ModuleConfig for RemapStart {
36+
fn with_defaults() -> Result<Self, ModuleError> {
37+
Ok(RemapStart {})
38+
}
39+
40+
// FIXME: drop this, no need for preset here
41+
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> {
42+
if let Some(preset) = config.get("preset") {
43+
RemapStart::with_preset(preset)
44+
} else {
45+
Err(ModuleError::NotSupported)
46+
}
47+
}
48+
}
49+
3350
impl ModuleTranslator for RemapStart {
3451
fn translate_inplace(&self, module: &mut Module) -> Result<bool, ModuleError> {
3552
Ok(remap_start(module))

libchisel/src/repack.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use std::collections::HashMap;
2+
13
use parity_wasm::builder;
24
use parity_wasm::elements::Module;
35

4-
use super::{ChiselModule, ModuleError, ModuleKind, ModuleTranslator};
6+
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModuleTranslator};
57

68
pub struct Repack;
79

@@ -27,6 +29,16 @@ impl<'a> ChiselModule<'a> for Repack {
2729
}
2830
}
2931

32+
impl ModuleConfig for Repack {
33+
fn with_defaults() -> Result<Self, ModuleError> {
34+
Ok(Repack::new())
35+
}
36+
37+
fn with_config(_config: &HashMap<String, String>) -> Result<Self, ModuleError> {
38+
Err(ModuleError::NotSupported)
39+
}
40+
}
41+
3042
impl ModuleTranslator for Repack {
3143
fn translate_inplace(&self, _module: &mut Module) -> Result<bool, ModuleError> {
3244
Err(ModuleError::NotSupported)

libchisel/src/snip.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use std::collections::HashMap;
2+
13
use parity_wasm::elements::Module;
24

3-
use super::{ChiselModule, ModuleError, ModuleKind, ModuleTranslator};
5+
use super::{ChiselModule, ModuleConfig, ModuleError, ModuleKind, ModuleTranslator};
46

57
#[derive(Clone)]
68
pub struct Snip(wasm_snip::Options);
@@ -32,6 +34,30 @@ impl<'a> ChiselModule<'a> for Snip {
3234
}
3335
}
3436

37+
// TODO: consider making this a generic helper?
38+
fn check_bool_option(config: &HashMap<String, String>, option: &str, default: bool) -> bool {
39+
if let Some(value) = config.get(option) {
40+
value == "true"
41+
} else {
42+
default
43+
}
44+
}
45+
46+
impl ModuleConfig for Snip {
47+
fn with_defaults() -> Result<Self, ModuleError> {
48+
Ok(Snip::new())
49+
}
50+
51+
fn with_config(config: &HashMap<String, String>) -> Result<Self, ModuleError> {
52+
let mut options = wasm_snip::Options::default();
53+
options.snip_rust_fmt_code = check_bool_option(&config, "snip_rust_fmt_code", true);
54+
options.snip_rust_panicking_code =
55+
check_bool_option(&config, "snip_rust_panicking_code", true);
56+
options.skip_producers_section = check_bool_option(&config, "skip_producers_section", true);
57+
Ok(Snip { 0: options })
58+
}
59+
}
60+
3561
impl From<failure::Error> for ModuleError {
3662
fn from(error: failure::Error) -> Self {
3763
ModuleError::Custom(error.to_string())

0 commit comments

Comments
 (0)