-
Notifications
You must be signed in to change notification settings - Fork 10
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 directory mapping and WASI file functions #208
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright (c) 2023-present Samsung Electronics Co., Ltd | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
namespace Walrus { | ||
|
||
void WASI::environ_sizes_get(ExecutionState& state, Value* argv, Value* result, Instance* instance) | ||
{ | ||
uint32_t count = argv[0].asI32(); | ||
uint32_t buf = argv[1].asI32(); | ||
|
||
uvwasi_size_t* uvCount = reinterpret_cast<uvwasi_size_t*>(instance->memory(0)->buffer() + count); | ||
uvwasi_size_t* uvBufSize = reinterpret_cast<uvwasi_size_t*>(instance->memory(0)->buffer() + buf); | ||
|
||
result[0] = Value(static_cast<uint16_t>(uvwasi_environ_sizes_get(WASI::m_uvwasi, uvCount, uvBufSize))); | ||
} | ||
|
||
void WASI::environ_get(ExecutionState& state, Value* argv, Value* result, Instance* instance) | ||
{ | ||
uint32_t env = argv[0].asI32(); | ||
uint32_t environBuf = argv[1].asI32(); | ||
|
||
char** uvEnviron = reinterpret_cast<char**>(instance->memory(0)->buffer() + env); | ||
char* uvEnvironBuf = reinterpret_cast<char*>(instance->memory(0)->buffer() + environBuf); | ||
|
||
result[0] = Value(static_cast<uint16_t>(uvwasi_environ_get(WASI::m_uvwasi, uvEnviron, uvEnvironBuf))); | ||
} | ||
|
||
} // namespace Walrus |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (c) 2023-present Samsung Electronics Co., Ltd | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
namespace Walrus { | ||
|
||
void WASI::path_open(ExecutionState& state, Value* argv, Value* result, Instance* instance) | ||
{ | ||
uint32_t fd = argv[0].asI32(); | ||
uint32_t dirflags = argv[1].asI32(); | ||
uint32_t path_offset = argv[2].asI32(); | ||
uint32_t len = argv[3].asI32(); | ||
uint32_t oflags = argv[4].asI32(); | ||
uint64_t rights = argv[5].asI64(); | ||
uint64_t right_inheriting = argv[6].asI64(); | ||
uint32_t fdflags = argv[7].asI32(); | ||
uint32_t ret_fd_offset = argv[8].asI32(); | ||
|
||
uvwasi_fd_t* ret_fd = reinterpret_cast<uvwasi_fd_t*>(instance->memory(0)->buffer() + ret_fd_offset); | ||
|
||
const char* path = reinterpret_cast<char*>(instance->memory(0)->buffer() + path_offset); | ||
|
||
result[0] = Value(static_cast<uint16_t>( | ||
uvwasi_path_open(WASI::m_uvwasi, | ||
fd, | ||
dirflags, | ||
path, | ||
len, | ||
oflags, | ||
rights, | ||
right_inheriting, | ||
fdflags, | ||
ret_fd))); | ||
} | ||
|
||
} // namespace Walrus |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,8 @@ | |
|
||
#include "wasi/Wasi.h" | ||
#include "wasi/Fd.h" | ||
#include "wasi/Path.h" | ||
#include "wasi/Environ.h" | ||
|
||
// https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md | ||
|
||
|
@@ -93,11 +95,10 @@ void WASI::fillWasiFuncTable() | |
#undef WASI_FUNC_TABLE | ||
} | ||
|
||
WASI::WASI() | ||
WASI::WASI(std::vector<uvwasi_preopen_s>& preopenDirs, bool shareHostEnv) | ||
{ | ||
fillWasiFuncTable(); | ||
|
||
uvwasi_t uvwasi; | ||
WASI::m_uvwasi = reinterpret_cast<uvwasi_t*>(malloc(sizeof(uvwasi_t))); | ||
|
||
uvwasi_options_t init_options; | ||
|
@@ -108,12 +109,83 @@ WASI::WASI() | |
init_options.argc = 0; | ||
init_options.argv = nullptr; | ||
init_options.envp = nullptr; | ||
init_options.preopenc = 0; | ||
if (shareHostEnv) { | ||
std::vector<std::string> variables = { | ||
// Common Unix environment variables. | ||
"PATH", | ||
"LIB", | ||
"PWD", | ||
"SHELL", | ||
Comment on lines
+113
to
+118
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder about how did you define these common env variables There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I've used these sites: Please tell me if there are any more that I should add or if I should remove some |
||
"TERM", | ||
"HOME", | ||
"LOGNAME", | ||
"HOSTNAME", | ||
"UID", | ||
"TEMP", | ||
"EDITOR" | ||
"LANG", | ||
"LC_TIME", | ||
// Common Windows environment variables. | ||
"APPDATA", | ||
"USERPROFILE", | ||
"USERDOMAIN", | ||
"windir", | ||
"ProgramFiles", | ||
"OS" | ||
"LOCALAPPDATA", | ||
"SystemRoot", | ||
"SystemDrive", | ||
}; | ||
|
||
char** envp = (char**)malloc(sizeof(char**) * variables.size()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about simply allocating a vector of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After spending some time thinking how I would change it to be easily used with uvwasi, I could not think of a way. If you have an idea, it would be greatly appriciated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. I'll revise this later |
||
|
||
size_t j = 0; | ||
for (size_t i = 0; i < variables.size(); i++) { | ||
if (getenv(variables[i].c_str()) == nullptr) { | ||
continue; | ||
} | ||
|
||
size_t length = strlen(variables[i].c_str()); | ||
length += strlen(getenv(variables[i].c_str())); | ||
length += 2; | ||
envp[j] = (char*)malloc(length); | ||
strcpy(envp[j], variables[i].c_str()); | ||
envp[j][variables[i].size()] = '='; | ||
strcpy(envp[j] + variables[i].size() + 1, getenv(variables[i].c_str())); | ||
envp[j][length - 1] = '\0'; | ||
j++; | ||
} | ||
|
||
while (j < variables.size()) { | ||
envp[j] = nullptr; | ||
j++; | ||
} | ||
|
||
init_options.envp = const_cast<const char**>(envp); | ||
} | ||
init_options.preopenc = preopenDirs.size(); | ||
init_options.preopens = preopenDirs.data(); | ||
init_options.preopen_socketc = 0; | ||
init_options.allocator = nullptr; | ||
|
||
uvwasi_errno_t err = uvwasi_init(WASI::m_uvwasi, &init_options); | ||
assert(err == UVWASI_ESUCCESS); | ||
|
||
if (init_options.envp != nullptr) { | ||
for (size_t i = 0; init_options.envp[i] != nullptr; i++) { | ||
free((void*)init_options.envp[i]); | ||
} | ||
free(init_options.envp); | ||
} | ||
|
||
for (auto& elem : preopenDirs) { | ||
if (elem.mapped_path != nullptr) { | ||
free((void*)elem.mapped_path); | ||
} | ||
if (elem.real_path != nullptr) { | ||
free((void*)elem.real_path); | ||
} | ||
} | ||
} | ||
|
||
} // namespace Walrus |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will these strings allocated by
calloc
be correctly freed at the end of Walrus?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I forgot about those. After running valgrind I fixed these and also added initialization to wasi envrionment variables, so valgrind did not return any errors.