Skip to content

improve dbg intrinsic with fflush #7126

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

Merged
merged 5 commits into from
Apr 30, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
improve dbg intrinsic with fflush
  • Loading branch information
xunilrj committed Apr 28, 2025
commit 6a26c19ba382610e05c908ab32ac5a1ee73a2173
15 changes: 12 additions & 3 deletions forc-test/src/ecal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,33 @@ use fuel_vm::{

// ssize_t write(int fd, const void buf[.count], size_t count);
pub const WRITE_SYSCALL: u64 = 1000;
pub const FFLUSH_SYSCALL: u64 = 1001;

#[derive(Debug, Clone)]
pub enum Syscall {
Write { fd: u64, bytes: Vec<u8> },
Fflush { fd: u64 },
Unknown { ra: u64, rb: u64, rc: u64, rd: u64 },
}

impl Syscall {
pub fn apply(&self) {
use std::io::Write;
use std::os::fd::FromRawFd;
match self {
Syscall::Write { fd, bytes } => {
let s = std::str::from_utf8(bytes.as_slice()).unwrap();

use std::io::Write;
use std::os::fd::FromRawFd;

let mut f = unsafe { std::fs::File::from_raw_fd(*fd as i32) };
write!(&mut f, "{}", s).unwrap();

// Dont close the fd
std::mem::forget(f);
}
Syscall::Fflush { fd } => {
let mut f = unsafe { std::fs::File::from_raw_fd(*fd as i32) };
let _ = f.flush();
}
Syscall::Unknown { ra, rb, rc, rd } => {
println!("Unknown ecal: {} {} {} {}", ra, rb, rc, rd);
}
Expand Down Expand Up @@ -99,6 +104,10 @@ impl EcalHandler for EcalSyscallHandler {
let bytes = vm.memory().read(addr, count).unwrap().to_vec();
Syscall::Write { fd, bytes }
}
FFLUSH_SYSCALL => {
let fd = regs[b.to_u8() as usize];
Syscall::Fflush { fd }
}
_ => {
let ra = regs[a.to_u8() as usize];
let rb = regs[b.to_u8() as usize];
Expand Down
24 changes: 24 additions & 0 deletions sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2050,6 +2050,7 @@ fn expr_func_app_to_expression_kind(
// f.print_str("[{current_file}:{current_line}:{current_col}] = ");
// let arg = arg;
// arg.fmt(f);
// f.flush();
// arg
// }"
Some(Intrinsic::Dbg)
Expand Down Expand Up @@ -2221,6 +2222,29 @@ fn expr_func_app_to_expression_kind(
},
// f.print_str(<newline>);
ast_node_to_print_str(f_ident.clone(), "\n", &span),
// f.flush();
AstNode {
content: AstNodeContent::Expression(Expression {
kind: ExpressionKind::MethodApplication(Box::new(
MethodApplicationExpression {
method_name_binding: TypeBinding {
inner: MethodName::FromModule {
method_name: BaseIdent::new_no_span("flush".into()),
},
type_arguments: TypeArgs::Regular(vec![]),
span: span.clone(),
},
contract_call_params: vec![],
arguments: vec![Expression {
kind: ExpressionKind::Variable(f_ident.clone()),
span: span.clone(),
}],
},
)),
span: span.clone(),
}),
span: span.clone(),
},
// arg
AstNode {
content: AstNodeContent::Expression(Expression {
Expand Down
21 changes: 16 additions & 5 deletions sway-lib-std/src/debug.sw
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ fn syscall_write(fd: u64, buf: raw_ptr, count: u64) {
}
}

// int fflush(FILE *_Nullable stream);
fn syscall_fflush(fd: u64) {
asm(id: 1001, fd: fd) {
ecal id fd zero zero;
}
}

pub struct DebugStruct {
f: Formatter,
has_fields: bool,
Expand Down Expand Up @@ -45,7 +52,7 @@ impl Formatter {
let mut i = 63;
while value > 0 {
let digit = value % 10;
digits[i] = digit + 48; // ascii zero = 48
digits[i] = digit + 48; // ascii zero = 48
i -= 1;
value = value / 10;
}
Expand All @@ -61,7 +68,7 @@ impl Formatter {
let digit = asm(v: value % 10) {
v: u8
};
digits[i] = digit + 48; // ascii zero = 48
digits[i] = digit + 48; // ascii zero = 48
i -= 1;
value = value / 10;
}
Expand All @@ -77,7 +84,7 @@ impl Formatter {
let digit = asm(v: value % 10) {
v: u8
};
digits[i] = digit + 48; // ascii zero = 48
digits[i] = digit + 48; // ascii zero = 48
i -= 1;
value = value / 10;
}
Expand All @@ -93,7 +100,7 @@ impl Formatter {
let digit = asm(v: value % 10) {
v: u8
};
digits[i] = digit + 48; // ascii zero = 48
digits[i] = digit + 48; // ascii zero = 48
i -= 1;
value = value / 10;
}
Expand All @@ -114,7 +121,7 @@ impl Formatter {
let digit = asm(v: digit % 10) {
v: u8
};
digits[i] = digit + 48; // ascii zero = 48
digits[i] = digit + 48; // ascii zero = 48
i -= 1;
value = value / 10;
}
Expand Down Expand Up @@ -150,6 +157,10 @@ impl Formatter {
has_fields: false,
}
}

pub fn flush(self) {
syscall_fflush(STDERR);
}
}

impl DebugStruct {
Expand Down
1 change: 1 addition & 0 deletions test/src/e2e_vm_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ impl TestContext {
let s = std::str::from_utf8(bytes.as_slice()).unwrap();
output.push_str(s);
}
Syscall::Fflush { .. } => {}
Syscall::Unknown { ra, rb, rc, rd } => {
let _ = writeln!(
output,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
ecal $r4 $r2 $r3 $r0 ; ecal id fd buf count
ecal $r2 $r1 $zero $zero ; ecal id fd zero zero
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count

> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg --release --asm final | grep ecal
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@ ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
ecal $r4 $r2 $r3 $r0 ; ecal id fd buf count
ecal $r2 $r1 $zero $zero ; ecal id fd zero zero
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count

> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release --release --asm final | grep ecal
ecal $r2 $r6 $r0 $r1 ; ecal id fd buf count
ecal $r7 $r8 $r3 $r6 ; ecal id fd buf count
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r6 $r7 $r2 $r3 ; ecal id fd buf count
ecal $r2 $r3 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r3 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
ecal $r3 $r4 $r2 $r0 ; ecal id fd buf count
ecal $r3 $r4 $r1 $r2 ; ecal id fd buf count
Loading