From 9e7c56b944b41a33263eee47b49aeffc2d9f20ad Mon Sep 17 00:00:00 2001 From: xunilrj Date: Wed, 3 Jul 2024 14:12:13 +0100 Subject: [PATCH] better debug for bytecode printing --- forc-pkg/src/manifest/build_profile.rs | 5 ++ forc-pkg/src/pkg.rs | 8 +- forc-plugins/forc-client/src/op/deploy.rs | 1 + forc-plugins/forc-client/src/op/run/mod.rs | 1 + forc/src/cli/commands/test.rs | 1 + forc/src/ops/forc_build.rs | 1 + forc/src/ops/forc_contract_id.rs | 1 + forc/src/ops/forc_predicate_root.rs | 1 + sway-core/src/asm_generation/finalized_asm.rs | 48 ++++++++++- sway-core/src/build_config.rs | 7 +- .../typed/typed_match_expression.rs | 8 ++ test/src/e2e_vm_tests/harness.rs | 1 + .../match_expressions_all/src/main.sw | 86 +------------------ 13 files changed, 79 insertions(+), 90 deletions(-) diff --git a/forc-pkg/src/manifest/build_profile.rs b/forc-pkg/src/manifest/build_profile.rs index 0922ba59124..78957808872 100644 --- a/forc-pkg/src/manifest/build_profile.rs +++ b/forc-pkg/src/manifest/build_profile.rs @@ -24,6 +24,8 @@ pub struct BuildProfile { #[serde(default)] pub print_bytecode: bool, #[serde(default)] + pub print_bytecode_spans: bool, + #[serde(default)] pub terse: bool, #[serde(default)] pub time_phases: bool, @@ -57,6 +59,7 @@ impl BuildProfile { print_ir: PrintIr::default(), print_asm: PrintAsm::default(), print_bytecode: false, + print_bytecode_spans: false, terse: false, time_phases: false, metrics_outfile: None, @@ -80,6 +83,7 @@ impl BuildProfile { print_ir: PrintIr::default(), print_asm: PrintAsm::default(), print_bytecode: false, + print_bytecode_spans: false, terse: false, time_phases: false, metrics_outfile: None, @@ -152,6 +156,7 @@ mod tests { print_ir: PrintIr::r#final(), print_asm: PrintAsm::all(), print_bytecode: true, + print_bytecode_spans: true, terse: true, time_phases: true, metrics_outfile: Some("metrics_outfile".into()), diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 09b00fa5057..e735ffa1d62 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -262,6 +262,8 @@ pub struct PrintOpts { pub asm: PrintAsm, /// Print the bytecode. This is the final output of the compiler. pub bytecode: bool, + /// Print the original source code together with bytecode. + pub bytecode_spans: bool, /// Print the generated Sway IR (Intermediate Representation). pub ir: PrintIr, /// Output build errors and warnings in reverse order. @@ -1549,7 +1551,10 @@ pub fn sway_build_config( .with_print_dca_graph(build_profile.print_dca_graph.clone()) .with_print_dca_graph_url_format(build_profile.print_dca_graph_url_format.clone()) .with_print_asm(build_profile.print_asm) - .with_print_bytecode(build_profile.print_bytecode) + .with_print_bytecode( + build_profile.print_bytecode, + build_profile.print_bytecode_spans, + ) .with_print_ir(build_profile.print_ir.clone()) .with_include_tests(build_profile.include_tests) .with_time_phases(build_profile.time_phases) @@ -2079,6 +2084,7 @@ fn build_profile_from_opts( profile.print_ir |= print.ir.clone(); profile.print_asm |= print.asm; profile.print_bytecode |= print.bytecode; + profile.print_bytecode_spans |= print.bytecode_spans; profile.terse |= pkg.terse; profile.time_phases |= time_phases; if profile.metrics_outfile.is_none() { diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index e0270fa5245..e5daeb0c5b6 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -353,6 +353,7 @@ fn build_opts_from_cmd(cmd: &cmd::Deploy) -> pkg::BuildOpts { dca_graph_url_format: cmd.print.dca_graph_url_format.clone(), asm: cmd.print.asm(), bytecode: cmd.print.bytecode, + bytecode_spans: false, ir: cmd.print.ir(), reverse_order: cmd.print.reverse_order, }, diff --git a/forc-plugins/forc-client/src/op/run/mod.rs b/forc-plugins/forc-client/src/op/run/mod.rs index 0ea4f073b2a..384da48ff55 100644 --- a/forc-plugins/forc-client/src/op/run/mod.rs +++ b/forc-plugins/forc-client/src/op/run/mod.rs @@ -221,6 +221,7 @@ fn build_opts_from_cmd(cmd: &cmd::Run) -> pkg::BuildOpts { dca_graph_url_format: cmd.print.dca_graph_url_format.clone(), asm: cmd.print.asm(), bytecode: cmd.print.bytecode, + bytecode_spans: false, ir: cmd.print.ir(), reverse_order: cmd.print.reverse_order, }, diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index f8e4001fa42..225c5c14ee0 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -237,6 +237,7 @@ fn opts_from_cmd(cmd: Command) -> forc_test::TestOpts { dca_graph_url_format: cmd.build.print.dca_graph_url_format.clone(), asm: cmd.build.print.asm(), bytecode: cmd.build.print.bytecode, + bytecode_spans: false, ir: cmd.build.print.ir(), reverse_order: cmd.build.print.reverse_order, }, diff --git a/forc/src/ops/forc_build.rs b/forc/src/ops/forc_build.rs index 35a03b611a7..91e316c37ba 100644 --- a/forc/src/ops/forc_build.rs +++ b/forc/src/ops/forc_build.rs @@ -26,6 +26,7 @@ fn opts_from_cmd(cmd: BuildCommand) -> pkg::BuildOpts { dca_graph_url_format: cmd.build.print.dca_graph_url_format.clone(), asm: cmd.build.print.asm(), bytecode: cmd.build.print.bytecode, + bytecode_spans: false, ir: cmd.build.print.ir(), reverse_order: cmd.build.print.reverse_order, }, diff --git a/forc/src/ops/forc_contract_id.rs b/forc/src/ops/forc_contract_id.rs index 3a6d975ac40..51e9a7cd708 100644 --- a/forc/src/ops/forc_contract_id.rs +++ b/forc/src/ops/forc_contract_id.rs @@ -61,6 +61,7 @@ fn build_opts_from_cmd(cmd: &ContractIdCommand) -> pkg::BuildOpts { dca_graph_url_format: cmd.print.dca_graph_url_format.clone(), asm: cmd.print.asm(), bytecode: cmd.print.bytecode, + bytecode_spans: false, ir: cmd.print.ir(), reverse_order: cmd.print.reverse_order, }, diff --git a/forc/src/ops/forc_predicate_root.rs b/forc/src/ops/forc_predicate_root.rs index febf7b96ca6..efca0f92bec 100644 --- a/forc/src/ops/forc_predicate_root.rs +++ b/forc/src/ops/forc_predicate_root.rs @@ -30,6 +30,7 @@ fn build_opts_from_cmd(cmd: PredicateRootCommand) -> pkg::BuildOpts { dca_graph_url_format: cmd.print.dca_graph_url_format.clone(), asm: cmd.print.asm(), bytecode: cmd.print.bytecode, + bytecode_spans: false, ir: cmd.print.ir(), reverse_order: cmd.print.reverse_order, }, diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index 2fc0fe4326d..8f32505e57a 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -151,6 +151,13 @@ fn to_bytecode_mut( println!(";; --- START OF TARGET BYTECODE ---\n"); } + let mut last_span = None; + let mut indentation = if build_config.print_bytecode_spans { + 4 + } else { + 0 + }; + let mut half_word_ix = 0; let mut offset_from_instr_start = 0; for op in ops.iter() { @@ -165,7 +172,7 @@ fn to_bytecode_mut( match fuel_op { Either::Right(data) => { if build_config.print_bytecode { - print!("{:#010x} ", bytecode.len()); + print!("{}{:#010x} ", " ".repeat(indentation), bytecode.len()); println!( " ;; {:?}", data @@ -181,8 +188,45 @@ fn to_bytecode_mut( } Either::Left(instructions) => { for instruction in instructions { + // Print original source span only once + if build_config.print_bytecode_spans { + last_span = match (last_span, &span) { + (None, Some(span)) => { + indentation = 4; + let line_col = span.start_pos().line_col(); + println!( + "{} @ {}:{}:{}", + span.as_str(), + span.source_id() + .map(|source_id| source_engine.get_path(source_id)) + .map(|x| x.display().to_string()) + .unwrap_or("".to_string()), + line_col.line, + line_col.col + ); + Some(span.clone()) + } + (Some(last), Some(span)) if last != *span => { + indentation = 4; + let line_col = span.start_pos().line_col(); + println!( + "{} @ {}:{}:{}", + span.as_str(), + span.source_id() + .map(|source_id| source_engine.get_path(source_id)) + .map(|x| x.display().to_string()) + .unwrap_or("".to_string()), + line_col.line, + line_col.col + ); + Some(span.clone()) + } + (last, _) => last, + }; + } + if build_config.print_bytecode { - print!("{:#010x} ", bytecode.len()); + print!("{}{:#010x} ", " ".repeat(indentation), bytecode.len()); print_instruction(&instruction); } diff --git a/sway-core/src/build_config.rs b/sway-core/src/build_config.rs index b79f2112d66..ab1b3f4b78b 100644 --- a/sway-core/src/build_config.rs +++ b/sway-core/src/build_config.rs @@ -187,6 +187,7 @@ pub struct BuildConfig { pub(crate) print_dca_graph_url_format: Option, pub(crate) print_asm: PrintAsm, pub(crate) print_bytecode: bool, + pub(crate) print_bytecode_spans: bool, pub(crate) print_ir: PrintIr, pub(crate) include_tests: bool, pub(crate) optimization_level: OptLevel, @@ -234,6 +235,7 @@ impl BuildConfig { print_dca_graph_url_format: None, print_asm: PrintAsm::default(), print_bytecode: false, + print_bytecode_spans: false, print_ir: PrintIr::default(), include_tests: false, time_phases: false, @@ -264,9 +266,10 @@ impl BuildConfig { Self { print_asm, ..self } } - pub fn with_print_bytecode(self, a: bool) -> Self { + pub fn with_print_bytecode(self, bytecode: bool, bytecode_spans: bool) -> Self { Self { - print_bytecode: a, + print_bytecode: bytecode, + print_bytecode_spans: bytecode_spans, ..self } } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs index 9a657561d52..85cc2ee0634 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs @@ -307,6 +307,10 @@ impl ty::TyMatchExpression { }; } + if RADIX_TREE_DEBUG { + println!("return wildcard branch"); + } + Ok(block) } @@ -580,6 +584,10 @@ impl ty::TyMatchExpression { }; } + if RADIX_TREE_DEBUG { + println!("{}return wildcard branch", " ".repeat(depth * 4),); + } + block } diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index 72ca391a3d1..cb839dc2608 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -278,6 +278,7 @@ pub(crate) async fn compile_to_bytes(file_name: &str, run_config: &RunConfig) -> dca_graph_url_format: None, asm: run_config.print_asm, bytecode: run_config.print_bytecode, + bytecode_spans: run_config.print_bytecode, ir: run_config.print_ir.clone(), reverse_order: false, }, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_all/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_all/src/main.sw index f3115d8a357..fe9bf914c26 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_all/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_all/src/main.sw @@ -28,89 +28,5 @@ fn return_match_on_str_slice(param: str) -> u64 { } fn main() { - let x = match 8 { - 7 => { 4 }, - 9 => { 5 }, - 8 => { 42 }, - _ => { 100 }, - }; - assert(x == 42); - - let a = 5; - let x = match a { - 7 => { 4 }, - 5 => { 42 }, - _ => { 24 }, - }; - assert(x == 42); - - let a = 5; - let x = match a { - 7 | 8 | 9 => { 4 }, - 3 | 4 | 5 => { 42 }, - _ => { 24 }, - }; - assert(x == 42); - - // Test side effects. `inc_i` must be called exactly once. - let mut i = 0; - let x = match inc_i(i) { - Struct { x, y, z: 0 } => x + y, - Struct { x, y, z: 1 } => x + y, - _ => 24, - }; - assert(i == 11); - assert(x == 42); - - // Test match expressions with just one arm. - let e = Enum::A(42); - - let x = match e { - _ => 9999, - }; - assert(x == 9999); - - let e = Enum::B(42); - let x = match e { - Enum::A(x) | Enum::B(x) => x, - }; - assert(x == 42); - - let x = match e { - Enum::A(_) | Enum::B(_) => 9999, - }; - assert(x == 9999); - - let e = 42u64; - let x = match e { - y => y, - }; - assert(x == 42); - - let mut i = 0; - match e { - _ => { - let _s = inc_i(i); - } - }; - assert(i == 11); - - let r = match 42 { - 0 => { 24 }, - foo => { foo }, - }; - assert(r == 42); - - // string slice - //assert(return_match_on_str_slice("") == 1000); - //assert(return_match_on_str_slice("g") == 1000); - //assert(return_match_on_str_slice("ge") == 1000); - //assert(return_match_on_str_slice("get") == 1000); - //assert(return_match_on_str_slice("get_") == 1000); - //assert(return_match_on_str_slice("get_a") == 1); - //assert(return_match_on_str_slice("get_a_") == 1000); - assert(return_match_on_str_slice("get_a_b") == 2); - - //assert(return_match_on_str_slice("get_b") == 3); - //assert(return_match_on_str_slice("get_c") == 1000); + assert(return_match_on_str_slice("") == 1000); }