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
This commit is contained in:
Xu Jun 2020-04-07 11:04:46 +08:00 committed by GitHub
parent 374e687938
commit 5e196253f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 512 additions and 143 deletions

3
.gitignore vendored
View File

@ -5,3 +5,6 @@ core/deps/llvm
core/deps/lvgl core/deps/lvgl
core/shared/mem-alloc/tlsf core/shared/mem-alloc/tlsf
wamr-sdk/out/
wamr-sdk/runtime/build_runtime_sdk/
test-tools/host-tool/bin/

129
_clang-format Normal file
View File

@ -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
# ...

View File

@ -94,33 +94,33 @@ message (" CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE})
if (WAMR_BUILD_INTERP EQUAL 1) if (WAMR_BUILD_INTERP EQUAL 1)
message (" WAMR Interpreter enabled") message (" WAMR Interpreter enabled")
else () else ()
message (" WAMR Interpreter disbled") message (" WAMR Interpreter disabled")
endif () endif ()
if (WAMR_BUILD_AOT EQUAL 1) if (WAMR_BUILD_AOT EQUAL 1)
message (" WAMR AOT enabled") message (" WAMR AOT enabled")
else () else ()
message (" WAMR AOT disbled") message (" WAMR AOT disabled")
endif () endif ()
if (WAMR_BUILD_JIT EQUAL 1) if (WAMR_BUILD_JIT EQUAL 1)
message (" WAMR JIT enabled") message (" WAMR JIT enabled")
else () else ()
message (" WAMR JIT disbled") message (" WAMR JIT disabled")
endif () endif ()
if (WAMR_BUILD_LIBC_BUILTIN EQUAL 1) if (WAMR_BUILD_LIBC_BUILTIN EQUAL 1)
message (" Libc builtin enabled") message (" Libc builtin enabled")
else () else ()
message (" Libc builtin disbled") message (" Libc builtin disabled")
endif () endif ()
if (WAMR_BUILD_LIBC_WASI EQUAL 1) if (WAMR_BUILD_LIBC_WASI EQUAL 1)
message (" Libc WASI enabled") message (" Libc WASI enabled")
else () else ()
message (" Libc WASI disbled") message (" Libc WASI disabled")
endif () endif ()
if (WAMR_BUILD_FAST_INTERP EQUAL 1) if (WAMR_BUILD_FAST_INTERP EQUAL 1)
add_definitions (-DWASM_ENABLE_FAST_INTERP=1) add_definitions (-DWASM_ENABLE_FAST_INTERP=1)
message (" Fast interpreter enabled") message (" Fast interpreter enabled")
else () else ()
add_definitions (-DWASM_ENABLE_FAST_INTERP=0) add_definitions (-DWASM_ENABLE_FAST_INTERP=0)
message (" Fast interpreter disbled") message (" Fast interpreter disabled")
endif () endif ()

View File

@ -794,7 +794,8 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end,
} }
#if WASM_ENABLE_LIBC_WASI != 0 #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; module->is_wasi_module = true;
#endif #endif
} }

View File

@ -855,7 +855,8 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
bool bool
aot_call_indirect(WASMExecEnv *exec_env, 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 *frame_lp, uint32 argc, uint32 *argv_ret)
{ {
AOTModuleInstance *module_inst = (AOTModuleInstance*) AOTModuleInstance *module_inst = (AOTModuleInstance*)
@ -863,7 +864,7 @@ aot_call_indirect(WASMExecEnv *exec_env,
AOTModule *aot_module = (AOTModule*)module_inst->aot_module.ptr; AOTModule *aot_module = (AOTModule*)module_inst->aot_module.ptr;
uint32 *func_type_indexes = (uint32*)module_inst->func_type_indexes.ptr; uint32 *func_type_indexes = (uint32*)module_inst->func_type_indexes.ptr;
uint32 *table_data = (uint32*)module_inst->table_data.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; void **func_ptrs = (void**)module_inst->func_ptrs.ptr, *func_ptr;
uint32 table_size = module_inst->table_size; uint32 table_size = module_inst->table_size;
uint32 func_idx, func_type_idx1; uint32 func_idx, func_type_idx1;
@ -884,10 +885,14 @@ aot_call_indirect(WASMExecEnv *exec_env,
} }
func_type_idx1 = func_type_indexes[func_idx]; func_type_idx1 = func_type_indexes[func_idx];
if (!aot_is_wasm_type_equal(module_inst, func_type_idx, func_type_idx1)) { if (check_func_type
aot_set_exception_with_id(module_inst, EXCE_INVALID_FUNCTION_TYPE_INDEX); && !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; return false;
} }
func_type = aot_module->func_types[func_type_idx1];
if (!(func_ptr = func_ptrs[func_idx])) { if (!(func_ptr = func_ptrs[func_idx])) {
bh_assert(func_idx < aot_module->import_func_count); 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) { if (import_func->call_conv_raw) {
attachment = import_func->attachment; attachment = import_func->attachment;
return wasm_runtime_invoke_native_raw(exec_env, func_ptr, return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
func_type, signature, attachment, func_type, signature,
attachment,
frame_lp, argc, argv_ret); frame_lp, argc, argv_ret);
} }
} }
@ -915,4 +921,3 @@ aot_call_indirect(WASMExecEnv *exec_env,
func_type, signature, attachment, func_type, signature, attachment,
frame_lp, argc, argv_ret); frame_lp, argc, argv_ret);
} }

View File

@ -445,7 +445,8 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
bool bool
aot_call_indirect(WASMExecEnv *exec_env, 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 *frame_lp, uint32 argc, uint32 *argv_ret);
uint32 uint32

View File

@ -9,19 +9,19 @@ include_directories (${IWASM_AOT_DIR})
file (GLOB c_source_all ${IWASM_AOT_DIR}/*.c) 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) 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) 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) 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) 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) 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) 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) set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_xtensa.c)
else () else ()
message (FATAL_ERROR "Build target isn't set") message (FATAL_ERROR "Build target isn't set")

View File

@ -10,29 +10,29 @@ add_definitions(-DBH_FREE=wasm_runtime_free)
file (GLOB c_source_all ${IWASM_COMMON_DIR}/*.c) 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) 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) set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_ia32.s)
elseif (${WAMR_BUILD_TARGET} MATCHES "ARM.*") elseif (WAMR_BUILD_TARGET MATCHES "ARM.*")
if (${WAMR_BUILD_TARGET} MATCHES "ARM.*_VFP") if (WAMR_BUILD_TARGET MATCHES "ARM.*_VFP")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_arm_vfp.s) set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_arm_vfp.s)
else () else ()
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_arm.s) set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_arm.s)
endif () endif ()
elseif (${WAMR_BUILD_TARGET} MATCHES "THUMB.*") elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*")
if (${WAMR_BUILD_TARGET} MATCHES "THUMB.*_VFP") if (WAMR_BUILD_TARGET MATCHES "THUMB.*_VFP")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_thumb_vfp.s) set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_thumb_vfp.s)
else () else ()
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_thumb.s) set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_thumb.s)
endif () 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) 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) 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) 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, # Use invokeNative_general.c instead of assembly code,
# but the maximum number of native arguments is limited to 20, # but the maximum number of native arguments is limited to 20,
# and there are possible issues when passing arguments to # and there are possible issues when passing arguments to

View File

@ -251,6 +251,9 @@ wasm_native_init()
if (!wasm_native_register_natives("wasi_unstable", if (!wasm_native_register_natives("wasi_unstable",
native_symbols, n_native_symbols)) native_symbols, n_native_symbols))
return false; return false;
if (!wasm_native_register_natives("wasi_snapshot_preview1",
native_symbols, n_native_symbols))
return false;
#endif #endif
#if WASM_ENABLE_BASE_LIB != 0 #if WASM_ENABLE_BASE_LIB != 0

View File

@ -37,6 +37,17 @@ wasm_runtime_env_init()
return true; 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 bool
wasm_runtime_init() wasm_runtime_init()
{ {
@ -276,12 +287,7 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
WASMFunctionInstanceCommon *function, WASMFunctionInstanceCommon *function,
unsigned argc, uint32 argv[]) unsigned argc, uint32 argv[])
{ {
if (!exec_env if (!wasm_runtime_env_check(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) {
LOG_ERROR("Invalid exec env stack info."); LOG_ERROR("Invalid exec env stack info.");
return false; return false;
} }
@ -1392,15 +1398,19 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
break; break;
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
{ {
char buf[16];
union { uint64 val; uint32 parts[2]; } u; union { uint64 val; uint32 parts[2]; } u;
u.parts[0] = argv1[0]; u.parts[0] = argv1[0];
u.parts[1] = argv1[1]; u.parts[1] = argv1[1];
#ifdef PRIx64
os_printf("0x%"PRIx64":i64", u.val);
#else
char buf[16];
if (sizeof(long) == 4) if (sizeof(long) == 4)
snprintf(buf, sizeof(buf), "%s", "0x%llx:i64"); snprintf(buf, sizeof(buf), "%s", "0x%llx:i64");
else else
snprintf(buf, sizeof(buf), "%s", "0x%lx:i64"); snprintf(buf, sizeof(buf), "%s", "0x%lx:i64");
os_printf(buf, u.val); os_printf(buf, u.val);
#endif
break; break;
} }
case VALUE_TYPE_F32: case VALUE_TYPE_F32:
@ -2110,6 +2120,33 @@ fail:
return ret; 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) \ #endif /* end of defined(BUILD_TARGET_X86_64) \
|| defined(BUILD_TARGET_AMD_64) \ || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64) */ || defined(BUILD_TARGET_AARCH64) */

View File

@ -131,6 +131,28 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
WASMFunctionInstanceCommon *function, WASMFunctionInstanceCommon *function,
unsigned argc, uint32 argv[]); 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 bool
wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst, wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst,
WASMFunctionInstanceCommon *function, WASMFunctionInstanceCommon *function,
@ -269,6 +291,7 @@ wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst,
WASIContext * WASIContext *
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst); wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst);
#endif /* end of WASM_ENABLE_LIBC_WASI */ #endif /* end of WASM_ENABLE_LIBC_WASI */
/** /**
@ -305,7 +328,6 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
void *attachment, void *attachment,
uint32 *argv, uint32 argc, uint32 *ret); uint32 *argv, uint32 argc, uint32 *ret);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -395,21 +395,22 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef ret_type, uint8 wasm_ret_type, LLVMTypeRef ret_type, uint8 wasm_ret_type,
LLVMValueRef *p_value_ret, LLVMValueRef *p_res) 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; LLVMTypeRef ret_ptr_type, elem_ptr_type;
LLVMValueRef func, elem_idx, elem_ptr; 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"; char buf[32], *func_name = "aot_call_indirect";
uint32 i, cell_num = 0; uint32 i, cell_num = 0;
/* prepare function type of aot_call_indirect */ /* prepare function type of aot_call_indirect */
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */ func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
func_param_types[1] = I32_TYPE; /* func_type_idx */ func_param_types[1] = INT8_TYPE; /* check_func_type */
func_param_types[2] = I32_TYPE; /* table_elem_idx */ func_param_types[2] = I32_TYPE; /* func_type_idx */
func_param_types[3] = INT32_PTR_TYPE; /* frame_lp */ func_param_types[3] = I32_TYPE; /* table_elem_idx */
func_param_types[4] = I32_TYPE; /* argc */ func_param_types[4] = INT32_PTR_TYPE; /* frame_lp */
func_param_types[5] = INT32_PTR_TYPE; /* argv_ret */ func_param_types[5] = I32_TYPE; /* argc */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 6, false))) { 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."); aot_set_last_error("llvm add function type failed.");
return false; 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[0] = func_ctx->exec_env;
func_param_values[1] = func_type_idx; func_param_values[1] = I8_CONST(true);
func_param_values[2] = table_elem_idx; func_param_values[2] = func_type_idx;
func_param_values[3] = func_ctx->argv_buf; func_param_values[3] = table_elem_idx;
func_param_values[4] = I32_CONST(param_cell_num); func_param_values[4] = func_ctx->argv_buf;
func_param_values[5] = value_ret_ptr; 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."); aot_set_last_error("llvm create const failed.");
return false; return false;
} }
/* call aot_call_indirect() function */ /* call aot_call_indirect() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func, 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."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }

View File

@ -675,9 +675,11 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
p = p_old; 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) if (!const_str_list_insert((uint8*)"env", 3, module, error_buf, error_buf_size)
|| !const_str_list_insert((uint8*)"wasi_unstable", 13, module, || !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)) { error_buf, error_buf_size)) {
return false; return false;
} }
@ -797,7 +799,8 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
import = module->import_functions; import = module->import_functions;
for (i = 0; i < module->import_function_count; i++, import++) { 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; module->is_wasi_module = true;
break; break;
} }
@ -2377,6 +2380,9 @@ typedef struct WASMLoaderContext {
int16 start_dynamic_offset; int16 start_dynamic_offset;
int16 max_dynamic_offset; int16 max_dynamic_offset;
/* preserved local offset */
int16 preserved_local_offset;
/* const buffer */ /* const buffer */
uint8 *const_buf; uint8 *const_buf;
uint16 num_const; uint16 num_const;
@ -2873,6 +2879,9 @@ wasm_loader_ctx_reinit(WASMLoaderContext *ctx)
ctx->frame_offset = ctx->frame_offset_bottom; ctx->frame_offset = ctx->frame_offset_bottom;
ctx->dynamic_offset = ctx->start_dynamic_offset; ctx->dynamic_offset = ctx->start_dynamic_offset;
/* init preserved local offsets */
ctx->preserved_local_offset = ctx->max_dynamic_offset;
/* const buf is reserved */ /* const buf is reserved */
return true; return true;
} }
@ -2950,19 +2959,21 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
skip_label(); skip_label();
if (local_type == VALUE_TYPE_I32 if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32) { || 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); emit_label(EXT_OP_COPY_STACK_TOP);
} }
else { else {
preserved_offset = loader_ctx->dynamic_offset; preserved_offset = loader_ctx->preserved_local_offset;
loader_ctx->dynamic_offset += 2; if (loader_ctx->p_code_compiled)
loader_ctx->preserved_local_offset += 2;
emit_label(EXT_OP_COPY_STACK_TOP_I64); emit_label(EXT_OP_COPY_STACK_TOP_I64);
} }
emit_operand(loader_ctx, local_index); emit_operand(loader_ctx, local_index);
emit_operand(loader_ctx, preserved_offset); emit_operand(loader_ctx, preserved_offset);
emit_label(opcode); 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; 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) { if (type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32) {
ctx->frame_offset -= 1; 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; ctx->dynamic_offset -= 1;
} }
else { else {
ctx->frame_offset -= 2; 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; ctx->dynamic_offset -= 2;
} }
emit_operand(ctx, *(ctx->frame_offset)); 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; loader_ctx->start_dynamic_offset + 1;
#else #else
func->max_stack_cell_num = loader_ctx->max_stack_cell_num; func->max_stack_cell_num = loader_ctx->max_stack_cell_num;

View File

@ -1166,3 +1166,42 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
#endif /* end of WASM_ENABLE_MEMORY_GROW */ #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;
}

View File

@ -280,6 +280,11 @@ wasm_get_native_addr_range(WASMModuleInstance *module_inst,
bool bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -1908,6 +1908,21 @@ __wasi_errno_t wasmtime_ssp_path_open(
close(nfd); close(nfd);
return error; 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, return fd_table_insert_fd(curfds, nfd, type, rights_base & max_base,
rights_inheriting & max_inheriting, fd); rights_inheriting & max_inheriting, fd);
} }
@ -2273,8 +2288,14 @@ __wasi_errno_t wasmtime_ssp_path_filestat_set_times(
__wasi_timestamp_t st_mtim, __wasi_timestamp_t st_mtim,
__wasi_fstflags_t fstflags __wasi_fstflags_t fstflags
) { ) {
if ((fstflags & ~(__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW | if (((fstflags & ~(__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW |
__WASI_FILESTAT_SET_MTIM | __WASI_FILESTAT_SET_MTIM_NOW)) != 0) __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; return __WASI_EINVAL;
struct path_access pa; struct path_access pa;

View File

@ -325,7 +325,7 @@ int os_thread_join(korp_tid thread, void **value_ptr)
k_sem_take(&node->sem, K_FOREVER); k_sem_take(&node->sem, K_FOREVER);
/* Wait some time for the thread to be actually terminated */ /* Wait some time for the thread to be actually terminated */
k_sleep(100); k_sleep(Z_TIMEOUT_MS(100));
/* Destroy resource */ /* Destroy resource */
BH_FREE(node); 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 */ /* Unlock mutex, wait sem and lock mutex again */
k_mutex_unlock(mutex); 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); k_mutex_lock(mutex, K_FOREVER);
/* Remove wait node from wait list */ /* Remove wait node from wait list */

View File

@ -218,22 +218,11 @@ cp -a <wamr_root_dir>/product-mini/platforms/zephyr/simple .
cd simple cd simple
ln -s <wamr_root_dir> wamr ln -s <wamr_root_dir> wamr
source ../../zephyr-env.sh 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: 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. 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.

View File

@ -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

View File

@ -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

1
samples/basic/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/out/

View File

@ -44,6 +44,7 @@ OUT_FILE=${i%.*}.wasm
-Wl,--no-threads,--strip-all,--no-entry -nostdlib \ -Wl,--no-threads,--strip-all,--no-entry -nostdlib \
-Wl,--export=generate_float \ -Wl,--export=generate_float \
-Wl,--export=float_to_string \ -Wl,--export=float_to_string \
-Wl,--export=calculate\
-Wl,--allow-undefined \ -Wl,--allow-undefined \
-o ${OUT_DIR}/wasm-apps/${OUT_FILE} ${APP_SRC} -o ${OUT_DIR}/wasm-apps/${OUT_FILE} ${APP_SRC}

View File

@ -9,6 +9,7 @@
int intToStr(int x, char* str, int str_len, int digit); int intToStr(int x, char* str, int str_len, int digit);
int get_pow(int x, int y); int get_pow(int x, int y);
int32_t calculate_native(int32_t n, int32_t func1, int32_t func2);
void print_usage(void) void print_usage(void)
{ {
@ -75,6 +76,12 @@ int main(int argc, char *argv_main[])
get_pow, // the native function pointer get_pow, // the native function pointer
"(ii)i", // the function prototype signature, avoid to use i32 "(ii)i", // the function prototype signature, avoid to use i32
NULL // attachment is NULL NULL // attachment is NULL
},
{
"calculate_native",
calculate_native,
"(iii)i",
NULL
} }
}; };
@ -167,6 +174,23 @@ int main(int argc, char *argv_main[])
goto fail; 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: fail:
if(exec_env) wasm_runtime_destroy_exec_env(exec_env); if(exec_env) wasm_runtime_destroy_exec_env(exec_env);
if(module_inst) { if(module_inst) {

View File

@ -7,6 +7,11 @@
#include "wasm_export.h" #include "wasm_export.h"
#include "math.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 // The first parameter is not exec_env because it is invoked by native funtions
void reverse(char * str, int len) 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__); printf ("calling into native function: %s\n", __FUNCTION__);
return (int)pow(x, y); 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;
}

View File

@ -6,9 +6,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h>
int intToStr(int x, char* str, int str_len, int digit); int intToStr(int x, char* str, int str_len, int digit);
int get_pow(int x, int y); int get_pow(int x, int y);
int32_t calculate_native(int32_t n, int32_t func1, int32_t func2);
// //
// Primitive parameters functions // 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); 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);
}

1
samples/simple/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/out