Skip to content

Commit 42321ef

Browse files
xunilrjtritao
andauthored
improve dbg intrinsic with fflush (#7126)
## Description This PR brings a new syscall "fflush" to help `EcalHandler` know when the `__dbg` is finished and they flush their buffers. In theory, Linux `fflush` is not a syscall because it just flushes "user-space" buffers. As we do not have this difference, we are still going to call `fflush` as a syscall. ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. Co-authored-by: João Matos <[email protected]>
1 parent 5f64b96 commit 42321ef

File tree

6 files changed

+69
-9
lines changed

6 files changed

+69
-9
lines changed

forc-test/src/ecal.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,33 @@ use fuel_vm::{
55

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

910
#[derive(Debug, Clone)]
1011
pub enum Syscall {
1112
Write { fd: u64, bytes: Vec<u8> },
13+
Fflush { fd: u64 },
1214
Unknown { ra: u64, rb: u64, rc: u64, rd: u64 },
1315
}
1416

1517
impl Syscall {
1618
pub fn apply(&self) {
19+
use std::io::Write;
20+
use std::os::fd::FromRawFd;
1721
match self {
1822
Syscall::Write { fd, bytes } => {
1923
let s = std::str::from_utf8(bytes.as_slice()).unwrap();
2024

21-
use std::io::Write;
22-
use std::os::fd::FromRawFd;
23-
2425
let mut f = unsafe { std::fs::File::from_raw_fd(*fd as i32) };
2526
write!(&mut f, "{}", s).unwrap();
2627

2728
// Dont close the fd
2829
std::mem::forget(f);
2930
}
31+
Syscall::Fflush { fd } => {
32+
let mut f = unsafe { std::fs::File::from_raw_fd(*fd as i32) };
33+
let _ = f.flush();
34+
}
3035
Syscall::Unknown { ra, rb, rc, rd } => {
3136
println!("Unknown ecal: {} {} {} {}", ra, rb, rc, rd);
3237
}
@@ -99,6 +104,10 @@ impl EcalHandler for EcalSyscallHandler {
99104
let bytes = vm.memory().read(addr, count).unwrap().to_vec();
100105
Syscall::Write { fd, bytes }
101106
}
107+
FFLUSH_SYSCALL => {
108+
let fd = regs[b.to_u8() as usize];
109+
Syscall::Fflush { fd }
110+
}
102111
_ => {
103112
let ra = regs[a.to_u8() as usize];
104113
let rb = regs[b.to_u8() as usize];

sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,7 @@ fn expr_func_app_to_expression_kind(
20912091
// f.print_str("[{current_file}:{current_line}:{current_col}] = ");
20922092
// let arg = arg;
20932093
// arg.fmt(f);
2094+
// f.flush();
20942095
// arg
20952096
// }"
20962097
Some(Intrinsic::Dbg)
@@ -2262,6 +2263,29 @@ fn expr_func_app_to_expression_kind(
22622263
},
22632264
// f.print_str(<newline>);
22642265
ast_node_to_print_str(f_ident.clone(), "\n", &span),
2266+
// f.flush();
2267+
AstNode {
2268+
content: AstNodeContent::Expression(Expression {
2269+
kind: ExpressionKind::MethodApplication(Box::new(
2270+
MethodApplicationExpression {
2271+
method_name_binding: TypeBinding {
2272+
inner: MethodName::FromModule {
2273+
method_name: BaseIdent::new_no_span("flush".into()),
2274+
},
2275+
type_arguments: TypeArgs::Regular(vec![]),
2276+
span: span.clone(),
2277+
},
2278+
contract_call_params: vec![],
2279+
arguments: vec![Expression {
2280+
kind: ExpressionKind::Variable(f_ident.clone()),
2281+
span: span.clone(),
2282+
}],
2283+
},
2284+
)),
2285+
span: span.clone(),
2286+
}),
2287+
span: span.clone(),
2288+
},
22652289
// arg
22662290
AstNode {
22672291
content: AstNodeContent::Expression(Expression {

sway-lib-std/src/debug.sw

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ fn syscall_write(fd: u64, buf: raw_ptr, count: u64) {
1212
}
1313
}
1414

15+
// int fflush(FILE *_Nullable stream);
16+
fn syscall_fflush(fd: u64) {
17+
asm(id: 1001, fd: fd) {
18+
ecal id fd zero zero;
19+
}
20+
}
21+
1522
pub struct DebugStruct {
1623
f: Formatter,
1724
has_fields: bool,
@@ -45,7 +52,7 @@ impl Formatter {
4552
let mut i = 63;
4653
while value > 0 {
4754
let digit = value % 10;
48-
digits[i] = digit + 48; // ascii zero = 48
55+
digits[i] = digit + 48; // ascii zero = 48
4956
i -= 1;
5057
value = value / 10;
5158
}
@@ -61,7 +68,7 @@ impl Formatter {
6168
let digit = asm(v: value % 10) {
6269
v: u8
6370
};
64-
digits[i] = digit + 48; // ascii zero = 48
71+
digits[i] = digit + 48; // ascii zero = 48
6572
i -= 1;
6673
value = value / 10;
6774
}
@@ -77,7 +84,7 @@ impl Formatter {
7784
let digit = asm(v: value % 10) {
7885
v: u8
7986
};
80-
digits[i] = digit + 48; // ascii zero = 48
87+
digits[i] = digit + 48; // ascii zero = 48
8188
i -= 1;
8289
value = value / 10;
8390
}
@@ -93,7 +100,7 @@ impl Formatter {
93100
let digit = asm(v: value % 10) {
94101
v: u8
95102
};
96-
digits[i] = digit + 48; // ascii zero = 48
103+
digits[i] = digit + 48; // ascii zero = 48
97104
i -= 1;
98105
value = value / 10;
99106
}
@@ -114,7 +121,7 @@ impl Formatter {
114121
let digit = asm(v: digit % 10) {
115122
v: u8
116123
};
117-
digits[i] = digit + 48; // ascii zero = 48
124+
digits[i] = digit + 48; // ascii zero = 48
118125
i -= 1;
119126
value = value / 10;
120127
}
@@ -150,6 +157,10 @@ impl Formatter {
150157
has_fields: false,
151158
}
152159
}
160+
161+
pub fn flush(self) {
162+
syscall_fflush(STDERR);
163+
}
153164
}
154165

155166
impl DebugStruct {

test/src/e2e_vm_tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ impl TestContext {
416416
let s = std::str::from_utf8(bytes.as_slice()).unwrap();
417417
output.push_str(s);
418418
}
419+
Syscall::Fflush { .. } => {}
419420
Syscall::Unknown { ra, rb, rc, rd } => {
420421
let _ = writeln!(
421422
output,

test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
77
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
88
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
99
ecal $r4 $r2 $r3 $r0 ; ecal id fd buf count
10+
ecal $r2 $r1 $zero $zero ; ecal id fd zero zero
1011
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
1112

1213
> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg --release --asm final | grep ecal

test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,24 @@ ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
77
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
88
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
99
ecal $r4 $r2 $r3 $r0 ; ecal id fd buf count
10+
ecal $r2 $r1 $zero $zero ; ecal id fd zero zero
1011
ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count
1112

1213
> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release --release --asm final | grep ecal
1314
ecal $r2 $r6 $r0 $r1 ; ecal id fd buf count
14-
ecal $r7 $r8 $r3 $r6 ; ecal id fd buf count
15+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
16+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
17+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
18+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
19+
ecal $r6 $r7 $r2 $r3 ; ecal id fd buf count
20+
ecal $r2 $r3 $zero $zero ; ecal id fd zero zero
21+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
22+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
23+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
24+
ecal $r0 $r3 $zero $zero ; ecal id fd zero zero
25+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
26+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
27+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
28+
ecal $r0 $r1 $zero $zero ; ecal id fd zero zero
1529
ecal $r3 $r4 $r2 $r0 ; ecal id fd buf count
1630
ecal $r3 $r4 $r1 $r2 ; ecal id fd buf count

0 commit comments

Comments
 (0)