diff options
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_native.c')
-rw-r--r-- | fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_native.c | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_native.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_native.c new file mode 100644 index 000000000..1acaed6ee --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_native.c @@ -0,0 +1,526 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_native.h" +#include "wasm_runtime_common.h" +#include "bh_log.h" + +#if !defined(BH_PLATFORM_ZEPHYR) && !defined(BH_PLATFORM_ALIOS_THINGS) \ + && !defined(BH_PLATFORM_OPENRTOS) && !defined(BH_PLATFORM_ESP_IDF) +#define ENABLE_QUICKSORT 1 +#else +#define ENABLE_QUICKSORT 0 +#endif + +#define ENABLE_SORT_DEBUG 0 + +#if ENABLE_SORT_DEBUG != 0 +#include <sys/time.h> +#endif + +static NativeSymbolsList g_native_symbols_list = NULL; + +uint32 +get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis); + +#if WASM_ENABLE_SPEC_TEST != 0 +uint32 +get_spectest_export_apis(NativeSymbol **p_libc_builtin_apis); +#endif + +uint32 +get_libc_wasi_export_apis(NativeSymbol **p_libc_wasi_apis); + +uint32_t +get_wasi_nn_export_apis(NativeSymbol **p_libc_wasi_apis); + +uint32 +get_base_lib_export_apis(NativeSymbol **p_base_lib_apis); + +uint32 +get_ext_lib_export_apis(NativeSymbol **p_ext_lib_apis); + +#if WASM_ENABLE_LIB_PTHREAD != 0 +bool +lib_pthread_init(); + +void +lib_pthread_destroy(); + +uint32 +get_lib_pthread_export_apis(NativeSymbol **p_lib_pthread_apis); +#endif + +#if WASM_ENABLE_LIB_WASI_THREADS != 0 +bool +lib_wasi_threads_init(void); + +void +lib_wasi_threads_destroy(void); + +uint32 +get_lib_wasi_threads_export_apis(NativeSymbol **p_lib_wasi_threads_apis); +#endif + +uint32 +get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis); + +uint32 +get_lib_rats_export_apis(NativeSymbol **p_lib_rats_apis); + +static bool +compare_type_with_signautre(uint8 type, const char signature) +{ + const char num_sig_map[] = { 'F', 'f', 'I', 'i' }; + + if (VALUE_TYPE_F64 <= type && type <= VALUE_TYPE_I32 + && signature == num_sig_map[type - VALUE_TYPE_F64]) { + return true; + } + +#if WASM_ENABLE_REF_TYPES != 0 + if ('r' == signature && type == VALUE_TYPE_EXTERNREF) + return true; +#endif + + /* TODO: a v128 parameter */ + return false; +} + +static bool +check_symbol_signature(const WASMType *type, const char *signature) +{ + const char *p = signature, *p_end; + char sig; + uint32 i = 0; + + if (!p || strlen(p) < 2) + return false; + + p_end = p + strlen(signature); + + if (*p++ != '(') + return false; + + if ((uint32)(p_end - p) < (uint32)(type->param_count + 1)) + /* signatures of parameters, and ')' */ + return false; + + for (i = 0; i < type->param_count; i++) { + sig = *p++; + + /* a f64/f32/i64/i32/externref parameter */ + if (compare_type_with_signautre(type->types[i], sig)) + continue; + + /* a pointer/string paramter */ + if (type->types[i] != VALUE_TYPE_I32) + /* pointer and string must be i32 type */ + return false; + + if (sig == '*') { + /* it is a pointer */ + if (i + 1 < type->param_count + && type->types[i + 1] == VALUE_TYPE_I32 && *p == '~') { + /* pointer length followed */ + i++; + p++; + } + } + else if (sig == '$') { + /* it is a string */ + } + else { + /* invalid signature */ + return false; + } + } + + if (*p++ != ')') + return false; + + if (type->result_count) { + if (p >= p_end) + return false; + + /* result types includes: f64,f32,i64,i32,externref */ + if (!compare_type_with_signautre(type->types[i], *p)) + return false; + + p++; + } + + if (*p != '\0') + return false; + + return true; +} + +#if ENABLE_QUICKSORT == 0 +static void +sort_symbol_ptr(NativeSymbol *native_symbols, uint32 n_native_symbols) +{ + uint32 i, j; + NativeSymbol temp; + + for (i = 0; i < n_native_symbols - 1; i++) { + for (j = i + 1; j < n_native_symbols; j++) { + if (strcmp(native_symbols[i].symbol, native_symbols[j].symbol) + > 0) { + temp = native_symbols[i]; + native_symbols[i] = native_symbols[j]; + native_symbols[j] = temp; + } + } + } +} +#else +static void +swap_symbol(NativeSymbol *left, NativeSymbol *right) +{ + NativeSymbol temp = *left; + *left = *right; + *right = temp; +} + +static void +quick_sort_symbols(NativeSymbol *native_symbols, int left, int right) +{ + NativeSymbol base_symbol; + int pin_left = left; + int pin_right = right; + + if (left >= right) { + return; + } + + base_symbol = native_symbols[left]; + while (left < right) { + while (left < right + && strcmp(native_symbols[right].symbol, base_symbol.symbol) + > 0) { + right--; + } + + if (left < right) { + swap_symbol(&native_symbols[left], &native_symbols[right]); + left++; + } + + while (left < right + && strcmp(native_symbols[left].symbol, base_symbol.symbol) < 0) { + left++; + } + + if (left < right) { + swap_symbol(&native_symbols[left], &native_symbols[right]); + right--; + } + } + native_symbols[left] = base_symbol; + + quick_sort_symbols(native_symbols, pin_left, left - 1); + quick_sort_symbols(native_symbols, left + 1, pin_right); +} +#endif /* end of ENABLE_QUICKSORT */ + +static void * +lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols, + const char *symbol, const char **p_signature, void **p_attachment) +{ + int low = 0, mid, ret; + int high = (int32)n_native_symbols - 1; + + while (low <= high) { + mid = (low + high) / 2; + ret = strcmp(symbol, native_symbols[mid].symbol); + if (ret == 0) { + *p_signature = native_symbols[mid].signature; + *p_attachment = native_symbols[mid].attachment; + return native_symbols[mid].func_ptr; + } + else if (ret < 0) + high = mid - 1; + else + low = mid + 1; + } + + return NULL; +} + +/** + * allow func_type and all outputs, like p_signature, p_attachment and + * p_call_conv_raw to be NULL + */ +void * +wasm_native_resolve_symbol(const char *module_name, const char *field_name, + const WASMType *func_type, const char **p_signature, + void **p_attachment, bool *p_call_conv_raw) +{ + NativeSymbolsNode *node, *node_next; + const char *signature = NULL; + void *func_ptr = NULL, *attachment; + + node = g_native_symbols_list; + while (node) { + node_next = node->next; + if (!strcmp(node->module_name, module_name)) { + if ((func_ptr = + lookup_symbol(node->native_symbols, node->n_native_symbols, + field_name, &signature, &attachment)) + || (field_name[0] == '_' + && (func_ptr = lookup_symbol( + node->native_symbols, node->n_native_symbols, + field_name + 1, &signature, &attachment)))) + break; + } + node = node_next; + } + + if (!p_signature || !p_attachment || !p_call_conv_raw) + return func_ptr; + + if (func_ptr) { + if (signature && signature[0] != '\0') { + /* signature is not empty, check its format */ + if (!func_type || !check_symbol_signature(func_type, signature)) { +#if WASM_ENABLE_WAMR_COMPILER == 0 + /* Output warning except running aot compiler */ + LOG_WARNING("failed to check signature '%s' and resolve " + "pointer params for import function (%s %s)\n", + signature, module_name, field_name); +#endif + return NULL; + } + else + /* Save signature for runtime to do pointer check and + address conversion */ + *p_signature = signature; + } + else + /* signature is empty */ + *p_signature = NULL; + + *p_attachment = attachment; + *p_call_conv_raw = node->call_conv_raw; + } + + return func_ptr; +} + +static bool +register_natives(const char *module_name, NativeSymbol *native_symbols, + uint32 n_native_symbols, bool call_conv_raw) +{ + NativeSymbolsNode *node; +#if ENABLE_SORT_DEBUG != 0 + struct timeval start; + struct timeval end; + unsigned long timer; +#endif + + if (!(node = wasm_runtime_malloc(sizeof(NativeSymbolsNode)))) + return false; +#if WASM_ENABLE_MEMORY_TRACING != 0 + os_printf("Register native, size: %u\n", sizeof(NativeSymbolsNode)); +#endif + + node->module_name = module_name; + node->native_symbols = native_symbols; + node->n_native_symbols = n_native_symbols; + node->call_conv_raw = call_conv_raw; + + /* Add to list head */ + node->next = g_native_symbols_list; + g_native_symbols_list = node; + +#if ENABLE_SORT_DEBUG != 0 + gettimeofday(&start, NULL); +#endif + +#if ENABLE_QUICKSORT == 0 + sort_symbol_ptr(native_symbols, n_native_symbols); +#else + quick_sort_symbols(native_symbols, 0, (int)(n_native_symbols - 1)); +#endif + +#if ENABLE_SORT_DEBUG != 0 + gettimeofday(&end, NULL); + timer = + 1000000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec); + LOG_ERROR("module_name: %s, nums: %d, sorted used: %ld us", module_name, + n_native_symbols, timer); +#endif + return true; +} + +bool +wasm_native_register_natives(const char *module_name, + NativeSymbol *native_symbols, + uint32 n_native_symbols) +{ + return register_natives(module_name, native_symbols, n_native_symbols, + false); +} + +bool +wasm_native_register_natives_raw(const char *module_name, + NativeSymbol *native_symbols, + uint32 n_native_symbols) +{ + return register_natives(module_name, native_symbols, n_native_symbols, + true); +} + +bool +wasm_native_unregister_natives(const char *module_name, + NativeSymbol *native_symbols) +{ + NativeSymbolsNode **prevp; + NativeSymbolsNode *node; + + prevp = &g_native_symbols_list; + while ((node = *prevp) != NULL) { + if (node->native_symbols == native_symbols + && !strcmp(node->module_name, module_name)) { + *prevp = node->next; + wasm_runtime_free(node); + return true; + } + prevp = &node->next; + } + return false; +} + +bool +wasm_native_init() +{ +#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \ + || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \ + || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \ + || WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \ + || WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0 + NativeSymbol *native_symbols; + uint32 n_native_symbols; +#endif + +#if WASM_ENABLE_LIBC_BUILTIN != 0 + n_native_symbols = get_libc_builtin_export_apis(&native_symbols); + if (!wasm_native_register_natives("env", native_symbols, n_native_symbols)) + goto fail; +#endif /* WASM_ENABLE_LIBC_BUILTIN */ + +#if WASM_ENABLE_SPEC_TEST + n_native_symbols = get_spectest_export_apis(&native_symbols); + if (!wasm_native_register_natives("spectest", native_symbols, + n_native_symbols)) + goto fail; +#endif /* WASM_ENABLE_SPEC_TEST */ + +#if WASM_ENABLE_LIBC_WASI != 0 + n_native_symbols = get_libc_wasi_export_apis(&native_symbols); + if (!wasm_native_register_natives("wasi_unstable", native_symbols, + n_native_symbols)) + goto fail; + if (!wasm_native_register_natives("wasi_snapshot_preview1", native_symbols, + n_native_symbols)) + goto fail; +#endif + +#if WASM_ENABLE_BASE_LIB != 0 + n_native_symbols = get_base_lib_export_apis(&native_symbols); + if (n_native_symbols > 0 + && !wasm_native_register_natives("env", native_symbols, + n_native_symbols)) + goto fail; +#endif + +#if WASM_ENABLE_APP_FRAMEWORK != 0 + n_native_symbols = get_ext_lib_export_apis(&native_symbols); + if (n_native_symbols > 0 + && !wasm_native_register_natives("env", native_symbols, + n_native_symbols)) + goto fail; +#endif + +#if WASM_ENABLE_LIB_PTHREAD != 0 + if (!lib_pthread_init()) + goto fail; + + n_native_symbols = get_lib_pthread_export_apis(&native_symbols); + if (n_native_symbols > 0 + && !wasm_native_register_natives("env", native_symbols, + n_native_symbols)) + goto fail; +#endif + +#if WASM_ENABLE_LIB_WASI_THREADS != 0 + if (!lib_wasi_threads_init()) + goto fail; + + n_native_symbols = get_lib_wasi_threads_export_apis(&native_symbols); + if (n_native_symbols > 0 + && !wasm_native_register_natives("wasi", native_symbols, + n_native_symbols)) + goto fail; +#endif + +#if WASM_ENABLE_LIBC_EMCC != 0 + n_native_symbols = get_libc_emcc_export_apis(&native_symbols); + if (n_native_symbols > 0 + && !wasm_native_register_natives("env", native_symbols, + n_native_symbols)) + goto fail; +#endif /* WASM_ENABLE_LIBC_EMCC */ + +#if WASM_ENABLE_LIB_RATS != 0 + n_native_symbols = get_lib_rats_export_apis(&native_symbols); + if (n_native_symbols > 0 + && !wasm_native_register_natives("env", native_symbols, + n_native_symbols)) + goto fail; +#endif /* WASM_ENABLE_LIB_RATS */ + +#if WASM_ENABLE_WASI_NN != 0 + n_native_symbols = get_wasi_nn_export_apis(&native_symbols); + if (!wasm_native_register_natives("wasi_nn", native_symbols, + n_native_symbols)) + goto fail; +#endif + + return true; +#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \ + || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \ + || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \ + || WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \ + || WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0 +fail: + wasm_native_destroy(); + return false; +#endif +} + +void +wasm_native_destroy() +{ + NativeSymbolsNode *node, *node_next; + +#if WASM_ENABLE_LIB_PTHREAD != 0 + lib_pthread_destroy(); +#endif + +#if WASM_ENABLE_LIB_WASI_THREADS != 0 + lib_wasi_threads_destroy(); +#endif + + node = g_native_symbols_list; + while (node) { + node_next = node->next; + wasm_runtime_free(node); + node = node_next; + } + + g_native_symbols_list = NULL; +} |