Skip to content

Commit

Permalink
better debug for bytecode generation
Browse files Browse the repository at this point in the history
  • Loading branch information
xunilrj committed Jul 4, 2024
1 parent 64a0ab9 commit 98e704d
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 16 deletions.
59 changes: 58 additions & 1 deletion sway-core/src/asm_generation/finalized_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::{
fuel::{checks, data_section::DataSection},
ProgramABI, ProgramKind,
};
use crate::asm_generation::fuel::data_section::{DataId, Datum, Entry};
use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode};
use crate::decl_engine::DeclRefFunction;
use crate::source_map::SourceMap;
Expand Down Expand Up @@ -246,8 +247,64 @@ fn to_bytecode_mut(
}
}
}

if build_config.print_bytecode {
println!("{}", data_section);
println!(".data_section:");

let offset = bytecode.len();

fn print_entry(indentation: usize, offset: usize, pair: &Entry) {
print!("{}{:#010x} ", " ".repeat(indentation), offset);

match &pair.value {
Datum::Byte(w) => println!(".byte i{w}, as hex {w:02X}"),
Datum::Word(w) => {
println!(".word i{w}, as hex be bytes ({:02X?})", w.to_be_bytes())
}
Datum::ByteArray(bs) => {
print!(".bytes as hex ({bs:02X?}), len i{}, as ascii \"", bs.len());

for b in bs {
print!(
"{}",
if *b == b' ' || b.is_ascii_graphic() {
*b as char
} else {
'.'
}
);
}
println!("\"");
}
Datum::Slice(bs) => {
print!(".slice as hex ({bs:02X?}), len i{}, as ascii \"", bs.len());

for b in bs {
print!(
"{}",
if *b == b' ' || b.is_ascii_graphic() {
*b as char
} else {
'.'
}
);
}
println!("\"");
}
Datum::Collection(els) => {
println!(".collection");
for e in els {
print_entry(indentation + 1, offset, e);
}
}
};
}

for (i, entry) in data_section.value_pairs.iter().enumerate() {
let entry_offset = data_section.data_id_to_offset(&DataId(i as u32));
print_entry(indentation, offset + entry_offset, entry);
}

println!(";; --- END OF TARGET BYTECODE ---\n");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,14 @@ impl AllocatedAbstractInstructionSet {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::PSHL(mask_l)),
comment: "Save registers 16..40".into(),
owning_span: None,
owning_span: op.owning_span.clone(),
});
}
if mask_h.value != 0 {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::PSHH(mask_h)),
comment: "Save registers 40..64".into(),
owning_span: None,
owning_span: op.owning_span.clone(),
});
}
}
Expand All @@ -147,14 +147,14 @@ impl AllocatedAbstractInstructionSet {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::POPH(mask_h)),
comment: "Restore registers 40..64".into(),
owning_span: None,
owning_span: op.owning_span.clone(),
});
}
if mask_l.value != 0 {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::POPL(mask_l)),
comment: "Restore registers 16..40".into(),
owning_span: None,
owning_span: op.owning_span.clone(),
});
}
}
Expand Down
6 changes: 3 additions & 3 deletions sway-core/src/asm_generation/fuel/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
function.get_name(self.context)
);

self.cur_bytecode.push(match span {
Some(span) => Op::jump_label_comment(start_label, span, comment),
self.cur_bytecode.push(match &span {
Some(span) => Op::jump_label_comment(start_label, span.clone(), comment),
None => Op::unowned_jump_label_comment(start_label, comment),
});

Expand All @@ -285,7 +285,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
self.cur_bytecode.push(Op {
opcode: Either::Right(OrganizationalOp::PushAll(start_label)),
comment: "save all regs".to_owned(),
owning_span: None,
owning_span: span.clone(),
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ impl ty::TyMatchExpression {
let typed_if_exp =
handler.scope(
|handler| match &*ctx.engines().te().get(self.value_type_id) {
TypeInfo::StringSlice => self.desugar_to_radix_tree(ctx),
TypeInfo::StringSlice => self.desugar_to_radix_trie(ctx),
_ => self.desugar_to_typed_if_expression(instantiate, ctx, handler),
},
)?;

Ok(typed_if_exp)
}

fn desugar_to_radix_tree(
fn desugar_to_radix_trie(
&self,
mut ctx: TypeCheckContext<'_>,
) -> Result<TyExpression, ErrorEmitted> {
Expand Down Expand Up @@ -220,6 +220,7 @@ impl ty::TyMatchExpression {

// Now create the outer expression checking the size of the string slice
let mut block = wildcard_return_expr.clone();

for ((k, _), trie) in match_arms_by_size.into_iter().zip(tries.into_iter()) {
if RADIX_TREE_DEBUG {
println!("if str.len() == {k}");
Expand Down Expand Up @@ -277,7 +278,7 @@ impl ty::TyMatchExpression {
},
Span::dummy(),
)),
whole_block_span: Span::dummy(),
whole_block_span: self.span.clone(),
};

let then_node = self
Expand All @@ -297,13 +298,13 @@ impl ty::TyMatchExpression {
condition: Box::new(TyExpression {
expression,
return_type: bool_type_id,
span: Span::dummy(),
span: self.span.clone(),
}),
then: Box::new(then_node),
r#else: Some(Box::new(block)),
},
return_type: branch_return_type_id,
span: Span::dummy(),
span: self.span.clone(),
};
}

Expand Down Expand Up @@ -397,7 +398,7 @@ impl ty::TyMatchExpression {
span: Span::dummy(),
};

let expr = self.generate_radrix_tree_code(
let expr = self.generate_radrix_trie_code(
matched_value,
packed_strings,
&packed_strings_expr,
Expand All @@ -415,7 +416,7 @@ impl ty::TyMatchExpression {
}

#[allow(clippy::too_many_arguments)]
fn generate_radrix_tree_code(
fn generate_radrix_trie_code(
&self,
matched_value: &TyExpression,
packed_strings: &str,
Expand Down Expand Up @@ -460,7 +461,7 @@ impl ty::TyMatchExpression {
);
}

let then_node = self.generate_radrix_tree_code(
let then_node = self.generate_radrix_trie_code(
matched_value,
packed_strings,
packed_strings_expr,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fn inc_i(ref mut i: u64) -> Struct {
Struct { x: 21, y: 21, z: 1 }
}

#[inline(never)]
fn return_match_on_str_slice(param: str) -> u64 {
match param {
"get_a" => { 1u64 },
Expand All @@ -28,5 +29,89 @@ 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);
}

0 comments on commit 98e704d

Please sign in to comment.