mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-31 22:17:27 +00:00
Merge main into dev/fast_jit
This commit is contained in:
commit
dc0e28b790
|
@ -11,6 +11,8 @@ WAMR project reused some components from other open source project:
|
|||
- **wasmtime**: for the wasi libc implementation
|
||||
- **zephyr**: for several platform specific examples
|
||||
- **WebAssembly debugging patch for LLDB**: for extending the ability of LLDB to support wasm debugging
|
||||
- **libuv**: for the WASI Libc with uvwasi implementation
|
||||
- **uvwasi**: for the WASI Libc with uvwasi implementation
|
||||
|
||||
The WAMR fast interpreter is a clean room development. We would acknowledge the inspirations by [WASM3](https://github.com/wasm3/wasm3) open source project for the approach of pre-calculated oprand stack location.
|
||||
|
||||
|
@ -25,6 +27,8 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
|
|||
| wasmtime | unspecified | v0.26.0 | https://github.com/bytecodealliance/wasmtime | |
|
||||
| zephyr | unspecified | v2.5.0 | https://www.zephyrproject.org/ | https://www.cvedetails.com/vendor/19255/Zephyrproject.html |
|
||||
| WebAssembly debugging patch for LLDB | unspecified | unspecified | https://reviews.llvm.org/D78801 | |
|
||||
| libuv | v1.42.0 | v1.44.1 | https://github.com/libuv/libuv | https://www.cvedetails.com/vendor/15402/Libuv-Project.html |
|
||||
| uvwasi | unspecified | v0.0.12 | https://github.com/nodejs/uvwasi | |
|
||||
|
||||
## Licenses
|
||||
|
||||
|
@ -69,3 +73,9 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
|
|||
### wac
|
||||
|
||||
[LICENSE](./tests/wamr-test-suites/spec-test-script/LICENSE)
|
||||
|
||||
### libuv
|
||||
[LICENSE](./core/iwasm/libraries/libc-uvwasi/LICENSE_LIBUV)
|
||||
|
||||
### uvwasi
|
||||
[LICENSE](./core/iwasm/libraries/libc-uvwasi/LICENSE_UVWASI)
|
||||
|
|
|
@ -42,6 +42,7 @@ iwasm VM core
|
|||
- [Source debugging support](./doc/source_debugging.md), ref to [document](./doc/source_debugging.md)
|
||||
- [WAMR-IDE (Experimental)](./test-tools/wamr-ide) to develop WebAssembly applications with build, run and debug support, ref to [document](./test-tools/wamr-ide)
|
||||
- [XIP (Execution In Place) support](./doc/xip.md), ref to [document](./doc/xip.md)
|
||||
- [Berkeley/Posix Socket support](./doc/socket_api.md), ref to [document](./doc/socket_api.md) and [sample](./samples/socket-api)
|
||||
|
||||
### WASM post-MVP features
|
||||
- [wasm-c-api](https://github.com/WebAssembly/wasm-c-api), ref to [document](doc/wasm_c_api.md) and [sample](samples/wasm-c-api)
|
||||
|
@ -153,6 +154,7 @@ The WAMR [samples](./samples) integrate the iwasm VM core, application manager a
|
|||
- **[multi-module](./samples/multi-module)**: Demonstrating the [multiple modules as dependencies](./doc/multi_module.md) feature which implements the [load-time dynamic linking](https://webassembly.org/docs/dynamic-linking/).
|
||||
- **[ref-types](./samples/ref-types)**: Demonstrating how to call wasm functions with argument of externref type introduced by [reference types proposal](https://github.com/WebAssembly/reference-types).
|
||||
- **[wasm-c-api](./samples/wasm-c-api/README.md)**: Demonstrating how to run some samples from [wasm-c-api proposal](https://github.com/WebAssembly/wasm-c-api) and showing the supported API's.
|
||||
- **[socket-api](./samples/socket-api/README.md)**: Demonstrating how to run wasm tcp server and tcp client applications, and how they communicate with each other.
|
||||
- **[workload](./samples/workload/README.md)**: Demonstrating how to build and run some complex workloads, e.g. tensorflow-lite, XNNPACK, wasm-av1, meshoptimizer and bwa.
|
||||
|
||||
|
||||
|
|
|
@ -96,10 +96,17 @@ def run_clang_format(file_path: pathlib, root: pathlib) -> bool:
|
|||
|
||||
def run_clang_format_diff(root: pathlib, commits: str) -> bool:
|
||||
"""
|
||||
Use `clang-format-12` and `git-clang-format-12` to check code
|
||||
format of the PR, which specificed a commit range. It is required to
|
||||
format code before `git commit` or when failed the PR check:
|
||||
Use `clang-format-12` or `git-clang-format-12` to check code format of
|
||||
the PR, with a commit range specified. It is required to format the
|
||||
code before committing the PR, or it might fail to pass the CI check:
|
||||
|
||||
1. Install clang-format-12.0.0
|
||||
Normally we can install it by `sudo apt-get install clang-format-12`,
|
||||
or download the `clang+llvm-12.0.0-xxx-tar.xz` package from
|
||||
https://github.com/llvm/llvm-project/releases/tag/llvmorg-12.0.0
|
||||
and install it
|
||||
|
||||
2. Format the C/C++ source file
|
||||
``` shell
|
||||
cd path/to/wamr/root
|
||||
clang-format-12 --style file -i path/to/file
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "debug/jit_debug.h"
|
||||
#endif
|
||||
|
||||
#define YMM_PLT_PREFIX "__ymm@"
|
||||
#define XMM_PLT_PREFIX "__xmm@"
|
||||
#define REAL_PLT_PREFIX "__real@"
|
||||
|
||||
|
@ -1805,7 +1806,8 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
|
|||
is_literal ? module->literal_size : module->code_size;
|
||||
uint32 i, func_index, symbol_len;
|
||||
#if defined(BH_PLATFORM_WINDOWS)
|
||||
uint32 xmm_plt_index = 0, real_plt_index = 0, float_plt_index = 0;
|
||||
uint32 ymm_plt_index = 0, xmm_plt_index = 0;
|
||||
uint32 real_plt_index = 0, float_plt_index = 0, j;
|
||||
#endif
|
||||
char symbol_buf[128] = { 0 }, *symbol, *p;
|
||||
void *symbol_addr;
|
||||
|
@ -1860,31 +1862,45 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
|
|||
symbol_addr = module->literal;
|
||||
}
|
||||
#if defined(BH_PLATFORM_WINDOWS)
|
||||
/* Relocation for symbols which start with "__xmm@" or "__real@" and
|
||||
end with the xmm value or real value. In Windows PE file, the data
|
||||
is stored in some individual ".rdata" sections. We simply create
|
||||
extra plt data, parse the values from the symbols and stored them
|
||||
into the extra plt data. */
|
||||
/* Relocation for symbols which start with "__ymm@", "__xmm@" or
|
||||
"__real@" and end with the ymm value, xmm value or real value.
|
||||
In Windows PE file, the data is stored in some individual ".rdata"
|
||||
sections. We simply create extra plt data, parse the values from
|
||||
the symbols and stored them into the extra plt data. */
|
||||
else if (!strcmp(group->section_name, ".text")
|
||||
&& !strncmp(symbol, YMM_PLT_PREFIX, strlen(YMM_PLT_PREFIX))
|
||||
&& strlen(symbol) == strlen(YMM_PLT_PREFIX) + 64) {
|
||||
char ymm_buf[17] = { 0 };
|
||||
|
||||
symbol_addr = module->extra_plt_data + ymm_plt_index * 32;
|
||||
for (j = 0; j < 4; j++) {
|
||||
bh_memcpy_s(ymm_buf, sizeof(ymm_buf),
|
||||
symbol + strlen(YMM_PLT_PREFIX) + 48 - 16 * j, 16);
|
||||
if (!str2uint64(ymm_buf,
|
||||
(uint64 *)((uint8 *)symbol_addr + 8 * j))) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"resolve symbol %s failed", symbol);
|
||||
goto check_symbol_fail;
|
||||
}
|
||||
}
|
||||
ymm_plt_index++;
|
||||
}
|
||||
else if (!strcmp(group->section_name, ".text")
|
||||
&& !strncmp(symbol, XMM_PLT_PREFIX, strlen(XMM_PLT_PREFIX))
|
||||
&& strlen(symbol) == strlen(XMM_PLT_PREFIX) + 32) {
|
||||
char xmm_buf[17] = { 0 };
|
||||
|
||||
symbol_addr = module->extra_plt_data + xmm_plt_index * 16;
|
||||
bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
|
||||
symbol + strlen(XMM_PLT_PREFIX) + 16, 16);
|
||||
if (!str2uint64(xmm_buf, (uint64 *)symbol_addr)) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"resolve symbol %s failed", symbol);
|
||||
goto check_symbol_fail;
|
||||
}
|
||||
|
||||
bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
|
||||
symbol + strlen(XMM_PLT_PREFIX), 16);
|
||||
if (!str2uint64(xmm_buf, (uint64 *)((uint8 *)symbol_addr + 8))) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"resolve symbol %s failed", symbol);
|
||||
goto check_symbol_fail;
|
||||
symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
|
||||
+ xmm_plt_index * 16;
|
||||
for (j = 0; j < 2; j++) {
|
||||
bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
|
||||
symbol + strlen(XMM_PLT_PREFIX) + 16 - 16 * j, 16);
|
||||
if (!str2uint64(xmm_buf,
|
||||
(uint64 *)((uint8 *)symbol_addr + 8 * j))) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"resolve symbol %s failed", symbol);
|
||||
goto check_symbol_fail;
|
||||
}
|
||||
}
|
||||
xmm_plt_index++;
|
||||
}
|
||||
|
@ -1893,8 +1909,8 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
|
|||
&& strlen(symbol) == strlen(REAL_PLT_PREFIX) + 16) {
|
||||
char real_buf[17] = { 0 };
|
||||
|
||||
symbol_addr = module->extra_plt_data + module->xmm_plt_count * 16
|
||||
+ real_plt_index * 8;
|
||||
symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
|
||||
+ module->xmm_plt_count * 16 + real_plt_index * 8;
|
||||
bh_memcpy_s(real_buf, sizeof(real_buf),
|
||||
symbol + strlen(REAL_PLT_PREFIX), 16);
|
||||
if (!str2uint64(real_buf, (uint64 *)symbol_addr)) {
|
||||
|
@ -1909,7 +1925,8 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
|
|||
&& strlen(symbol) == strlen(REAL_PLT_PREFIX) + 8) {
|
||||
char float_buf[9] = { 0 };
|
||||
|
||||
symbol_addr = module->extra_plt_data + module->xmm_plt_count * 16
|
||||
symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
|
||||
+ module->xmm_plt_count * 16
|
||||
+ module->real_plt_count * 8 + float_plt_index * 4;
|
||||
bh_memcpy_s(float_buf, sizeof(float_buf),
|
||||
symbol + strlen(REAL_PLT_PREFIX), 8);
|
||||
|
@ -2121,11 +2138,19 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
|
|||
|| (module->is_indirect_mode
|
||||
&& group_name_len == strlen(".text") + 1))
|
||||
&& !strncmp(group_name, ".text", strlen(".text"))) {
|
||||
if ((symbol_name_len == strlen(XMM_PLT_PREFIX) + 32
|
||||
if ((symbol_name_len == strlen(YMM_PLT_PREFIX) + 64
|
||||
|| (module->is_indirect_mode
|
||||
&& symbol_name_len == strlen(XMM_PLT_PREFIX) + 32 + 1))
|
||||
&& !strncmp(symbol_name, XMM_PLT_PREFIX,
|
||||
strlen(XMM_PLT_PREFIX))) {
|
||||
&& symbol_name_len == strlen(YMM_PLT_PREFIX) + 64 + 1))
|
||||
&& !strncmp(symbol_name, YMM_PLT_PREFIX,
|
||||
strlen(YMM_PLT_PREFIX))) {
|
||||
module->ymm_plt_count++;
|
||||
}
|
||||
else if ((symbol_name_len == strlen(XMM_PLT_PREFIX) + 32
|
||||
|| (module->is_indirect_mode
|
||||
&& symbol_name_len
|
||||
== strlen(XMM_PLT_PREFIX) + 32 + 1))
|
||||
&& !strncmp(symbol_name, XMM_PLT_PREFIX,
|
||||
strlen(XMM_PLT_PREFIX))) {
|
||||
module->xmm_plt_count++;
|
||||
}
|
||||
else if ((symbol_name_len == strlen(REAL_PLT_PREFIX) + 16
|
||||
|
@ -2149,7 +2174,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
|
|||
}
|
||||
|
||||
/* Allocate memory for extra plt data */
|
||||
size = sizeof(uint64) * 2 * module->xmm_plt_count
|
||||
size = sizeof(uint64) * 4 * module->ymm_plt_count
|
||||
+ sizeof(uint64) * 2 * module->xmm_plt_count
|
||||
+ sizeof(uint64) * module->real_plt_count
|
||||
+ sizeof(uint32) * module->float_plt_count;
|
||||
if (size > 0) {
|
||||
|
|
|
@ -1020,6 +1020,7 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
|
|||
module->wasi_args.dir_list, module->wasi_args.dir_count,
|
||||
module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
|
||||
module->wasi_args.env, module->wasi_args.env_count,
|
||||
module->wasi_args.addr_pool, module->wasi_args.addr_count,
|
||||
module->wasi_args.argv, module->wasi_args.argc,
|
||||
module->wasi_args.stdio[0], module->wasi_args.stdio[1],
|
||||
module->wasi_args.stdio[2], error_buf, error_buf_size))
|
||||
|
@ -2818,8 +2819,8 @@ aot_table_copy(AOTModuleInstance *module_inst, uint32 src_tbl_idx,
|
|||
dst_tbl_inst = aot_get_table_inst(module_inst, dst_tbl_idx);
|
||||
bh_assert(dst_tbl_inst);
|
||||
|
||||
if ((uint64)src_offset + length > dst_tbl_inst->cur_size
|
||||
|| (uint64)dst_offset + length > src_tbl_inst->cur_size) {
|
||||
if ((uint64)dst_offset + length > dst_tbl_inst->cur_size
|
||||
|| (uint64)src_offset + length > src_tbl_inst->cur_size) {
|
||||
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
|
||||
return;
|
||||
}
|
||||
|
@ -3024,7 +3025,8 @@ aot_dump_call_stack(WASMExecEnv *exec_env)
|
|||
|
||||
/* release previous stack frames and create new ones */
|
||||
if (!bh_vector_destroy(module_inst->frames.ptr)
|
||||
|| !bh_vector_init(module_inst->frames.ptr, n, sizeof(WASMCApiFrame))) {
|
||||
|| !bh_vector_init(module_inst->frames.ptr, n, sizeof(WASMCApiFrame),
|
||||
false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -197,10 +197,11 @@ typedef struct AOTModule {
|
|||
uint32 literal_size;
|
||||
|
||||
#if defined(BH_PLATFORM_WINDOWS)
|
||||
/* extra plt data area for __xmm and __real constants
|
||||
/* extra plt data area for __ymm, __xmm and __real constants
|
||||
in Windows platform, NULL for JIT mode */
|
||||
uint8 *extra_plt_data;
|
||||
uint32 extra_plt_data_size;
|
||||
uint32 ymm_plt_count;
|
||||
uint32 xmm_plt_count;
|
||||
uint32 real_plt_count;
|
||||
uint32 float_plt_count;
|
||||
|
|
|
@ -109,113 +109,115 @@ failed: \
|
|||
}
|
||||
|
||||
/* vectors with no ownership management of elements */
|
||||
#define WASM_DEFINE_VEC_PLAIN(name) \
|
||||
WASM_DEFINE_VEC(name) \
|
||||
void wasm_##name##_vec_new(own wasm_##name##_vec_t *out, size_t size, \
|
||||
own wasm_##name##_t const data[]) \
|
||||
{ \
|
||||
if (!out) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
memset(out, 0, sizeof(wasm_##name##_vec_t)); \
|
||||
\
|
||||
if (!size) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t))) { \
|
||||
LOG_DEBUG("bh_vector_init failed"); \
|
||||
goto failed; \
|
||||
} \
|
||||
\
|
||||
if (data) { \
|
||||
uint32 size_in_bytes = 0; \
|
||||
size_in_bytes = (uint32)(size * sizeof(wasm_##name##_t)); \
|
||||
bh_memcpy_s(out->data, size_in_bytes, data, size_in_bytes); \
|
||||
out->num_elems = size; \
|
||||
} \
|
||||
\
|
||||
RETURN_VOID(out, wasm_##name##_vec_delete) \
|
||||
} \
|
||||
void wasm_##name##_vec_copy(wasm_##name##_vec_t *out, \
|
||||
const wasm_##name##_vec_t *src) \
|
||||
{ \
|
||||
wasm_##name##_vec_new(out, src->size, src->data); \
|
||||
} \
|
||||
void wasm_##name##_vec_delete(wasm_##name##_vec_t *v) \
|
||||
{ \
|
||||
if (v) { \
|
||||
bh_vector_destroy((Vector *)v); \
|
||||
} \
|
||||
#define WASM_DEFINE_VEC_PLAIN(name) \
|
||||
WASM_DEFINE_VEC(name) \
|
||||
void wasm_##name##_vec_new(own wasm_##name##_vec_t *out, size_t size, \
|
||||
own wasm_##name##_t const data[]) \
|
||||
{ \
|
||||
if (!out) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
memset(out, 0, sizeof(wasm_##name##_vec_t)); \
|
||||
\
|
||||
if (!size) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t), \
|
||||
true)) { \
|
||||
LOG_DEBUG("bh_vector_init failed"); \
|
||||
goto failed; \
|
||||
} \
|
||||
\
|
||||
if (data) { \
|
||||
uint32 size_in_bytes = 0; \
|
||||
size_in_bytes = (uint32)(size * sizeof(wasm_##name##_t)); \
|
||||
bh_memcpy_s(out->data, size_in_bytes, data, size_in_bytes); \
|
||||
out->num_elems = size; \
|
||||
} \
|
||||
\
|
||||
RETURN_VOID(out, wasm_##name##_vec_delete) \
|
||||
} \
|
||||
void wasm_##name##_vec_copy(wasm_##name##_vec_t *out, \
|
||||
const wasm_##name##_vec_t *src) \
|
||||
{ \
|
||||
wasm_##name##_vec_new(out, src->size, src->data); \
|
||||
} \
|
||||
void wasm_##name##_vec_delete(wasm_##name##_vec_t *v) \
|
||||
{ \
|
||||
if (v) { \
|
||||
bh_vector_destroy((Vector *)v); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* vectors that own their elements */
|
||||
#define WASM_DEFINE_VEC_OWN(name, elem_destroy_func) \
|
||||
WASM_DEFINE_VEC(name) \
|
||||
void wasm_##name##_vec_new(own wasm_##name##_vec_t *out, size_t size, \
|
||||
own wasm_##name##_t *const data[]) \
|
||||
{ \
|
||||
if (!out) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
memset(out, 0, sizeof(wasm_##name##_vec_t)); \
|
||||
\
|
||||
if (!size) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t *))) { \
|
||||
LOG_DEBUG("bh_vector_init failed"); \
|
||||
goto failed; \
|
||||
} \
|
||||
\
|
||||
if (data) { \
|
||||
uint32 size_in_bytes = 0; \
|
||||
size_in_bytes = (uint32)(size * sizeof(wasm_##name##_t *)); \
|
||||
bh_memcpy_s(out->data, size_in_bytes, data, size_in_bytes); \
|
||||
out->num_elems = size; \
|
||||
} \
|
||||
\
|
||||
RETURN_VOID(out, wasm_##name##_vec_delete) \
|
||||
} \
|
||||
void wasm_##name##_vec_copy(own wasm_##name##_vec_t *out, \
|
||||
const wasm_##name##_vec_t *src) \
|
||||
{ \
|
||||
size_t i = 0; \
|
||||
memset(out, 0, sizeof(Vector)); \
|
||||
\
|
||||
if (!src || !src->size) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (!bh_vector_init((Vector *)out, src->size, \
|
||||
sizeof(wasm_##name##_t *))) { \
|
||||
LOG_DEBUG("bh_vector_init failed"); \
|
||||
goto failed; \
|
||||
} \
|
||||
\
|
||||
for (i = 0; i != src->num_elems; ++i) { \
|
||||
if (!(out->data[i] = wasm_##name##_copy(src->data[i]))) { \
|
||||
LOG_DEBUG("wasm_%s_copy failed", #name); \
|
||||
goto failed; \
|
||||
} \
|
||||
} \
|
||||
out->num_elems = src->num_elems; \
|
||||
\
|
||||
RETURN_VOID(out, wasm_##name##_vec_delete) \
|
||||
} \
|
||||
void wasm_##name##_vec_delete(wasm_##name##_vec_t *v) \
|
||||
{ \
|
||||
size_t i = 0; \
|
||||
if (!v) { \
|
||||
return; \
|
||||
} \
|
||||
for (i = 0; i != v->num_elems; ++i) { \
|
||||
elem_destroy_func(*(v->data + i)); \
|
||||
} \
|
||||
bh_vector_destroy((Vector *)v); \
|
||||
#define WASM_DEFINE_VEC_OWN(name, elem_destroy_func) \
|
||||
WASM_DEFINE_VEC(name) \
|
||||
void wasm_##name##_vec_new(own wasm_##name##_vec_t *out, size_t size, \
|
||||
own wasm_##name##_t *const data[]) \
|
||||
{ \
|
||||
if (!out) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
memset(out, 0, sizeof(wasm_##name##_vec_t)); \
|
||||
\
|
||||
if (!size) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t *), \
|
||||
true)) { \
|
||||
LOG_DEBUG("bh_vector_init failed"); \
|
||||
goto failed; \
|
||||
} \
|
||||
\
|
||||
if (data) { \
|
||||
uint32 size_in_bytes = 0; \
|
||||
size_in_bytes = (uint32)(size * sizeof(wasm_##name##_t *)); \
|
||||
bh_memcpy_s(out->data, size_in_bytes, data, size_in_bytes); \
|
||||
out->num_elems = size; \
|
||||
} \
|
||||
\
|
||||
RETURN_VOID(out, wasm_##name##_vec_delete) \
|
||||
} \
|
||||
void wasm_##name##_vec_copy(own wasm_##name##_vec_t *out, \
|
||||
const wasm_##name##_vec_t *src) \
|
||||
{ \
|
||||
size_t i = 0; \
|
||||
memset(out, 0, sizeof(Vector)); \
|
||||
\
|
||||
if (!src || !src->size) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (!bh_vector_init((Vector *)out, src->size, \
|
||||
sizeof(wasm_##name##_t *), true)) { \
|
||||
LOG_DEBUG("bh_vector_init failed"); \
|
||||
goto failed; \
|
||||
} \
|
||||
\
|
||||
for (i = 0; i != src->num_elems; ++i) { \
|
||||
if (!(out->data[i] = wasm_##name##_copy(src->data[i]))) { \
|
||||
LOG_DEBUG("wasm_%s_copy failed", #name); \
|
||||
goto failed; \
|
||||
} \
|
||||
} \
|
||||
out->num_elems = src->num_elems; \
|
||||
\
|
||||
RETURN_VOID(out, wasm_##name##_vec_delete) \
|
||||
} \
|
||||
void wasm_##name##_vec_delete(wasm_##name##_vec_t *v) \
|
||||
{ \
|
||||
size_t i = 0; \
|
||||
if (!v) { \
|
||||
return; \
|
||||
} \
|
||||
for (i = 0; i != v->num_elems; ++i) { \
|
||||
elem_destroy_func(*(v->data + i)); \
|
||||
} \
|
||||
bh_vector_destroy((Vector *)v); \
|
||||
}
|
||||
|
||||
WASM_DEFINE_VEC_PLAIN(byte)
|
||||
|
@ -320,6 +322,8 @@ wasm_engine_new()
|
|||
singleton_engine =
|
||||
wasm_engine_new_internal(Alloc_With_System_Allocator, NULL);
|
||||
}
|
||||
if (singleton_engine)
|
||||
singleton_engine->ref_count++;
|
||||
return singleton_engine;
|
||||
}
|
||||
|
||||
|
@ -336,6 +340,8 @@ wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts)
|
|||
if (!singleton_engine) {
|
||||
singleton_engine = wasm_engine_new_internal(type, opts);
|
||||
}
|
||||
if (singleton_engine)
|
||||
singleton_engine->ref_count++;
|
||||
return singleton_engine;
|
||||
}
|
||||
|
||||
|
@ -343,7 +349,7 @@ wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts)
|
|||
void
|
||||
wasm_engine_delete(wasm_engine_t *engine)
|
||||
{
|
||||
if (engine) {
|
||||
if (engine && (--engine->ref_count == 0)) {
|
||||
wasm_engine_delete_internal(engine);
|
||||
singleton_engine = NULL;
|
||||
}
|
||||
|
@ -375,7 +381,7 @@ wasm_store_new(wasm_engine_t *engine)
|
|||
DEFAULT_VECTOR_INIT_LENGTH);
|
||||
|
||||
if (!(store->foreigns = malloc_internal(sizeof(Vector)))
|
||||
|| !(bh_vector_init(store->foreigns, 24, sizeof(Vector *)))) {
|
||||
|| !(bh_vector_init(store->foreigns, 24, sizeof(Vector *), true))) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ WASM_DECLARE_VEC(store, *)
|
|||
struct wasm_engine_t {
|
||||
/* support one store for now */
|
||||
wasm_store_vec_t *stores;
|
||||
uint32_t ref_count;
|
||||
};
|
||||
|
||||
struct wasm_store_t {
|
||||
|
|
|
@ -772,7 +772,7 @@ register_module_with_null_name(WASMModuleCommon *module_common, char *error_buf,
|
|||
}
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_load(const uint8 *buf, uint32 size, char *error_buf,
|
||||
wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleCommon *module_common = NULL;
|
||||
|
@ -1328,7 +1328,8 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
|||
|
||||
bh_assert((argv && ret_argv) || (argc == 0));
|
||||
|
||||
if (argv == ret_argv) {
|
||||
if (argv == ret_argv || argc == 0) {
|
||||
/* no need to transfrom externref results */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2210,14 +2211,36 @@ wasm_runtime_set_wasi_args(WASMModuleCommon *module, const char *dir_list[],
|
|||
argc, -1, -1, -1);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
|
||||
uint32 addr_pool_size)
|
||||
{
|
||||
WASIArguments *wasi_args = NULL;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
wasi_args = &((WASMModule *)module)->wasi_args;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
wasi_args = &((AOTModule *)module)->wasi_args;
|
||||
#endif
|
||||
|
||||
if (wasi_args) {
|
||||
wasi_args->addr_pool = addr_pool;
|
||||
wasi_args->addr_count = addr_pool_size;
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_UVWASI == 0
|
||||
bool
|
||||
wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||
const char *dir_list[], uint32 dir_count,
|
||||
const char *map_dir_list[], uint32 map_dir_count,
|
||||
const char *env[], uint32 env_count, char *argv[],
|
||||
uint32 argc, int stdinfd, int stdoutfd, int stderrfd,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
const char *env[], uint32 env_count,
|
||||
const char *addr_pool[], uint32 addr_pool_size,
|
||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
||||
int stderrfd, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASIContext *wasi_ctx;
|
||||
char *argv_buf = NULL;
|
||||
|
@ -2229,8 +2252,10 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
|||
struct fd_table *curfds = NULL;
|
||||
struct fd_prestats *prestats = NULL;
|
||||
struct argv_environ_values *argv_environ = NULL;
|
||||
struct addr_pool *apool = NULL;
|
||||
bool fd_table_inited = false, fd_prestats_inited = false;
|
||||
bool argv_environ_inited = false;
|
||||
bool addr_pool_inited = false;
|
||||
__wasi_fd_t wasm_fd = 3;
|
||||
int32 raw_fd;
|
||||
char *path, resolved_path[PATH_MAX];
|
||||
|
@ -2304,7 +2329,8 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
|||
if (!(curfds = wasm_runtime_malloc(sizeof(struct fd_table)))
|
||||
|| !(prestats = wasm_runtime_malloc(sizeof(struct fd_prestats)))
|
||||
|| !(argv_environ =
|
||||
wasm_runtime_malloc(sizeof(struct argv_environ_values)))) {
|
||||
wasm_runtime_malloc(sizeof(struct argv_environ_values)))
|
||||
|| !(apool = wasm_runtime_malloc(sizeof(struct addr_pool)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed");
|
||||
goto fail;
|
||||
|
@ -2335,6 +2361,14 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
|||
}
|
||||
argv_environ_inited = true;
|
||||
|
||||
if (!addr_pool_init(apool)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: "
|
||||
"init the address pool failed");
|
||||
goto fail;
|
||||
}
|
||||
addr_pool_inited = true;
|
||||
|
||||
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
|
||||
if (!fd_table_insert_existing(curfds, 0, (stdinfd != -1) ? stdinfd : 0)
|
||||
|| !fd_table_insert_existing(curfds, 1, (stdoutfd != -1) ? stdoutfd : 1)
|
||||
|
@ -2369,9 +2403,34 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
|||
fd_prestats_insert(prestats, dir_list[i], wasm_fd);
|
||||
}
|
||||
|
||||
/* addr_pool(textual) -> apool */
|
||||
for (i = 0; i < addr_pool_size; i++) {
|
||||
char *cp, *address, *mask;
|
||||
bool ret = false;
|
||||
|
||||
cp = bh_strdup(addr_pool[i]);
|
||||
if (!cp) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: copy address failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
address = strtok(cp, "/");
|
||||
mask = strtok(NULL, "/");
|
||||
|
||||
ret = addr_pool_insert(apool, address, (uint8)(mask ? atoi(mask) : 0));
|
||||
wasm_runtime_free(cp);
|
||||
if (!ret) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: store address failed");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
wasi_ctx->curfds = curfds;
|
||||
wasi_ctx->prestats = prestats;
|
||||
wasi_ctx->argv_environ = argv_environ;
|
||||
wasi_ctx->addr_pool = apool;
|
||||
wasi_ctx->argv_buf = argv_buf;
|
||||
wasi_ctx->argv_list = argv_list;
|
||||
wasi_ctx->env_buf = env_buf;
|
||||
|
@ -2386,12 +2445,16 @@ fail:
|
|||
fd_prestats_destroy(prestats);
|
||||
if (fd_table_inited)
|
||||
fd_table_destroy(curfds);
|
||||
if (addr_pool_inited)
|
||||
addr_pool_destroy(apool);
|
||||
if (curfds)
|
||||
wasm_runtime_free(curfds);
|
||||
if (prestats)
|
||||
wasm_runtime_free(prestats);
|
||||
if (argv_environ)
|
||||
wasm_runtime_free(argv_environ);
|
||||
if (apool)
|
||||
wasm_runtime_free(apool);
|
||||
if (argv_buf)
|
||||
wasm_runtime_free(argv_buf);
|
||||
if (argv_list)
|
||||
|
@ -2449,9 +2512,10 @@ bool
|
|||
wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||
const char *dir_list[], uint32 dir_count,
|
||||
const char *map_dir_list[], uint32 map_dir_count,
|
||||
const char *env[], uint32 env_count, char *argv[],
|
||||
uint32 argc, int stdinfd, int stdoutfd, int stderrfd,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
const char *env[], uint32 env_count,
|
||||
const char *addr_pool[], uint32 addr_pool_size,
|
||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
||||
int stderrfd, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uvwasi_t *uvwasi = NULL;
|
||||
uvwasi_options_t init_options;
|
||||
|
@ -2614,6 +2678,10 @@ wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
|
|||
fd_prestats_destroy(wasi_ctx->prestats);
|
||||
wasm_runtime_free(wasi_ctx->prestats);
|
||||
}
|
||||
if (wasi_ctx->addr_pool) {
|
||||
addr_pool_destroy(wasi_ctx->addr_pool);
|
||||
wasm_runtime_free(wasi_ctx->addr_pool);
|
||||
}
|
||||
if (wasi_ctx->argv_buf)
|
||||
wasm_runtime_free(wasi_ctx->argv_buf);
|
||||
if (wasi_ctx->argv_list)
|
||||
|
|
|
@ -352,6 +352,7 @@ typedef struct WASIContext {
|
|||
struct fd_table *curfds;
|
||||
struct fd_prestats *prestats;
|
||||
struct argv_environ_values *argv_environ;
|
||||
struct addr_pool *addr_pool;
|
||||
char *argv_buf;
|
||||
char **argv_list;
|
||||
char *env_buf;
|
||||
|
@ -412,7 +413,7 @@ wasm_runtime_is_xip_file(const uint8 *buf, uint32 size);
|
|||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN WASMModuleCommon *
|
||||
wasm_runtime_load(const uint8 *buf, uint32 size, char *error_buf,
|
||||
wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
|
@ -712,9 +713,10 @@ bool
|
|||
wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||
const char *dir_list[], uint32 dir_count,
|
||||
const char *map_dir_list[], uint32 map_dir_count,
|
||||
const char *env[], uint32 env_count, char *argv[],
|
||||
uint32 argc, int stdinfd, int stdoutfd, int stderrfd,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
const char *env[], uint32 env_count,
|
||||
const char *addr_pool[], uint32 addr_pool_size,
|
||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
||||
int stderrfd, char *error_buf, uint32 error_buf_size);
|
||||
|
||||
void
|
||||
wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst);
|
||||
|
@ -726,6 +728,9 @@ wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst,
|
|||
WASIContext *
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
|
||||
uint32 addr_pool_size);
|
||||
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
|
|
|
@ -374,7 +374,8 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
|||
|
||||
if (timeout < 0)
|
||||
timeout = BHT_WAIT_FOREVER;
|
||||
os_cond_reltimedwait(&wait_node->wait_cond, &wait_node->wait_lock, timeout);
|
||||
os_cond_reltimedwait(&wait_node->wait_cond, &wait_node->wait_lock,
|
||||
timeout / 1000);
|
||||
|
||||
os_mutex_unlock(&wait_node->wait_lock);
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ typedef double float64_t;
|
|||
wasm_##name##_t ptr_or_none* data; \
|
||||
size_t num_elems; \
|
||||
size_t size_of_elem; \
|
||||
void *lock; \
|
||||
} wasm_##name##_vec_t; \
|
||||
\
|
||||
WASM_API_EXTERN void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \
|
||||
|
@ -589,8 +590,8 @@ WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_exte
|
|||
|
||||
// Vectors
|
||||
|
||||
#define WASM_EMPTY_VEC {0, NULL, 0, 0}
|
||||
#define WASM_ARRAY_VEC(array) {sizeof(array)/sizeof(*(array)), array, sizeof(array)/sizeof(*(array)), sizeof(*(array))}
|
||||
#define WASM_EMPTY_VEC {0, NULL, 0, 0, NULL}
|
||||
#define WASM_ARRAY_VEC(array) {sizeof(array)/sizeof(*(array)), array, sizeof(array)/sizeof(*(array)), sizeof(*(array)), NULL}
|
||||
|
||||
|
||||
// Value Type construction short-hands
|
||||
|
|
|
@ -300,7 +300,10 @@ wasm_runtime_find_module_registered(const char *module_name);
|
|||
* WASM binary data when interpreter or JIT is enabled, or AOT binary data
|
||||
* when AOT is enabled. If it is AOT binary data, it must be 4-byte aligned.
|
||||
*
|
||||
* @param buf the byte buffer which contains the WASM binary data
|
||||
* @param buf the byte buffer which contains the WASM/AOT binary data,
|
||||
* note that the byte buffer must be writable since runtime may
|
||||
* change its content for footprint and performance purpose, and
|
||||
* it must be referencable until wasm_runtime_unload is called
|
||||
* @param size the size of the buffer
|
||||
* @param error_buf output of the exception info
|
||||
* @param error_buf_size the size of the exception string
|
||||
|
@ -308,7 +311,7 @@ wasm_runtime_find_module_registered(const char *module_name);
|
|||
* @return return WASM module loaded, NULL if failed
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_module_t
|
||||
wasm_runtime_load(const uint8_t *buf, uint32_t size,
|
||||
wasm_runtime_load(uint8_t *buf, uint32_t size,
|
||||
char *error_buf, uint32_t error_buf_size);
|
||||
|
||||
/**
|
||||
|
@ -348,6 +351,10 @@ wasm_runtime_set_wasi_args(wasm_module_t module,
|
|||
const char *env[], uint32_t env_count,
|
||||
char *argv[], int argc);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
|
||||
uint32_t addr_pool_size);
|
||||
|
||||
/**
|
||||
* Instantiate a WASM module.
|
||||
*
|
||||
|
|
|
@ -308,6 +308,9 @@ typedef struct WASIArguments {
|
|||
uint32 map_dir_count;
|
||||
const char **env;
|
||||
uint32 env_count;
|
||||
/* in CIDR noation */
|
||||
const char **addr_pool;
|
||||
uint32 addr_count;
|
||||
char **argv;
|
||||
uint32 argc;
|
||||
int stdio[3];
|
||||
|
|
|
@ -73,8 +73,14 @@ typedef struct WASMInterpFrame {
|
|||
static inline unsigned
|
||||
wasm_interp_interp_frame_size(unsigned all_cell_num)
|
||||
{
|
||||
return align_uint((uint32)offsetof(WASMInterpFrame, lp) + all_cell_num * 5,
|
||||
4);
|
||||
unsigned frame_size;
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
frame_size = (uint32)offsetof(WASMInterpFrame, lp) + all_cell_num * 4;
|
||||
#else
|
||||
frame_size = (uint32)offsetof(WASMInterpFrame, operand) + all_cell_num * 4;
|
||||
#endif
|
||||
return align_uint(frame_size, 4);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -229,15 +229,15 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
|||
frame_sp += 2; \
|
||||
} while (0)
|
||||
|
||||
#define PUSH_CSP(_label_type, cell_num, _target_addr) \
|
||||
do { \
|
||||
bh_assert(frame_csp < frame->csp_boundary); \
|
||||
/* frame_csp->label_type = _label_type; */ \
|
||||
frame_csp->cell_num = cell_num; \
|
||||
frame_csp->begin_addr = frame_ip; \
|
||||
frame_csp->target_addr = _target_addr; \
|
||||
frame_csp->frame_sp = frame_sp; \
|
||||
frame_csp++; \
|
||||
#define PUSH_CSP(_label_type, param_cell_num, cell_num, _target_addr) \
|
||||
do { \
|
||||
bh_assert(frame_csp < frame->csp_boundary); \
|
||||
/* frame_csp->label_type = _label_type; */ \
|
||||
frame_csp->cell_num = cell_num; \
|
||||
frame_csp->begin_addr = frame_ip; \
|
||||
frame_csp->target_addr = _target_addr; \
|
||||
frame_csp->frame_sp = frame_sp - param_cell_num; \
|
||||
frame_csp++; \
|
||||
} while (0)
|
||||
|
||||
#define POP_I32() (--frame_sp, *(int32 *)frame_sp)
|
||||
|
@ -994,7 +994,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
uint8 *else_addr, *end_addr, *maddr = NULL;
|
||||
uint32 local_idx, local_offset, global_idx;
|
||||
uint8 local_type, *global_addr;
|
||||
uint32 cache_index, type_index, cell_num;
|
||||
uint32 cache_index, type_index, param_cell_num, cell_num;
|
||||
uint8 value_type;
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
|
@ -1022,6 +1022,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(EXT_OP_BLOCK)
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
param_cell_num = wasm_types[type_index]->param_cell_num;
|
||||
cell_num = wasm_types[type_index]->ret_cell_num;
|
||||
goto handle_op_block;
|
||||
}
|
||||
|
@ -1029,6 +1030,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_BLOCK)
|
||||
{
|
||||
value_type = *frame_ip++;
|
||||
param_cell_num = 0;
|
||||
cell_num = wasm_value_type_cell_num(value_type);
|
||||
handle_op_block:
|
||||
cache_index = ((uintptr_t)frame_ip)
|
||||
|
@ -1052,13 +1054,14 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
else {
|
||||
end_addr = NULL;
|
||||
}
|
||||
PUSH_CSP(LABEL_TYPE_BLOCK, cell_num, end_addr);
|
||||
PUSH_CSP(LABEL_TYPE_BLOCK, param_cell_num, cell_num, end_addr);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
|
||||
HANDLE_OP(EXT_OP_LOOP)
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
param_cell_num = wasm_types[type_index]->param_cell_num;
|
||||
cell_num = wasm_types[type_index]->param_cell_num;
|
||||
goto handle_op_loop;
|
||||
}
|
||||
|
@ -1066,15 +1069,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_LOOP)
|
||||
{
|
||||
value_type = *frame_ip++;
|
||||
param_cell_num = 0;
|
||||
cell_num = wasm_value_type_cell_num(value_type);
|
||||
handle_op_loop:
|
||||
PUSH_CSP(LABEL_TYPE_LOOP, cell_num, frame_ip);
|
||||
PUSH_CSP(LABEL_TYPE_LOOP, param_cell_num, cell_num, frame_ip);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
|
||||
HANDLE_OP(EXT_OP_IF)
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
param_cell_num = wasm_types[type_index]->param_cell_num;
|
||||
cell_num = wasm_types[type_index]->ret_cell_num;
|
||||
goto handle_op_if;
|
||||
}
|
||||
|
@ -1082,6 +1087,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_IF)
|
||||
{
|
||||
value_type = *frame_ip++;
|
||||
param_cell_num = 0;
|
||||
cell_num = wasm_value_type_cell_num(value_type);
|
||||
handle_op_if:
|
||||
cache_index = ((uintptr_t)frame_ip)
|
||||
|
@ -1106,7 +1112,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
cond = (uint32)POP_I32();
|
||||
|
||||
if (cond) { /* if branch is met */
|
||||
PUSH_CSP(LABEL_TYPE_IF, cell_num, end_addr);
|
||||
PUSH_CSP(LABEL_TYPE_IF, param_cell_num, cell_num, end_addr);
|
||||
}
|
||||
else { /* if branch is not met */
|
||||
/* if there is no else branch, go to the end addr */
|
||||
|
@ -1115,7 +1121,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
}
|
||||
/* if there is an else branch, go to the else addr */
|
||||
else {
|
||||
PUSH_CSP(LABEL_TYPE_IF, cell_num, end_addr);
|
||||
PUSH_CSP(LABEL_TYPE_IF, param_cell_num, cell_num,
|
||||
end_addr);
|
||||
frame_ip = else_addr + 1;
|
||||
}
|
||||
}
|
||||
|
@ -3063,8 +3070,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
s = (uint32)POP_I32();
|
||||
d = (uint32)POP_I32();
|
||||
|
||||
if (s + n > dst_tbl_inst->cur_size
|
||||
|| d + n > src_tbl_inst->cur_size) {
|
||||
if (d + n > dst_tbl_inst->cur_size
|
||||
|| s + n > src_tbl_inst->cur_size) {
|
||||
wasm_set_exception(module,
|
||||
"out of bounds table access");
|
||||
goto got_exception;
|
||||
|
@ -3659,7 +3666,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
/* Push function block as first block */
|
||||
cell_num = func_type->ret_cell_num;
|
||||
PUSH_CSP(LABEL_TYPE_FUNCTION, cell_num, frame_ip_end - 1);
|
||||
PUSH_CSP(LABEL_TYPE_FUNCTION, 0, cell_num, frame_ip_end - 1);
|
||||
|
||||
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)frame);
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
|
|
|
@ -2984,8 +2984,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
s = (uint32)POP_I32();
|
||||
d = (uint32)POP_I32();
|
||||
|
||||
if (s + n > dst_tbl_inst->cur_size
|
||||
|| d + n > src_tbl_inst->cur_size) {
|
||||
if (d + n > dst_tbl_inst->cur_size
|
||||
|| s + n > src_tbl_inst->cur_size) {
|
||||
wasm_set_exception(module,
|
||||
"out of bounds table access");
|
||||
goto got_exception;
|
||||
|
|
|
@ -3593,7 +3593,7 @@ check_wasi_abi_compatibility(const WASMModule *module, bool main_module,
|
|||
#endif
|
||||
|
||||
WASMModule *
|
||||
wasm_loader_load(const uint8 *buf, uint32 size,
|
||||
wasm_loader_load(uint8 *buf, uint32 size,
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
bool main_module,
|
||||
#endif
|
||||
|
@ -6436,6 +6436,7 @@ re_scan:
|
|||
uint8 value_type;
|
||||
BlockType block_type;
|
||||
|
||||
p_org = p - 1;
|
||||
value_type = read_uint8(p);
|
||||
if (is_byte_a_type(value_type)) {
|
||||
/* If the first byte is one of these special values:
|
||||
|
@ -6463,9 +6464,9 @@ re_scan:
|
|||
* the block quickly.
|
||||
*/
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p - 2, *(p - 2));
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*(p - 2) = EXT_OP_BLOCK + (opcode - WASM_OP_BLOCK);
|
||||
*p_org = EXT_OP_BLOCK + (opcode - WASM_OP_BLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -7332,33 +7333,21 @@ re_scan:
|
|||
PUSH_OFFSET_TYPE(local_type);
|
||||
#else
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0) \
|
||||
&& (WASM_ENABLE_FAST_JIT == 0)
|
||||
&& (WASM_ENABLE_FAST_JIT == 0) && (WASM_ENABLE_DEBUG_INTERP == 0)
|
||||
if (local_offset < 0x80) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = EXT_OP_GET_LOCAL_FAST;
|
||||
if (is_32bit_type(local_type)) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)local_offset;
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)(local_offset | 0x80);
|
||||
}
|
||||
while (p_org < p) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = WASM_OP_NOP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* end of WASM_ENABLE_FAST_INTERP != 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -7408,33 +7397,21 @@ re_scan:
|
|||
}
|
||||
#else
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0) \
|
||||
&& (WASM_ENABLE_FAST_JIT == 0)
|
||||
&& (WASM_ENABLE_FAST_JIT == 0) && (WASM_ENABLE_DEBUG_INTERP == 0)
|
||||
if (local_offset < 0x80) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = EXT_OP_SET_LOCAL_FAST;
|
||||
if (is_32bit_type(local_type)) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)local_offset;
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)(local_offset | 0x80);
|
||||
}
|
||||
while (p_org < p) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = WASM_OP_NOP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* end of WASM_ENABLE_FAST_INTERP != 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -7480,33 +7457,21 @@ re_scan:
|
|||
- wasm_value_type_cell_num(local_type)));
|
||||
#else
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0) \
|
||||
&& (WASM_ENABLE_FAST_JIT == 0)
|
||||
&& (WASM_ENABLE_FAST_JIT == 0) && (WASM_ENABLE_DEBUG_INTERP == 0)
|
||||
if (local_offset < 0x80) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = EXT_OP_TEE_LOCAL_FAST;
|
||||
if (is_32bit_type(local_type)) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)local_offset;
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)(local_offset | 0x80);
|
||||
}
|
||||
while (p_org < p) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = WASM_OP_NOP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* end of WASM_ENABLE_FAST_INTERP != 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
|||
* @return return module loaded, NULL if failed
|
||||
*/
|
||||
WASMModule *
|
||||
wasm_loader_load(const uint8 *buf, uint32 size,
|
||||
wasm_loader_load(uint8 *buf, uint32 size,
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
bool main_module,
|
||||
#endif
|
||||
|
|
|
@ -2346,7 +2346,7 @@ load(const uint8 *buf, uint32 size, WASMModule *module, char *error_buf,
|
|||
}
|
||||
|
||||
WASMModule *
|
||||
wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf,
|
||||
wasm_loader_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *module = create_module(error_buf, error_buf_size);
|
||||
|
@ -4823,6 +4823,7 @@ re_scan:
|
|||
uint8 value_type;
|
||||
BlockType block_type;
|
||||
|
||||
p_org = p - 1;
|
||||
value_type = read_uint8(p);
|
||||
if (is_byte_a_type(value_type)) {
|
||||
/* If the first byte is one of these special values:
|
||||
|
@ -4845,7 +4846,7 @@ re_scan:
|
|||
* to new extended opcode so that interpreter can resolve
|
||||
* the block quickly.
|
||||
*/
|
||||
*(p - 2) = EXT_OP_BLOCK + (opcode - WASM_OP_BLOCK);
|
||||
*p_org = EXT_OP_BLOCK + (opcode - WASM_OP_BLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -5754,12 +5755,10 @@ re_scan:
|
|||
PUSH_TYPE(global_type);
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
|
||||
if (global_type == VALUE_TYPE_I64
|
||||
|| global_type == VALUE_TYPE_F64) {
|
||||
*p_org = WASM_OP_GET_GLOBAL_64;
|
||||
}
|
||||
#endif
|
||||
#else /* else of WASM_ENABLE_FAST_INTERP */
|
||||
if (is_64bit_type(global_type)) {
|
||||
skip_label();
|
||||
|
@ -5799,7 +5798,6 @@ re_scan:
|
|||
POP_TYPE(global_type);
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
|
||||
if (is_64bit_type(global_type)) {
|
||||
*p_org = WASM_OP_SET_GLOBAL_64;
|
||||
}
|
||||
|
@ -5807,7 +5805,6 @@ re_scan:
|
|||
&& global_idx == module->aux_stack_top_global_index) {
|
||||
*p_org = WASM_OP_SET_GLOBAL_AUX_STACK;
|
||||
}
|
||||
#endif
|
||||
#else /* else of WASM_ENABLE_FAST_INTERP */
|
||||
if (is_64bit_type(global_type)) {
|
||||
skip_label();
|
||||
|
|
|
@ -45,7 +45,7 @@ set_error_buf_v(char *error_buf, uint32 error_buf_size, const char *format, ...)
|
|||
}
|
||||
|
||||
WASMModule *
|
||||
wasm_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size)
|
||||
wasm_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
return wasm_loader_load(buf, size,
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
|
@ -1522,6 +1522,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
|
|||
module->wasi_args.dir_list, module->wasi_args.dir_count,
|
||||
module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
|
||||
module->wasi_args.env, module->wasi_args.env_count,
|
||||
module->wasi_args.addr_pool, module->wasi_args.addr_count,
|
||||
module->wasi_args.argv, module->wasi_args.argc,
|
||||
module->wasi_args.stdio[0], module->wasi_args.stdio[1],
|
||||
module->wasi_args.stdio[2], error_buf, error_buf_size)) {
|
||||
|
@ -2503,7 +2504,8 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env)
|
|||
|
||||
/* release previous stack frames and create new ones */
|
||||
if (!bh_vector_destroy(module_inst->frames)
|
||||
|| !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame))) {
|
||||
|| !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame),
|
||||
false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -273,8 +273,7 @@ wasm_get_func_code_end(WASMFunctionInstance *func)
|
|||
}
|
||||
|
||||
WASMModule *
|
||||
wasm_load(const uint8 *buf, uint32 size, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
wasm_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size);
|
||||
|
||||
WASMModule *
|
||||
wasm_load_from_sections(WASMSection *section_list, char *error_buf,
|
||||
|
|
|
@ -224,6 +224,8 @@ on_rsp_byte_arrive(unsigned char ch, rsp_recv_context_t *ctx)
|
|||
if (ctx->size_in_phase == 2) {
|
||||
ctx->size_in_phase = 0;
|
||||
|
||||
bh_assert(ctx->receive_index >= 3);
|
||||
|
||||
if ((hex(ctx->receive_buffer[ctx->receive_index - 2]) << 4
|
||||
| hex(ctx->receive_buffer[ctx->receive_index - 1]))
|
||||
!= ctx->check_sum) {
|
||||
|
|
410
core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h
Normal file
410
core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h
Normal file
|
@ -0,0 +1,410 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _WASI_SOCKET_EXT_H_
|
||||
#define _WASI_SOCKET_EXT_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*Be a part of <wasi/api.h>*/
|
||||
|
||||
typedef enum {
|
||||
SOCKET_DGRAM = 0,
|
||||
SOCKET_STREAM,
|
||||
} __wasi_sock_type_t;
|
||||
|
||||
typedef uint16_t __wasi_ip_port_t;
|
||||
|
||||
typedef enum { IPv4 = 0, IPv6 } __wasi_addr_type_t;
|
||||
|
||||
/* n0.n1.n2.n3 */
|
||||
typedef struct __wasi_addr_ip4_t {
|
||||
uint8_t n0;
|
||||
uint8_t n1;
|
||||
uint8_t n2;
|
||||
uint8_t n3;
|
||||
} __wasi_addr_ip4_t;
|
||||
|
||||
typedef struct __wasi_addr_ip4_port_t {
|
||||
__wasi_addr_ip4_t addr;
|
||||
__wasi_ip_port_t port;
|
||||
} __wasi_addr_ip4_port_t;
|
||||
|
||||
typedef struct __wasi_addr_ip6_t {
|
||||
uint16_t n0;
|
||||
uint16_t n1;
|
||||
uint16_t n2;
|
||||
uint16_t n3;
|
||||
uint16_t h0;
|
||||
uint16_t h1;
|
||||
uint16_t h2;
|
||||
uint16_t h3;
|
||||
} __wasi_addr_ip6_t;
|
||||
|
||||
typedef struct __wasi_addr_ip6_port_t {
|
||||
__wasi_addr_ip6_t addr;
|
||||
__wasi_ip_port_t port;
|
||||
} __wasi_addr_ip6_port_t;
|
||||
|
||||
typedef struct __wasi_addr_t {
|
||||
__wasi_addr_type_t kind;
|
||||
union {
|
||||
__wasi_addr_ip4_port_t ip4;
|
||||
__wasi_addr_ip6_port_t ip6;
|
||||
} addr;
|
||||
} __wasi_addr_t;
|
||||
|
||||
typedef enum { INET4 = 0, INET6 } __wasi_address_family_t;
|
||||
|
||||
#ifdef __wasi__
|
||||
/**
|
||||
* Reimplement below POSIX APIs with __wasi_sock_XXX functions.
|
||||
*
|
||||
* Keep sync with
|
||||
* <sys/socket.h>
|
||||
* <sys/types.h>
|
||||
*/
|
||||
|
||||
int
|
||||
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
int
|
||||
bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
int
|
||||
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
int
|
||||
listen(int sockfd, int backlog);
|
||||
|
||||
int
|
||||
socket(int domain, int type, int protocol);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Accept a connection on a socket
|
||||
* Note: This is similar to `accept`
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_accept(int32_t arg0, int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_accept")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_accept(__wasi_fd_t fd, __wasi_fd_t *fd_new)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_accept(
|
||||
(int32_t)fd, (int32_t)fd_new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local address to which the socket is bound.
|
||||
*
|
||||
* Note: This is similar to `getsockname` in POSIX
|
||||
*
|
||||
* When successful, the contents of the output buffer consist of an IP address,
|
||||
* either IP4 or IP6.
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_addr_local(int32_t arg0, int32_t arg1,
|
||||
int32_t arg2)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_addr_local")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_addr_local(__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_local(
|
||||
(int32_t)fd, (int32_t)buf, (int32_t)buf_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remote address to which the socket is connected to.
|
||||
*
|
||||
* Note: This is similar to `getpeername` in POSIX
|
||||
*
|
||||
* When successful, the contents of the output buffer consist of an IP address,
|
||||
* either IP4 or IP6.
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_addr_remote(int32_t arg0, int32_t arg1,
|
||||
int32_t arg2)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_addr_remote")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_addr_remote(__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_remote(
|
||||
(int32_t)fd, (int32_t)buf, (int32_t)buf_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a hostname and a port to one or more IP addresses. Port is optional
|
||||
* and you can pass 0 (zero) in most cases, it is used a hint for protocol.
|
||||
*
|
||||
* Note: This is similar to `getaddrinfo` in POSIX
|
||||
*
|
||||
* When successful, the contents of the output buffer consist of a sequence of
|
||||
* IPv4 and/or IPv6 addresses. Each address entry consists of a addr_t object.
|
||||
*
|
||||
* This function fills the output buffer as much as possible, potentially
|
||||
* truncating the last address entry. It is advisable that the buffer is
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_addr_resolve(int32_t arg0, int32_t arg1,
|
||||
int32_t arg2, int32_t arg3,
|
||||
int32_t arg4)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("addr_resolve")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_addr_resolve(__wasi_fd_t fd, const char *host, __wasi_ip_port_t port,
|
||||
uint8_t *buf, __wasi_size_t size)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_addr_resolve(
|
||||
(int32_t)fd, (int32_t)host, (int32_t)port, (int32_t)buf, (int32_t)size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind a socket
|
||||
* Note: This is similar to `bind` in POSIX using PF_INET
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_bind(int32_t arg0, int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_bind")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_bind(__wasi_fd_t fd, __wasi_addr_t *addr)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_bind(
|
||||
(int32_t)fd, (int32_t)addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a socket (this is an alias for `fd_close`)
|
||||
* Note: This is similar to `close` in POSIX.
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_close(int32_t arg0)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_close")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_close(__wasi_fd_t fd)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_close(
|
||||
(int32_t)fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a connection on a socket to the specified address
|
||||
* Note: This is similar to `connect` in POSIX
|
||||
*/
|
||||
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_connect(int32_t arg0, int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_connect")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_connect(__wasi_fd_t fd, __wasi_addr_t *addr)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_connect(
|
||||
(int32_t)fd, (int32_t)addr);
|
||||
}
|
||||
/**
|
||||
* Retrieve the size of the receive buffer
|
||||
* Note: This is similar to `getsockopt` in POSIX for SO_RCVBUF
|
||||
*/
|
||||
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_get_recv_buf_size(int32_t arg0,
|
||||
int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_get_recv_buf_size")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_get_recv_buf_size(__wasi_fd_t fd, __wasi_size_t *size)
|
||||
{
|
||||
return (__wasi_errno_t)
|
||||
__imported_wasi_snapshot_preview1_sock_get_recv_buf_size((int32_t)fd,
|
||||
(int32_t)size);
|
||||
}
|
||||
/**
|
||||
* Retrieve status of address reuse on a socket
|
||||
* Note: This is similar to `getsockopt` in POSIX for SO_REUSEADDR
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_get_reuse_addr(int32_t arg0,
|
||||
int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_get_reuse_addr")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_get_reuse_addr(__wasi_fd_t fd, uint8_t *reuse)
|
||||
{
|
||||
return (__wasi_errno_t)
|
||||
__imported_wasi_snapshot_preview1_sock_get_reuse_addr((int32_t)fd,
|
||||
(int32_t)reuse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve status of port reuse on a socket
|
||||
* Note: This is similar to `getsockopt` in POSIX for SO_REUSEPORT
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_get_reuse_port(int32_t arg0,
|
||||
int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_get_reuse_port")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_get_reuse_port(__wasi_fd_t fd, int8_t *reuse)
|
||||
{
|
||||
return (__wasi_errno_t)
|
||||
__imported_wasi_snapshot_preview1_sock_get_reuse_port((int32_t)fd,
|
||||
(int32_t)reuse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the size of the send buffer
|
||||
* Note: This is similar to `getsockopt` in POSIX for SO_SNDBUF
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_get_send_buf_size(int32_t arg0,
|
||||
int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_get_send_buf_size")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_get_send_buf_size(__wasi_fd_t fd, __wasi_size_t *size)
|
||||
{
|
||||
return (__wasi_errno_t)
|
||||
__imported_wasi_snapshot_preview1_sock_get_send_buf_size((int32_t)fd,
|
||||
(int32_t)size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for connections on a socket
|
||||
* Note: This is similar to `listen`
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_listen(int32_t arg0, int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_listen")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_listen(__wasi_fd_t fd, __wasi_size_t backlog)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_listen(
|
||||
(int32_t)fd, (int32_t)backlog);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a socket
|
||||
|
||||
* The first argument to this function is a handle to an
|
||||
* address pool. The address pool determines what actions can
|
||||
* be performed and at which addresses they can be performed to.
|
||||
|
||||
* The address pool cannot be re-assigned. You will need to close
|
||||
* the socket and open a new one to use a different address pool.
|
||||
|
||||
* Note: This is similar to `socket` in POSIX using PF_INET
|
||||
*/
|
||||
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_open(int32_t arg0, int32_t arg1,
|
||||
int32_t arg2, int32_t arg3)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_open")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_open(__wasi_fd_t fd, __wasi_address_family_t af,
|
||||
__wasi_sock_type_t socktype, __wasi_fd_t *sockfd)
|
||||
{
|
||||
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_open(
|
||||
(int32_t)fd, (int32_t)af, (int32_t)socktype, (int32_t)sockfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set size of receive buffer
|
||||
* Note: This is similar to `setsockopt` in POSIX for SO_RCVBUF
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_set_recv_buf_size(int32_t arg0,
|
||||
int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_set_recv_buf_size")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_set_recv_buf_size(__wasi_fd_t fd, __wasi_size_t size)
|
||||
{
|
||||
return (__wasi_errno_t)
|
||||
__imported_wasi_snapshot_preview1_sock_set_recv_buf_size((int32_t)fd,
|
||||
(int32_t)size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable address reuse on a socket
|
||||
* Note: This is similar to `setsockopt` in POSIX for SO_REUSEADDR
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_set_reuse_addr(int32_t arg0,
|
||||
int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_set_reuse_addr")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_set_reuse_addr(__wasi_fd_t fd, uint8_t reuse)
|
||||
{
|
||||
return (__wasi_errno_t)
|
||||
__imported_wasi_snapshot_preview1_sock_set_reuse_addr((int32_t)fd,
|
||||
(int32_t)reuse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable port reuse on a socket
|
||||
* Note: This is similar to `setsockopt` in POSIX for SO_REUSEPORT
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_set_reuse_port(int32_t arg0,
|
||||
int32_t arg1)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_set_reuse_port")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_set_reuse_port(__wasi_fd_t fd, uint8_t reuse)
|
||||
{
|
||||
return (__wasi_errno_t)
|
||||
__imported_wasi_snapshot_preview1_sock_set_reuse_port((int32_t)fd,
|
||||
(int32_t)reuse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set size of send buffer
|
||||
* Note: This is similar to `setsockopt` in POSIX for SO_SNDBUF
|
||||
*/
|
||||
int32_t
|
||||
__imported_wasi_snapshot_preview1_sock_set_send_buf_size(int32_t arg0)
|
||||
__attribute__((__import_module__("wasi_snapshot_preview1"),
|
||||
__import_name__("sock_set_send_buf_size")));
|
||||
|
||||
static inline __wasi_errno_t
|
||||
__wasi_sock_set_send_buf_size(__wasi_fd_t fd)
|
||||
{
|
||||
return (__wasi_errno_t)
|
||||
__imported_wasi_snapshot_preview1_sock_set_send_buf_size((int32_t)fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: modify recv() and send()
|
||||
* since don't want to re-compile the wasi-libc,
|
||||
* we tend to keep original implentations of recv() and send().
|
||||
*/
|
||||
#endif
|
9
core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
Normal file
9
core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required (VERSION 2.8...3.16)
|
||||
|
||||
project(socket_wasi_ext)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${CMAKE_CURRENT_LIST_DIR}/src/wasi/wasi_socket_ext.c)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/inc/)
|
180
core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c
Normal file
180
core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <wasi/api.h>
|
||||
#include <wasi_socket_ext.h>
|
||||
|
||||
#define HANDLE_ERROR(error) \
|
||||
if (error != __WASI_ERRNO_SUCCESS) { \
|
||||
errno = error; \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
/* addr_num and port are in network order */
|
||||
static void
|
||||
ipv4_addr_to_wasi_addr(uint32_t addr_num, uint16_t port, __wasi_addr_t *out)
|
||||
{
|
||||
out->kind = IPv4;
|
||||
out->addr.ip4.port = ntohs(port);
|
||||
out->addr.ip4.addr.n3 = (addr_num & 0xFF000000) >> 24;
|
||||
out->addr.ip4.addr.n2 = (addr_num & 0x00FF0000) >> 16;
|
||||
out->addr.ip4.addr.n1 = (addr_num & 0x0000FF00) >> 8;
|
||||
out->addr.ip4.addr.n0 = (addr_num & 0x000000FF);
|
||||
}
|
||||
|
||||
static __wasi_errno_t
|
||||
sockaddr_to_wasi_addr(const struct sockaddr *sock_addr, socklen_t addrlen,
|
||||
__wasi_addr_t *wasi_addr)
|
||||
{
|
||||
__wasi_errno_t ret = __WASI_ERRNO_SUCCESS;
|
||||
if (AF_INET == sock_addr->sa_family) {
|
||||
assert(sizeof(struct sockaddr_in) == addrlen);
|
||||
|
||||
ipv4_addr_to_wasi_addr(
|
||||
((struct sockaddr_in *)sock_addr)->sin_addr.s_addr,
|
||||
((struct sockaddr_in *)sock_addr)->sin_port, wasi_addr);
|
||||
}
|
||||
else if (AF_INET6 == sock_addr->sa_family) {
|
||||
// TODO: IPV6
|
||||
ret = __WASI_ERRNO_AFNOSUPPORT;
|
||||
}
|
||||
else {
|
||||
ret = __WASI_ERRNO_AFNOSUPPORT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __wasi_errno_t
|
||||
sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen)
|
||||
{
|
||||
__wasi_addr_t wasi_addr = { 0 };
|
||||
__wasi_errno_t error;
|
||||
|
||||
error =
|
||||
__wasi_sock_addr_remote(fd, (uint8_t *)&wasi_addr, sizeof(wasi_addr));
|
||||
if (__WASI_ERRNO_SUCCESS != error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (IPv4 == wasi_addr.kind) {
|
||||
struct sockaddr_in sock_addr_in = { 0 };
|
||||
|
||||
sock_addr_in.sin_family = AF_INET;
|
||||
sock_addr_in.sin_addr.s_addr = (wasi_addr.addr.ip4.addr.n3 << 24)
|
||||
| (wasi_addr.addr.ip4.addr.n2 << 16)
|
||||
| (wasi_addr.addr.ip4.addr.n1 << 8)
|
||||
| wasi_addr.addr.ip4.addr.n0;
|
||||
sock_addr_in.sin_port = htons(wasi_addr.addr.ip4.port);
|
||||
memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in));
|
||||
|
||||
*addrlen = sizeof(sock_addr_in);
|
||||
}
|
||||
else if (IPv6 == wasi_addr.kind) {
|
||||
// TODO: IPV6
|
||||
return __WASI_ERRNO_AFNOSUPPORT;
|
||||
}
|
||||
else {
|
||||
return __WASI_ERRNO_AFNOSUPPORT;
|
||||
}
|
||||
|
||||
return __WASI_ERRNO_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
__wasi_addr_t wasi_addr = { 0 };
|
||||
__wasi_fd_t new_sockfd;
|
||||
__wasi_errno_t error;
|
||||
|
||||
error = __wasi_sock_accept(sockfd, &new_sockfd);
|
||||
HANDLE_ERROR(error)
|
||||
|
||||
// error = sock_addr_remote(new_sockfd, addr, addrlen);
|
||||
// HANDLE_ERROR(error)
|
||||
*addrlen = 0;
|
||||
|
||||
return new_sockfd;
|
||||
}
|
||||
|
||||
int
|
||||
bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
__wasi_addr_t wasi_addr = { 0 };
|
||||
__wasi_errno_t error;
|
||||
|
||||
error = sockaddr_to_wasi_addr(addr, addrlen, &wasi_addr);
|
||||
HANDLE_ERROR(error)
|
||||
|
||||
error = __wasi_sock_bind(sockfd, &wasi_addr);
|
||||
HANDLE_ERROR(error)
|
||||
|
||||
return __WASI_ERRNO_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
__wasi_addr_t wasi_addr = { 0 };
|
||||
__wasi_errno_t error;
|
||||
|
||||
error = sockaddr_to_wasi_addr(addr, addrlen, &wasi_addr);
|
||||
HANDLE_ERROR(error)
|
||||
|
||||
error = __wasi_sock_connect(sockfd, &wasi_addr);
|
||||
HANDLE_ERROR(error)
|
||||
|
||||
return __WASI_ERRNO_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
listen(int sockfd, int backlog)
|
||||
{
|
||||
__wasi_errno_t error = __wasi_sock_listen(sockfd, backlog);
|
||||
HANDLE_ERROR(error)
|
||||
return __WASI_ERRNO_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
socket(int domain, int type, int protocol)
|
||||
{
|
||||
// the stub of address pool fd
|
||||
__wasi_fd_t poolfd = -1;
|
||||
__wasi_fd_t sockfd;
|
||||
__wasi_errno_t error;
|
||||
__wasi_address_family_t af;
|
||||
__wasi_sock_type_t socktype;
|
||||
|
||||
if (AF_INET == domain) {
|
||||
af = INET4;
|
||||
}
|
||||
else if (AF_INET6 == domain) {
|
||||
af = INET6;
|
||||
}
|
||||
else {
|
||||
return __WASI_ERRNO_NOPROTOOPT;
|
||||
}
|
||||
|
||||
if (SOCK_DGRAM == type) {
|
||||
socktype = SOCKET_DGRAM;
|
||||
}
|
||||
else if (SOCK_STREAM == type) {
|
||||
socktype = SOCKET_STREAM;
|
||||
}
|
||||
else {
|
||||
return __WASI_ERRNO_NOPROTOOPT;
|
||||
}
|
||||
|
||||
error = __wasi_sock_open(poolfd, af, socktype, &sockfd);
|
||||
HANDLE_ERROR(error)
|
||||
|
||||
return sockfd;
|
||||
}
|
66
core/iwasm/libraries/libc-uvwasi/LICENSE_LIBUV
Normal file
66
core/iwasm/libraries/libc-uvwasi/LICENSE_LIBUV
Normal file
|
@ -0,0 +1,66 @@
|
|||
libuv is licensed for use as follows:
|
||||
|
||||
====
|
||||
Copyright (c) 2015-present libuv project contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
====
|
||||
|
||||
This license applies to parts of libuv originating from the
|
||||
https://github.com/joyent/libuv repository:
|
||||
|
||||
====
|
||||
|
||||
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
|
||||
====
|
||||
|
||||
This license applies to all parts of libuv that are not externally
|
||||
maintained libraries.
|
||||
|
||||
The externally maintained libraries used by libuv are:
|
||||
|
||||
- tree.h (from FreeBSD), copyright Niels Provos. Two clause BSD license.
|
||||
|
||||
- inet_pton and inet_ntop implementations, contained in src/inet.c, are
|
||||
copyright the Internet Systems Consortium, Inc., and licensed under the ISC
|
||||
license.
|
||||
|
||||
- stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three
|
||||
clause BSD license.
|
||||
|
||||
- pthread-fixes.c, copyright Google Inc. and Sony Mobile Communications AB.
|
||||
Three clause BSD license.
|
21
core/iwasm/libraries/libc-uvwasi/LICENSE_UVWASI
Normal file
21
core/iwasm/libraries/libc-uvwasi/LICENSE_UVWASI
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 Colin Ihrig and Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -2,21 +2,22 @@
|
|||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (LIBC_WASI_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
set (UVWASI_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../deps/uvwasi)
|
||||
|
||||
set (LIBUV_VERSION v1.42.0)
|
||||
|
||||
add_definitions (-DWASM_ENABLE_LIBC_WASI=1 -DWASM_ENABLE_UVWASI=1)
|
||||
|
||||
include(FetchContent)
|
||||
## https://libuv.org
|
||||
|
||||
## libuv
|
||||
FetchContent_Declare(
|
||||
libuv
|
||||
GIT_REPOSITORY https://github.com/libuv/libuv.git
|
||||
GIT_TAG ${LIBUV_VERSION})
|
||||
|
||||
GIT_TAG ${LIBUV_VERSION}
|
||||
)
|
||||
FetchContent_GetProperties(libuv)
|
||||
if(NOT libuv_POPULATED)
|
||||
message ("-- Fetching libuv ..")
|
||||
if (NOT libuv_POPULATED)
|
||||
message("-- Fetching libuv ..")
|
||||
FetchContent_Populate(libuv)
|
||||
include_directories("${libuv_SOURCE_DIR}/include")
|
||||
add_subdirectory(${libuv_SOURCE_DIR} ${libuv_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
|
@ -24,8 +25,20 @@ if(NOT libuv_POPULATED)
|
|||
set_target_properties(uv_a PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
endif()
|
||||
|
||||
include_directories(${UVWASI_DIR}/include)
|
||||
## uvwasi
|
||||
FetchContent_Declare(
|
||||
uvwasi
|
||||
GIT_REPOSITORY https://github.com/nodejs/uvwasi.git
|
||||
GIT_TAG main
|
||||
)
|
||||
FetchContent_GetProperties(uvwasi)
|
||||
if (NOT uvwasi_POPULATED)
|
||||
message("-- Fetching uvwasi ..")
|
||||
FetchContent_Populate(uvwasi)
|
||||
include_directories("${uvwasi_SOURCE_DIR}/include")
|
||||
add_subdirectory(${uvwasi_SOURCE_DIR} ${uvwasi_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
file (GLOB_RECURSE source_all ${LIBC_WASI_DIR}/*.c ${UVWASI_DIR}/src/*.c)
|
||||
file (GLOB_RECURSE source_all ${LIBC_WASI_DIR}/*.c ${uvwasi_SOURCE_DIR}/src/*.c)
|
||||
|
||||
set (LIBC_WASI_SOURCE ${source_all})
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef struct WASIContext {
|
|||
struct fd_table *curfds;
|
||||
struct fd_prestats *prestats;
|
||||
struct argv_environ_values *argv_environ;
|
||||
struct addr_pool *addr_pool;
|
||||
char *argv_buf;
|
||||
char **argv_list;
|
||||
char *env_buf;
|
||||
|
@ -83,6 +84,14 @@ wasi_ctx_get_prestats(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
|
|||
return wasi_ctx->prestats;
|
||||
}
|
||||
|
||||
static inline struct addr_pool *
|
||||
wasi_ctx_get_addr_pool(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
|
||||
{
|
||||
if (!wasi_ctx)
|
||||
return NULL;
|
||||
return wasi_ctx->addr_pool;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
|
||||
{
|
||||
|
@ -987,112 +996,277 @@ wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len)
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
|
||||
uint32 ri_data_len, wasi_riflags_t ri_flags,
|
||||
uint32 *ro_datalen_app, wasi_roflags_t *ro_flags)
|
||||
wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fd_t *fd_new)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = NULL;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return __WASI_EACCES;
|
||||
|
||||
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
|
||||
return wasi_ssp_sock_accept(curfds, fd, fd_new);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *buf,
|
||||
wasi_size_t buf_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = NULL;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return __WASI_EACCES;
|
||||
|
||||
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
|
||||
return wasi_ssp_sock_addr_local(curfds, fd, buf, buf_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *buf,
|
||||
wasi_size_t buf_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = NULL;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return __WASI_EACCES;
|
||||
|
||||
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
|
||||
return wasi_ssp_sock_addr_remote(curfds, fd, buf, buf_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_addr_resolve(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *host,
|
||||
wasi_ip_port_t port, uint8 *buf, wasi_size_t size)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_bind(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = NULL;
|
||||
struct addr_pool *addr_pool = NULL;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return __WASI_EACCES;
|
||||
|
||||
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
|
||||
|
||||
return wasi_ssp_sock_bind(curfds, addr_pool, fd, addr);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_close(wasm_exec_env_t exec_env, wasi_fd_t fd)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_connect(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = NULL;
|
||||
struct addr_pool *addr_pool = NULL;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return __WASI_EACCES;
|
||||
|
||||
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
|
||||
|
||||
return wasi_ssp_sock_connect(curfds, addr_pool, fd, addr);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_get_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_size_t *size)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_get_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *reuse)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_get_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *reuse)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_get_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_size_t *size)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_listen(wasm_exec_env_t exec_env, wasi_fd_t fd, uint32 backlog)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = NULL;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return __WASI_EACCES;
|
||||
|
||||
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
|
||||
return wasi_ssp_sock_listen(curfds, fd, backlog);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_open(wasm_exec_env_t exec_env, wasi_fd_t poolfd,
|
||||
wasi_address_family_t af, wasi_sock_type_t socktype,
|
||||
wasi_fd_t *sockfd)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = NULL;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return __WASI_EACCES;
|
||||
|
||||
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
|
||||
return wasi_ssp_sock_open(curfds, poolfd, af, socktype, sockfd);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_set_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_size_t size)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_set_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 reuse)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_set_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 reuse)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_set_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_size_t size)
|
||||
{
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
|
||||
uint32 ri_data_len, wasi_riflags_t ri_flags, uint32 *ro_data_len,
|
||||
wasi_roflags_t *ro_flags)
|
||||
{
|
||||
/**
|
||||
* ri_data_len is the length of a list of iovec_app_t, which head is
|
||||
* ri_data. ro_data_len is the number of bytes received
|
||||
**/
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
wasi_iovec_t *iovec, *iovec_begin;
|
||||
uint64 total_size;
|
||||
size_t ro_datalen;
|
||||
uint32 i;
|
||||
wasi_errno_t err;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return (wasi_errno_t)-1;
|
||||
return __WASI_EINVAL;
|
||||
|
||||
total_size = sizeof(iovec_app_t) * (uint64)ri_data_len;
|
||||
if (!validate_native_addr(ro_datalen_app, (uint32)sizeof(uint32))
|
||||
if (!validate_native_addr(ro_data_len, (uint32)sizeof(uint32))
|
||||
|| !validate_native_addr(ro_flags, (uint32)sizeof(wasi_roflags_t))
|
||||
|| total_size >= UINT32_MAX
|
||||
|| !validate_native_addr(ri_data, (uint32)total_size))
|
||||
return (wasi_errno_t)-1;
|
||||
return __WASI_EINVAL;
|
||||
|
||||
total_size = sizeof(wasi_iovec_t) * (uint64)ri_data_len;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
|
||||
return (wasi_errno_t)-1;
|
||||
/* recv ri_data one by one */
|
||||
*ro_data_len = 0;
|
||||
for (i = 0; i < ri_data_len; ri_data++, i++) {
|
||||
void *buf;
|
||||
size_t bytes_recv;
|
||||
|
||||
iovec = iovec_begin;
|
||||
|
||||
for (i = 0; i < ri_data_len; i++, ri_data++, iovec++) {
|
||||
if (!validate_app_addr(ri_data->buf_offset, ri_data->buf_len)) {
|
||||
err = (wasi_errno_t)-1;
|
||||
goto fail;
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
iovec->buf = (void *)addr_app_to_native(ri_data->buf_offset);
|
||||
iovec->buf_len = ri_data->buf_len;
|
||||
|
||||
buf = (void *)addr_app_to_native(ri_data->buf_offset);
|
||||
err = wasmtime_ssp_sock_recv(curfds, sock, buf, ri_data->buf_len,
|
||||
&bytes_recv);
|
||||
if (err != __WASI_ESUCCESS) {
|
||||
return err;
|
||||
}
|
||||
*ro_data_len += bytes_recv;
|
||||
}
|
||||
|
||||
err = wasmtime_ssp_sock_recv(curfds, sock, iovec_begin, ri_data_len,
|
||||
ri_flags, &ro_datalen, ro_flags);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
*(uint32 *)ro_datalen_app = (uint32)ro_datalen;
|
||||
|
||||
/* success */
|
||||
err = 0;
|
||||
|
||||
fail:
|
||||
wasm_runtime_free(iovec_begin);
|
||||
return err;
|
||||
*ro_flags = ri_flags;
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
|
||||
const iovec_app_t *si_data, uint32 si_data_len,
|
||||
wasi_siflags_t si_flags, uint32 *so_datalen_app)
|
||||
wasi_siflags_t si_flags, uint32 *so_data_len)
|
||||
{
|
||||
/**
|
||||
* si_data_len is the length of a list of iovec_app_t, which head is
|
||||
* si_data. so_data_len is the number of bytes sent
|
||||
**/
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
wasi_ciovec_t *ciovec, *ciovec_begin;
|
||||
uint64 total_size;
|
||||
size_t so_datalen;
|
||||
uint32 i;
|
||||
wasi_errno_t err;
|
||||
|
||||
if (!wasi_ctx)
|
||||
return (wasi_errno_t)-1;
|
||||
return __WASI_EINVAL;
|
||||
|
||||
total_size = sizeof(iovec_app_t) * (uint64)si_data_len;
|
||||
if (!validate_native_addr(so_datalen_app, sizeof(uint32))
|
||||
if (!validate_native_addr(so_data_len, sizeof(uint32))
|
||||
|| total_size >= UINT32_MAX
|
||||
|| !validate_native_addr((void *)si_data, (uint32)total_size))
|
||||
return (wasi_errno_t)-1;
|
||||
return __WASI_EINVAL;
|
||||
|
||||
total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
|
||||
return (wasi_errno_t)-1;
|
||||
/* send si_data one by one */
|
||||
*so_data_len = 0;
|
||||
for (i = 0; i < si_data_len; i++, si_data++) {
|
||||
void *buf;
|
||||
size_t bytes_sent;
|
||||
|
||||
ciovec = ciovec_begin;
|
||||
|
||||
for (i = 0; i < si_data_len; i++, si_data++, ciovec++) {
|
||||
if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) {
|
||||
err = (wasi_errno_t)-1;
|
||||
goto fail;
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
ciovec->buf = (char *)addr_app_to_native(si_data->buf_offset);
|
||||
ciovec->buf_len = si_data->buf_len;
|
||||
|
||||
buf = (void *)addr_app_to_native(si_data->buf_offset);
|
||||
err = wasmtime_ssp_sock_send(curfds, sock, buf, si_data->buf_len,
|
||||
&bytes_sent);
|
||||
if (err != __WASI_ESUCCESS) {
|
||||
return err;
|
||||
}
|
||||
*so_data_len += bytes_sent;
|
||||
}
|
||||
|
||||
err = wasmtime_ssp_sock_send(curfds, sock, ciovec_begin, si_data_len,
|
||||
si_flags, &so_datalen);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
*so_datalen_app = (uint32)so_datalen;
|
||||
|
||||
/* success */
|
||||
err = 0;
|
||||
|
||||
fail:
|
||||
wasm_runtime_free(ciovec_begin);
|
||||
return err;
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
|
@ -1103,9 +1277,9 @@ wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
|
|||
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||
|
||||
if (!wasi_ctx)
|
||||
return (wasi_errno_t)-1;
|
||||
return __WASI_EINVAL;
|
||||
|
||||
return wasmtime_ssp_sock_shutdown(curfds, sock, how);
|
||||
return wasmtime_ssp_sock_shutdown(curfds, sock);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
|
@ -1161,8 +1335,25 @@ static NativeSymbol native_symbols_libc_wasi[] = {
|
|||
REG_NATIVE_FUNC(proc_exit, "(i)"),
|
||||
REG_NATIVE_FUNC(proc_raise, "(i)i"),
|
||||
REG_NATIVE_FUNC(random_get, "(*~)i"),
|
||||
REG_NATIVE_FUNC(sock_accept, "(i*)i"),
|
||||
REG_NATIVE_FUNC(sock_addr_local, "(i*i)i"),
|
||||
REG_NATIVE_FUNC(sock_addr_remote, "(i*i)i"),
|
||||
REG_NATIVE_FUNC(sock_addr_resolve, "(i*i*i)i"),
|
||||
REG_NATIVE_FUNC(sock_bind, "(i*)i"),
|
||||
REG_NATIVE_FUNC(sock_close, "(i)i"),
|
||||
REG_NATIVE_FUNC(sock_connect, "(i*)i"),
|
||||
REG_NATIVE_FUNC(sock_get_recv_buf_size, "(i*)i"),
|
||||
REG_NATIVE_FUNC(sock_get_reuse_addr, "(i*)i"),
|
||||
REG_NATIVE_FUNC(sock_get_reuse_port, "(i*)i"),
|
||||
REG_NATIVE_FUNC(sock_get_send_buf_size, "(i*)i"),
|
||||
REG_NATIVE_FUNC(sock_listen, "(ii)i"),
|
||||
REG_NATIVE_FUNC(sock_open, "(iii*)i"),
|
||||
REG_NATIVE_FUNC(sock_recv, "(i*ii**)i"),
|
||||
REG_NATIVE_FUNC(sock_send, "(i*ii*)i"),
|
||||
REG_NATIVE_FUNC(sock_set_recv_buf_size, "(ii)i"),
|
||||
REG_NATIVE_FUNC(sock_set_reuse_addr, "(ii)i"),
|
||||
REG_NATIVE_FUNC(sock_set_reuse_port, "(ii)i"),
|
||||
REG_NATIVE_FUNC(sock_set_send_buf_size, "(ii)i"),
|
||||
REG_NATIVE_FUNC(sock_shutdown, "(ii)i"),
|
||||
REG_NATIVE_FUNC(sched_yield, "()i"),
|
||||
};
|
||||
|
|
|
@ -13,38 +13,43 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef __wasi_errno_t wasi_errno_t;
|
||||
typedef __wasi_fd_t wasi_fd_t;
|
||||
typedef __wasi_clockid_t wasi_clockid_t;
|
||||
typedef __wasi_timestamp_t wasi_timestamp_t;
|
||||
typedef __wasi_prestat_t wasi_prestat_t;
|
||||
typedef __wasi_iovec_t wasi_iovec_t;
|
||||
typedef __wasi_ciovec_t wasi_ciovec_t;
|
||||
typedef __wasi_filetype_t wasi_filetype_t;
|
||||
typedef __wasi_filesize_t wasi_filesize_t;
|
||||
typedef __wasi_filedelta_t wasi_filedelta_t;
|
||||
typedef __wasi_whence_t wasi_whence_t;
|
||||
typedef __wasi_fdstat_t wasi_fdstat_t;
|
||||
typedef __wasi_fdflags_t wasi_fdflags_t;
|
||||
typedef __wasi_rights_t wasi_rights_t;
|
||||
typedef __wasi_address_family_t wasi_address_family_t;
|
||||
typedef __wasi_addr_t wasi_addr_t;
|
||||
typedef __wasi_advice_t wasi_advice_t;
|
||||
typedef __wasi_lookupflags_t wasi_lookupflags_t;
|
||||
typedef __wasi_oflags_t wasi_oflags_t;
|
||||
typedef __wasi_ciovec_t wasi_ciovec_t;
|
||||
typedef __wasi_clockid_t wasi_clockid_t;
|
||||
typedef __wasi_dircookie_t wasi_dircookie_t;
|
||||
typedef __wasi_filestat_t wasi_filestat_t;
|
||||
typedef __wasi_fstflags_t wasi_fstflags_t;
|
||||
typedef __wasi_subscription_t wasi_subscription_t;
|
||||
typedef __wasi_errno_t wasi_errno_t;
|
||||
typedef __wasi_event_t wasi_event_t;
|
||||
typedef __wasi_exitcode_t wasi_exitcode_t;
|
||||
typedef __wasi_signal_t wasi_signal_t;
|
||||
typedef __wasi_riflags_t wasi_riflags_t;
|
||||
typedef __wasi_roflags_t wasi_roflags_t;
|
||||
typedef __wasi_siflags_t wasi_siflags_t;
|
||||
typedef __wasi_sdflags_t wasi_sdflags_t;
|
||||
typedef __wasi_fdflags_t wasi_fdflags_t;
|
||||
typedef __wasi_fdstat_t wasi_fdstat_t;
|
||||
typedef __wasi_fd_t wasi_fd_t;
|
||||
typedef __wasi_filedelta_t wasi_filedelta_t;
|
||||
typedef __wasi_filesize_t wasi_filesize_t;
|
||||
typedef __wasi_filestat_t wasi_filestat_t;
|
||||
typedef __wasi_filetype_t wasi_filetype_t;
|
||||
typedef __wasi_fstflags_t wasi_fstflags_t;
|
||||
typedef __wasi_iovec_t wasi_iovec_t;
|
||||
typedef __wasi_ip_port_t wasi_ip_port_t;
|
||||
typedef __wasi_lookupflags_t wasi_lookupflags_t;
|
||||
typedef __wasi_oflags_t wasi_oflags_t;
|
||||
typedef __wasi_preopentype_t wasi_preopentype_t;
|
||||
typedef __wasi_prestat_t wasi_prestat_t;
|
||||
typedef __wasi_riflags_t wasi_riflags_t;
|
||||
typedef __wasi_rights_t wasi_rights_t;
|
||||
typedef __wasi_roflags_t wasi_roflags_t;
|
||||
typedef __wasi_sdflags_t wasi_sdflags_t;
|
||||
typedef __wasi_siflags_t wasi_siflags_t;
|
||||
typedef __wasi_signal_t wasi_signal_t;
|
||||
typedef __wasi_size_t wasi_size_t;
|
||||
typedef __wasi_sock_type_t wasi_sock_type_t;
|
||||
typedef __wasi_subscription_t wasi_subscription_t;
|
||||
typedef __wasi_timestamp_t wasi_timestamp_t;
|
||||
typedef __wasi_whence_t wasi_whence_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _LIBC_WASI_WRAPPER_H */
|
||||
#endif /* end of _LIBC_WASI_WRAPPER_H */
|
|
@ -49,6 +49,9 @@ _Static_assert(_Alignof(int64_t) == 8, "non-wasi data layout");
|
|||
_Static_assert(_Alignof(uint64_t) == 8, "non-wasi data layout");
|
||||
#endif
|
||||
|
||||
typedef uint32_t __wasi_size_t;
|
||||
_Static_assert(_Alignof(__wasi_size_t) == 4, "non-wasi data layout");
|
||||
|
||||
typedef uint8_t __wasi_advice_t;
|
||||
#define __WASI_ADVICE_NORMAL (0)
|
||||
#define __WASI_ADVICE_SEQUENTIAL (1)
|
||||
|
@ -211,35 +214,44 @@ typedef uint64_t __wasi_rights_t;
|
|||
* Observe that WASI defines rights in the plural form
|
||||
* TODO: refactor to use RIGHTS instead of RIGHT
|
||||
*/
|
||||
#define __WASI_RIGHT_FD_DATASYNC ((__wasi_rights_t)(1 << 0))
|
||||
#define __WASI_RIGHT_FD_READ ((__wasi_rights_t)(1 << 1))
|
||||
#define __WASI_RIGHT_FD_SEEK ((__wasi_rights_t)(1 << 2))
|
||||
#define __WASI_RIGHT_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(1 << 3))
|
||||
#define __WASI_RIGHT_FD_SYNC ((__wasi_rights_t)(1 << 4))
|
||||
#define __WASI_RIGHT_FD_TELL ((__wasi_rights_t)(1 << 5))
|
||||
#define __WASI_RIGHT_FD_WRITE ((__wasi_rights_t)(1 << 6))
|
||||
#define __WASI_RIGHT_FD_ADVISE ((__wasi_rights_t)(1 << 7))
|
||||
#define __WASI_RIGHT_FD_ALLOCATE ((__wasi_rights_t)(1 << 8))
|
||||
#define __WASI_RIGHT_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(1 << 9))
|
||||
#define __WASI_RIGHT_PATH_CREATE_FILE ((__wasi_rights_t)(1 << 10))
|
||||
#define __WASI_RIGHT_PATH_LINK_SOURCE ((__wasi_rights_t)(1 << 11))
|
||||
#define __WASI_RIGHT_PATH_LINK_TARGET ((__wasi_rights_t)(1 << 12))
|
||||
#define __WASI_RIGHT_PATH_OPEN ((__wasi_rights_t)(1 << 13))
|
||||
#define __WASI_RIGHT_FD_READDIR ((__wasi_rights_t)(1 << 14))
|
||||
#define __WASI_RIGHT_PATH_READLINK ((__wasi_rights_t)(1 << 15))
|
||||
#define __WASI_RIGHT_PATH_RENAME_SOURCE ((__wasi_rights_t)(1 << 16))
|
||||
#define __WASI_RIGHT_PATH_RENAME_TARGET ((__wasi_rights_t)(1 << 17))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_GET ((__wasi_rights_t)(1 << 18))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 19))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 20))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_GET ((__wasi_rights_t)(1 << 21))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 22))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 23))
|
||||
#define __WASI_RIGHT_PATH_SYMLINK ((__wasi_rights_t)(1 << 24))
|
||||
#define __WASI_RIGHT_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(1 << 25))
|
||||
#define __WASI_RIGHT_PATH_UNLINK_FILE ((__wasi_rights_t)(1 << 26))
|
||||
#define __WASI_RIGHT_POLL_FD_READWRITE ((__wasi_rights_t)(1 << 27))
|
||||
#define __WASI_RIGHT_SOCK_SHUTDOWN ((__wasi_rights_t)(1 << 28))
|
||||
#define __WASI_RIGHT_FD_DATASYNC ((__wasi_rights_t)(UINT64_C(1) << 0))
|
||||
#define __WASI_RIGHT_FD_READ ((__wasi_rights_t)(UINT64_C(1) << 1))
|
||||
#define __WASI_RIGHT_FD_SEEK ((__wasi_rights_t)(UINT64_C(1) << 2))
|
||||
#define __WASI_RIGHT_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(UINT64_C(1) << 3))
|
||||
#define __WASI_RIGHT_FD_SYNC ((__wasi_rights_t)(UINT64_C(1) << 4))
|
||||
#define __WASI_RIGHT_FD_TELL ((__wasi_rights_t)(UINT64_C(1) << 5))
|
||||
#define __WASI_RIGHT_FD_WRITE ((__wasi_rights_t)(UINT64_C(1) << 6))
|
||||
#define __WASI_RIGHT_FD_ADVISE ((__wasi_rights_t)(UINT64_C(1) << 7))
|
||||
#define __WASI_RIGHT_FD_ALLOCATE ((__wasi_rights_t)(UINT64_C(1) << 8))
|
||||
#define __WASI_RIGHT_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(UINT64_C(1) << 9))
|
||||
#define __WASI_RIGHT_PATH_CREATE_FILE ((__wasi_rights_t)(UINT64_C(1) << 10))
|
||||
#define __WASI_RIGHT_PATH_LINK_SOURCE ((__wasi_rights_t)(UINT64_C(1) << 11))
|
||||
#define __WASI_RIGHT_PATH_LINK_TARGET ((__wasi_rights_t)(UINT64_C(1) << 12))
|
||||
#define __WASI_RIGHT_PATH_OPEN ((__wasi_rights_t)(UINT64_C(1) << 13))
|
||||
#define __WASI_RIGHT_FD_READDIR ((__wasi_rights_t)(UINT64_C(1) << 14))
|
||||
#define __WASI_RIGHT_PATH_READLINK ((__wasi_rights_t)(UINT64_C(1) << 15))
|
||||
#define __WASI_RIGHT_PATH_RENAME_SOURCE ((__wasi_rights_t)(UINT64_C(1) << 16))
|
||||
#define __WASI_RIGHT_PATH_RENAME_TARGET ((__wasi_rights_t)(UINT64_C(1) << 17))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_GET ((__wasi_rights_t)(UINT64_C(1) << 18))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(UINT64_C(1) << 19))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(UINT64_C(1) << 20))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_GET ((__wasi_rights_t)(UINT64_C(1) << 21))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(UINT64_C(1) << 22))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(UINT64_C(1) << 23))
|
||||
#define __WASI_RIGHT_PATH_SYMLINK ((__wasi_rights_t)(UINT64_C(1) << 24))
|
||||
#define __WASI_RIGHT_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(UINT64_C(1) << 25))
|
||||
#define __WASI_RIGHT_PATH_UNLINK_FILE ((__wasi_rights_t)(UINT64_C(1) << 26))
|
||||
#define __WASI_RIGHT_POLL_FD_READWRITE ((__wasi_rights_t)(UINT64_C(1) << 27))
|
||||
#define __WASI_RIGHT_SOCK_CONNECT ((__wasi_rights_t)(UINT64_C(1) << 28))
|
||||
#define __WASI_RIGHT_SOCK_LISTEN ((__wasi_rights_t)(UINT64_C(1) << 29))
|
||||
#define __WASI_RIGHT_SOCK_BIND ((__wasi_rights_t)(UINT64_C(1) << 30))
|
||||
#define __WASI_RIGHT_SOCK_ACCEPT ((__wasi_rights_t)(UINT64_C(1) << 31))
|
||||
#define __WASI_RIGHT_SOCK_RECV ((__wasi_rights_t)(UINT64_C(1) << 32))
|
||||
#define __WASI_RIGHT_SOCK_SEND ((__wasi_rights_t)(UINT64_C(1) << 33))
|
||||
#define __WASI_RIGHT_SOCK_ADDR_LOCAL ((__wasi_rights_t)(UINT64_C(1) << 34))
|
||||
#define __WASI_RIGHT_SOCK_ADDR_REMOTE ((__wasi_rights_t)(UINT64_C(1) << 35))
|
||||
#define __WASI_RIGHT_SOCK_RECV_FROM ((__wasi_rights_t)(UINT64_C(1) << 36))
|
||||
#define __WASI_RIGHT_SOCK_SEND_TO ((__wasi_rights_t)(UINT64_C(1) << 37))
|
||||
|
||||
typedef uint16_t __wasi_roflags_t;
|
||||
#define __WASI_SOCK_RECV_DATA_TRUNCATED (0x0001)
|
||||
|
@ -301,6 +313,7 @@ typedef uint8_t __wasi_preopentype_t;
|
|||
struct fd_table;
|
||||
struct fd_prestats;
|
||||
struct argv_environ_values;
|
||||
struct addr_pool;
|
||||
|
||||
typedef struct __wasi_dirent_t {
|
||||
__wasi_dircookie_t d_next;
|
||||
|
@ -536,6 +549,55 @@ _Static_assert(_Alignof(__wasi_subscription_t) == 8, "witx calculated align");
|
|||
_Static_assert(offsetof(__wasi_subscription_t, userdata) == 0, "witx calculated offset");
|
||||
_Static_assert(offsetof(__wasi_subscription_t, u) == 8, "witx calculated offset");
|
||||
|
||||
/* keep syncing with wasi_socket_ext.h */
|
||||
typedef enum {
|
||||
SOCKET_DGRAM = 0,
|
||||
SOCKET_STREAM,
|
||||
} __wasi_sock_type_t;
|
||||
|
||||
typedef uint16_t __wasi_ip_port_t;
|
||||
|
||||
typedef enum { IPv4 = 0, IPv6 } __wasi_addr_type_t;
|
||||
|
||||
/* n0.n1.n2.n3 */
|
||||
typedef struct __wasi_addr_ip4_t {
|
||||
uint8_t n0;
|
||||
uint8_t n1;
|
||||
uint8_t n2;
|
||||
uint8_t n3;
|
||||
} __wasi_addr_ip4_t;
|
||||
|
||||
typedef struct __wasi_addr_ip4_port_t {
|
||||
__wasi_addr_ip4_t addr;
|
||||
__wasi_ip_port_t port;
|
||||
} __wasi_addr_ip4_port_t;
|
||||
|
||||
typedef struct __wasi_addr_ip6_t {
|
||||
uint16_t n0;
|
||||
uint16_t n1;
|
||||
uint16_t n2;
|
||||
uint16_t n3;
|
||||
uint16_t h0;
|
||||
uint16_t h1;
|
||||
uint16_t h2;
|
||||
uint16_t h3;
|
||||
} __wasi_addr_ip6_t;
|
||||
|
||||
typedef struct __wasi_addr_ip6_port_t {
|
||||
__wasi_addr_ip6_t addr;
|
||||
__wasi_ip_port_t port;
|
||||
} __wasi_addr_ip6_port_t;
|
||||
|
||||
typedef struct __wasi_addr_t {
|
||||
__wasi_addr_type_t kind;
|
||||
union {
|
||||
__wasi_addr_ip4_port_t ip4;
|
||||
__wasi_addr_ip6_port_t ip6;
|
||||
} addr;
|
||||
} __wasi_addr_t;
|
||||
|
||||
typedef enum { INET4 = 0, INET6 } __wasi_address_family_t;
|
||||
|
||||
#if defined(WASMTIME_SSP_WASI_API)
|
||||
#define WASMTIME_SSP_SYSCALL_NAME(name) \
|
||||
asm("__wasi_" #name)
|
||||
|
@ -920,16 +982,71 @@ __wasi_errno_t wasmtime_ssp_random_get(
|
|||
size_t buf_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(random_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_accept(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd, __wasi_fd_t *fd_new
|
||||
) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_addr_local(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len
|
||||
) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_addr_remote(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len
|
||||
) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_open(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype,
|
||||
__wasi_fd_t *sockfd
|
||||
) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_bind(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds, struct addr_pool *addr_pool,
|
||||
#endif
|
||||
__wasi_fd_t fd, __wasi_addr_t *addr
|
||||
) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_connect(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds, struct addr_pool *addr_pool,
|
||||
#endif
|
||||
__wasi_fd_t fd, __wasi_addr_t *addr
|
||||
) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_listen(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd, __wasi_size_t backlog
|
||||
) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_sock_recv(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock,
|
||||
const __wasi_iovec_t *ri_data,
|
||||
size_t ri_data_len,
|
||||
__wasi_riflags_t ri_flags,
|
||||
size_t *ro_datalen,
|
||||
__wasi_roflags_t *ro_flags
|
||||
void *buf,
|
||||
size_t buf_len,
|
||||
size_t *recv_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(sock_recv) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_sock_send(
|
||||
|
@ -937,18 +1054,16 @@ __wasi_errno_t wasmtime_ssp_sock_send(
|
|||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock,
|
||||
const __wasi_ciovec_t *si_data,
|
||||
size_t si_data_len,
|
||||
__wasi_siflags_t si_flags,
|
||||
size_t *so_datalen
|
||||
const void *buf,
|
||||
size_t buf_len,
|
||||
size_t *sent_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(sock_send) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_sock_shutdown(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock,
|
||||
__wasi_sdflags_t how
|
||||
__wasi_fd_t sock
|
||||
) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_sched_yield(void)
|
||||
|
|
|
@ -60,6 +60,7 @@ static_assert(sizeof(struct iovec) == sizeof(__wasi_ciovec_t),
|
|||
static __thread struct fd_table *curfds;
|
||||
static __thread struct fd_prestats *prestats;
|
||||
static __thread struct argv_environ_values *argv_environ;
|
||||
static __thread struct addr_pool *addr_pool;
|
||||
#endif
|
||||
|
||||
// Converts a POSIX error code to a CloudABI error code.
|
||||
|
@ -2715,44 +2716,246 @@ wasmtime_ssp_random_get(void *buf, size_t nbyte)
|
|||
return 0;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_accept(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd, __wasi_fd_t *fd_new)
|
||||
{
|
||||
__wasi_filetype_t wasi_type;
|
||||
__wasi_rights_t max_base, max_inheriting;
|
||||
struct fd_object *fo;
|
||||
bh_socket_t new_sock;
|
||||
int ret;
|
||||
__wasi_errno_t error =
|
||||
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ACCEPT, 0);
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
ret = os_socket_accept(fd_number(fo), &new_sock, NULL, NULL);
|
||||
fd_object_release(fo);
|
||||
if (ret == BHT_ERROR)
|
||||
return convert_errno(errno);
|
||||
|
||||
error = fd_determine_type_rights(new_sock, &wasi_type, &max_base,
|
||||
&max_inheriting);
|
||||
if (error != __WASI_ESUCCESS) {
|
||||
os_socket_close(ret);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = fd_table_insert_fd(curfds, new_sock, wasi_type, max_base,
|
||||
max_inheriting, fd_new);
|
||||
if (error != __WASI_ESUCCESS) {
|
||||
os_socket_close(ret);
|
||||
return error;
|
||||
}
|
||||
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_addr_local(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd, uint8 *buf, __wasi_size_t buf_len)
|
||||
{
|
||||
struct fd_object *fo;
|
||||
__wasi_errno_t error =
|
||||
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_LOCAL, 0);
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
fd_object_release(fo);
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_addr_remote(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd, uint8 *buf, __wasi_size_t buf_len)
|
||||
{
|
||||
struct fd_object *fo;
|
||||
__wasi_errno_t error =
|
||||
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_REMOTE, 0);
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
fd_object_release(fo);
|
||||
return __WASI_ENOSYS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_bind(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds, struct addr_pool *addr_pool,
|
||||
#endif
|
||||
__wasi_fd_t fd, __wasi_addr_t *addr)
|
||||
{
|
||||
char buf[24] = { 0 };
|
||||
const char *format = "%u.%u.%u.%u";
|
||||
struct fd_object *fo;
|
||||
__wasi_errno_t error;
|
||||
int port = addr->addr.ip4.port;
|
||||
int ret;
|
||||
|
||||
snprintf(buf, 24, format, addr->addr.ip4.addr.n0, addr->addr.ip4.addr.n1,
|
||||
addr->addr.ip4.addr.n2, addr->addr.ip4.addr.n3);
|
||||
|
||||
if (!addr_pool_search(addr_pool, buf)) {
|
||||
return __WASI_EACCES;
|
||||
}
|
||||
|
||||
error = fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_BIND, 0);
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
ret = os_socket_bind(fd_number(fo), buf, &port);
|
||||
fd_object_release(fo);
|
||||
if (ret == BHT_ERROR) {
|
||||
return convert_errno(errno);
|
||||
}
|
||||
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_connect(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds, struct addr_pool *addr_pool,
|
||||
#endif
|
||||
__wasi_fd_t fd, __wasi_addr_t *addr)
|
||||
{
|
||||
char buf[24] = { 0 };
|
||||
const char *format = "%u.%u.%u.%u";
|
||||
struct fd_object *fo;
|
||||
__wasi_errno_t error;
|
||||
int ret;
|
||||
|
||||
snprintf(buf, 24, format, addr->addr.ip4.addr.n0, addr->addr.ip4.addr.n1,
|
||||
addr->addr.ip4.addr.n2, addr->addr.ip4.addr.n3);
|
||||
|
||||
if (!addr_pool_search(addr_pool, buf)) {
|
||||
return __WASI_EACCES;
|
||||
}
|
||||
|
||||
error = fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_BIND, 0);
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
ret = os_socket_connect(fd_number(fo), buf, addr->addr.ip4.port);
|
||||
fd_object_release(fo);
|
||||
if (ret == BHT_ERROR) {
|
||||
return convert_errno(errno);
|
||||
}
|
||||
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_listen(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd, __wasi_size_t backlog)
|
||||
{
|
||||
struct fd_object *fo;
|
||||
int ret;
|
||||
__wasi_errno_t error =
|
||||
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_LISTEN, 0);
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
ret = os_socket_listen(fd_number(fo), backlog);
|
||||
fd_object_release(fo);
|
||||
if (ret == BHT_ERROR) {
|
||||
return convert_errno(errno);
|
||||
}
|
||||
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
wasi_ssp_sock_open(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype,
|
||||
__wasi_fd_t *sockfd)
|
||||
{
|
||||
bh_socket_t sock;
|
||||
int tcp_or_udp = 0;
|
||||
int ret;
|
||||
__wasi_filetype_t wasi_type;
|
||||
__wasi_rights_t max_base, max_inheriting;
|
||||
__wasi_errno_t error;
|
||||
|
||||
(void)poolfd;
|
||||
|
||||
if (INET4 != af) {
|
||||
return __WASI_EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
tcp_or_udp = SOCKET_DGRAM == socktype ? 0 : 1;
|
||||
|
||||
ret = os_socket_create(&sock, tcp_or_udp);
|
||||
if (ret == BHT_ERROR) {
|
||||
return convert_errno(errno);
|
||||
}
|
||||
|
||||
error =
|
||||
fd_determine_type_rights(sock, &wasi_type, &max_base, &max_inheriting);
|
||||
if (error != __WASI_ESUCCESS) {
|
||||
os_socket_close(sock);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (SOCKET_DGRAM == socktype) {
|
||||
assert(wasi_type == __WASI_FILETYPE_SOCKET_DGRAM);
|
||||
}
|
||||
else {
|
||||
assert(wasi_type == __WASI_FILETYPE_SOCKET_STREAM);
|
||||
}
|
||||
|
||||
// TODO: base rights and inheriting rights ?
|
||||
error = fd_table_insert_fd(curfds, sock, wasi_type, max_base,
|
||||
max_inheriting, sockfd);
|
||||
if (error != __WASI_ESUCCESS) {
|
||||
os_socket_close(sock);
|
||||
return error;
|
||||
}
|
||||
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
wasmtime_ssp_sock_recv(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock, const __wasi_iovec_t *ri_data, size_t ri_data_len,
|
||||
__wasi_riflags_t ri_flags, size_t *ro_datalen, __wasi_roflags_t *ro_flags)
|
||||
__wasi_fd_t sock, void *buf, size_t buf_len, size_t *recv_len)
|
||||
{
|
||||
// Convert input to msghdr.
|
||||
struct msghdr hdr = {
|
||||
.msg_iov = (struct iovec *)ri_data,
|
||||
.msg_iovlen = ri_data_len,
|
||||
};
|
||||
int nflags = 0;
|
||||
if ((ri_flags & __WASI_SOCK_RECV_PEEK) != 0)
|
||||
nflags |= MSG_PEEK;
|
||||
if ((ri_flags & __WASI_SOCK_RECV_WAITALL) != 0)
|
||||
nflags |= MSG_WAITALL;
|
||||
|
||||
struct fd_object *fo;
|
||||
__wasi_errno_t error =
|
||||
fd_object_get(curfds, &fo, sock, __WASI_RIGHT_FD_READ, 0);
|
||||
__wasi_errno_t error;
|
||||
int ret;
|
||||
|
||||
error = fd_object_get(curfds, &fo, sock, __WASI_RIGHT_FD_READ, 0);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
ssize_t datalen = recvmsg(fd_number(fo), &hdr, nflags);
|
||||
ret = os_socket_recv(fd_number(fo), buf, buf_len);
|
||||
fd_object_release(fo);
|
||||
if (datalen < 0) {
|
||||
if (ret == BHT_ERROR) {
|
||||
return convert_errno(errno);
|
||||
}
|
||||
|
||||
// Convert msghdr to output.
|
||||
*ro_datalen = (size_t)datalen;
|
||||
*ro_flags = 0;
|
||||
if ((hdr.msg_flags & MSG_TRUNC) != 0)
|
||||
*ro_flags |= __WASI_SOCK_RECV_DATA_TRUNCATED;
|
||||
return 0;
|
||||
*recv_len = (size_t)ret;
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
|
@ -2760,34 +2963,25 @@ wasmtime_ssp_sock_send(
|
|||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock, const __wasi_ciovec_t *si_data, size_t si_data_len,
|
||||
__wasi_siflags_t si_flags, size_t *so_datalen) NO_LOCK_ANALYSIS
|
||||
__wasi_fd_t sock, const void *buf, size_t buf_len, size_t *sent_len)
|
||||
{
|
||||
// Convert input to msghdr.
|
||||
struct msghdr hdr = {
|
||||
.msg_iov = (struct iovec *)si_data,
|
||||
.msg_iovlen = si_data_len,
|
||||
};
|
||||
|
||||
// Attach file descriptors if present.
|
||||
__wasi_errno_t error;
|
||||
|
||||
// Send message.
|
||||
struct fd_object *fo;
|
||||
__wasi_errno_t error;
|
||||
int ret;
|
||||
|
||||
error = fd_object_get(curfds, &fo, sock, __WASI_RIGHT_FD_WRITE, 0);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
ssize_t len = sendmsg(fd_number(fo), &hdr, 0);
|
||||
fd_object_release(fo);
|
||||
if (len < 0) {
|
||||
error = convert_errno(errno);
|
||||
}
|
||||
else {
|
||||
*so_datalen = (size_t)len;
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
out:
|
||||
return error;
|
||||
ret = os_socket_send(fd_number(fo), buf, buf_len);
|
||||
fd_object_release(fo);
|
||||
if (ret == BHT_ERROR) {
|
||||
return convert_errno(errno);
|
||||
}
|
||||
|
||||
*sent_len = (size_t)ret;
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
|
@ -2795,34 +2989,22 @@ wasmtime_ssp_sock_shutdown(
|
|||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock, __wasi_sdflags_t how)
|
||||
__wasi_fd_t sock)
|
||||
{
|
||||
int nhow;
|
||||
switch (how) {
|
||||
case __WASI_SHUT_RD:
|
||||
nhow = SHUT_RD;
|
||||
break;
|
||||
case __WASI_SHUT_WR:
|
||||
nhow = SHUT_WR;
|
||||
break;
|
||||
case __WASI_SHUT_RD | __WASI_SHUT_WR:
|
||||
nhow = SHUT_RDWR;
|
||||
break;
|
||||
default:
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
|
||||
struct fd_object *fo;
|
||||
__wasi_errno_t error =
|
||||
fd_object_get(curfds, &fo, sock, __WASI_RIGHT_SOCK_SHUTDOWN, 0);
|
||||
__wasi_errno_t error;
|
||||
int ret;
|
||||
|
||||
error = fd_object_get(curfds, &fo, sock, 0, 0);
|
||||
if (error != 0)
|
||||
return error;
|
||||
|
||||
int ret = shutdown(fd_number(fo), nhow);
|
||||
ret = os_socket_shutdown(fd_number(fo));
|
||||
fd_object_release(fo);
|
||||
if (ret < 0)
|
||||
if (ret == BHT_ERROR)
|
||||
return convert_errno(errno);
|
||||
return 0;
|
||||
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
|
@ -2943,3 +3125,88 @@ fd_prestats_destroy(struct fd_prestats *pt)
|
|||
wasm_runtime_free(pt->prestats);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
addr_pool_init(struct addr_pool *addr_pool)
|
||||
{
|
||||
addr_pool->next = NULL;
|
||||
addr_pool->addr = 0;
|
||||
addr_pool->mask = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
addr_pool_insert(struct addr_pool *addr_pool, const char *addr, uint8 mask)
|
||||
{
|
||||
struct addr_pool *cur = addr_pool;
|
||||
struct addr_pool *next;
|
||||
|
||||
if (!addr_pool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(next = wasm_runtime_malloc(sizeof(struct addr_pool)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
next->next = NULL;
|
||||
next->mask = mask;
|
||||
if (os_socket_inet_network(addr, &next->addr) != BHT_OK) {
|
||||
wasm_runtime_free(next);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* attach with */
|
||||
while (cur->next) {
|
||||
cur = cur->next;
|
||||
}
|
||||
cur->next = next;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
compare_address(const struct addr_pool *addr_pool_entry, const char *addr)
|
||||
{
|
||||
/* host order */
|
||||
uint32 target;
|
||||
uint32 address = addr_pool_entry->addr;
|
||||
/* 0.0.0.0 means any address */
|
||||
if (0 == address) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (os_socket_inet_network(addr, &target) != BHT_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 mask = addr_pool_entry->mask;
|
||||
uint32 first_address = address & mask;
|
||||
uint32 last_address = address | (~mask);
|
||||
return first_address <= target && target <= last_address;
|
||||
}
|
||||
|
||||
bool
|
||||
addr_pool_search(struct addr_pool *addr_pool, const char *addr)
|
||||
{
|
||||
struct addr_pool *cur = addr_pool->next;
|
||||
|
||||
while (cur) {
|
||||
if (compare_address(cur, addr))
|
||||
return true;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
addr_pool_destroy(struct addr_pool *addr_pool)
|
||||
{
|
||||
struct addr_pool *cur = addr_pool->next;
|
||||
|
||||
while (cur) {
|
||||
struct addr_pool *next = cur->next;
|
||||
wasm_runtime_free(cur);
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,13 @@ struct argv_environ_values {
|
|||
size_t environ_count;
|
||||
};
|
||||
|
||||
struct addr_pool {
|
||||
struct addr_pool *next;
|
||||
/* addr and mask in host order */
|
||||
uint32 addr;
|
||||
uint8 mask;
|
||||
};
|
||||
|
||||
bool
|
||||
fd_table_init(struct fd_table *);
|
||||
bool
|
||||
|
@ -66,4 +73,13 @@ fd_table_destroy(struct fd_table *ft);
|
|||
void
|
||||
fd_prestats_destroy(struct fd_prestats *pt);
|
||||
|
||||
bool
|
||||
addr_pool_init(struct addr_pool *);
|
||||
bool
|
||||
addr_pool_insert(struct addr_pool *, const char *, uint8 mask);
|
||||
bool
|
||||
addr_pool_search(struct addr_pool *, const char *);
|
||||
void
|
||||
addr_pool_destroy(struct addr_pool *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,13 @@
|
|||
__WASI_RIGHT_FD_FILESTAT_SET_SIZE | \
|
||||
__WASI_RIGHT_PATH_SYMLINK | __WASI_RIGHT_PATH_UNLINK_FILE | \
|
||||
__WASI_RIGHT_PATH_REMOVE_DIRECTORY | \
|
||||
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
|
||||
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_CONNECT | \
|
||||
__WASI_RIGHT_SOCK_LISTEN | __WASI_RIGHT_SOCK_BIND | \
|
||||
__WASI_RIGHT_SOCK_ACCEPT | __WASI_RIGHT_SOCK_RECV | \
|
||||
__WASI_RIGHT_SOCK_SEND | __WASI_RIGHT_SOCK_ADDR_LOCAL | \
|
||||
__WASI_RIGHT_SOCK_ADDR_REMOTE | __WASI_RIGHT_SOCK_RECV_FROM | \
|
||||
__WASI_RIGHT_SOCK_SEND_TO)
|
||||
|
||||
|
||||
// Block and character device interaction is outside the scope of
|
||||
// CloudABI. Simply allow everything.
|
||||
|
@ -71,10 +77,15 @@
|
|||
#define RIGHTS_REGULAR_FILE_INHERITING 0
|
||||
|
||||
// Operations that apply to sockets and socket pairs.
|
||||
#define RIGHTS_SOCKET_BASE \
|
||||
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
|
||||
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
|
||||
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
|
||||
#define RIGHTS_SOCKET_BASE \
|
||||
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
|
||||
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
|
||||
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_CONNECT | \
|
||||
__WASI_RIGHT_SOCK_LISTEN | __WASI_RIGHT_SOCK_BIND | \
|
||||
__WASI_RIGHT_SOCK_ACCEPT | __WASI_RIGHT_SOCK_RECV | \
|
||||
__WASI_RIGHT_SOCK_SEND | __WASI_RIGHT_SOCK_ADDR_LOCAL | \
|
||||
__WASI_RIGHT_SOCK_ADDR_REMOTE | __WASI_RIGHT_SOCK_RECV_FROM | \
|
||||
__WASI_RIGHT_SOCK_SEND_TO)
|
||||
#define RIGHTS_SOCKET_INHERITING RIGHTS_ALL
|
||||
|
||||
// Operations that apply to TTYs.
|
||||
|
|
|
@ -362,6 +362,9 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
|||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasm_module_t module;
|
||||
wasm_module_inst_t new_module_inst;
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
WASIContext *wasi_ctx;
|
||||
#endif
|
||||
WASMExecEnv *new_exec_env;
|
||||
uint32 aux_stack_start, aux_stack_size;
|
||||
uint32 stack_size = 8192;
|
||||
|
@ -393,6 +396,11 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
|||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
|
||||
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
|
||||
#endif
|
||||
|
||||
new_exec_env = wasm_exec_env_create_internal(new_module_inst,
|
||||
exec_env->wasm_stack_size);
|
||||
if (!new_exec_env)
|
||||
|
|
|
@ -8,6 +8,16 @@
|
|||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
static void
|
||||
textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr_in *out)
|
||||
{
|
||||
assert(textual);
|
||||
|
||||
out->sin_family = AF_INET;
|
||||
out->sin_port = htons(port);
|
||||
out->sin_addr.s_addr = inet_addr(textual);
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_create(bh_socket_t *sock, int tcp_or_udp)
|
||||
{
|
||||
|
@ -113,6 +123,23 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
|||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_connect(bh_socket_t socket, const char *addr, int port)
|
||||
{
|
||||
struct sockaddr_in addr_in = { 0 };
|
||||
socklen_t addr_len = sizeof(struct sockaddr_in);
|
||||
int ret = 0;
|
||||
|
||||
textual_addr_to_sockaddr(addr, port, &addr_in);
|
||||
|
||||
ret = connect(socket, (struct sockaddr *)&addr_in, addr_len);
|
||||
if (ret == -1) {
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
|
||||
{
|
||||
|
@ -138,3 +165,13 @@ os_socket_shutdown(bh_socket_t socket)
|
|||
shutdown(socket, O_RDWR);
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_inet_network(const char *cp, uint32 *out)
|
||||
{
|
||||
if (!cp)
|
||||
return BHT_ERROR;
|
||||
|
||||
*out = inet_network(cp);
|
||||
return BHT_OK;
|
||||
}
|
|
@ -265,6 +265,17 @@ int
|
|||
os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
||||
unsigned int *addrlen);
|
||||
|
||||
/**
|
||||
* initiate a connection on a socket
|
||||
*
|
||||
* @param socket the socket to connect with
|
||||
* @param addr the ip address, only IPv4 supported currently
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_connect(bh_socket_t socket, const char *addr, int port);
|
||||
|
||||
/**
|
||||
* Blocking receive message from a socket.
|
||||
*
|
||||
|
@ -310,6 +321,18 @@ os_socket_close(bh_socket_t socket);
|
|||
int
|
||||
os_socket_shutdown(bh_socket_t socket);
|
||||
|
||||
/**
|
||||
* converts cp into a number in host byte order suitable for use as
|
||||
* an Internet network address
|
||||
*
|
||||
* @param cp a string in IPv4 numbers-and-dots notation
|
||||
*
|
||||
* @return On success, the converted address is returned.
|
||||
* If the input is invalid, -1 is returned
|
||||
*/
|
||||
int
|
||||
os_socket_inet_network(const char *cp, uint32 *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -227,4 +227,72 @@ shutdown(int sockfd, int how)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
||||
unsigned int *addrlen)
|
||||
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
int
|
||||
os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_close(bh_socket_t socket)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_connect(bh_socket_t socket, const char *addr, int port)
|
||||
{}
|
||||
|
||||
int
|
||||
os_socket_create(bh_socket_t *sock, int tcp_or_udp)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_inet_network(const char *cp, uint32 *out)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_listen(bh_socket_t socket, int max_client)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_shutdown(bh_socket_t socket)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -152,3 +152,13 @@ os_socket_shutdown(bh_socket_t socket)
|
|||
shutdown(socket, SD_BOTH);
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_inet_network(const char *cp, uint32 *out)
|
||||
{
|
||||
if (!cp)
|
||||
return BHT_ERROR;
|
||||
|
||||
*out = inet_addr(cp);
|
||||
return BHT_OK;
|
||||
}
|
|
@ -38,15 +38,21 @@ extend_vector(Vector *vector, size_t length)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (vector->lock)
|
||||
os_mutex_lock(vector->lock);
|
||||
memcpy(data, vector->data, vector->size_elem * vector->max_elems);
|
||||
BH_FREE(vector->data);
|
||||
|
||||
vector->data = data;
|
||||
vector->max_elems = length;
|
||||
if (vector->lock)
|
||||
os_mutex_unlock(vector->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
bh_vector_init(Vector *vector, size_t init_length, size_t size_elem)
|
||||
bh_vector_init(Vector *vector, size_t init_length, size_t size_elem,
|
||||
bool use_lock)
|
||||
{
|
||||
if (!vector) {
|
||||
LOG_ERROR("Init vector failed: vector is NULL.\n");
|
||||
|
@ -65,6 +71,26 @@ bh_vector_init(Vector *vector, size_t init_length, size_t size_elem)
|
|||
vector->size_elem = size_elem;
|
||||
vector->max_elems = init_length;
|
||||
vector->num_elems = 0;
|
||||
vector->lock = NULL;
|
||||
|
||||
if (use_lock) {
|
||||
if (!(vector->lock = BH_MALLOC(sizeof(korp_mutex)))) {
|
||||
LOG_ERROR("Init vector failed: alloc locker failed.\n");
|
||||
bh_vector_destroy(vector);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BHT_OK != os_mutex_init(vector->lock)) {
|
||||
LOG_ERROR("Init vector failed: init locker failed.\n");
|
||||
|
||||
BH_FREE(vector->lock);
|
||||
vector->lock = NULL;
|
||||
|
||||
bh_vector_destroy(vector);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -81,13 +107,17 @@ bh_vector_set(Vector *vector, uint32 index, const void *elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (vector->lock)
|
||||
os_mutex_lock(vector->lock);
|
||||
memcpy(vector->data + vector->size_elem * index, elem_buf,
|
||||
vector->size_elem);
|
||||
if (vector->lock)
|
||||
os_mutex_unlock(vector->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
bh_vector_get(const Vector *vector, uint32 index, void *elem_buf)
|
||||
bh_vector_get(Vector *vector, uint32 index, void *elem_buf)
|
||||
{
|
||||
if (!vector || !elem_buf) {
|
||||
LOG_ERROR("Get vector elem failed: vector or elem buf is NULL.\n");
|
||||
|
@ -99,8 +129,12 @@ bh_vector_get(const Vector *vector, uint32 index, void *elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (vector->lock)
|
||||
os_mutex_lock(vector->lock);
|
||||
memcpy(elem_buf, vector->data + vector->size_elem * index,
|
||||
vector->size_elem);
|
||||
if (vector->lock)
|
||||
os_mutex_unlock(vector->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -125,6 +159,8 @@ bh_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (vector->lock)
|
||||
os_mutex_lock(vector->lock);
|
||||
p = vector->data + vector->size_elem * vector->num_elems;
|
||||
for (i = vector->num_elems - 1; i > index; i--) {
|
||||
memcpy(p, p - vector->size_elem, vector->size_elem);
|
||||
|
@ -133,6 +169,8 @@ bh_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
|
|||
|
||||
memcpy(p, elem_buf, vector->size_elem);
|
||||
vector->num_elems++;
|
||||
if (vector->lock)
|
||||
os_mutex_unlock(vector->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -149,9 +187,13 @@ bh_vector_append(Vector *vector, const void *elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (vector->lock)
|
||||
os_mutex_lock(vector->lock);
|
||||
memcpy(vector->data + vector->size_elem * vector->num_elems, elem_buf,
|
||||
vector->size_elem);
|
||||
vector->num_elems++;
|
||||
if (vector->lock)
|
||||
os_mutex_unlock(vector->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -171,6 +213,8 @@ bh_vector_remove(Vector *vector, uint32 index, void *old_elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (vector->lock)
|
||||
os_mutex_lock(vector->lock);
|
||||
p = vector->data + vector->size_elem * index;
|
||||
|
||||
if (old_elem_buf) {
|
||||
|
@ -183,6 +227,8 @@ bh_vector_remove(Vector *vector, uint32 index, void *old_elem_buf)
|
|||
}
|
||||
|
||||
vector->num_elems--;
|
||||
if (vector->lock)
|
||||
os_mutex_unlock(vector->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -202,6 +248,12 @@ bh_vector_destroy(Vector *vector)
|
|||
|
||||
if (vector->data)
|
||||
BH_FREE(vector->data);
|
||||
|
||||
if (vector->lock) {
|
||||
os_mutex_destroy(vector->lock);
|
||||
BH_FREE(vector->lock);
|
||||
}
|
||||
|
||||
memset(vector, 0, sizeof(Vector));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ typedef struct Vector {
|
|||
size_t num_elems;
|
||||
/* size of each element */
|
||||
size_t size_elem;
|
||||
void *lock;
|
||||
} Vector;
|
||||
|
||||
/**
|
||||
|
@ -35,7 +36,8 @@ typedef struct Vector {
|
|||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
bh_vector_init(Vector *vector, size_t init_length, size_t size_elem);
|
||||
bh_vector_init(Vector *vector, size_t init_length, size_t size_elem,
|
||||
bool use_lock);
|
||||
|
||||
/**
|
||||
* Set element of vector
|
||||
|
@ -60,7 +62,7 @@ bh_vector_set(Vector *vector, uint32 index, const void *elem_buf);
|
|||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
bh_vector_get(const Vector *vector, uint32 index, void *elem_buf);
|
||||
bh_vector_get(Vector *vector, uint32 index, void *elem_buf);
|
||||
|
||||
/**
|
||||
* Insert element of vector
|
||||
|
|
|
@ -51,12 +51,7 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
|
|||
|
||||
- **WAMR_BUILD_LIBC_UVWASI**=1/0 (Experiment), build the [WASI](https://github.com/WebAssembly/WASI) libc subset for WASM app based on [uvwasi](https://github.com/nodejs/uvwasi) implementation, default to disable if not set
|
||||
|
||||
> Note: for platform which doesn't support **WAMR_BUILD_LIBC_WASI**, e.g. Windows, developer can try using **WAMR_BUILD_LIBC_UVWASI**. And the uvwasi source code must be cloned under core/deps:
|
||||
>
|
||||
> ```bash
|
||||
> cd <WAMR-ROOT>/core/deps
|
||||
> git clone https://github.com/nodejs/uvwasi.git
|
||||
> ```
|
||||
> Note: for platform which doesn't support **WAMR_BUILD_LIBC_WASI**, e.g. Windows, developer can try using **WAMR_BUILD_LIBC_UVWASI**.
|
||||
|
||||
#### **Enable Multi-Module feature**
|
||||
|
||||
|
@ -297,9 +292,6 @@ Make sure `MSVC` and `cmake` are installed and available in the command line env
|
|||
|
||||
Then build the source codes:
|
||||
``` Bash
|
||||
cd core/deps/
|
||||
git clone https://github.com/nodejs/uvwasi.git
|
||||
|
||||
cd product-mini/platforms/windows/
|
||||
mkdir build
|
||||
cd build
|
||||
|
@ -335,8 +327,8 @@ pacman -R cmake
|
|||
pacman -S mingw-w64-x86_64-cmake
|
||||
```
|
||||
|
||||
Then follow the build instructions for Windows above, minus cloning uvwasi and
|
||||
adding the following arguments for cmake:
|
||||
Then follow the build instructions for Windows above, and add the following
|
||||
arguments for cmake:
|
||||
|
||||
```Bash
|
||||
cmake .. -G"Unix Makefiles" \
|
||||
|
|
|
@ -1,9 +1,31 @@
|
|||
Embedding WAMR guideline
|
||||
=====================================
|
||||
|
||||
|
||||
**Note**: All the embedding APIs supported by the runtime are defined under folder [core/iwasm/include](../core/iwasm/include). The API details are available in the header files.
|
||||
|
||||
## Embed WAMR into developer's project
|
||||
|
||||
WAMR is designed to be easy embeddable in any project, a typical way of building WAMR is to use cmake, developer can configure features by setting cmake variables and then include the script `runtime_lib.cmake` under folder [build-scripts](../build-scripts) in his CMakeList.txt, for example:
|
||||
``` cmake
|
||||
set (WAMR_BUILD_PLATFORM "linux")
|
||||
set (WAMR_BUILD_TARGET "X86_64")
|
||||
set (WAMR_BUILD_INTERP 1)
|
||||
set (WAMR_BUILD_FAST_INTERP 1)
|
||||
set (WAMR_BUILD_AOT 1)
|
||||
set (WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
set (WAMR_BUILD_LIBC_WASI 1)
|
||||
set (WAMR_BUILD_SIMD 1)
|
||||
set (WAMR_ROOT_DIR path/to/wamr/root)
|
||||
|
||||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
|
||||
target_link_libraries (your_project vmlib)
|
||||
```
|
||||
Examples can be found in [CMakeLists.txt of linux platform](../product-mini/platforms/linux/CMakeLists.txt) and [other platforms](../product-mini/platforms). The available features to configure can be found in [Build WAMR vmcore](./build_wamr.md#wamr-vmcore-cmake-building-configurations).
|
||||
|
||||
Developer can also use Makefile to embed WAMR, by defining macros and including directories, and adding the source files, examples can be found in [makefile of alios-things platform](../product-mini/platforms/alios-things/aos.mk) and [makefile of nuttx platform](../product-mini/platforms/nuttx/wamr.mk).
|
||||
|
||||
## The runtime initialization
|
||||
|
||||
``` C
|
||||
|
|
66
doc/socket_api.md
Normal file
66
doc/socket_api.md
Normal file
|
@ -0,0 +1,66 @@
|
|||
# How to use Berkeley/Posix Socket APIs in WebAssembly
|
||||
|
||||
**_Berkeley sockets_** usually means an API for Internet sockets and Unix domain
|
||||
sockets. A socket is an abstract representation of the local endpoint of a
|
||||
network communication path.
|
||||
|
||||
Currently, WAMR supports a limit set of all well-known functions:
|
||||
`accept()`, `bind()`, `connect()`, `listen()`, `recv()`, `send()`, `shutdown()`
|
||||
and `socket()`. Users can call those functions in WebAssembly code directly.
|
||||
Those WebAssembly socket calls will be dispatched to the imported
|
||||
functions and eventually will be implemented by host socket APIs.
|
||||
|
||||
This document introduces a way to support _Berkeley/Posix Socket APIs_ in
|
||||
WebAssembly code.
|
||||
|
||||
## Patch the native code
|
||||
|
||||
The first step is to include a header file of the WAMR socket extension in the
|
||||
native source code.
|
||||
|
||||
```c
|
||||
#ifdef __wasi__
|
||||
#include <wasi_socket_ext.h>
|
||||
#endif
|
||||
```
|
||||
|
||||
`__wasi__` is a Marco defined by WASI. The host compiler will not enable it.
|
||||
|
||||
## CMake files
|
||||
|
||||
It is recommended that the project should use CMake as its build system. Use
|
||||
[_wasi-sdk_](https://github.com/WebAssembly/wasi-sdk)
|
||||
as a toolchain to compile C/C++ to WebAssembly
|
||||
|
||||
```bash
|
||||
$ cmake -DWASI_SDK_PREFIX=${WASI_SDK_DIR}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${WASI_TOOLCHAIN_FILE}
|
||||
-DCMAKE_SYSROOT=${WASI_SYS_ROOT}
|
||||
..
|
||||
```
|
||||
|
||||
In the *CMakeLists.txt*, include an extension of socket support and link with it.
|
||||
|
||||
```cmake
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake)
|
||||
add_executable(socket_example tcp_server.c)
|
||||
target_link_libraries(socket_example socket_wasi_ext)
|
||||
```
|
||||
|
||||
Now, the native code with socket APIs is ready for compilation.
|
||||
|
||||
## Run with iwasm
|
||||
|
||||
If having the _.wasm_, the last step is to run it with _iwasm_.
|
||||
|
||||
The _iwasm_ should be compiled with `WAMR_BUILD_LIBC_WASI=1`. By default, it is
|
||||
enabled.
|
||||
|
||||
_iwasm_ accepts address ranges via an option, `--addr-pool`, to implement
|
||||
the capability control. All IP address the WebAssebmly application may need to `bind()` or `connect()` should be announced first. Every IP address should be in CIRD notation.
|
||||
|
||||
```bash
|
||||
$ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm
|
||||
```
|
||||
|
||||
Refer to [socket api sample](../samples/socket-api) for more details.
|
|
@ -3,24 +3,42 @@
|
|||
All samples come from the commit 340fd9528cc3b26d22fe30ee1628c8c3f2b8c53b
|
||||
of [wasm-c-api](https://github.com/WebAssembly/wasm-c-api).
|
||||
|
||||
Developer can learn these *APIs* from
|
||||
Developer can learn these _APIs_ from
|
||||
[wasm.h](https://github.com/WebAssembly/wasm-c-api/blob/master/include/wasm.h).
|
||||
|
||||
And here are [examples](https://github.com/WebAssembly/wasm-c-api/tree/master/example) which
|
||||
are helpful.
|
||||
|
||||
## FYI
|
||||
|
||||
- The thread model of _wasm_c_api_ is
|
||||
|
||||
- An `wasm_engine_t` instance may only be created once per process
|
||||
- Every `wasm_store_t` and its objects may only be accessed in a single thread
|
||||
|
||||
- `wasm_engine_new`, `wasm_engine_new_with_config`, `wasm_engine_new_with_args`,
|
||||
`wasm_engine_delete`should be called in a thread-safe environment. Such
|
||||
behaviors are not recommended, and please make sure an appropriate calling
|
||||
sequence if it has to be.
|
||||
|
||||
- call `wasm_engine_new` and `wasm_engine_delete` in different threads
|
||||
- call `wasm_engine_new` or `wasm_engine_delete` multiple times in
|
||||
different threads
|
||||
|
||||
## unspported list
|
||||
|
||||
Currently WAMR supports most of the APIs, the unsupported APIs are listed as below:
|
||||
|
||||
- References
|
||||
|
||||
``` c
|
||||
```c
|
||||
WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*);
|
||||
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
|
||||
```
|
||||
|
||||
- Several Module APIs
|
||||
|
||||
``` c
|
||||
```c
|
||||
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
||||
WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
|
||||
```
|
||||
|
@ -30,12 +48,12 @@ by host-side function callings.
|
|||
|
||||
- Table Grow APIs
|
||||
|
||||
``` c
|
||||
```c
|
||||
WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
|
||||
```
|
||||
|
||||
- Memory Grow APIs
|
||||
|
||||
``` c
|
||||
```c
|
||||
WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
|
||||
```
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
static int app_argc;
|
||||
static char **app_argv;
|
||||
|
||||
#define MODULE_PATH ("--module-path=")
|
||||
|
||||
/* clang-format off */
|
||||
static int
|
||||
print_help()
|
||||
|
@ -41,6 +39,10 @@ print_help()
|
|||
printf(" --dir=<dir> Grant wasi access to the given host directories\n");
|
||||
printf(" to the program, for example:\n");
|
||||
printf(" --dir=<dir1> --dir=<dir2>\n");
|
||||
printf(" --addr-pool= Grant wasi access to the given network addresses in\n");
|
||||
printf(" CIRD notation to the program, seperated with ',',\n");
|
||||
printf(" for example:\n");
|
||||
printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
|
||||
#endif
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
printf(" --module-path= Indicate a module search path. default is current\n"
|
||||
|
@ -244,6 +246,8 @@ main(int argc, char *argv[])
|
|||
uint32 dir_list_size = 0;
|
||||
const char *env_list[8] = { NULL };
|
||||
uint32 env_list_size = 0;
|
||||
const char *addr_pool[8] = { NULL };
|
||||
uint32 addr_pool_size = 0;
|
||||
#endif
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
char *ip_addr = NULL;
|
||||
|
@ -312,9 +316,30 @@ main(int argc, char *argv[])
|
|||
return print_help();
|
||||
}
|
||||
}
|
||||
/* TODO: parse the configuration file via --addr-pool-file */
|
||||
else if (!strncmp(argv[0], "--addr-pool=", strlen("--addr-pool="))) {
|
||||
/* like: --addr-pool=100.200.244.255/30 */
|
||||
char *token = NULL;
|
||||
|
||||
if ('\0' == argv[0][12])
|
||||
return print_help();
|
||||
|
||||
token = strtok(argv[0] + strlen("--addr-pool="), ",");
|
||||
while (token) {
|
||||
if (addr_pool_size >= sizeof(addr_pool) / sizeof(char *)) {
|
||||
printf("Only allow max address number %d\n",
|
||||
(int)(sizeof(addr_pool) / sizeof(char *)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr_pool[addr_pool_size++] = token;
|
||||
token = strtok(NULL, ";");
|
||||
}
|
||||
}
|
||||
#endif /* WASM_ENABLE_LIBC_WASI */
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
else if (!strncmp(argv[0], MODULE_PATH, strlen(MODULE_PATH))) {
|
||||
else if (!strncmp(argv[0],
|
||||
"--module-path=", strlen("--module-path="))) {
|
||||
module_search_path = handle_module_path(argv[0]);
|
||||
if (!strlen(module_search_path)) {
|
||||
return print_help();
|
||||
|
@ -422,6 +447,8 @@ main(int argc, char *argv[])
|
|||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size, NULL, 0,
|
||||
env_list, env_list_size, argv, argc);
|
||||
|
||||
wasm_runtime_set_wasi_addr_pool(wasm_module, addr_pool, addr_pool_size);
|
||||
#endif
|
||||
|
||||
/* instantiate the module */
|
||||
|
|
|
@ -103,7 +103,8 @@ set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
|||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
|
||||
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN -D_WINSOCK_DEPRECATED_NO_WARNINGS")
|
||||
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WINSOCK_DEPRECATED_NO_WARNINGS")
|
||||
if (NOT MINGW)
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
|
||||
|
|
162
samples/socket-api/CMakeLists.txt
Normal file
162
samples/socket-api/CMakeLists.txt
Normal file
|
@ -0,0 +1,162 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.8...3.18)
|
||||
project(socket_api_sample)
|
||||
|
||||
#######################################
|
||||
## Detect toolchain
|
||||
#######################################
|
||||
message(CHECK_START "Detecting WASI-SDK at /opt/wasi-sdk")
|
||||
if(NOT (DEFINED WASI_SDK_DIR OR DEFINED CACHE{WASI_SDK_DIR}))
|
||||
find_path(WASI_SDK_PARENT
|
||||
wasi-sdk
|
||||
PATHS /opt
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
if(WASI_SDK_PARENT)
|
||||
set(WASI_SDK_DIR ${WASI_SDK_PARENT}/wasi-sdk)
|
||||
endif()
|
||||
endif()
|
||||
if(WASI_SDK_DIR)
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(CHECK_FAIL "not found")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${WASI_SDK_DIR})
|
||||
message(FATAL_ERROR "Please install WASI-SDK under /opt/wasi-sdk")
|
||||
endif()
|
||||
|
||||
message(CHECK_START "Detecting WASI_TOOLCHAIN_FILE at ${WASI_SDK_DIR}")
|
||||
find_file(WASI_TOOLCHAIN_FILE
|
||||
wasi-sdk.cmake
|
||||
PATHS "${WASI_SDK_DIR}/share/cmake"
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
if(WASI_TOOLCHAIN_FILE)
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(CHECK_FAIL "not found")
|
||||
endif()
|
||||
|
||||
if(WASI_TOOLCHAIN_FILE-NOTFOUND)
|
||||
message(FATAL_ERROR "Can not find wasi-sdk.cmake under ${WASI_SDK_DIR}")
|
||||
endif()
|
||||
|
||||
message(CHECK_START "Detecting WASI_SYS_ROOT at ${WASI_SDK_DIR}")
|
||||
find_path(WASI_SYS_ROOT
|
||||
wasi-sysroot
|
||||
PATHS "${WASI_SDK_DIR}/share"
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
if(WASI_SYS_ROOT)
|
||||
message(CHECK_PASS "found")
|
||||
set(WASI_SYS_ROOT ${WASI_SYS_ROOT}/wasi-sysroot)
|
||||
else()
|
||||
message(CHECK_FAIL "not found")
|
||||
endif()
|
||||
|
||||
if(WASI_SYS_ROOT-NOTFOUND)
|
||||
message(FATAL_ERROR "Can not find wasi-sysroot/ under ${WASI_SDK_DIR}")
|
||||
endif()
|
||||
|
||||
message(STATUS "WASI_SDK_DIR is ${WASI_SDK_DIR}")
|
||||
message(STATUS "WASI_TOOLCHAIN_FILE is ${WASI_TOOLCHAIN_FILE}")
|
||||
message(STATUS "WASI_SYS_ROOT is ${WASI_SYS_ROOT}")
|
||||
|
||||
###############################################################
|
||||
## Build socket applications of wasm version and native version
|
||||
###############################################################
|
||||
include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(wasm-app
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/wasm-src
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../wamr-sdk/app/libc-builtin-sysroot/include/pthread.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm-src/inc
|
||||
&& ${CMAKE_COMMAND}
|
||||
-DWASI_SDK_PREFIX=${WASI_SDK_DIR}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${WASI_TOOLCHAIN_FILE}
|
||||
-DCMAKE_SYSROOT=${WASI_SYS_ROOT}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm-src
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build .
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy
|
||||
tcp_client.wasm ${CMAKE_CURRENT_SOURCE_DIR}/build
|
||||
tcp_server.wasm ${CMAKE_CURRENT_SOURCE_DIR}/build
|
||||
tcp_client.wasm.dump ${CMAKE_CURRENT_SOURCE_DIR}/build
|
||||
tcp_server.wasm.dump ${CMAKE_CURRENT_SOURCE_DIR}/build
|
||||
)
|
||||
|
||||
add_executable(tcp_server ${CMAKE_CURRENT_SOURCE_DIR}/wasm-src/tcp_server.c)
|
||||
target_link_libraries(tcp_server pthread)
|
||||
add_executable(tcp_client ${CMAKE_CURRENT_SOURCE_DIR}/wasm-src/tcp_client.c)
|
||||
|
||||
############################################
|
||||
## Build iwasm with wasi and pthread support
|
||||
############################################
|
||||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||
if (APPLE)
|
||||
add_definitions(-DBH_PLATFORM_DARWIN)
|
||||
endif ()
|
||||
|
||||
# Reset linker flags
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||
|
||||
# Set WAMR features
|
||||
|
||||
# Set WAMR_BUILD_TARGET, currently values supported:
|
||||
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
|
||||
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
|
||||
if (NOT DEFINED WAMR_BUILD_TARGET)
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
|
||||
set (WAMR_BUILD_TARGET "AARCH64")
|
||||
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
|
||||
set (WAMR_BUILD_TARGET "RISCV64")
|
||||
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
# Build as X86_64 by default in 64-bit platform
|
||||
set (WAMR_BUILD_TARGET "X86_64")
|
||||
else ()
|
||||
# Build as X86_32 by default in 32-bit platform
|
||||
set (WAMR_BUILD_TARGET "X86_32")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set (CMAKE_BUILD_TYPE Release)
|
||||
endif ()
|
||||
|
||||
set(WAMR_BUILD_INTERP 1)
|
||||
set(WAMR_BUILD_FAST_INTERP 1)
|
||||
set(WAMR_BUILD_AOT 1)
|
||||
set(WAMR_BUILD_JIT 0)
|
||||
set(WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
set(WAMR_BUILD_LIBC_WASI 1)
|
||||
set(WAMR_BUILD_LIB_PTHREAD 1)
|
||||
|
||||
# compiling and linking flags
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -fPIE")
|
||||
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
endif ()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
|
||||
|
||||
# build vmlib static lib
|
||||
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
|
||||
# build iwasm
|
||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
set (RUNTIME_SOURCE_ALL
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../product-mini/platforms/linux/main.c
|
||||
${UNCOMMON_SHARED_SOURCE}
|
||||
)
|
||||
add_executable (iwasm ${RUNTIME_SOURCE_ALL})
|
||||
target_link_libraries(iwasm vmlib -lpthread -lm)
|
57
samples/socket-api/README.md
Normal file
57
samples/socket-api/README.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
"socket-api" sample introduction
|
||||
================================
|
||||
|
||||
This sample demonstrates how to use WAMR socket-api to develop wasm network applications.
|
||||
Two wasm applications are provided: tcp-server and tcp-client, and this sample demonstrates
|
||||
how they communicate with each other.
|
||||
|
||||
## Preparation
|
||||
|
||||
Please install WASI SDK, download the [wasi-sdk release](https://github.com/CraneStation/wasi-sdk/releases) and extract the archive to default path `/opt/wasi-sdk`.
|
||||
And install wabt, download the [wabt release](https://github.com/WebAssembly/wabt/releases) and extract the archive to default path `/opt/wabt`
|
||||
|
||||
## Build the sample
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
The file `tcp_server.wasm`, `tcp_client.wasm` and `iwasm` will be created.
|
||||
And also file `tcp_server` and `tcp_client` of native version are created.
|
||||
|
||||
Note that iwasm is built with libc-wasi and lib-pthread enabled.
|
||||
|
||||
## Run workload
|
||||
|
||||
Start the tcp server, which opens port 1234 and waits for clients to connect.
|
||||
```bash
|
||||
cd build
|
||||
./iwasm --addr-pool=0.0.0.0/15 tcp_server.wasm
|
||||
```
|
||||
|
||||
Start the tcp client, which connects the server and receives message.
|
||||
```bash
|
||||
cd build
|
||||
./iwasm --addr-pool=127.0.0.1/15 tcp_client.wasm
|
||||
```
|
||||
|
||||
The output of client is like:
|
||||
```bash
|
||||
[Client] Create socket
|
||||
[Client] Connect socket
|
||||
[Client] Client receive
|
||||
[Client] 115 bytes received:
|
||||
Buffer recieved:
|
||||
Say Hi from the Server
|
||||
Say Hi from the Server
|
||||
Say Hi from the Server
|
||||
Say Hi from the Server
|
||||
Say Hi from the Server
|
||||
|
||||
[Client] BYE
|
||||
```
|
||||
|
||||
Refer to [socket api document](../../doc/socket_api.md) for more details.
|
80
samples/socket-api/wasm-src/CMakeLists.txt
Normal file
80
samples/socket-api/wasm-src/CMakeLists.txt
Normal file
|
@ -0,0 +1,80 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.8...3.18)
|
||||
project(socket_api_sample_wasm_app)
|
||||
|
||||
message(CHECK_START "Detecting WABT")
|
||||
if(NOT (DEFINED WABT_DIR OR DEFINED CACHE{WABT_DIR}))
|
||||
find_path(WABT_DIR
|
||||
wabt
|
||||
PATHS /opt
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
if(DEFINED WABT_DIR)
|
||||
set(WABT_DIR ${WABT_DIR}/wabt)
|
||||
endif()
|
||||
endif()
|
||||
if(WABT_DIR)
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(CHECK_FAIL "not found")
|
||||
endif()
|
||||
|
||||
message(CHECK_START "Detecting WASM_OBJDUMP at ${WABT_DIR}")
|
||||
find_program(WASM_OBJDUMP
|
||||
wasm-objdump
|
||||
PATHS "${WABT_DIR}/bin"
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
if(WASM_OBJDUMP)
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(CHECK_FAIL "not found")
|
||||
endif()
|
||||
|
||||
set(SRC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake)
|
||||
|
||||
function(COMPILE_WITH_CLANG SOURCE_FILE)
|
||||
get_filename_component(FILE_NAME ${SOURCE_FILE} NAME_WLE)
|
||||
|
||||
set(WASM_MODULE ${FILE_NAME}.wasm)
|
||||
|
||||
set(MAIN_TARGET_NAME MODULE_${FILE_NAME})
|
||||
|
||||
add_executable(${MAIN_TARGET_NAME} ${SOURCE_FILE})
|
||||
set_target_properties(${MAIN_TARGET_NAME} PROPERTIES OUTPUT_NAME ${WASM_MODULE})
|
||||
target_include_directories(${MAIN_TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc)
|
||||
target_compile_options(${MAIN_TARGET_NAME} INTERFACE -pthread)
|
||||
target_link_libraries(${MAIN_TARGET_NAME} socket_wasi_ext)
|
||||
target_link_options(${MAIN_TARGET_NAME} PRIVATE
|
||||
LINKER:--export=__heap_base
|
||||
LINKER:--export=__data_end
|
||||
LINKER:--shared-memory,--max-memory=196608
|
||||
LINKER:--no-check-features
|
||||
LINKER:--allow-undefined
|
||||
)
|
||||
|
||||
if(EXISTS ${WASM_OBJDUMP})
|
||||
message(STATUS "Dumping ${WASM_MODULE}...")
|
||||
set(WASM_DUMP ${WASM_MODULE}.dump)
|
||||
set(DUMP_TARGET_NAME DUMP_${FILE_NAME})
|
||||
|
||||
add_custom_command(OUTPUT ${WASM_DUMP}
|
||||
COMMAND ${WASM_OBJDUMP} -dx ${WASM_MODULE} > ${WASM_DUMP}
|
||||
COMMENT "Dumping ${WASM_MODULE}..."
|
||||
DEPENDS ${MAIN_TARGET_NAME}
|
||||
)
|
||||
|
||||
add_custom_target(${DUMP_TARGET_NAME} ALL
|
||||
DEPENDS ${WASM_DUMP}
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
compile_with_clang(tcp_server.c)
|
||||
compile_with_clang(tcp_client.c)
|
62
samples/socket-api/wasm-src/tcp_client.c
Normal file
62
samples/socket-api/wasm-src/tcp_client.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __wasi__
|
||||
#include <wasi_socket_ext.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int socket_fd, ret, total_size = 0;
|
||||
char buffer[1024] = { 0 };
|
||||
struct sockaddr_in server_address = { 0 };
|
||||
|
||||
printf("[Client] Create socket\n");
|
||||
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socket_fd == -1) {
|
||||
perror("Create socket failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* 127.0.0.1:1234 */
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_port = htons(1234);
|
||||
server_address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
printf("[Client] Connect socket\n");
|
||||
if (connect(socket_fd, (struct sockaddr *)&server_address,
|
||||
sizeof(server_address))
|
||||
== -1) {
|
||||
perror("Connect failed");
|
||||
close(socket_fd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("[Client] Client receive\n");
|
||||
while (1) {
|
||||
ret = recv(socket_fd, buffer + total_size, sizeof(buffer) - total_size,
|
||||
0);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
total_size += ret;
|
||||
}
|
||||
|
||||
printf("[Client] %d bytes received:\n", total_size);
|
||||
if (total_size > 0) {
|
||||
printf("Buffer recieved:\n%s\n", buffer);
|
||||
}
|
||||
|
||||
close(socket_fd);
|
||||
printf("[Client] BYE \n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
118
samples/socket-api/wasm-src/tcp_server.c
Normal file
118
samples/socket-api/wasm-src/tcp_server.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __wasi__
|
||||
#include <wasi_socket_ext.h>
|
||||
#endif
|
||||
|
||||
#define WORKER_NUM 5
|
||||
|
||||
void *
|
||||
run(void *arg)
|
||||
{
|
||||
const char *message = "Say Hi from the Server\n";
|
||||
int new_socket = *(int *)arg;
|
||||
int i;
|
||||
|
||||
printf("[Server] Communicate with the new connection #%u @ %p ..\n",
|
||||
new_socket, (void *)(uintptr_t)pthread_self());
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (send(new_socket, message, strlen(message), 0) < 0) {
|
||||
perror("Send failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("[Server] Shuting down the new connection #%u ..\n", new_socket);
|
||||
shutdown(new_socket, SHUT_RDWR);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int socket_fd = -1, addrlen = 0;
|
||||
struct sockaddr_in addr = { 0 };
|
||||
unsigned connections = 0;
|
||||
pthread_t workers[WORKER_NUM] = { 0 };
|
||||
int client_sock_fds[WORKER_NUM] = { 0 };
|
||||
|
||||
printf("[Server] Create socket\n");
|
||||
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socket_fd < 0) {
|
||||
perror("Create socket failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 0.0.0.0:1234 */
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(1234);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
printf("[Server] Bind socket\n");
|
||||
addrlen = sizeof(addr);
|
||||
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
|
||||
perror("Bind failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printf("[Server] Listening on socket\n");
|
||||
if (listen(socket_fd, 3) < 0) {
|
||||
perror("Listen failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printf("[Server] Wait for clients to connect ..\n");
|
||||
while (connections < WORKER_NUM) {
|
||||
client_sock_fds[connections] =
|
||||
accept(socket_fd, (struct sockaddr *)&addr, (socklen_t *)&addrlen);
|
||||
if (client_sock_fds[connections] < 0) {
|
||||
perror("Accept failed");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("[Server] Client connected\n");
|
||||
if (pthread_create(&workers[connections], NULL, run,
|
||||
&client_sock_fds[connections])) {
|
||||
perror("Create a worker thread failed");
|
||||
shutdown(client_sock_fds[connections], SHUT_RDWR);
|
||||
break;
|
||||
}
|
||||
|
||||
connections++;
|
||||
}
|
||||
|
||||
if (connections == WORKER_NUM) {
|
||||
printf("[Server] Achieve maximum amount of connections\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < WORKER_NUM; i++) {
|
||||
pthread_join(workers[i], NULL);
|
||||
}
|
||||
|
||||
printf("[Server] Shuting down ..\n");
|
||||
shutdown(socket_fd, SHUT_RDWR);
|
||||
sleep(3);
|
||||
printf("[Server] BYE \n");
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
fail:
|
||||
printf("[Server] Shuting down ..\n");
|
||||
if (socket_fd >= 0)
|
||||
close(socket_fd);
|
||||
sleep(3);
|
||||
return EXIT_FAILURE;
|
||||
}
|
|
@ -34,7 +34,7 @@ void check(bool success) {
|
|||
|
||||
void check_call(wasm_func_t* func, int i, wasm_val_t args[], int32_t expected) {
|
||||
wasm_val_t r[] = {WASM_INIT_VAL};
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t), NULL};
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
||||
if (wasm_func_call(func, &args_, &results) || r[0].of.i32 != expected) {
|
||||
printf("> Error on result\n");
|
||||
|
@ -57,7 +57,7 @@ void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected
|
|||
}
|
||||
|
||||
void check_ok(wasm_func_t* func, int i, wasm_val_t args[]) {
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t), NULL};
|
||||
wasm_val_vec_t results = WASM_EMPTY_VEC;
|
||||
if (wasm_func_call(func, &args_, &results)) {
|
||||
printf("> Error on result, expected empty\n");
|
||||
|
@ -72,7 +72,7 @@ void check_ok2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
|
|||
|
||||
void check_trap(wasm_func_t* func, int i, wasm_val_t args[]) {
|
||||
wasm_val_t r[] = {WASM_INIT_VAL};
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t), NULL};
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
||||
own wasm_trap_t* trap = wasm_func_call(func, &args_, &results);
|
||||
if (! trap) {
|
||||
|
|
|
@ -15,6 +15,10 @@ void print_mutability(wasm_mutability_t mut) {
|
|||
}
|
||||
|
||||
void print_limits(const wasm_limits_t* limits) {
|
||||
if (!limits) {
|
||||
printf("unknown limits");
|
||||
return;
|
||||
}
|
||||
printf("%ud", limits->min);
|
||||
if (limits->max < wasm_limits_max_default) printf(" %ud", limits->max);
|
||||
}
|
||||
|
@ -43,6 +47,10 @@ void print_valtypes(const wasm_valtype_vec_t* types) {
|
|||
}
|
||||
|
||||
void print_externtype(const wasm_externtype_t* type) {
|
||||
if (!type) {
|
||||
printf("unknown extern type");
|
||||
return;
|
||||
}
|
||||
switch (wasm_externtype_kind(type)) {
|
||||
case WASM_EXTERN_FUNC: {
|
||||
const wasm_functype_t* functype =
|
||||
|
@ -78,6 +86,10 @@ void print_externtype(const wasm_externtype_t* type) {
|
|||
}
|
||||
|
||||
void print_name(const wasm_name_t* name) {
|
||||
if (!name) {
|
||||
printf("unknown name");
|
||||
return;
|
||||
}
|
||||
printf("\"%.*s\"", (int)name->size, name->data);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,9 @@ g++ -O3 -msse2 -msse3 -msse4 -o ${OUT_DIR}/gcc-loops_native gcc-loops.cpp
|
|||
echo "Build gcc-loops with em++ .."
|
||||
em++ -O3 -s STANDALONE_WASM=1 -msimd128 \
|
||||
-s INITIAL_MEMORY=1048576 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s TOTAL_STACK=32768 \
|
||||
-s TOTAL_STACK=32768 \
|
||||
-s "EXPORTED_FUNCTIONS=['_main']" \
|
||||
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
|
||||
-o ${OUT_DIR}/gcc-loops.wasm gcc-loops.cpp
|
||||
|
||||
echo "Compile gcc-loops.wasm to gcc-loops.aot"
|
||||
|
@ -38,7 +39,7 @@ gcc -O3 -msse2 -msse3 -msse4 -o ${OUT_DIR}/quicksort_native quicksort.c
|
|||
echo "Build quicksort with emcc .."
|
||||
emcc -O3 -s STANDALONE_WASM=1 -msimd128 \
|
||||
-s INITIAL_MEMORY=1048576 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s TOTAL_STACK=32768 \
|
||||
-s TOTAL_STACK=32768 \
|
||||
-s "EXPORTED_FUNCTIONS=['_main']" \
|
||||
-o ${OUT_DIR}/quicksort.wasm quicksort.c
|
||||
|
||||
|
@ -52,7 +53,7 @@ g++ -O3 -msse2 -msse3 -msse4 -o ${OUT_DIR}/HashSet_native HashSet.cpp \
|
|||
echo "Build HashSet with em++ .."
|
||||
em++ -O3 -s STANDALONE_WASM=1 -msimd128 \
|
||||
-s INITIAL_MEMORY=1048576 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s TOTAL_STACK=32768 \
|
||||
-s TOTAL_STACK=32768 \
|
||||
-s "EXPORTED_FUNCTIONS=['_main']" \
|
||||
-o ${OUT_DIR}/HashSet.wasm HashSet.cpp
|
||||
|
||||
|
@ -65,7 +66,7 @@ gcc -O3 -msse2 -msse3 -msse4 -o ${OUT_DIR}/float-mm_native float-mm.c
|
|||
echo "Build float-mm with emcc .."
|
||||
emcc -O3 -s STANDALONE_WASM=1 -msimd128 \
|
||||
-s INITIAL_MEMORY=1048576 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s TOTAL_STACK=32768 \
|
||||
-s TOTAL_STACK=32768 \
|
||||
-s "EXPORTED_FUNCTIONS=['_main']" \
|
||||
-o ${OUT_DIR}/float-mm.wasm float-mm.c
|
||||
|
||||
|
|
|
@ -181,7 +181,13 @@ include (${SHARED_DIR}/utils/shared_utils.cmake)
|
|||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
include (${IWASM_DIR}/libraries/thread-mgr/thread_mgr.cmake)
|
||||
include (${IWASM_DIR}/libraries/libc-builtin/libc_builtin.cmake)
|
||||
include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake)
|
||||
if (NOT MINGW)
|
||||
if (NOT MSVC)
|
||||
include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake)
|
||||
else()
|
||||
include (${IWASM_DIR}/libraries/libc-uvwasi/libc_uvwasi.cmake)
|
||||
endif()
|
||||
endif()
|
||||
include (${IWASM_DIR}/libraries/lib-pthread/lib_pthread.cmake)
|
||||
include (${IWASM_DIR}/common/iwasm_common.cmake)
|
||||
include (${IWASM_DIR}/interpreter/iwasm_interp.cmake)
|
||||
|
@ -253,10 +259,13 @@ add_executable (wamrc main.c)
|
|||
|
||||
if (NOT MSVC)
|
||||
target_link_libraries (wamrc aotclib vmlib LLVMDemangle ${LLVM_AVAILABLE_LIBS} ${lib_ubsan}
|
||||
-lm -ldl -lpthread ${lib_lldb})
|
||||
-lm -lpthread ${lib_lldb} ${UV_A_LIBS})
|
||||
if (MINGW)
|
||||
target_link_libraries (wamrc -lssp -lWs2_32)
|
||||
else()
|
||||
target_link_libraries (wamrc -ldl)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries (wamrc aotclib vmlib ${lib_lldb} ${LLVM_AVAILABLE_LIBS} ${lib_ubsan})
|
||||
target_link_libraries (wamrc aotclib vmlib ${lib_lldb} ${LLVM_AVAILABLE_LIBS} ${lib_ubsan}
|
||||
${UV_A_LIBS})
|
||||
endif()
|
||||
|
|
Loading…
Reference in New Issue
Block a user