Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
22 changes: 22 additions & 0 deletions src/wasi/WASI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,28 @@ void WASI::fd_close(ExecutionState& state, Value* argv, Value* result, Instance*
result[0] = Value(uvwasi_fd_close(WASI::g_uvwasi, fd));
}

void WASI::fd_datasync(ExecutionState& state, Value* argv, Value* result, Instance* instance)
{
uint32_t fd = argv[0].asI32();

result[0] = Value(uvwasi_fd_datasync(WASI::g_uvwasi, fd));
}

void WASI::fd_sync(ExecutionState& state, Value* argv, Value* result, Instance* instance)
{
uint32_t fd = argv[0].asI32();

result[0] = Value(uvwasi_fd_sync(WASI::g_uvwasi, fd));
}

void WASI::fd_renumber(ExecutionState& state, Value* argv, Value* result, Instance* instance)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add newlines between the functions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I've added the newlines between functions and updated the commit. Thanks for the review!

{
uint32_t from = argv[0].asI32();
uint32_t to = argv[1].asI32();

result[0] = Value(uvwasi_fd_renumber(WASI::g_uvwasi, from, to));
}

void WASI::fd_fdstat_get(ExecutionState& state, Value* argv, Value* result, Instance* instance)
{
uint32_t fd = argv[0].asI32();
Expand Down
3 changes: 3 additions & 0 deletions src/wasi/WASI.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class WASI {
F(fd_pread, I32I32I32I64I32_RI32) \
F(fd_readdir, I32I32I32I64I32_RI32) \
F(fd_close, I32_RI32) \
F(fd_datasync, I32_RI32) \
F(fd_sync, I32_RI32) \
F(fd_renumber, I32I32_RI32) \
F(fd_fdstat_get, I32I32_RI32) \
F(fd_fdstat_set_flags, I32I32_RI32) \
F(fd_prestat_get, I32I32_RI32) \
Expand Down
81 changes: 81 additions & 0 deletions test/wasi/fd_datasync.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
(module
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to the project!

By the way, could you let me know where these test codes came from?
Did you create them yourself?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented this by referencing the existing tests in src/test/wasi/. To determine the correct rights values and expected error cases, I consulted wasi_types.h, uvwasi.h, and uvwasi.c within third_party

Could you please review this and let me know if I got these details right?

(import "wasi_snapshot_preview1" "path_open"
(func $path_open (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_write"
(func $fd_write (param i32 i32 i32 i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_datasync"
(func $fd_datasync (param i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_close"
(func $fd_close (param i32) (result i32)))

(memory 1)
(data (i32.const 200) "datasync test\n") ;; 14 bytes, written to file
(data (i32.const 300) "./write_to_this.txt") ;; 19 bytes, file path

;; Open file, write data, call fd_datasync, close. Returns errno of fd_datasync.
(func (export "test_datasync") (result i32)
;; --- path_open ---
;; fd=3 (first preopened dir), lookupflags=1, path@300 len=19
;; oflags=9 (creat|trunc), rights=8257 (path_open|fd_write|fd_datasync)
i32.const 3
i32.const 1
i32.const 300
i32.const 19
i32.const 9
i64.const 8257 ;; fd_datasync(1) | fd_write(64) | path_open(8192)
i64.const 8257
i32.const 0
i32.const 0 ;; store opened fd at memory[0]
call $path_open
i32.eqz
(if (then) (else i32.const 1 return)) ;; abort if open failed

;; --- set up iovec at offset 500: (buf=200, len=14) ---
i32.const 500
i32.const 200
i32.store
i32.const 504
i32.const 14
i32.store

;; --- fd_write ---
i32.const 0
i32.load ;; fd
i32.const 500 ;; iovec array
i32.const 1 ;; iovec count
i32.const 600 ;; nwritten output
call $fd_write
drop

;; --- fd_datasync: test target ---
i32.const 0
i32.load ;; fd
call $fd_datasync
;; stash errno at memory[700] so we can close before returning
i32.const 700
i32.store

;; --- fd_close ---
i32.const 0
i32.load
call $fd_close
drop

i32.const 700
i32.load ;; return stashed errno
)

;; Call fd_datasync with an invalid fd. Expects errno::badf (8).
(func (export "test_datasync_invalid_fd") (result i32)
i32.const 99 ;; non-existent fd
call $fd_datasync
)

(export "memory" (memory 0))
)

;; Valid fd: fd_datasync should succeed (errno::success = 0)
(assert_return (invoke "test_datasync") (i32.const 0))

;; Invalid fd: should return errno::badf (8)
(assert_return (invoke "test_datasync_invalid_fd") (i32.const 8))
91 changes: 91 additions & 0 deletions test/wasi/fd_renumber.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
(module
(import "wasi_snapshot_preview1" "path_open"
(func $path_open (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_write"
(func $fd_write (param i32 i32 i32 i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_renumber"
(func $fd_renumber (param i32 i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_close"
(func $fd_close (param i32) (result i32)))

(memory 1)
(data (i32.const 200) "renumber test\n") ;; 14 bytes, written to file
(data (i32.const 300) "./write_to_this.txt") ;; 19 bytes, file path

;; Set up iovec at offset 500: (buf=200, len=14)
(func $setup_iovec
i32.const 500
i32.const 200
i32.store
i32.const 504
i32.const 14
i32.store
)

;; Open write_to_this.txt and store fd at memory[offset].
(func $open_file (param $fd_offset i32) (result i32)
i32.const 3
i32.const 1
i32.const 300
i32.const 19
i32.const 9 ;; oflags: creat|trunc
i64.const 8256 ;; fd_write | path_open
i64.const 8256
i32.const 0
local.get $fd_offset
call $path_open
)

;; Open file (fd stored at memory[0] = "from"),
;; renumber it to fd 10 ("to"),
;; write using fd 10 to confirm it works.
;; Returns errno of fd_renumber.
(func (export "test_renumber") (result i32)
;; open file → fd at memory[0]
i32.const 0
call $open_file
i32.eqz
(if (then) (else i32.const 1 return))

call $setup_iovec

;; fd_renumber(from=memory[0], to=10)
i32.const 0
i32.load ;; from fd
i32.const 10 ;; to fd number
call $fd_renumber
i32.const 700
i32.store ;; stash errno

;; write via new fd (10) to confirm renumber worked
i32.const 10 ;; to fd
i32.const 500
i32.const 1
i32.const 600
call $fd_write
drop

;; close new fd
i32.const 10
call $fd_close
drop

i32.const 700
i32.load ;; return stashed errno of fd_renumber
)

;; fd_renumber with an invalid "from" fd. Expects errno::badf (8).
(func (export "test_renumber_invalid_fd") (result i32)
i32.const 99 ;; non-existent from fd
i32.const 10
call $fd_renumber
)

(export "memory" (memory 0))
)

;; fd_renumber succeeds (errno::success = 0)
(assert_return (invoke "test_renumber") (i32.const 0))

;; invalid from fd returns errno::badf (8)
(assert_return (invoke "test_renumber_invalid_fd") (i32.const 8))
79 changes: 79 additions & 0 deletions test/wasi/fd_sync.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
(module
(import "wasi_snapshot_preview1" "path_open"
(func $path_open (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_write"
(func $fd_write (param i32 i32 i32 i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_sync"
(func $fd_sync (param i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_close"
(func $fd_close (param i32) (result i32)))

(memory 1)
(data (i32.const 200) "fd_sync test\n") ;; 13 bytes, written to file
(data (i32.const 300) "./write_to_this.txt") ;; 19 bytes, file path

;; Open file, write data, call fd_sync, close. Returns errno of fd_sync.
(func (export "test_sync") (result i32)
;; --- path_open ---
i32.const 3
i32.const 1
i32.const 300
i32.const 19
i32.const 9 ;; oflags: creat|trunc
i64.const 8320 ;; fd_sync(64) | fd_write(64) | path_open(8192) = 8320
i64.const 8320
i32.const 0
i32.const 0 ;; store opened fd at memory[0]
call $path_open
i32.eqz
(if (then) (else i32.const 1 return)) ;; abort if open failed

;; --- set up iovec at offset 500: (buf=200, len=13) ---
i32.const 500
i32.const 200
i32.store
i32.const 504
i32.const 13
i32.store

;; --- fd_write ---
i32.const 0
i32.load ;; fd
i32.const 500 ;; iovec array
i32.const 1 ;; iovec count
i32.const 600 ;; nwritten output
call $fd_write
drop

;; --- fd_sync: test target ---
i32.const 0
i32.load ;; fd
call $fd_sync
;; stash errno at memory[700] so we can close before returning
i32.const 700
i32.store

;; --- fd_close ---
i32.const 0
i32.load
call $fd_close
drop

i32.const 700
i32.load ;; return stashed errno
)

;; Call fd_sync with an invalid fd. Expects errno::badf (8).
(func (export "test_sync_invalid_fd") (result i32)
i32.const 99 ;; non-existent fd
call $fd_sync
)

(export "memory" (memory 0))
)

;; Valid fd: fd_sync should succeed (errno::success = 0)
(assert_return (invoke "test_sync") (i32.const 0))

;; Invalid fd: should return errno::badf (8)
(assert_return (invoke "test_sync_invalid_fd") (i32.const 8))
Loading