From 684fc09891c1cfde3161bb7bef552709ff7c19c5 Mon Sep 17 00:00:00 2001 From: Aster Date: Tue, 24 Dec 2024 01:58:42 +0800 Subject: [PATCH 1/9] [wasmprinter] support custom indent text --- crates/wasmprinter/src/lib.rs | 28 ++++++++++++++++-- crates/wasmprinter/src/operator.rs | 4 +-- crates/wasmprinter/tests/all.rs | 47 +++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/crates/wasmprinter/src/lib.rs b/crates/wasmprinter/src/lib.rs index b7844bf8b4..ac9deb254e 100644 --- a/crates/wasmprinter/src/lib.rs +++ b/crates/wasmprinter/src/lib.rs @@ -50,12 +50,25 @@ pub fn print_bytes(wasm: impl AsRef<[u8]>) -> Result { /// /// This structure is used to control the overal structure of how wasm binaries /// are printed and tweaks various ways that configures the output. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct Config { print_offsets: bool, print_skeleton: bool, name_unnamed: bool, fold_instructions: bool, + indent_text: String, +} + +impl Default for Config { + fn default() -> Self { + Self { + print_offsets: false, + print_skeleton: false, + name_unnamed: false, + fold_instructions: false, + indent_text: " ".to_string(), + } + } } /// This structure is the actual structure that prints WebAssembly binaries. @@ -226,6 +239,17 @@ impl Config { self } + /// Select the string to use when indenting. + /// + /// The indent allowed here are arbitrary and unchecked. You should enter + /// blank text like `" "` or `"\t"`, rather than something like `"(;;)"`. + /// + /// The default setting is double spaces `" "` + pub fn indent_text(&mut self, text: impl Into) -> &mut Self { + self.indent_text = text.into(); + self + } + /// Prints a WebAssembly binary into a `String` /// /// This function takes an entire `wasm` binary blob and will print it to @@ -1413,7 +1437,7 @@ impl Printer<'_, '_> { // reasonable to avoid generating hundreds of megabytes of whitespace // for small-ish modules that have deep-ish nesting. for _ in 0..self.nesting.min(MAX_NESTING_TO_PRINT) { - self.result.write_str(" ")?; + self.result.write_str(&self.config.indent_text)?; } Ok(()) } diff --git a/crates/wasmprinter/src/operator.rs b/crates/wasmprinter/src/operator.rs index 5b6f728dfc..a87df5066a 100644 --- a/crates/wasmprinter/src/operator.rs +++ b/crates/wasmprinter/src/operator.rs @@ -1453,10 +1453,8 @@ impl OpPrinter for PrintOperatorFolded<'_, '_, '_, '_> { let mut buf_color = PrintTermcolor(Ansi::new(Vec::new())); let mut buf_nocolor = PrintTermcolor(NoColor::new(Vec::new())); let internal_config = Config { - print_offsets: false, - print_skeleton: false, name_unnamed: self.printer.config.name_unnamed, - fold_instructions: false, + ..Default::default() }; let mut internal_printer = Printer { config: &internal_config, diff --git a/crates/wasmprinter/tests/all.rs b/crates/wasmprinter/tests/all.rs index 3d4d3bb255..1ce219066b 100644 --- a/crates/wasmprinter/tests/all.rs +++ b/crates/wasmprinter/tests/all.rs @@ -13,18 +13,19 @@ fn no_oom() { assert!(wat.len() < 500_000_000); } +const MODULE_1: &str = r#" + (;@0 ;) (module + (;@b ;) (type (;0;) (func (param i32) (result i32))) + (;@1f ;) (func (;0;) (type 0) (param i32) (result i32) + (;@20 ;) local.get 0 + ) + (;@17 ;) (export "f" (func 0)) + ) +"#; + #[test] fn offsets_and_lines_smoke_test() { - const MODULE: &str = r#" - (;@0 ;) (module - (;@b ;) (type (;0;) (func (param i32) (result i32))) - (;@1f ;) (func (;0;) (type 0) (param i32) (result i32) - (;@20 ;) local.get 0 - ) - (;@17 ;) (export "f" (func 0)) - ) - "#; - let bytes = wat::parse_str(MODULE).unwrap(); + let bytes = wat::parse_str(MODULE_1).unwrap(); let mut storage = String::new(); let actual: Vec<_> = wasmprinter::Config::new() @@ -46,3 +47,29 @@ fn offsets_and_lines_smoke_test() { assert_eq!(actual, expected); } + +#[test] +fn custom_indent_text() { + let bytes = wat::parse_str(MODULE_1).unwrap(); + + let mut storage = String::new(); + let actual: Vec<_> = wasmprinter::Config::new() + .indent_text('\t') + .offsets_and_lines(&bytes, &mut storage) + .unwrap() + .collect(); + + #[rustfmt::skip] + let expected = vec![ + (Some(0), "(module\n"), + (Some(0xb), "\t(type (;0;) (func (param i32) (result i32)))\n"), + (Some(0x17), "\t(export \"f\" (func 0))\n"), + (Some(0x1f), "\t(func (;0;) (type 0) (param i32) (result i32)\n"), + (Some(0x20), "\t\tlocal.get 0\n"), + (None, "\t)\n"), + (None, ")\n"), + (Some(0x23), ""), + ]; + + assert_eq!(actual, expected); +} From 80c553d9c4543c30feceb71ea67e67767c62c5a8 Mon Sep 17 00:00:00 2001 From: Aster Date: Tue, 24 Dec 2024 02:04:26 +0800 Subject: [PATCH 2/9] [wasm-tools] support config `--indent-text` for `print` command --- src/bin/wasm-tools/print.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/bin/wasm-tools/print.rs b/src/bin/wasm-tools/print.rs index 08a15446f0..f48bdb77a7 100644 --- a/src/bin/wasm-tools/print.rs +++ b/src/bin/wasm-tools/print.rs @@ -30,6 +30,10 @@ pub struct Opts { /// Print instructions in the folded format. #[clap(short, long)] fold_instructions: bool, + + /// The string to use when indenting. + #[clap(long)] + indent_text: Option, } impl Opts { @@ -45,6 +49,9 @@ impl Opts { config.print_skeleton(self.skeleton); config.name_unnamed(self.name_unnamed); config.fold_instructions(self.fold_instructions); + if let Some(s) = self.indent_text.as_ref() { + config.indent_text(s); + } self.io.output(wasm_tools::Output::Wat { wasm: &wasm, config, From 96b6a6e4bd2791ff94c9ac1081ec8048b90cc2db Mon Sep 17 00:00:00 2001 From: Aster Date: Fri, 27 Dec 2024 14:22:00 +0800 Subject: [PATCH 3/9] [wasm-tools] support config `--indent-text` for `print` command --- crates/wasmprinter/tests/all.rs | 46 ++++--------------- tests/cli/print-custom-indent-text.wat | 8 ++++ tests/cli/print-custom-indent-text.wat.stdout | 7 +++ 3 files changed, 25 insertions(+), 36 deletions(-) create mode 100644 tests/cli/print-custom-indent-text.wat create mode 100644 tests/cli/print-custom-indent-text.wat.stdout diff --git a/crates/wasmprinter/tests/all.rs b/crates/wasmprinter/tests/all.rs index 1ce219066b..3f30a83c1e 100644 --- a/crates/wasmprinter/tests/all.rs +++ b/crates/wasmprinter/tests/all.rs @@ -13,19 +13,19 @@ fn no_oom() { assert!(wat.len() < 500_000_000); } -const MODULE_1: &str = r#" - (;@0 ;) (module - (;@b ;) (type (;0;) (func (param i32) (result i32))) - (;@1f ;) (func (;0;) (type 0) (param i32) (result i32) - (;@20 ;) local.get 0 - ) - (;@17 ;) (export "f" (func 0)) - ) -"#; #[test] fn offsets_and_lines_smoke_test() { - let bytes = wat::parse_str(MODULE_1).unwrap(); + const MODULE: &str = r#" + (;@0 ;) (module + (;@b ;) (type (;0;) (func (param i32) (result i32))) + (;@1f ;) (func (;0;) (type 0) (param i32) (result i32) + (;@20 ;) local.get 0 + ) + (;@17 ;) (export "f" (func 0)) + ) + "#; + let bytes = wat::parse_str(MODULE).unwrap(); let mut storage = String::new(); let actual: Vec<_> = wasmprinter::Config::new() @@ -47,29 +47,3 @@ fn offsets_and_lines_smoke_test() { assert_eq!(actual, expected); } - -#[test] -fn custom_indent_text() { - let bytes = wat::parse_str(MODULE_1).unwrap(); - - let mut storage = String::new(); - let actual: Vec<_> = wasmprinter::Config::new() - .indent_text('\t') - .offsets_and_lines(&bytes, &mut storage) - .unwrap() - .collect(); - - #[rustfmt::skip] - let expected = vec![ - (Some(0), "(module\n"), - (Some(0xb), "\t(type (;0;) (func (param i32) (result i32)))\n"), - (Some(0x17), "\t(export \"f\" (func 0))\n"), - (Some(0x1f), "\t(func (;0;) (type 0) (param i32) (result i32)\n"), - (Some(0x20), "\t\tlocal.get 0\n"), - (None, "\t)\n"), - (None, ")\n"), - (Some(0x23), ""), - ]; - - assert_eq!(actual, expected); -} diff --git a/tests/cli/print-custom-indent-text.wat b/tests/cli/print-custom-indent-text.wat new file mode 100644 index 0000000000..eef9818c1f --- /dev/null +++ b/tests/cli/print-custom-indent-text.wat @@ -0,0 +1,8 @@ +;; RUN: print --indent-text '\t' +(;@0 ;) (module +(;@b ;) (type (;0;) (func (param i32) (result i32))) +(;@1f ;) (func (;0;) (type 0) (param i32) (result i32) +(;@20 ;) local.get 0 + ) +(;@17 ;) (export "f" (func 0)) + ) \ No newline at end of file diff --git a/tests/cli/print-custom-indent-text.wat.stdout b/tests/cli/print-custom-indent-text.wat.stdout new file mode 100644 index 0000000000..94eb186998 --- /dev/null +++ b/tests/cli/print-custom-indent-text.wat.stdout @@ -0,0 +1,7 @@ +(module + (type (;0;) (func (param i32) (result i32))) + (func (;0;) (type 0) (param i32) (result i32) + local.get 0 + ) + (export "f" (func 0)) +) \ No newline at end of file From 4bd9ee8fdad358fa6578c081a44b7e15ed8a4e8e Mon Sep 17 00:00:00 2001 From: Aster Date: Fri, 27 Dec 2024 14:23:53 +0800 Subject: [PATCH 4/9] [wasm-tools] support config `--indent-text` for `print` command --- tests/cli/print-custom-indent-text.wat | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cli/print-custom-indent-text.wat b/tests/cli/print-custom-indent-text.wat index eef9818c1f..39f7b036b9 100644 --- a/tests/cli/print-custom-indent-text.wat +++ b/tests/cli/print-custom-indent-text.wat @@ -1,4 +1,5 @@ ;; RUN: print --indent-text '\t' + (;@0 ;) (module (;@b ;) (type (;0;) (func (param i32) (result i32))) (;@1f ;) (func (;0;) (type 0) (param i32) (result i32) From c66062bd8da9ab63163755f33cfef553b575132b Mon Sep 17 00:00:00 2001 From: Aster Date: Fri, 27 Dec 2024 14:32:27 +0800 Subject: [PATCH 5/9] [wasmprinter] Add custom-indent test cases --- tests/cli/print-custom-indent-text.wat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cli/print-custom-indent-text.wat b/tests/cli/print-custom-indent-text.wat index 39f7b036b9..593bb02f25 100644 --- a/tests/cli/print-custom-indent-text.wat +++ b/tests/cli/print-custom-indent-text.wat @@ -1,4 +1,4 @@ -;; RUN: print --indent-text '\t' +;; RUN: print --indent-text "\t" % (;@0 ;) (module (;@b ;) (type (;0;) (func (param i32) (result i32))) From 35ea70b2565d249fe21d51a01e6098e8777528a9 Mon Sep 17 00:00:00 2001 From: Aster Date: Fri, 27 Dec 2024 14:34:40 +0800 Subject: [PATCH 6/9] [wasmprinter] Add custom-indent test cases --- crates/wasmprinter/tests/all.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/wasmprinter/tests/all.rs b/crates/wasmprinter/tests/all.rs index 3f30a83c1e..3d4d3bb255 100644 --- a/crates/wasmprinter/tests/all.rs +++ b/crates/wasmprinter/tests/all.rs @@ -13,7 +13,6 @@ fn no_oom() { assert!(wat.len() < 500_000_000); } - #[test] fn offsets_and_lines_smoke_test() { const MODULE: &str = r#" From 725b3243a7a714e610ae6f3e30f10b95406d56e3 Mon Sep 17 00:00:00 2001 From: Aster Date: Fri, 27 Dec 2024 14:47:19 +0800 Subject: [PATCH 7/9] [wasm-tools] support config `--indent` for `print` command --- src/bin/wasm-tools/print.rs | 12 ++++++++++-- tests/cli/print-custom-indent-width.wat | 9 +++++++++ tests/cli/print-custom-indent-width.wat.stdout | 7 +++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 tests/cli/print-custom-indent-width.wat create mode 100644 tests/cli/print-custom-indent-width.wat.stdout diff --git a/src/bin/wasm-tools/print.rs b/src/bin/wasm-tools/print.rs index f48bdb77a7..c1839b7e14 100644 --- a/src/bin/wasm-tools/print.rs +++ b/src/bin/wasm-tools/print.rs @@ -34,6 +34,9 @@ pub struct Opts { /// The string to use when indenting. #[clap(long)] indent_text: Option, + /// Number of spaces used for indentation, has lower priority than `--indent-text` + #[clap(long)] + indent: Option, } impl Opts { @@ -49,8 +52,13 @@ impl Opts { config.print_skeleton(self.skeleton); config.name_unnamed(self.name_unnamed); config.fold_instructions(self.fold_instructions); - if let Some(s) = self.indent_text.as_ref() { - config.indent_text(s); + match self.indent_text.as_ref() { + Some(s) => { + config.indent_text(s); + } + None => if let Some(s) = self.indent { + config.indent_text(&" ".repeat(s)); + }, } self.io.output(wasm_tools::Output::Wat { wasm: &wasm, diff --git a/tests/cli/print-custom-indent-width.wat b/tests/cli/print-custom-indent-width.wat new file mode 100644 index 0000000000..b14203c668 --- /dev/null +++ b/tests/cli/print-custom-indent-width.wat @@ -0,0 +1,9 @@ +;; RUN: print --indent 4 % + +(;@0 ;) (module +(;@b ;) (type (;0;) (func (param i32) (result i32))) +(;@1f ;) (func (;0;) (type 0) (param i32) (result i32) +(;@20 ;) local.get 0 + ) +(;@17 ;) (export "f" (func 0)) + ) \ No newline at end of file diff --git a/tests/cli/print-custom-indent-width.wat.stdout b/tests/cli/print-custom-indent-width.wat.stdout new file mode 100644 index 0000000000..8b2e19c9b9 --- /dev/null +++ b/tests/cli/print-custom-indent-width.wat.stdout @@ -0,0 +1,7 @@ +(module + (type (;0;) (func (param i32) (result i32))) + (func (;0;) (type 0) (param i32) (result i32) + local.get 0 + ) + (export "f" (func 0)) +) \ No newline at end of file From f00dc0d0f1313b82cebe8a8660992658813f1ae7 Mon Sep 17 00:00:00 2001 From: Aster Date: Fri, 27 Dec 2024 15:03:06 +0800 Subject: [PATCH 8/9] [wasm-tools] test the precedence of ``--indent-text` and ``--indent` --- src/bin/wasm-tools/print.rs | 8 +++++--- tests/cli/print-custom-indent-text.wat | 2 +- tests/cli/print-custom-indent-text.wat.stdout | 2 +- tests/cli/print-custom-indent-width.wat.stdout | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/bin/wasm-tools/print.rs b/src/bin/wasm-tools/print.rs index c1839b7e14..a88e2de9a2 100644 --- a/src/bin/wasm-tools/print.rs +++ b/src/bin/wasm-tools/print.rs @@ -56,9 +56,11 @@ impl Opts { Some(s) => { config.indent_text(s); } - None => if let Some(s) = self.indent { - config.indent_text(&" ".repeat(s)); - }, + None => { + if let Some(s) = self.indent { + config.indent_text(&" ".repeat(s)); + } + } } self.io.output(wasm_tools::Output::Wat { wasm: &wasm, diff --git a/tests/cli/print-custom-indent-text.wat b/tests/cli/print-custom-indent-text.wat index 593bb02f25..fcbffc4edf 100644 --- a/tests/cli/print-custom-indent-text.wat +++ b/tests/cli/print-custom-indent-text.wat @@ -1,4 +1,4 @@ -;; RUN: print --indent-text "\t" % +;; RUN: print --indent-text \t --indent 2 % (;@0 ;) (module (;@b ;) (type (;0;) (func (param i32) (result i32))) diff --git a/tests/cli/print-custom-indent-text.wat.stdout b/tests/cli/print-custom-indent-text.wat.stdout index 94eb186998..ba78109310 100644 --- a/tests/cli/print-custom-indent-text.wat.stdout +++ b/tests/cli/print-custom-indent-text.wat.stdout @@ -1,7 +1,7 @@ (module (type (;0;) (func (param i32) (result i32))) + (export "f" (func 0)) (func (;0;) (type 0) (param i32) (result i32) local.get 0 ) - (export "f" (func 0)) ) \ No newline at end of file diff --git a/tests/cli/print-custom-indent-width.wat.stdout b/tests/cli/print-custom-indent-width.wat.stdout index 8b2e19c9b9..11b324786b 100644 --- a/tests/cli/print-custom-indent-width.wat.stdout +++ b/tests/cli/print-custom-indent-width.wat.stdout @@ -1,7 +1,7 @@ (module (type (;0;) (func (param i32) (result i32))) + (export "f" (func 0)) (func (;0;) (type 0) (param i32) (result i32) local.get 0 ) - (export "f" (func 0)) ) \ No newline at end of file From 0ae8c23aba785f5fd333f53ff491f0935d8269c4 Mon Sep 17 00:00:00 2001 From: Aster Date: Mon, 30 Dec 2024 12:59:13 +0800 Subject: [PATCH 9/9] [wasm-tools] remove indent text test --- tests/cli/print-custom-indent-text.wat | 9 --------- tests/cli/print-custom-indent-text.wat.stdout | 7 ------- 2 files changed, 16 deletions(-) delete mode 100644 tests/cli/print-custom-indent-text.wat delete mode 100644 tests/cli/print-custom-indent-text.wat.stdout diff --git a/tests/cli/print-custom-indent-text.wat b/tests/cli/print-custom-indent-text.wat deleted file mode 100644 index fcbffc4edf..0000000000 --- a/tests/cli/print-custom-indent-text.wat +++ /dev/null @@ -1,9 +0,0 @@ -;; RUN: print --indent-text \t --indent 2 % - -(;@0 ;) (module -(;@b ;) (type (;0;) (func (param i32) (result i32))) -(;@1f ;) (func (;0;) (type 0) (param i32) (result i32) -(;@20 ;) local.get 0 - ) -(;@17 ;) (export "f" (func 0)) - ) \ No newline at end of file diff --git a/tests/cli/print-custom-indent-text.wat.stdout b/tests/cli/print-custom-indent-text.wat.stdout deleted file mode 100644 index ba78109310..0000000000 --- a/tests/cli/print-custom-indent-text.wat.stdout +++ /dev/null @@ -1,7 +0,0 @@ -(module - (type (;0;) (func (param i32) (result i32))) - (export "f" (func 0)) - (func (;0;) (type 0) (param i32) (result i32) - local.get 0 - ) -) \ No newline at end of file