From 5e196253f66e4d6605cb1ed2c1c0636ccb51e448 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Tue, 7 Apr 2020 11:04:46 +0800 Subject: [PATCH] Fix function type not set issue of aot_call_indirect (#229) Add registration of libc-wasi to 'wasi_snapshot_preview1' to support cargo-wasi change zephyr build method from cmake to west fix problem when preserve space for local vars fix wasi authority problem --- .gitignore | 3 + _clang-format | 129 ++++++++++++++++++ build-scripts/config_common.cmake | 12 +- core/iwasm/aot/aot_loader.c | 3 +- core/iwasm/aot/aot_runtime.c | 17 ++- core/iwasm/aot/aot_runtime.h | 3 +- core/iwasm/aot/iwasm_aot.cmake | 14 +- core/iwasm/common/iwasm_common.cmake | 20 +-- core/iwasm/common/wasm_native.c | 3 + core/iwasm/common/wasm_runtime_common.c | 51 ++++++- core/iwasm/common/wasm_runtime_common.h | 24 +++- core/iwasm/compilation/aot_emit_function.c | 32 +++-- core/iwasm/interpreter/wasm_loader.c | 33 +++-- core/iwasm/interpreter/wasm_runtime.c | 39 ++++++ core/iwasm/interpreter/wasm_runtime.h | 5 + .../sandboxed-system-primitives/src/posix.c | 25 +++- core/shared/platform/zephyr/zephyr_thread.c | 4 +- doc/build_wamr.md | 15 +- product-mini/platforms/zephyr/simple/build.sh | 62 --------- .../platforms/zephyr/simple/build_and_run.sh | 77 +++++++++++ samples/basic/.gitignore | 1 + samples/basic/build.sh | 1 + samples/basic/src/main.c | 24 ++++ samples/basic/src/native_impl.c | 31 +++++ samples/basic/wasm-apps/testapp.c | 26 ++++ samples/simple/.gitignore | 1 + 26 files changed, 512 insertions(+), 143 deletions(-) create mode 100644 _clang-format delete mode 100755 product-mini/platforms/zephyr/simple/build.sh create mode 100644 product-mini/platforms/zephyr/simple/build_and_run.sh create mode 100644 samples/basic/.gitignore create mode 100644 samples/simple/.gitignore diff --git a/.gitignore b/.gitignore index e6464977..0b2d0711 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ core/deps/llvm core/deps/lvgl core/shared/mem-alloc/tlsf +wamr-sdk/out/ +wamr-sdk/runtime/build_runtime_sdk/ +test-tools/host-tool/bin/ diff --git a/_clang-format b/_clang-format new file mode 100644 index 00000000..c9999702 --- /dev/null +++ b/_clang-format @@ -0,0 +1,129 @@ +--- +BasedOnStyle: Mozilla +IndentWidth: 4 + +--- +Language: Cpp +AlignConsecutiveMacros: true +AllowShortBlocksOnASingleLine: true +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: false + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: false + SplitEmptyNamespace: true +ColumnLimit: 79 +DerivePointerAlignment: false +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 1 + - Regex: ".*" + Priority: 3 +PointerAlignment: Right +ReflowComments: false +Standard: Cpp03 +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +# AccessModifierOffset: -2 +# AlignAfterOpenBracket: Align +# AlignConsecutiveAssignments: false +# AlignConsecutiveDeclarations: false +# AlignEscapedNewlines: Right +# AlignOperands: true +# AlignTrailingComments: true +# AllowAllArgumentsOnNextLine: true +# AllowAllConstructorInitializersOnNextLine: true +# AllowAllParametersOfDeclarationOnNextLine: false +# AllowShortCaseLabelsOnASingleLine: false +# AllowShortFunctionsOnASingleLine: Inline +# AllowShortLambdasOnASingleLine: All +# AllowShortIfStatementsOnASingleLine: Never +# AllowShortLoopsOnASingleLine: false +# AlwaysBreakAfterDefinitionReturnType: TopLevel +# AlwaysBreakAfterReturnType: TopLevel +# AlwaysBreakBeforeMultilineStrings: false +# AlwaysBreakTemplateDeclarations: Yes +# BreakBeforeBinaryOperators: None +# BreakBeforeInheritanceComma: false +# BreakInheritanceList: BeforeComma +# BreakBeforeTernaryOperators: true +# BreakConstructorInitializersBeforeComma: false +# BreakConstructorInitializers: BeforeComma +# BreakAfterJavaFieldAnnotations: false +# BreakStringLiterals: true +# CommentPragmas: '^ IWYU pragma:' +# CompactNamespaces: false +# ConstructorInitializerAllOnOneLineOrOnePerLine: false +# ConstructorInitializerIndentWidth: 2 +# ContinuationIndentWidth: 2 +# Cpp11BracedListStyle: false +# DisableFormat: false +# ExperimentalAutoDetectBinPacking: false +# FixNamespaceComments: false +# ForEachMacros: +# - foreach +# - Q_FOREACH +# - BOOST_FOREACH +# IncludeIsMainRegex: '(Test)?$' +# IndentCaseLabels: true +# IndentPPDirectives: None +# IndentWrappedFunctionNames: false +# JavaScriptQuotes: Leave +# JavaScriptWrapImports: true +# KeepEmptyLinesAtTheStartOfBlocks: true +# MacroBlockBegin: '' +# MacroBlockEnd: '' +# MaxEmptyLinesToKeep: 1 +# NamespaceIndentation: None +# ObjCBinPackProtocolList: Auto +# ObjCBlockIndentWidth: 2 +# ObjCSpaceAfterProperty: true +# ObjCSpaceBeforeProtocolList: false +# PenaltyBreakAssignment: 2 +# PenaltyBreakBeforeFirstCallParameter: 19 +# PenaltyBreakComment: 300 +# PenaltyBreakFirstLessLess: 120 +# PenaltyBreakString: 1000 +# PenaltyBreakTemplateDeclaration: 10 +# PenaltyExcessCharacter: 1000000 +# PenaltyReturnTypeOnItsOwnLine: 200 +# SortIncludes: true +# SortUsingDeclarations: true +# SpaceAfterCStyleCast: false +# SpaceAfterLogicalNot: false +# SpaceAfterTemplateKeyword: false +# SpaceBeforeAssignmentOperators: true +# SpaceBeforeCpp11BracedList: false +# SpaceBeforeCtorInitializerColon: true +# SpaceBeforeInheritanceColon: true +# SpaceBeforeParens: ControlStatements +# SpaceBeforeRangeBasedForLoopColon: true +# SpaceInEmptyParentheses: false +# SpacesBeforeTrailingComments: 1 +# SpacesInAngles: false +# SpacesInContainerLiterals: true +# SpacesInCStyleCastParentheses: false +# SpacesInParentheses: false +# SpacesInSquareBrackets: false +# TabWidth: 4 +# UseTab: Never +# ... + diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 572e8aec..2ec4d64f 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -94,33 +94,33 @@ message (" CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE}) if (WAMR_BUILD_INTERP EQUAL 1) message (" WAMR Interpreter enabled") else () - message (" WAMR Interpreter disbled") + message (" WAMR Interpreter disabled") endif () if (WAMR_BUILD_AOT EQUAL 1) message (" WAMR AOT enabled") else () - message (" WAMR AOT disbled") + message (" WAMR AOT disabled") endif () if (WAMR_BUILD_JIT EQUAL 1) message (" WAMR JIT enabled") else () - message (" WAMR JIT disbled") + message (" WAMR JIT disabled") endif () if (WAMR_BUILD_LIBC_BUILTIN EQUAL 1) message (" Libc builtin enabled") else () - message (" Libc builtin disbled") + message (" Libc builtin disabled") endif () if (WAMR_BUILD_LIBC_WASI EQUAL 1) message (" Libc WASI enabled") else () - message (" Libc WASI disbled") + message (" Libc WASI disabled") endif () if (WAMR_BUILD_FAST_INTERP EQUAL 1) add_definitions (-DWASM_ENABLE_FAST_INTERP=1) message (" Fast interpreter enabled") else () add_definitions (-DWASM_ENABLE_FAST_INTERP=0) - message (" Fast interpreter disbled") + message (" Fast interpreter disabled") endif () diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 00684221..f4115bbd 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -794,7 +794,8 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, } #if WASM_ENABLE_LIBC_WASI != 0 - if (!strcmp(import_funcs[i].module_name, "wasi_unstable")) + if (!strcmp(import_funcs[i].module_name, "wasi_unstable") + || !strcmp(import_funcs[i].module_name, "wasi_snapshot_preview1")) module->is_wasi_module = true; #endif } diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 6eaac0a6..c9397460 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -855,7 +855,8 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, bool aot_call_indirect(WASMExecEnv *exec_env, - uint32 func_type_idx, uint32 table_elem_idx, + bool check_func_type, uint32 func_type_idx, + uint32 table_elem_idx, uint32 *frame_lp, uint32 argc, uint32 *argv_ret) { AOTModuleInstance *module_inst = (AOTModuleInstance*) @@ -863,7 +864,7 @@ aot_call_indirect(WASMExecEnv *exec_env, AOTModule *aot_module = (AOTModule*)module_inst->aot_module.ptr; uint32 *func_type_indexes = (uint32*)module_inst->func_type_indexes.ptr; uint32 *table_data = (uint32*)module_inst->table_data.ptr; - AOTFuncType *func_type = aot_module->func_types[func_type_idx];; + AOTFuncType *func_type; void **func_ptrs = (void**)module_inst->func_ptrs.ptr, *func_ptr; uint32 table_size = module_inst->table_size; uint32 func_idx, func_type_idx1; @@ -884,10 +885,14 @@ aot_call_indirect(WASMExecEnv *exec_env, } func_type_idx1 = func_type_indexes[func_idx]; - if (!aot_is_wasm_type_equal(module_inst, func_type_idx, func_type_idx1)) { - aot_set_exception_with_id(module_inst, EXCE_INVALID_FUNCTION_TYPE_INDEX); + if (check_func_type + && !aot_is_wasm_type_equal(module_inst, func_type_idx, + func_type_idx1)) { + aot_set_exception_with_id(module_inst, + EXCE_INVALID_FUNCTION_TYPE_INDEX); return false; } + func_type = aot_module->func_types[func_type_idx1]; if (!(func_ptr = func_ptrs[func_idx])) { bh_assert(func_idx < aot_module->import_func_count); @@ -906,7 +911,8 @@ aot_call_indirect(WASMExecEnv *exec_env, if (import_func->call_conv_raw) { attachment = import_func->attachment; return wasm_runtime_invoke_native_raw(exec_env, func_ptr, - func_type, signature, attachment, + func_type, signature, + attachment, frame_lp, argc, argv_ret); } } @@ -915,4 +921,3 @@ aot_call_indirect(WASMExecEnv *exec_env, func_type, signature, attachment, frame_lp, argc, argv_ret); } - diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 35edd168..0bd4c765 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -445,7 +445,8 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, bool aot_call_indirect(WASMExecEnv *exec_env, - uint32 func_type_idx, uint32 table_elem_idx, + bool check_func_type, uint32 func_type_idx, + uint32 table_elem_idx, uint32 *frame_lp, uint32 argc, uint32 *argv_ret); uint32 diff --git a/core/iwasm/aot/iwasm_aot.cmake b/core/iwasm/aot/iwasm_aot.cmake index db26357e..e7d0549d 100644 --- a/core/iwasm/aot/iwasm_aot.cmake +++ b/core/iwasm/aot/iwasm_aot.cmake @@ -9,19 +9,19 @@ include_directories (${IWASM_AOT_DIR}) file (GLOB c_source_all ${IWASM_AOT_DIR}/*.c) -if (${WAMR_BUILD_TARGET} STREQUAL "X86_64" OR ${WAMR_BUILD_TARGET} STREQUAL "AMD_64") +if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_x86_64.c) -elseif (${WAMR_BUILD_TARGET} STREQUAL "X86_32") +elseif (WAMR_BUILD_TARGET STREQUAL "X86_32") set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_x86_32.c) -elseif (${WAMR_BUILD_TARGET} MATCHES "AARCH64.*") +elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*") set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_aarch64.c) -elseif (${WAMR_BUILD_TARGET} MATCHES "ARM.*") +elseif (WAMR_BUILD_TARGET MATCHES "ARM.*") set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_arm.c) -elseif (${WAMR_BUILD_TARGET} MATCHES "THUMB.*") +elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*") set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_thumb.c) -elseif (${WAMR_BUILD_TARGET} STREQUAL "MIPS") +elseif (WAMR_BUILD_TARGET STREQUAL "MIPS") set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_mips.c) -elseif (${WAMR_BUILD_TARGET} STREQUAL "XTENSA") +elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA") set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_xtensa.c) else () message (FATAL_ERROR "Build target isn't set") diff --git a/core/iwasm/common/iwasm_common.cmake b/core/iwasm/common/iwasm_common.cmake index 5dfd9ee2..aa3683d3 100644 --- a/core/iwasm/common/iwasm_common.cmake +++ b/core/iwasm/common/iwasm_common.cmake @@ -10,29 +10,29 @@ add_definitions(-DBH_FREE=wasm_runtime_free) file (GLOB c_source_all ${IWASM_COMMON_DIR}/*.c) -if (${WAMR_BUILD_TARGET} STREQUAL "X86_64" OR ${WAMR_BUILD_TARGET} STREQUAL "AMD_64") +if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_em64.s) -elseif (${WAMR_BUILD_TARGET} STREQUAL "X86_32") +elseif (WAMR_BUILD_TARGET STREQUAL "X86_32") set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_ia32.s) -elseif (${WAMR_BUILD_TARGET} MATCHES "ARM.*") - if (${WAMR_BUILD_TARGET} MATCHES "ARM.*_VFP") +elseif (WAMR_BUILD_TARGET MATCHES "ARM.*") + if (WAMR_BUILD_TARGET MATCHES "ARM.*_VFP") set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_arm_vfp.s) else () set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_arm.s) endif () -elseif (${WAMR_BUILD_TARGET} MATCHES "THUMB.*") - if (${WAMR_BUILD_TARGET} MATCHES "THUMB.*_VFP") +elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*") + if (WAMR_BUILD_TARGET MATCHES "THUMB.*_VFP") set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_thumb_vfp.s) else () set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_thumb.s) endif () -elseif (${WAMR_BUILD_TARGET} MATCHES "AARCH64.*") +elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*") set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_aarch64.s) -elseif (${WAMR_BUILD_TARGET} STREQUAL "MIPS") +elseif (WAMR_BUILD_TARGET STREQUAL "MIPS") set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_mips.s) -elseif (${WAMR_BUILD_TARGET} STREQUAL "XTENSA") +elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA") set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_xtensa.s) -elseif (${WAMR_BUILD_TARGET} STREQUAL "GENERAL") +elseif (WAMR_BUILD_TARGET STREQUAL "GENERAL") # Use invokeNative_general.c instead of assembly code, # but the maximum number of native arguments is limited to 20, # and there are possible issues when passing arguments to diff --git a/core/iwasm/common/wasm_native.c b/core/iwasm/common/wasm_native.c index d16dd9c3..cbbf2fbd 100644 --- a/core/iwasm/common/wasm_native.c +++ b/core/iwasm/common/wasm_native.c @@ -251,6 +251,9 @@ wasm_native_init() if (!wasm_native_register_natives("wasi_unstable", native_symbols, n_native_symbols)) return false; + if (!wasm_native_register_natives("wasi_snapshot_preview1", + native_symbols, n_native_symbols)) + return false; #endif #if WASM_ENABLE_BASE_LIB != 0 diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 02041657..ea86d952 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -37,6 +37,17 @@ wasm_runtime_env_init() return true; } +static bool +wasm_runtime_env_check(WASMExecEnv *exec_env) +{ + return !(!exec_env + || !exec_env->module_inst + || exec_env->wasm_stack_size == 0 + || exec_env->wasm_stack.s.top_boundary != + exec_env->wasm_stack.s.bottom + exec_env->wasm_stack_size + || exec_env->wasm_stack.s.top > exec_env->wasm_stack.s.top_boundary); +} + bool wasm_runtime_init() { @@ -276,12 +287,7 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env, WASMFunctionInstanceCommon *function, unsigned argc, uint32 argv[]) { - if (!exec_env - || !exec_env->module_inst - || exec_env->wasm_stack_size == 0 - || exec_env->wasm_stack.s.top_boundary != - exec_env->wasm_stack.s.bottom + exec_env->wasm_stack_size - || exec_env->wasm_stack.s.top > exec_env->wasm_stack.s.top_boundary) { + if (!wasm_runtime_env_check(exec_env)) { LOG_ERROR("Invalid exec env stack info."); return false; } @@ -1392,15 +1398,19 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst, break; case VALUE_TYPE_I64: { - char buf[16]; union { uint64 val; uint32 parts[2]; } u; u.parts[0] = argv1[0]; u.parts[1] = argv1[1]; +#ifdef PRIx64 + os_printf("0x%"PRIx64":i64", u.val); +#else + char buf[16]; if (sizeof(long) == 4) snprintf(buf, sizeof(buf), "%s", "0x%llx:i64"); else snprintf(buf, sizeof(buf), "%s", "0x%lx:i64"); os_printf(buf, u.val); +#endif break; } case VALUE_TYPE_F32: @@ -2110,6 +2120,33 @@ fail: return ret; } +bool +wasm_runtime_call_indirect(WASMExecEnv *exec_env, + uint32_t element_indices, + uint32_t argc, uint32_t argv[]) +{ + if (!wasm_runtime_env_check(exec_env)) { + LOG_ERROR("Invalid exec env stack info."); + return false; + } + + exec_env->handle = os_self_thread(); + +#if WASM_ENABLE_INTERP != 0 + if (exec_env->module_inst->module_type == Wasm_Module_Bytecode) + return wasm_call_indirect(exec_env, + element_indices, + argc, argv); +#endif +#if WASM_ENABLE_AOT != 0 + if (exec_env->module_inst->module_type == Wasm_Module_AoT) + return aot_call_indirect(exec_env, false, 0, + element_indices, + argv, argc, argv); +#endif + return false; +} + #endif /* end of defined(BUILD_TARGET_X86_64) \ || defined(BUILD_TARGET_AMD_64) \ || defined(BUILD_TARGET_AARCH64) */ diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 3006d730..3490620b 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -131,6 +131,28 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env, WASMFunctionInstanceCommon *function, unsigned argc, uint32 argv[]); +/** + * Call a function reference of a given WASM runtime instance with + * arguments. + * + * @param exec_env the execution environment to call the function + * which must be created from wasm_create_exec_env() + * @param element_indices the function ference indicies, usually + * prvovided by the caller of a registed native function + * @param argc the number of arguments + * @param argv the arguments. If the function method has return value, + * the first (or first two in case 64-bit return value) element of + * argv stores the return value of the called WASM function after this + * function returns. + * + * @return true if success, false otherwise and exception will be thrown, + * the caller can call wasm_runtime_get_exception to get exception info. + */ +bool +wasm_runtime_call_indirect(WASMExecEnv *exec_env, + uint32_t element_indices, + uint32_t argc, uint32_t argv[]); + bool wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst, WASMFunctionInstanceCommon *function, @@ -269,6 +291,7 @@ wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst, WASIContext * wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst); + #endif /* end of WASM_ENABLE_LIBC_WASI */ /** @@ -305,7 +328,6 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr, void *attachment, uint32 *argv, uint32 argc, uint32 *ret); - #ifdef __cplusplus } #endif diff --git a/core/iwasm/compilation/aot_emit_function.c b/core/iwasm/compilation/aot_emit_function.c index 72ea7c67..0a8d2a1a 100644 --- a/core/iwasm/compilation/aot_emit_function.c +++ b/core/iwasm/compilation/aot_emit_function.c @@ -395,21 +395,22 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMTypeRef ret_type, uint8 wasm_ret_type, LLVMValueRef *p_value_ret, LLVMValueRef *p_res) { - LLVMTypeRef func_type, func_ptr_type, func_param_types[6]; + LLVMTypeRef func_type, func_ptr_type, func_param_types[7]; LLVMTypeRef ret_ptr_type, elem_ptr_type; LLVMValueRef func, elem_idx, elem_ptr; - LLVMValueRef func_param_values[6], value_ret = NULL, value_ret_ptr, res = NULL; + LLVMValueRef func_param_values[7], value_ret = NULL, value_ret_ptr, res = NULL; char buf[32], *func_name = "aot_call_indirect"; uint32 i, cell_num = 0; /* prepare function type of aot_call_indirect */ func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */ - func_param_types[1] = I32_TYPE; /* func_type_idx */ - func_param_types[2] = I32_TYPE; /* table_elem_idx */ - func_param_types[3] = INT32_PTR_TYPE; /* frame_lp */ - func_param_types[4] = I32_TYPE; /* argc */ - func_param_types[5] = INT32_PTR_TYPE; /* argv_ret */ - if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 6, false))) { + func_param_types[1] = INT8_TYPE; /* check_func_type */ + func_param_types[2] = I32_TYPE; /* func_type_idx */ + func_param_types[3] = I32_TYPE; /* table_elem_idx */ + func_param_types[4] = INT32_PTR_TYPE; /* frame_lp */ + func_param_types[5] = I32_TYPE; /* argc */ + func_param_types[6] = INT32_PTR_TYPE; /* argv_ret */ + if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 7, false))) { aot_set_last_error("llvm add function type failed."); return false; } @@ -493,20 +494,21 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } func_param_values[0] = func_ctx->exec_env; - func_param_values[1] = func_type_idx; - func_param_values[2] = table_elem_idx; - func_param_values[3] = func_ctx->argv_buf; - func_param_values[4] = I32_CONST(param_cell_num); - func_param_values[5] = value_ret_ptr; + func_param_values[1] = I8_CONST(true); + func_param_values[2] = func_type_idx; + func_param_values[3] = table_elem_idx; + func_param_values[4] = func_ctx->argv_buf; + func_param_values[5] = I32_CONST(param_cell_num); + func_param_values[6] = value_ret_ptr; - if (!func_param_values[4]) { + if (!func_param_values[1] || !func_param_values[4]) { aot_set_last_error("llvm create const failed."); return false; } /* call aot_call_indirect() function */ if (!(res = LLVMBuildCall(comp_ctx->builder, func, - func_param_values, 6, "res"))) { + func_param_values, 7, "res"))) { aot_set_last_error("llvm build call failed."); return false; } diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index d64f106f..f136f4c1 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -675,9 +675,11 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, p = p_old; - /* insert "env" and "wasi_unstable" to const str list */ + /* insert "env", "wasi_unstable" and "wasi_snapshot_preview1" to const str list */ if (!const_str_list_insert((uint8*)"env", 3, module, error_buf, error_buf_size) || !const_str_list_insert((uint8*)"wasi_unstable", 13, module, + error_buf, error_buf_size) + || !const_str_list_insert((uint8*)"wasi_snapshot_preview1", 22, module, error_buf, error_buf_size)) { return false; } @@ -797,7 +799,8 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, #if WASM_ENABLE_LIBC_WASI != 0 import = module->import_functions; for (i = 0; i < module->import_function_count; i++, import++) { - if (!strcmp(import->u.names.module_name, "wasi_unstable")) { + if (!strcmp(import->u.names.module_name, "wasi_unstable") + || !strcmp(import->u.names.module_name, "wasi_snapshot_preview1")) { module->is_wasi_module = true; break; } @@ -2377,6 +2380,9 @@ typedef struct WASMLoaderContext { int16 start_dynamic_offset; int16 max_dynamic_offset; + /* preserved local offset */ + int16 preserved_local_offset; + /* const buffer */ uint8 *const_buf; uint16 num_const; @@ -2873,6 +2879,9 @@ wasm_loader_ctx_reinit(WASMLoaderContext *ctx) ctx->frame_offset = ctx->frame_offset_bottom; ctx->dynamic_offset = ctx->start_dynamic_offset; + /* init preserved local offsets */ + ctx->preserved_local_offset = ctx->max_dynamic_offset; + /* const buf is reserved */ return true; } @@ -2950,19 +2959,21 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode, skip_label(); if (local_type == VALUE_TYPE_I32 || local_type == VALUE_TYPE_F32) { - preserved_offset = loader_ctx->dynamic_offset++; + preserved_offset = loader_ctx->preserved_local_offset; + /* Only increase preserve offset in the second traversal */ + if (loader_ctx->p_code_compiled) + loader_ctx->preserved_local_offset++; emit_label(EXT_OP_COPY_STACK_TOP); } else { - preserved_offset = loader_ctx->dynamic_offset; - loader_ctx->dynamic_offset += 2; + preserved_offset = loader_ctx->preserved_local_offset; + if (loader_ctx->p_code_compiled) + loader_ctx->preserved_local_offset += 2; emit_label(EXT_OP_COPY_STACK_TOP_I64); } emit_operand(loader_ctx, local_index); emit_operand(loader_ctx, preserved_offset); emit_label(opcode); - if (loader_ctx->dynamic_offset > loader_ctx->max_dynamic_offset) - loader_ctx->max_dynamic_offset = loader_ctx->dynamic_offset; } loader_ctx->frame_offset_bottom[i] = preserved_offset; } @@ -3116,12 +3127,14 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type, if (type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32) { ctx->frame_offset -= 1; - if (*(ctx->frame_offset) > ctx->start_dynamic_offset) + if ((*(ctx->frame_offset) > ctx->start_dynamic_offset) + && (*(ctx->frame_offset) < ctx->max_dynamic_offset)) ctx->dynamic_offset -= 1; } else { ctx->frame_offset -= 2; - if (*(ctx->frame_offset) > ctx->start_dynamic_offset) + if ((*(ctx->frame_offset) > ctx->start_dynamic_offset) + && (*(ctx->frame_offset) < ctx->max_dynamic_offset)) ctx->dynamic_offset -= 2; } emit_operand(ctx, *(ctx->frame_offset)); @@ -4682,7 +4695,7 @@ handle_next_reachable_block: } } - func->max_stack_cell_num = loader_ctx->max_dynamic_offset - + func->max_stack_cell_num = loader_ctx->preserved_local_offset - loader_ctx->start_dynamic_offset + 1; #else func->max_stack_cell_num = loader_ctx->max_stack_cell_num; diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index d851c5ef..e69730da 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1166,3 +1166,42 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) #endif /* end of WASM_ENABLE_MEMORY_GROW */ } + +bool +wasm_call_indirect(WASMExecEnv *exec_env, + uint32_t element_indices, + uint32_t argc, uint32_t argv[]) +{ + WASMModuleInstance *module_inst = NULL; + WASMTableInstance *table_inst = NULL; + uint32_t function_indices = 0; + WASMFunctionInstance *function_inst = NULL; + + module_inst = + (WASMModuleInstance*)exec_env->module_inst; + bh_assert(module_inst); + + table_inst = module_inst->default_table; + if (!table_inst) { + wasm_set_exception(module_inst, "there is no table"); + goto got_exception; + } + + if (element_indices >= table_inst->cur_size) { + wasm_set_exception(module_inst, "undefined element"); + goto got_exception; + } + + function_indices = ((uint32_t*)table_inst->base_addr)[element_indices]; + if (function_indices == 0xFFFFFFFF) { + wasm_set_exception(module_inst, "uninitialized element"); + goto got_exception; + } + + function_inst = module_inst->functions + function_indices; + wasm_interp_call_wasm(module_inst, exec_env, function_inst, argc, argv); + return !wasm_get_exception(module_inst) ? true : false; + +got_exception: + return false; +} diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index bf172b28..03a5e4d4 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -280,6 +280,11 @@ wasm_get_native_addr_range(WASMModuleInstance *module_inst, bool wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count); +bool +wasm_call_indirect(WASMExecEnv *exec_env, + uint32_t element_indices, + uint32_t argc, uint32_t argv[]); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index e940dc19..bcad8361 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -1908,6 +1908,21 @@ __wasi_errno_t wasmtime_ssp_path_open( close(nfd); return error; } + + { + struct stat sb; + + if (fstat(nfd, &sb) < 0) { + close(nfd); + return convert_errno(errno); + } + + if (S_ISDIR(sb.st_mode)) + rights_base |= RIGHTS_DIRECTORY_BASE; + else if (S_ISREG(sb.st_mode)) + rights_base |= RIGHTS_REGULAR_FILE_BASE; + } + return fd_table_insert_fd(curfds, nfd, type, rights_base & max_base, rights_inheriting & max_inheriting, fd); } @@ -2273,8 +2288,14 @@ __wasi_errno_t wasmtime_ssp_path_filestat_set_times( __wasi_timestamp_t st_mtim, __wasi_fstflags_t fstflags ) { - if ((fstflags & ~(__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW | - __WASI_FILESTAT_SET_MTIM | __WASI_FILESTAT_SET_MTIM_NOW)) != 0) + if (((fstflags & ~(__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW | + __WASI_FILESTAT_SET_MTIM | __WASI_FILESTAT_SET_MTIM_NOW)) != 0) + /* ATIM & ATIM_NOW can't be set at the same time */ + || ((fstflags & __WASI_FILESTAT_SET_ATIM) != 0 + && (fstflags & __WASI_FILESTAT_SET_ATIM_NOW) != 0) + /* MTIM & MTIM_NOW can't be set at the same time */ + || ((fstflags & __WASI_FILESTAT_SET_MTIM) != 0 + && (fstflags & __WASI_FILESTAT_SET_MTIM_NOW) != 0)) return __WASI_EINVAL; struct path_access pa; diff --git a/core/shared/platform/zephyr/zephyr_thread.c b/core/shared/platform/zephyr/zephyr_thread.c index 0399ae03..cbed2596 100644 --- a/core/shared/platform/zephyr/zephyr_thread.c +++ b/core/shared/platform/zephyr/zephyr_thread.c @@ -325,7 +325,7 @@ int os_thread_join(korp_tid thread, void **value_ptr) k_sem_take(&node->sem, K_FOREVER); /* Wait some time for the thread to be actually terminated */ - k_sleep(100); + k_sleep(Z_TIMEOUT_MS(100)); /* Destroy resource */ BH_FREE(node); @@ -399,7 +399,7 @@ static int os_cond_wait_internal(korp_cond *cond, korp_mutex *mutex, /* Unlock mutex, wait sem and lock mutex again */ k_mutex_unlock(mutex); - k_sem_take(&node->sem, timed ? mills : K_FOREVER); + k_sem_take(&node->sem, timed ? Z_TIMEOUT_MS(mills) : K_FOREVER); k_mutex_lock(mutex, K_FOREVER); /* Remove wait node from wait list */ diff --git a/doc/build_wamr.md b/doc/build_wamr.md index 3bc01a48..4485a434 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -218,22 +218,11 @@ cp -a /product-mini/platforms/zephyr/simple . cd simple ln -s wamr source ../../zephyr-env.sh +# Execute the ./build_and_run.sh script with board name as parameter. Here take x86 as example: +./build_and_run.sh x86 ``` -1. build for x86 (qemu_x86_nommu) -``` Bash -./build.sh x86 -``` -2. build for ARM (nucleo_f767zi) -``` Bash -./build.sh stm32 -``` -3. build for AArch64 (qemu_cortex_a53) -``` Bash -./build.sh qemu_cortex_a53 -``` - Note: WAMR provides some features which can be easily configured by passing options to cmake, please see [Linux platform](./build_wamr.md#linux) for details. Currently in Zephyr, interpreter, AoT and builtin libc are enabled by default. diff --git a/product-mini/platforms/zephyr/simple/build.sh b/product-mini/platforms/zephyr/simple/build.sh deleted file mode 100755 index 245af8ac..00000000 --- a/product-mini/platforms/zephyr/simple/build.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -# Copyright (C) 2019 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -X86_TARGET="x86" -STM32_TARGET="stm32" -QEMU_CORTEX_A53="qemu_cortex_a53" -XTENSA_QEMU_TARGET="xtensa-qemu" -ESP32_TARGET="esp32" - -if [ $# != 1 ] ; then - echo "USAGE:" - echo "$0 $X86_TARGET|$STM32_TARGET|$QEMU_CORTEX_A53|$XTENSA_QEMU_TARGET|$ESP32_TARGET" - echo "Example:" - echo " $0 $X86_TARGET" - echo " $0 $STM32_TARGET" - echo " $0 $QEMU_CORTEX_A53" - echo " $0 $XTENSA_QEMU_TARGET" - echo " $0 $ESP32_TARGET" - exit 1 -fi - -TARGET=$1 - -if [ "$TARGET" = "$X86_TARGET" ] ; then - cp prj_qemu_x86_nommu.conf prj.conf - rm -fr build && mkdir build && cd build - cmake -GNinja -DBOARD=qemu_x86_nommu -DWAMR_BUILD_TARGET=X86_32 .. - ninja - ninja run -elif [ "$TARGET" = "$STM32_TARGET" ] ; then - cp prj_nucleo767zi.conf prj.conf - rm -fr build && mkdir build && cd build - cmake -GNinja -DBOARD=nucleo_f767zi -DWAMR_BUILD_TARGET=THUMBV7 .. - ninja - ninja flash -elif [ "$TARGET" = "$XTENSA_QEMU_TARGET" ] ; then - cp prj_qemu_xtensa.conf prj.conf - rm -fr build && mkdir build && cd build - cmake -GNinja -DBOARD=qemu_xtensa -DWAMR_BUILD_TARGET=XTENSA .. - ninja - ninja run -elif [ "$TARGET" = "$ESP32_TARGET" ] ; then - # suppose you have set environment variable ESP_IDF_PATH - west build -b esp32 . -p always -- \ - -DESP_IDF_PATH=$ESP_IDF_PATH \ - -DCONF_FILE=prj_esp32.conf \ - -DWAMR_BUILD_TARGET=XTENSA - # suppose the serial port is /dev/ttyUSB1 and you should change to - # the real name accordingly - west flash -d ./build --skip-rebuild --esp-device /dev/ttyUSB1 -elif [ "$TARGET" = "$QEMU_CORTEX_A53" ] ; then - cp prj_qemu_cortex_a53.conf prj.conf - rm -fr build && mkdir build && cd build - cmake -GNinja -DBOARD=qemu_cortex_a53 -DWAMR_BUILD_TARGET=AARCH64 .. - ninja - ninja run -else - echo "unsupported target: $TARGET" - exit 1 -fi diff --git a/product-mini/platforms/zephyr/simple/build_and_run.sh b/product-mini/platforms/zephyr/simple/build_and_run.sh new file mode 100644 index 00000000..e222366f --- /dev/null +++ b/product-mini/platforms/zephyr/simple/build_and_run.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +X86_TARGET="x86" +STM32_TARGET="stm32" +QEMU_CORTEX_A53="qemu_cortex_a53" +XTENSA_QEMU_TARGET="xtensa-qemu" +ESP32_TARGET="esp32" + +usage () +{ + echo "USAGE:" + echo "$0 $X86_TARGET|$STM32_TARGET|$QEMU_CORTEX_A53|$XTENSA_QEMU_TARGET|$ESP32_TARGET" + echo "Example:" + echo " $0 $X86_TARGET" + echo " $0 $STM32_TARGET" + echo " $0 $QEMU_CORTEX_A53" + echo " $0 $XTENSA_QEMU_TARGET" + echo " $0 $ESP32_TARGET" + exit 1 +} + +if [ $# != 1 ] ; then + usage +fi + +TARGET=$1 + +case $TARGET in + $X86_TARGET) + west build -b qemu_x86_nommu \ + . -p always -- \ + -DCONF_FILE=prj_qemu_x86_nommu.conf \ + -DWAMR_BUILD_TARGET=X86_32 + west build -t run + ;; + $STM32_TARGET) + west build -b nucleo_f767zi \ + . -p always -- \ + -DCONF_FILE=prj_nucleo767zi.conf \ + -DWAMR_BUILD_TARGET=THUMBV7 + west flash + ;; + $XTENSA_QEMU_TARGET) + west build -b qemu_xtensa \ + . -p always -- \ + -DCONF_FILE=prj_qemu_xtensa.conf \ + -DWAMR_BUILD_TARGET=XTENSA + west build -t run + ;; + $ESP32_TARGET) + # suppose you have set environment variable ESP_IDF_PATH + west build -b esp32 \ + . -p always -- \ + -DESP_IDF_PATH=$ESP_IDF_PATH \ + -DCONF_FILE=prj_esp32.conf \ + -DWAMR_BUILD_TARGET=XTENSA + # suppose the serial port is /dev/ttyUSB1 and you should change to + # the real name accordingly + west flash --esp-device /dev/ttyUSB1 + ;; + $QEMU_CORTEX_A53) + west build -b qemu_cortex_a53 \ + . -p always -- \ + -DCONF_FILE=prj_qemu_cortex_a53.conf \ + -DWAMR_BUILD_TARGET=AARCH64 + west build -t run + ;; + *) + echo "unsupported target: $TARGET" + usage + exit 1 + ;; +esac + diff --git a/samples/basic/.gitignore b/samples/basic/.gitignore new file mode 100644 index 00000000..0fa8a76b --- /dev/null +++ b/samples/basic/.gitignore @@ -0,0 +1 @@ +/out/ \ No newline at end of file diff --git a/samples/basic/build.sh b/samples/basic/build.sh index f16950e5..7e3442c5 100755 --- a/samples/basic/build.sh +++ b/samples/basic/build.sh @@ -44,6 +44,7 @@ OUT_FILE=${i%.*}.wasm -Wl,--no-threads,--strip-all,--no-entry -nostdlib \ -Wl,--export=generate_float \ -Wl,--export=float_to_string \ + -Wl,--export=calculate\ -Wl,--allow-undefined \ -o ${OUT_DIR}/wasm-apps/${OUT_FILE} ${APP_SRC} diff --git a/samples/basic/src/main.c b/samples/basic/src/main.c index 1e0e7b97..bbcd8335 100644 --- a/samples/basic/src/main.c +++ b/samples/basic/src/main.c @@ -9,6 +9,7 @@ int intToStr(int x, char* str, int str_len, int digit); int get_pow(int x, int y); +int32_t calculate_native(int32_t n, int32_t func1, int32_t func2); void print_usage(void) { @@ -75,6 +76,12 @@ int main(int argc, char *argv_main[]) get_pow, // the native function pointer "(ii)i", // the function prototype signature, avoid to use i32 NULL // attachment is NULL + }, + { + "calculate_native", + calculate_native, + "(iii)i", + NULL } }; @@ -167,6 +174,23 @@ int main(int argc, char *argv_main[]) goto fail; } + wasm_function_inst_t func3 = wasm_runtime_lookup_function(module_inst, + "calculate", + NULL); + if (!func3) { + printf("The wasm function calculate is not found.\n"); + goto fail; + } + + uint32_t argv3[1] = {3}; + if (wasm_runtime_call_wasm(exec_env, func3, 1, argv3)) { + uint32_t result = *(uint32_t*)argv3; + printf("Native finished calling wasm function: calculate, return: %d\n", result); + } else { + printf("call wasm function calculate failed. error: %s\n", wasm_runtime_get_exception(module_inst)); + goto fail; + } + fail: if(exec_env) wasm_runtime_destroy_exec_env(exec_env); if(module_inst) { diff --git a/samples/basic/src/native_impl.c b/samples/basic/src/native_impl.c index 6f27a3a4..b246d0e2 100644 --- a/samples/basic/src/native_impl.c +++ b/samples/basic/src/native_impl.c @@ -7,6 +7,11 @@ #include "wasm_export.h" #include "math.h" +extern bool +wasm_runtime_call_indirect(wasm_exec_env_t exec_env, + uint32_t element_indices, + uint32_t argc, uint32_t argv[]); + // The first parameter is not exec_env because it is invoked by native funtions void reverse(char * str, int len) { @@ -63,3 +68,29 @@ int get_pow(wasm_exec_env_t exec_env, int x, int y) { printf ("calling into native function: %s\n", __FUNCTION__); return (int)pow(x, y); } + +int32_t +calculate_native(wasm_exec_env_t exec_env, int32_t n, int32_t func1, + int32_t func2) +{ + printf("calling into native function: %s, n=%d, func1=%d, func2=%d\n", + __FUNCTION__, n, func1, func2); + + uint32_t argv[] = { n }; + if (!wasm_runtime_call_indirect(exec_env, func1, 1, argv)) { + printf("call func1 failed\n"); + return 0xDEAD; + } + + uint32_t n1 = argv[0]; + printf("call func1 and return n1=%d\n", n1); + + if (!wasm_runtime_call_indirect(exec_env, func2, 1, argv)) { + printf("call func2 failed\n"); + return 0xDEAD; + } + + uint32_t n2 = argv[0]; + printf("call func2 and return n2=%d\n", n2); + return n1 + n2; +} diff --git a/samples/basic/wasm-apps/testapp.c b/samples/basic/wasm-apps/testapp.c index b4e64f91..e5d4883d 100644 --- a/samples/basic/wasm-apps/testapp.c +++ b/samples/basic/wasm-apps/testapp.c @@ -6,9 +6,11 @@ #include #include #include +#include int intToStr(int x, char* str, int str_len, int digit); int get_pow(int x, int y); +int32_t calculate_native(int32_t n, int32_t func1, int32_t func2); // // Primitive parameters functions @@ -54,3 +56,27 @@ void float_to_string(float n, char* res, int res_size, int afterpoint) intToStr((int)fpart, res + i + 1, sizeof(res + i + 1), afterpoint); } } + +int32_t mul7(int32_t n) +{ + printf ("calling into WASM function: %s,", __FUNCTION__); + n = n * 7; + printf (" %s return %d \n", __FUNCTION__, n); + return n; +} + +int32_t mul5(int32_t n) +{ + printf ("calling into WASM function: %s,", __FUNCTION__); + n = n * 5; + printf (" %s return %d \n", __FUNCTION__, n); + return n; +} + +int32_t calculate(int32_t n) +{ + printf ("calling into WASM function: %s\n", __FUNCTION__); + int32_t (*f1)(int32_t) = &mul5; + int32_t (*f2)(int32_t) = &mul7; + return calculate_native(n, (uint32_t)f1, (uint32_t)f2); +} diff --git a/samples/simple/.gitignore b/samples/simple/.gitignore new file mode 100644 index 00000000..e2e7327c --- /dev/null +++ b/samples/simple/.gitignore @@ -0,0 +1 @@ +/out