Skip to content

Commit

Permalink
Implement file related function and simplify function declaration
Browse files Browse the repository at this point in the history
Implement fd_prestat_get, fd_prestat_dir_name and add tests for them.
Also simplify function declarations with a marco.

Signed-off-by: Ádám László Kulcsár <[email protected]>
  • Loading branch information
kulcsaradam authored and clover2123 committed Dec 11, 2024
1 parent e31ecbc commit 977dce0
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 15 deletions.
23 changes: 23 additions & 0 deletions src/runtime/DefinedFunctionTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ class DefinedFunctionTypes {
I32_RI32,
I32I32_RI32,
I32I64I32_RI32,
I32I32I32_RI32,
I32I32I32I32_RI32,
I32I64I32I32_RI32,
I32I64I64I32_RI32,
I32I32I32I32I32I64I64I32I32_RI32,
RI32,
I64R,
Expand Down Expand Up @@ -93,6 +95,16 @@ class DefinedFunctionTypes {
result->push_back(Value::Type::I32);
m_vector[index++] = new FunctionType(param, result);
}
{
// I32I32I32_RI32
param = new ValueTypeVector();
result = new ValueTypeVector();
param->push_back(Value::Type::I32);
param->push_back(Value::Type::I32);
param->push_back(Value::Type::I32);
result->push_back(Value::Type::I32);
m_vector[index++] = new FunctionType(param, result);
}
{
// I32I32I32I32_RI32
param = new ValueTypeVector();
Expand All @@ -115,6 +127,17 @@ class DefinedFunctionTypes {
result->push_back(Value::Type::I32);
m_vector[index++] = new FunctionType(param, result);
}
{
// I32I64I64I32_RI32
param = new ValueTypeVector();
result = new ValueTypeVector();
param->push_back(Value::Type::I32);
param->push_back(Value::Type::I64);
param->push_back(Value::Type::I64);
param->push_back(Value::Type::I32);
result->push_back(Value::Type::I32);
m_vector[index++] = new FunctionType(param, result);
}
{
// I32I32I32I32I32I64I64I32I32_RI32
param = new ValueTypeVector();
Expand Down
27 changes: 27 additions & 0 deletions src/wasi/WASI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,23 @@ void WASI::fd_fdstat_get(ExecutionState& state, Value* argv, Value* result, Inst
result[0] = Value(uvwasi_fd_fdstat_get(WASI::g_uvwasi, fd, fdstat));
}

void WASI::fd_prestat_get(ExecutionState& state, Value* argv, Value* result, Instance* instance)
{
uint32_t fd = argv[0].asI32();
uvwasi_prestat_t* buf = reinterpret_cast<uvwasi_prestat_t*>(get_memory_pointer(instance, argv[1], sizeof(uvwasi_prestat_t)));

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

void WASI::fd_prestat_dir_name(ExecutionState& state, Value* argv, Value* result, Instance* instance)
{
uint32_t fd = argv[0].asI32();
uint32_t length = argv[2].asI32();
char* path = reinterpret_cast<char*>(get_memory_pointer(instance, argv[1], length));

result[0] = Value(uvwasi_fd_prestat_dir_name(WASI::g_uvwasi, fd, path, length));
}

void WASI::fd_seek(ExecutionState& state, Value* argv, Value* result, Instance* instance)
{
uint32_t fd = argv[0].asI32();
Expand All @@ -253,6 +270,16 @@ void WASI::fd_seek(ExecutionState& state, Value* argv, Value* result, Instance*
result[0] = Value(uvwasi_fd_seek(WASI::g_uvwasi, fd, fileDelta, whence, file_size));
}

void WASI::fd_advise(ExecutionState& state, Value* argv, Value* result, Instance* instance)
{
uint32_t fd = argv[0].asI32();
uint64_t offset = argv[1].asI64();
uint64_t len = argv[2].asI64();
uint32_t advise = argv[3].asI32();

result[0] = Value(uvwasi_fd_advise(WASI::g_uvwasi, fd, offset, len, advise));
}

void WASI::path_open(ExecutionState& state, Value* argv, Value* result, Instance* instance)
{
uint32_t fd = argv[0].asI32();
Expand Down
21 changes: 6 additions & 15 deletions src/wasi/WASI.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ class WASI {
F(fd_read, I32I32I32I32_RI32) \
F(fd_close, I32_RI32) \
F(fd_fdstat_get, I32I32_RI32) \
F(fd_prestat_dir_name, I32I32I32_RI32) \
F(fd_prestat_get, I32I32_RI32) \
F(fd_seek, I32I64I32I32_RI32) \
F(fd_advise, I32I64I64I32_RI32) \
F(path_open, I32I32I32I32I32I64I64I32I32_RI32) \
F(environ_get, I32I32_RI32) \
F(environ_sizes_get, I32I32_RI32)
Expand Down Expand Up @@ -155,21 +158,9 @@ class WASI {

private:
// wasi functions
static void args_get(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void args_sizes_get(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void proc_exit(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void proc_raise(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void clock_res_get(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void clock_time_get(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void fd_write(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void fd_read(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void fd_close(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void fd_fdstat_get(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void fd_seek(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void path_open(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void environ_get(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void environ_sizes_get(ExecutionState& state, Value* argv, Value* result, Instance* instance);
static void random_get(ExecutionState& state, Value* argv, Value* result, Instance* instance);
#define DECLARE_FUNCTION(NAME, FUNCTYPE) static void NAME(ExecutionState& state, Value* argv, Value* result, Instance* instance);
FOR_EACH_WASI_FUNC(DECLARE_FUNCTION)
#undef DECLARE_FUNCTION

static uvwasi_t* g_uvwasi;
static WasiFuncInfo g_wasiFunctions[FuncEnd];
Expand Down
49 changes: 49 additions & 0 deletions test/wasi/fd_advise.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
(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_advise" (func $fd_advise (param i32 i64 i64 i32) (result i32)))

(memory $mem 1)
(data (i32.const 300) "./write_to_this.txt") ;; Filename in current directory (where Walrus is ran from)

(func (export "test_advise") (param i32) (result i32) ;; advice is passed as param, return is if the function returned succesfully
i32.const 3 ;; Directory file descriptior, by default 3 is the first opened directory
i32.const 1 ;; lookupflags: directory
i32.const 300 ;; Offset of file name in memory
i32.const 19 ;; Length of file name
i32.const 0 ;; oflags: none
i64.const 128 ;; rights: fd_advise
i64.const 128 ;; rights_inheriting: fd_advise
i32.const 0 ;; fdflags: none
i32.const 0 ;; Offset to store at the opened file descriptor in memory
call $path_open

i32.eqz ;; fail if file could not be opened
(if
(then)
(else
i32.const 1
return
)
)

i32.const 0
i32.load ;; Get the file descriptor
i64.const 0 ;; Start for 0 offset
i64.const 0 ;; For the entire file
local.get 0 ;; Advise
call $fd_advise
return
)

(export "memory" (memory 0))
)

(assert_return (invoke "test_advise" (i32.const 0)) (i32.const 0))
(assert_return (invoke "test_advise" (i32.const 1)) (i32.const 0))
(assert_return (invoke "test_advise" (i32.const 2)) (i32.const 0))
(assert_return (invoke "test_advise" (i32.const 3)) (i32.const 0))
(assert_return (invoke "test_advise" (i32.const 4)) (i32.const 0))
(assert_return (invoke "test_advise" (i32.const 5)) (i32.const 0))

(assert_return (invoke "test_advise" (i32.const 6)) (i32.const 28)) ;; Returns invalid function argument, as it should

28 changes: 28 additions & 0 deletions test/wasi/fd_prestat.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
(module
(import "wasi_snapshot_preview1" "fd_prestat_get" (func $fd_prestat_get (param i32 i32) (result i32)))
(import "wasi_snapshot_preview1" "fd_prestat_dir_name" (func $fd_prestat_dir_name (param i32 i32 i32) (result i32)))
(memory $mem 1)

(; fd_prestat_get return information about a preopened file,
meaning one that was passed with '--mapdirs' ;)

(func (export "test_prestat_get") (param i32) (result i32)
local.get 0 ;; file descriptor
i32.const 0 ;; stored information offset in memory
call $fd_prestat_get
)

(func (export "test_prestat_dir_name") (param i32) (result i32)
local.get 0 ;; file descriptor
i32.const 0 ;; stored information offset in memory
i32.const 128 ;; max lenght of file path
call $fd_prestat_dir_name
)
)

(assert_return (invoke "test_prestat_get" (i32.const 3)) (i32.const 0))
(assert_return (invoke "test_prestat_get" (i32.const 4)) (i32.const 8)) ;; Error 8: bad file descriptor because it does not exist
(assert_return (invoke "test_prestat_dir_name" (i32.const 3)) (i32.const 0)) ;; mapped directory
(assert_return (invoke "test_prestat_dir_name" (i32.const 0)) (i32.const 8)) ;; Error 8: bad file descriptor because stdin is not a mapped directory
(assert_return (invoke "test_prestat_dir_name" (i32.const 4)) (i32.const 8)) ;; Error 8: bad file descriptor because it does not exist

0 comments on commit 977dce0

Please sign in to comment.