Skip to content
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

Implement file related function and simplify function declaration #313

Merged
merged 1 commit into from
Dec 11, 2024
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
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

Loading