mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-07 12:16:24 +00:00
Implement Go language binding (#1196)
Implement Go binding APIs of runtime, module and instance Add sample, build scripts and update the document Co-authored-by: venus-taibai <97893654+venus-taibai@users.noreply.github.com>
This commit is contained in:
parent
3d34a91f0b
commit
5b1dcf2fa2
|
@ -445,7 +445,7 @@ wasm_runtime_register_module_internal(const char *module_name,
|
||||||
WASMModuleCommon *module,
|
WASMModuleCommon *module,
|
||||||
uint8 *orig_file_buf,
|
uint8 *orig_file_buf,
|
||||||
uint32 orig_file_buf_size,
|
uint32 orig_file_buf_size,
|
||||||
char *error_buf, uint32_t error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
WASMRegisteredModule *node = NULL;
|
WASMRegisteredModule *node = NULL;
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ wasm_runtime_register_module_internal(const char *module_name,
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_runtime_register_module(const char *module_name, WASMModuleCommon *module,
|
wasm_runtime_register_module(const char *module_name, WASMModuleCommon *module,
|
||||||
char *error_buf, uint32_t error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
if (!error_buf || !error_buf_size) {
|
if (!error_buf || !error_buf_size) {
|
||||||
LOG_ERROR("error buffer is required");
|
LOG_ERROR("error buffer is required");
|
||||||
|
@ -823,7 +823,7 @@ wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||||
|
|
||||||
WASMModuleCommon *
|
WASMModuleCommon *
|
||||||
wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
|
wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
|
||||||
char *error_buf, uint32_t error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
WASMModuleCommon *module_common;
|
WASMModuleCommon *module_common;
|
||||||
|
|
||||||
|
@ -980,6 +980,23 @@ wasm_runtime_destroy_thread_env(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_runtime_thread_env_inited(void)
|
||||||
|
{
|
||||||
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
|
if (!os_thread_env_inited())
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_AOT != 0
|
||||||
|
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
if (!os_thread_signal_inited())
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_MEMORY_TRACING != 0)
|
#if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_MEMORY_TRACING != 0)
|
||||||
void
|
void
|
||||||
wasm_runtime_dump_module_mem_consumption(const WASMModuleCommon *module)
|
wasm_runtime_dump_module_mem_consumption(const WASMModuleCommon *module)
|
||||||
|
@ -1222,8 +1239,81 @@ wasm_runtime_lookup_function(WASMModuleInstanceCommon *const module_inst,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
wasm_func_get_param_count(WASMFunctionInstanceCommon *const func_inst,
|
||||||
|
WASMModuleInstanceCommon *const module_inst)
|
||||||
|
{
|
||||||
|
WASMType *type =
|
||||||
|
wasm_runtime_get_function_type(func_inst, module_inst->module_type);
|
||||||
|
return type->param_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
wasm_func_get_result_count(WASMFunctionInstanceCommon *const func_inst,
|
||||||
|
WASMModuleInstanceCommon *const module_inst)
|
||||||
|
{
|
||||||
|
WASMType *type =
|
||||||
|
wasm_runtime_get_function_type(func_inst, module_inst->module_type);
|
||||||
|
return type->result_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8
|
||||||
|
val_type_to_val_kind(uint8 value_type)
|
||||||
|
{
|
||||||
|
switch (value_type) {
|
||||||
|
case VALUE_TYPE_I32:
|
||||||
|
return WASM_I32;
|
||||||
|
case VALUE_TYPE_I64:
|
||||||
|
return WASM_I64;
|
||||||
|
case VALUE_TYPE_F32:
|
||||||
|
return WASM_F32;
|
||||||
|
case VALUE_TYPE_F64:
|
||||||
|
return WASM_F64;
|
||||||
|
case VALUE_TYPE_FUNCREF:
|
||||||
|
return WASM_FUNCREF;
|
||||||
|
case VALUE_TYPE_EXTERNREF:
|
||||||
|
return WASM_ANYREF;
|
||||||
|
default:
|
||||||
|
#if WASM_ENABLE_GC != 0
|
||||||
|
if (wasm_is_type_reftype(value_type))
|
||||||
|
return WASM_ANYREF;
|
||||||
|
#endif
|
||||||
|
bh_assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_func_get_param_types(WASMFunctionInstanceCommon *const func_inst,
|
||||||
|
WASMModuleInstanceCommon *const module_inst,
|
||||||
|
wasm_valkind_t *param_types)
|
||||||
|
{
|
||||||
|
WASMType *type =
|
||||||
|
wasm_runtime_get_function_type(func_inst, module_inst->module_type);
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < type->param_count; i++) {
|
||||||
|
param_types[i] = val_type_to_val_kind(type->types[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_func_get_result_types(WASMFunctionInstanceCommon *const func_inst,
|
||||||
|
WASMModuleInstanceCommon *const module_inst,
|
||||||
|
wasm_valkind_t *result_types)
|
||||||
|
{
|
||||||
|
WASMType *type =
|
||||||
|
wasm_runtime_get_function_type(func_inst, module_inst->module_type);
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < type->result_count; i++) {
|
||||||
|
result_types[i] =
|
||||||
|
val_type_to_val_kind(type->types[type->param_count + i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
/* (uintptr_t)externref -> (uint32_t)index */
|
/* (uintptr_t)externref -> (uint32)index */
|
||||||
/* argv -> *ret_argv */
|
/* argv -> *ret_argv */
|
||||||
static bool
|
static bool
|
||||||
wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
||||||
|
@ -1321,7 +1411,7 @@ wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (uintptr_t)externref <- (uint32_t)index */
|
/* (uintptr_t)externref <- (uint32)index */
|
||||||
/* argv <- new_argv */
|
/* argv <- new_argv */
|
||||||
static bool
|
static bool
|
||||||
wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
||||||
|
@ -3952,8 +4042,8 @@ fail:
|
||||||
|| defined(BUILD_TARGET_RISCV64_LP64) */
|
|| defined(BUILD_TARGET_RISCV64_LP64) */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32_t element_indices,
|
wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_indices,
|
||||||
uint32_t argc, uint32_t argv[])
|
uint32 argc, uint32 argv[])
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_exec_env_check(exec_env)) {
|
if (!wasm_runtime_exec_env_check(exec_env)) {
|
||||||
LOG_ERROR("Invalid exec env stack info.");
|
LOG_ERROR("Invalid exec env stack info.");
|
||||||
|
|
|
@ -471,6 +471,28 @@ WASMType *
|
||||||
wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
|
wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
|
||||||
uint32 module_type);
|
uint32 module_type);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
WASM_RUNTIME_API_EXTERN uint32
|
||||||
|
wasm_func_get_param_count(WASMFunctionInstanceCommon *const func_inst,
|
||||||
|
WASMModuleInstanceCommon *const module_inst);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
WASM_RUNTIME_API_EXTERN uint32
|
||||||
|
wasm_func_get_result_count(WASMFunctionInstanceCommon *const func_inst,
|
||||||
|
WASMModuleInstanceCommon *const module_inst);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
WASM_RUNTIME_API_EXTERN void
|
||||||
|
wasm_func_get_param_types(WASMFunctionInstanceCommon *const func_inst,
|
||||||
|
WASMModuleInstanceCommon *const module_inst,
|
||||||
|
wasm_valkind_t *param_types);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
WASM_RUNTIME_API_EXTERN void
|
||||||
|
wasm_func_get_result_types(WASMFunctionInstanceCommon *const func_inst,
|
||||||
|
WASMModuleInstanceCommon *const module_inst,
|
||||||
|
wasm_valkind_t *result_types);
|
||||||
|
|
||||||
/* See wasm_export.h for description */
|
/* See wasm_export.h for description */
|
||||||
WASM_RUNTIME_API_EXTERN WASMExecEnv *
|
WASM_RUNTIME_API_EXTERN WASMExecEnv *
|
||||||
wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst,
|
wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst,
|
||||||
|
|
|
@ -407,6 +407,54 @@ WASM_RUNTIME_API_EXTERN wasm_function_inst_t
|
||||||
wasm_runtime_lookup_function(wasm_module_inst_t const module_inst,
|
wasm_runtime_lookup_function(wasm_module_inst_t const module_inst,
|
||||||
const char *name, const char *signature);
|
const char *name, const char *signature);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get parameter count of the function instance
|
||||||
|
*
|
||||||
|
* @param func_inst the function instance
|
||||||
|
* @param module_inst the module instance the function instance belongs to
|
||||||
|
*
|
||||||
|
* @return the parameter count of the function instance
|
||||||
|
*/
|
||||||
|
WASM_RUNTIME_API_EXTERN uint32_t
|
||||||
|
wasm_func_get_param_count(wasm_function_inst_t const func_inst,
|
||||||
|
wasm_module_inst_t const module_inst);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get result count of the function instance
|
||||||
|
*
|
||||||
|
* @param func_inst the function instance
|
||||||
|
* @param module_inst the module instance the function instance belongs to
|
||||||
|
*
|
||||||
|
* @return the result count of the function instance
|
||||||
|
*/
|
||||||
|
WASM_RUNTIME_API_EXTERN uint32_t
|
||||||
|
wasm_func_get_result_count(wasm_function_inst_t const func_inst,
|
||||||
|
wasm_module_inst_t const module_inst);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get parameter types of the function instance
|
||||||
|
*
|
||||||
|
* @param func_inst the function instance
|
||||||
|
* @param module_inst the module instance the function instance belongs to
|
||||||
|
* @param param_types the parameter types returned
|
||||||
|
*/
|
||||||
|
WASM_RUNTIME_API_EXTERN void
|
||||||
|
wasm_func_get_param_types(wasm_function_inst_t const func_inst,
|
||||||
|
wasm_module_inst_t const module_inst,
|
||||||
|
wasm_valkind_t *param_types);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get result types of the function instance
|
||||||
|
*
|
||||||
|
* @param func_inst the function instance
|
||||||
|
* @param module_inst the module instance the function instance belongs to
|
||||||
|
* @param result_types the result types returned
|
||||||
|
*/
|
||||||
|
WASM_RUNTIME_API_EXTERN void
|
||||||
|
wasm_func_get_result_types(wasm_function_inst_t const func_inst,
|
||||||
|
wasm_module_inst_t const module_inst,
|
||||||
|
wasm_valkind_t *result_types);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create execution environment for a WASM module instance.
|
* Create execution environment for a WASM module instance.
|
||||||
*
|
*
|
||||||
|
@ -449,7 +497,7 @@ WASM_RUNTIME_API_EXTERN uint32_t
|
||||||
wasm_runtime_start_debug_instance(wasm_exec_env_t exec_env);
|
wasm_runtime_start_debug_instance(wasm_exec_env_t exec_env);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize thread environment.
|
* Initialize the thread environment.
|
||||||
* Note:
|
* Note:
|
||||||
* If developer creates a child thread by himself to call the
|
* If developer creates a child thread by himself to call the
|
||||||
* the wasm function in that thread, he should call this API
|
* the wasm function in that thread, he should call this API
|
||||||
|
@ -464,11 +512,17 @@ WASM_RUNTIME_API_EXTERN bool
|
||||||
wasm_runtime_init_thread_env(void);
|
wasm_runtime_init_thread_env(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy thread environment
|
* Destroy the thread environment
|
||||||
*/
|
*/
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_destroy_thread_env(void);
|
wasm_runtime_destroy_thread_env(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the thread environment is initialized
|
||||||
|
*/
|
||||||
|
WASM_RUNTIME_API_EXTERN bool
|
||||||
|
wasm_runtime_thread_env_inited(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get WASM module instance from execution environment
|
* Get WASM module instance from execution environment
|
||||||
*
|
*
|
||||||
|
|
|
@ -107,6 +107,12 @@ os_thread_env_init();
|
||||||
void
|
void
|
||||||
os_thread_env_destroy();
|
os_thread_env_destroy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the thread environment is initialized
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
os_thread_env_inited();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suspend execution of the calling thread for (at least)
|
* Suspend execution of the calling thread for (at least)
|
||||||
* usec microseconds
|
* usec microseconds
|
||||||
|
|
|
@ -360,6 +360,13 @@ os_thread_env_destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
os_thread_env_inited()
|
||||||
|
{
|
||||||
|
os_thread_data *thread_data = TlsGetValue(thread_data_key);
|
||||||
|
return thread_data ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_sem_init(korp_sem *sem)
|
os_sem_init(korp_sem *sem)
|
||||||
{
|
{
|
||||||
|
|
104
language-bindings/go/README.md
Normal file
104
language-bindings/go/README.md
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
WAMR Go binding: Embedding WAMR in Go guideline
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
This Go library uses CGO to consume the runtime APIs of the WAMR project which are defined in [core/iwasm/include/wasm_export.h](../../core/iwasm/include/wasm_export.h). The API details are available in the header files.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Installing from the source code
|
||||||
|
|
||||||
|
Installing from local source tree is in _development mode_.
|
||||||
|
|
||||||
|
Run `./build.sh` in this folder to build the package, which builds the WAMR runtime library firstly and then builds the Go binding library.
|
||||||
|
|
||||||
|
Run `./build.sh` under `samples` folder to build and test the sample.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd samples
|
||||||
|
./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Supported APIs
|
||||||
|
|
||||||
|
All the embedding APIs supported are defined under folder [wamr](./wamr).
|
||||||
|
|
||||||
|
### Runtime APIs
|
||||||
|
|
||||||
|
```Go
|
||||||
|
func Runtime() *_Runtime
|
||||||
|
func (self *_Runtime) FullInit(alloc_with_pool bool, heap_buf []byte,
|
||||||
|
max_thread_num uint) error
|
||||||
|
func (self *_Runtime) Init() error
|
||||||
|
func (self *_Runtime) Destroy()
|
||||||
|
func (self *_Runtime) SetLogLevel(level LogLevel)
|
||||||
|
func (self *_Runtime) Malloc(size uint32) *uint8
|
||||||
|
func (self *_Runtime) Free(ptr *uint8)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Module APIs
|
||||||
|
|
||||||
|
```Go
|
||||||
|
func NewModule(wasmBytes []byte) (*Module, error)
|
||||||
|
func (self *Module) Destroy()
|
||||||
|
func (self *Module) SetWasiArgs(dirList [][]byte, mapDirList [][]byte,
|
||||||
|
env [][]byte, argv[][]byte)
|
||||||
|
func (self *Module) SetWasiArgsEx(dirList [][]byte, mapDirList [][]byte,
|
||||||
|
env [][]byte, argv[][]byte,
|
||||||
|
stdinfd int, stdoutfd int, stderrfd int)
|
||||||
|
func (self *Module) SetWasiAddrPool(addrPool [][]byte)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Instance APIs
|
||||||
|
|
||||||
|
```Go
|
||||||
|
func NewInstance(module *Module,
|
||||||
|
stackSize uint, heapSize uint) (*Instance, error)
|
||||||
|
func (self *Instance) Destroy()
|
||||||
|
func (self *Instance) CallFunc(funcName string,
|
||||||
|
argc uint32, args []uint32) error
|
||||||
|
func (self *Instance) CallFuncV(funcName string,
|
||||||
|
num_results uint32, results []interface{},
|
||||||
|
args ... interface{}) error
|
||||||
|
func (self *Instance) GetException() string
|
||||||
|
func (self Instance) ModuleMalloc(size uint32) (uint32, *uint8)
|
||||||
|
func (self Instance) ModuleFree(offset uint32)
|
||||||
|
func (self Instance) ValidateAppAddr(app_offset uint32, size uint32) bool
|
||||||
|
func (self Instance) ValidateNativeAddr(native_ptr *uint8, size uint32) bool
|
||||||
|
func (self Instance) AddrAppToNative(app_offset uint32) *uint8
|
||||||
|
func (self Instance) AddrNativeToApp(native_ptr *uint8) uint32
|
||||||
|
func (self Instance) GetAppAddrRange(app_offset uint32) (bool, uint32, uint32)
|
||||||
|
func (self Instance) GetNativeAddrRange(native_ptr *uint8) (bool, *uint8, *uint8)
|
||||||
|
func (self Instance) DumpMemoryConsumption()
|
||||||
|
func (self Instance) DumpCallStack()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sample codes
|
||||||
|
|
||||||
|
```Go
|
||||||
|
var module *wamr.Module
|
||||||
|
var instance *wamr.Instance
|
||||||
|
var results []interface{}
|
||||||
|
var err error
|
||||||
|
|
||||||
|
/* Runtime initialization */
|
||||||
|
err = wamr.Runtime().FullInit(false, nil, 1)
|
||||||
|
|
||||||
|
/* Read WASM/AOT file into a memory buffer */
|
||||||
|
wasmBytes := read_wasm_binary_to_buffer(...)
|
||||||
|
|
||||||
|
/* Load WASM/AOT module from the memory buffer */
|
||||||
|
module, err = wamr.NewModule(wasmBytes)
|
||||||
|
|
||||||
|
/* Create WASM/AOT instance from the module */
|
||||||
|
instance, err = wamr.NewInstance(module, 16384, 16384)
|
||||||
|
|
||||||
|
/* Call the `fib` function */
|
||||||
|
results = make([]interface{}, 1, 1)
|
||||||
|
err = instance.CallFuncV("fib", 1, results, (int32)32)
|
||||||
|
fmt.Printf("fib(32) return: %d\n", results[0].(int32));
|
||||||
|
|
||||||
|
/* Destroy runtime */
|
||||||
|
wamr.Runtime().Destroy()
|
||||||
|
```
|
||||||
|
|
||||||
|
More samples can be found in [test.go](./samples/test.go)
|
21
language-bindings/go/build.sh
Executable file
21
language-bindings/go/build.sh
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
PLATFORM=$(uname -s | tr A-Z a-z)
|
||||||
|
CUR_DIR=$PWD
|
||||||
|
WAMR_DIR=$PWD/../..
|
||||||
|
WAMR_GO_DIR=$PWD/wamr
|
||||||
|
|
||||||
|
cp -a ${WAMR_DIR}/core/iwasm/include/*.h ${WAMR_GO_DIR}/packaged/include
|
||||||
|
|
||||||
|
mkdir -p build && cd build
|
||||||
|
cmake ${WAMR_DIR}/product-mini/platforms/${PLATFORM} \
|
||||||
|
-DWAMR_BUILD_LIB_PTHREAD=1 -DWAMR_BUILD_DUMP_CALL_STACK=1 \
|
||||||
|
-DWAMR_BUILD_MEMORY_PROFILING=1
|
||||||
|
make -j ${nproc}
|
||||||
|
cp -a libvmlib.a ${WAMR_GO_DIR}/packaged/lib/${PLATFORM}-amd64
|
||||||
|
|
||||||
|
cd ${WAMR_GO_DIR}
|
||||||
|
go test
|
5
language-bindings/go/go.mod
Normal file
5
language-bindings/go/go.mod
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module gitlab.alipay-inc.com/TNT_Runtime/ant-runtime/bindings/go
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require github.com/stretchr/testify v1.7.0
|
10
language-bindings/go/go.sum
Normal file
10
language-bindings/go/go.sum
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
23
language-bindings/go/samples/build.sh
Executable file
23
language-bindings/go/samples/build.sh
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
PLATFORM=$(uname -s | tr A-Z a-z)
|
||||||
|
CUR_DIR=$PWD
|
||||||
|
WAMR_DIR=$PWD/../../..
|
||||||
|
WAMR_GO_DIR=$PWD/../wamr
|
||||||
|
|
||||||
|
cp -a ${WAMR_DIR}/core/iwasm/include/*.h ${WAMR_GO_DIR}/packaged/include
|
||||||
|
|
||||||
|
mkdir -p build && cd build
|
||||||
|
cmake ${WAMR_DIR}/product-mini/platforms/${PLATFORM} \
|
||||||
|
-DWAMR_BUILD_LIB_PTHREAD=1 -DWAMR_BUILD_DUMP_CALL_STACK=1 \
|
||||||
|
-DWAMR_BUILD_MEMORY_PROFILING=1
|
||||||
|
make -j ${nproc}
|
||||||
|
cp -a libvmlib.a ${WAMR_GO_DIR}/packaged/lib/${PLATFORM}-amd64
|
||||||
|
|
||||||
|
cd ${CUR_DIR}
|
||||||
|
rm -f test
|
||||||
|
go build test.go
|
||||||
|
./test
|
7
language-bindings/go/samples/run.sh
Executable file
7
language-bindings/go/samples/run.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
go build test.go
|
||||||
|
./test
|
235
language-bindings/go/samples/test.go
Normal file
235
language-bindings/go/samples/test.go
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitlab.alipay-inc.com/TNT_Runtime/ant-runtime/bindings/go/wamr"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var wasmBytes = []byte {
|
||||||
|
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x29, 0x07, 0x60,
|
||||||
|
0x01, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x01,
|
||||||
|
0x7F, 0x00, 0x60, 0x04, 0x7F, 0x7E, 0x7D, 0x7C, 0x00, 0x60, 0x02, 0x7E,
|
||||||
|
0x7E, 0x01, 0x7E, 0x60, 0x02, 0x7C, 0x7F, 0x01, 0x7D, 0x60, 0x02, 0x7D,
|
||||||
|
0x7C, 0x01, 0x7C, 0x02, 0x31, 0x04, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x70,
|
||||||
|
0x72, 0x69, 0x6E, 0x74, 0x66, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76, 0x04,
|
||||||
|
0x70, 0x75, 0x74, 0x73, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x6D,
|
||||||
|
0x61, 0x6C, 0x6C, 0x6F, 0x63, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x04,
|
||||||
|
0x66, 0x72, 0x65, 0x65, 0x00, 0x02, 0x03, 0x07, 0x06, 0x00, 0x03, 0x04,
|
||||||
|
0x06, 0x05, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x06, 0x13, 0x03, 0x7F,
|
||||||
|
0x01, 0x41, 0x90, 0x29, 0x0B, 0x7F, 0x00, 0x41, 0x90, 0x09, 0x0B, 0x7F,
|
||||||
|
0x00, 0x41, 0x90, 0x29, 0x0B, 0x07, 0x5F, 0x09, 0x06, 0x6D, 0x65, 0x6D,
|
||||||
|
0x6F, 0x72, 0x79, 0x02, 0x00, 0x04, 0x66, 0x69, 0x62, 0x32, 0x00, 0x04,
|
||||||
|
0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x00, 0x05, 0x05, 0x74, 0x65, 0x73,
|
||||||
|
0x74, 0x32, 0x00, 0x06, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x00, 0x07,
|
||||||
|
0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x00, 0x08, 0x10, 0x5F, 0x5F, 0x6D,
|
||||||
|
0x61, 0x69, 0x6E, 0x5F, 0x61, 0x72, 0x67, 0x63, 0x5F, 0x61, 0x72, 0x67,
|
||||||
|
0x76, 0x00, 0x09, 0x0A, 0x5F, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x65,
|
||||||
|
0x6E, 0x64, 0x03, 0x01, 0x0B, 0x5F, 0x5F, 0x68, 0x65, 0x61, 0x70, 0x5F,
|
||||||
|
0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x0A, 0xA5, 0x03, 0x06, 0x37, 0x01,
|
||||||
|
0x01, 0x7F, 0x41, 0x01, 0x21, 0x01, 0x20, 0x00, 0x41, 0x02, 0x4F, 0x04,
|
||||||
|
0x7F, 0x41, 0x00, 0x21, 0x01, 0x03, 0x40, 0x20, 0x00, 0x41, 0x02, 0x6B,
|
||||||
|
0x10, 0x04, 0x20, 0x01, 0x6A, 0x21, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6B,
|
||||||
|
0x22, 0x00, 0x41, 0x01, 0x4B, 0x0D, 0x00, 0x0B, 0x20, 0x01, 0x41, 0x01,
|
||||||
|
0x6A, 0x05, 0x41, 0x01, 0x0B, 0x0B, 0x3F, 0x01, 0x01, 0x7F, 0x23, 0x00,
|
||||||
|
0x41, 0x20, 0x6B, 0x22, 0x04, 0x24, 0x00, 0x20, 0x04, 0x41, 0x18, 0x6A,
|
||||||
|
0x20, 0x03, 0x39, 0x03, 0x00, 0x20, 0x04, 0x41, 0x10, 0x6A, 0x20, 0x02,
|
||||||
|
0xBB, 0x39, 0x03, 0x00, 0x20, 0x04, 0x20, 0x01, 0x37, 0x03, 0x08, 0x20,
|
||||||
|
0x04, 0x20, 0x00, 0x36, 0x02, 0x00, 0x41, 0xD0, 0x08, 0x20, 0x04, 0x10,
|
||||||
|
0x00, 0x1A, 0x20, 0x04, 0x41, 0x20, 0x6A, 0x24, 0x00, 0x0B, 0x3B, 0x01,
|
||||||
|
0x01, 0x7F, 0x23, 0x00, 0x41, 0x20, 0x6B, 0x22, 0x02, 0x24, 0x00, 0x20,
|
||||||
|
0x02, 0x20, 0x00, 0x37, 0x03, 0x00, 0x20, 0x02, 0x20, 0x01, 0x37, 0x03,
|
||||||
|
0x08, 0x20, 0x02, 0x41, 0x10, 0x6A, 0x20, 0x00, 0x20, 0x01, 0x7C, 0x22,
|
||||||
|
0x00, 0x37, 0x03, 0x00, 0x41, 0xF6, 0x08, 0x20, 0x02, 0x10, 0x00, 0x1A,
|
||||||
|
0x20, 0x02, 0x41, 0x20, 0x6A, 0x24, 0x00, 0x20, 0x00, 0x0B, 0x40, 0x02,
|
||||||
|
0x01, 0x7F, 0x01, 0x7C, 0x23, 0x00, 0x41, 0x20, 0x6B, 0x22, 0x02, 0x24,
|
||||||
|
0x00, 0x20, 0x02, 0x20, 0x01, 0x39, 0x03, 0x08, 0x20, 0x02, 0x20, 0x00,
|
||||||
|
0xBB, 0x22, 0x03, 0x39, 0x03, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6A, 0x20,
|
||||||
|
0x03, 0x20, 0x01, 0xA2, 0x22, 0x01, 0x39, 0x03, 0x00, 0x41, 0xB4, 0x08,
|
||||||
|
0x20, 0x02, 0x10, 0x00, 0x1A, 0x20, 0x02, 0x41, 0x20, 0x6A, 0x24, 0x00,
|
||||||
|
0x20, 0x01, 0x0B, 0x3D, 0x01, 0x01, 0x7F, 0x23, 0x00, 0x41, 0x20, 0x6B,
|
||||||
|
0x22, 0x02, 0x24, 0x00, 0x20, 0x02, 0x20, 0x00, 0x39, 0x03, 0x00, 0x20,
|
||||||
|
0x02, 0x20, 0x01, 0x36, 0x02, 0x08, 0x20, 0x02, 0x41, 0x10, 0x6A, 0x20,
|
||||||
|
0x00, 0x20, 0x01, 0xB7, 0xA3, 0x22, 0x00, 0x39, 0x03, 0x00, 0x41, 0xC2,
|
||||||
|
0x08, 0x20, 0x02, 0x10, 0x00, 0x1A, 0x20, 0x02, 0x41, 0x20, 0x6A, 0x24,
|
||||||
|
0x00, 0x20, 0x00, 0xB6, 0x0B, 0x70, 0x00, 0x23, 0x00, 0x41, 0x20, 0x6B,
|
||||||
|
0x22, 0x00, 0x24, 0x00, 0x41, 0x9A, 0x08, 0x10, 0x01, 0x1A, 0x02, 0x7F,
|
||||||
|
0x41, 0x80, 0x08, 0x10, 0x02, 0x22, 0x01, 0x45, 0x04, 0x40, 0x41, 0x88,
|
||||||
|
0x08, 0x10, 0x01, 0x1A, 0x41, 0x7F, 0x0C, 0x01, 0x0B, 0x20, 0x00, 0x20,
|
||||||
|
0x01, 0x36, 0x02, 0x10, 0x41, 0xA7, 0x08, 0x20, 0x00, 0x41, 0x10, 0x6A,
|
||||||
|
0x10, 0x00, 0x1A, 0x20, 0x01, 0x41, 0x04, 0x6A, 0x41, 0x8E, 0x09, 0x2F,
|
||||||
|
0x00, 0x00, 0x3B, 0x00, 0x00, 0x20, 0x01, 0x41, 0x8A, 0x09, 0x28, 0x00,
|
||||||
|
0x00, 0x36, 0x00, 0x00, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x00, 0x41,
|
||||||
|
0x80, 0x08, 0x20, 0x00, 0x10, 0x00, 0x1A, 0x20, 0x01, 0x10, 0x03, 0x41,
|
||||||
|
0x00, 0x0B, 0x20, 0x00, 0x41, 0x20, 0x6A, 0x24, 0x00, 0x0B, 0x0B, 0x97,
|
||||||
|
0x01, 0x01, 0x00, 0x41, 0x80, 0x08, 0x0B, 0x8F, 0x01, 0x62, 0x75, 0x66,
|
||||||
|
0x3A, 0x20, 0x25, 0x73, 0x00, 0x6D, 0x61, 0x6C, 0x6C, 0x6F, 0x63, 0x20,
|
||||||
|
0x62, 0x75, 0x66, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x00, 0x48,
|
||||||
|
0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00,
|
||||||
|
0x62, 0x75, 0x66, 0x20, 0x70, 0x74, 0x72, 0x3A, 0x20, 0x25, 0x70, 0x0A,
|
||||||
|
0x00, 0x25, 0x66, 0x20, 0x2A, 0x20, 0x25, 0x66, 0x20, 0x3D, 0x20, 0x25,
|
||||||
|
0x66, 0x0A, 0x00, 0x25, 0x66, 0x20, 0x2F, 0x20, 0x25, 0x64, 0x20, 0x3D,
|
||||||
|
0x20, 0x25, 0x66, 0x0A, 0x00, 0x69, 0x33, 0x32, 0x3A, 0x20, 0x25, 0x64,
|
||||||
|
0x2C, 0x20, 0x69, 0x36, 0x34, 0x3A, 0x20, 0x25, 0x6C, 0x6C, 0x64, 0x2C,
|
||||||
|
0x20, 0x66, 0x33, 0x32, 0x3A, 0x20, 0x25, 0x66, 0x2C, 0x20, 0x66, 0x36,
|
||||||
|
0x34, 0x3A, 0x20, 0x25, 0x66, 0x0A, 0x00, 0x25, 0x6C, 0x6C, 0x64, 0x20,
|
||||||
|
0x2B, 0x20, 0x25, 0x6C, 0x6C, 0x64, 0x20, 0x3D, 0x20, 0x25, 0x6C, 0x6C,
|
||||||
|
0x64, 0x0A, 0x00, 0x31, 0x32, 0x33, 0x34, 0x0A }
|
||||||
|
|
||||||
|
var global_heap []byte = make([]byte, 128 * 1024, 128 * 1024)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var module *wamr.Module
|
||||||
|
var instance *wamr.Instance
|
||||||
|
var argv []uint32
|
||||||
|
var results []interface{}
|
||||||
|
var offset uint32
|
||||||
|
var native_addr *uint8
|
||||||
|
var err error
|
||||||
|
|
||||||
|
fmt.Print("Init wasm runtime with global heap buf\n");
|
||||||
|
err = wamr.Runtime().FullInit(true, global_heap, 1)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Print("Destroy runtime\n");
|
||||||
|
wamr.Runtime().Destroy()
|
||||||
|
|
||||||
|
fmt.Print("Init wasm runtime without global heap buf\n");
|
||||||
|
err = wamr.Runtime().FullInit(false, nil, 1)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
wamr.Runtime().SetLogLevel(wamr.LOG_LEVEL_WARNING)
|
||||||
|
|
||||||
|
fmt.Print("Load wasm module\n");
|
||||||
|
module, err = wamr.NewModule(wasmBytes)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print("Instantiate wasm module\n");
|
||||||
|
instance, err = wamr.NewInstance(module, 16384, 16384)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
|
||||||
|
results = make([]interface{}, 8, 8)
|
||||||
|
argv = make([]uint32, 8)
|
||||||
|
|
||||||
|
fmt.Print("\nCall func __main_argc_argv with CallFunc:\n");
|
||||||
|
err = instance.CallFunc("__main_argc_argv", 2, argv)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print("\nCall func __main_argc_argv with CallFuncV:\n");
|
||||||
|
err = instance.CallFuncV("__main_argc_argv", 2, results,
|
||||||
|
(int32)(0), (int32)(0))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print("\nCall func `i32 fib2(i32)` with CallFunc:\n");
|
||||||
|
argv[0] = 32
|
||||||
|
err = instance.CallFunc("fib2", 1, argv)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
fmt.Printf("fib2(32) return: %d\n", argv[0]);
|
||||||
|
|
||||||
|
fmt.Print("\nCall func `void test1(i32, i64, f32, f64)` with CallFuncV:\n");
|
||||||
|
err = instance.CallFuncV("test1", 0, nil,
|
||||||
|
(int32)(12345678),
|
||||||
|
(int64)(3344556677889900),
|
||||||
|
(float32)(5678.1234),
|
||||||
|
(float64)(987654321.5678))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print("\nCall func `i64 test2(i64, i64)` with CallFuncV:\n");
|
||||||
|
err = instance.CallFuncV("test2", 1, results,
|
||||||
|
(int64)(3344556677889900),
|
||||||
|
(int64)(1122331122110099))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
fmt.Printf("test2(3344556677889900, 1122331122110099) return: %d\n",
|
||||||
|
results[0].(int64))
|
||||||
|
|
||||||
|
fmt.Print("\nCall func `f64 test3(f32, f64)` with CallFuncV:\n");
|
||||||
|
err = instance.CallFuncV("test3", 1, results,
|
||||||
|
(float32)(3456.1234),
|
||||||
|
(float64)(7890.4567))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
fmt.Printf("test3(3456.1234, 7890.4567) return: %f\n",
|
||||||
|
results[0].(float64))
|
||||||
|
|
||||||
|
fmt.Print("\nCall func `f32 test4(f64, i32)` with CallFuncV:\n");
|
||||||
|
err = instance.CallFuncV("test4", 1, results,
|
||||||
|
(float64)(8912.3456),
|
||||||
|
(int32)(123))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
fmt.Printf("test4(8912.3456, 123) return: %f\n",
|
||||||
|
results[0].(float32))
|
||||||
|
|
||||||
|
fmt.Print("\nTest ModuleMalloc")
|
||||||
|
offset, native_addr = instance.ModuleMalloc(1024)
|
||||||
|
fmt.Printf("ModuleMalloc(%d) return offset: %d, native addr: %p\n",
|
||||||
|
1024, offset, native_addr)
|
||||||
|
|
||||||
|
if (!instance.ValidateAppAddr(offset, 1024)) {
|
||||||
|
fmt.Print("Validate app addr failed\n")
|
||||||
|
}
|
||||||
|
if (!instance.ValidateNativeAddr(native_addr, 1024)) {
|
||||||
|
fmt.Print("Validate native addr failed\n")
|
||||||
|
}
|
||||||
|
if (native_addr != instance.AddrAppToNative(offset)) {
|
||||||
|
fmt.Print("Convert app addr to native addr failed\n")
|
||||||
|
}
|
||||||
|
if (offset != instance.AddrNativeToApp(native_addr)) {
|
||||||
|
fmt.Print("Convert app addr to native addr failed\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.ModuleFree(offset)
|
||||||
|
|
||||||
|
/*
|
||||||
|
instance.DumpMemoryConsumption()
|
||||||
|
instance.DumpCallStack()
|
||||||
|
*/
|
||||||
|
|
||||||
|
fmt.Print("\n");
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (instance != nil) {
|
||||||
|
fmt.Print("Destroy instance\n");
|
||||||
|
instance.Destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module != nil) {
|
||||||
|
fmt.Print("Destroy module\n");
|
||||||
|
module.Destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print("Destroy wasm runtime\n");
|
||||||
|
wamr.Runtime().Destroy()
|
||||||
|
}
|
32
language-bindings/go/samples/wasm-app/build.sh
Executable file
32
language-bindings/go/samples/wasm-app/build.sh
Executable file
|
@ -0,0 +1,32 @@
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
WAMR_DIR=${PWD}/../../..
|
||||||
|
|
||||||
|
echo "Build wasm app .."
|
||||||
|
/opt/wasi-sdk/bin/clang -O3 \
|
||||||
|
-z stack-size=4096 -Wl,--initial-memory=65536 \
|
||||||
|
-o test.wasm main.c \
|
||||||
|
-Wl,--export=main -Wl,--export=__main_argc_argv \
|
||||||
|
-Wl,--export=fib2 \
|
||||||
|
-Wl,--export=test1 \
|
||||||
|
-Wl,--export=test2 \
|
||||||
|
-Wl,--export=test3 \
|
||||||
|
-Wl,--export=test4 \
|
||||||
|
-Wl,--export=__data_end -Wl,--export=__heap_base \
|
||||||
|
-Wl,--strip-all,--no-entry \
|
||||||
|
-Wl,--allow-undefined \
|
||||||
|
-nostdlib \
|
||||||
|
|
||||||
|
echo "Build binarydump tool .."
|
||||||
|
rm -fr build && mkdir build && cd build
|
||||||
|
cmake ../../../../../test-tools/binarydump-tool
|
||||||
|
make
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
echo "Generate test_wasm.h .."
|
||||||
|
./build/binarydump -o test_wasm.h -n wasm_test_file test.wasm
|
||||||
|
|
||||||
|
rm -fr build
|
||||||
|
|
||||||
|
echo "Done"
|
65
language-bindings/go/samples/wasm-app/main.c
Normal file
65
language-bindings/go/samples/wasm-app/main.c
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
fib2(unsigned n)
|
||||||
|
{
|
||||||
|
if (n < 2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return fib2(n - 2) + fib2(n - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test1(int32_t i32, int64_t i64, float f32, double f64)
|
||||||
|
{
|
||||||
|
printf("i32: %d, i64: %lld, f32: %f, f64: %f\n", i32, i64, f32, f64);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
test2(int64_t x, int64_t y)
|
||||||
|
{
|
||||||
|
printf("%lld + %lld = %lld\n", x, y, x + y);
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
test3(float x, double y)
|
||||||
|
{
|
||||||
|
printf("%f * %f = %f\n", x, y, x * y);
|
||||||
|
return x * y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
test4(double x, int32_t y)
|
||||||
|
{
|
||||||
|
printf("%f / %d = %f\n", x, y, x / y);
|
||||||
|
return x / y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
printf("Hello world!\n");
|
||||||
|
|
||||||
|
buf = malloc(1024);
|
||||||
|
if (!buf) {
|
||||||
|
printf("malloc buf failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("buf ptr: %p\n", buf);
|
||||||
|
|
||||||
|
snprintf(buf, 1024, "%s", "1234\n");
|
||||||
|
printf("buf: %s", buf);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
20
language-bindings/go/wamr/cgo.go
Normal file
20
language-bindings/go/wamr/cgo.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wamr
|
||||||
|
|
||||||
|
// #cgo CFLAGS: -I${SRCDIR}/packaged/include
|
||||||
|
// #cgo LDFLAGS: -lvmlib -lm
|
||||||
|
//
|
||||||
|
// #cgo linux,amd64 LDFLAGS: -Wl,-rpath,${SRCDIR}/packaged/lib/linux-amd64 -L${SRCDIR}/packaged/lib/linux-amd64
|
||||||
|
// #cgo linux,arm64 LDFLAGS: -Wl,-rpath,${SRCDIR}/packaged/lib/linux-aarch64 -L${SRCDIR}/packaged/lib/linux-aarch64
|
||||||
|
// #cgo darwin,amd64 LDFLAGS: -Wl,-rpath,${SRCDIR}/packaged/lib/darwin-amd64 -L${SRCDIR}/packaged/lib/darwin-amd64
|
||||||
|
// #cgo darwin,arm64 LDFLAGS: -Wl,-rpath,${SRCDIR}/packaged/lib/darwin-aarch64 -L${SRCDIR}/packaged/lib/darwin-aarch64
|
||||||
|
//
|
||||||
|
// #include <wasm_export.h>
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
)
|
385
language-bindings/go/wamr/instance.go
Normal file
385
language-bindings/go/wamr/instance.go
Normal file
|
@ -0,0 +1,385 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wamr
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wasm_export.h>
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
PUT_I64_TO_ADDR(uint32_t *addr, int64_t value)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
int64_t val;
|
||||||
|
uint32_t parts[2];
|
||||||
|
} u;
|
||||||
|
u.val = value;
|
||||||
|
addr[0] = u.parts[0];
|
||||||
|
addr[1] = u.parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
PUT_F64_TO_ADDR(uint32_t *addr, double value)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
double val;
|
||||||
|
uint32_t parts[2];
|
||||||
|
} u;
|
||||||
|
u.val = value;
|
||||||
|
addr[0] = u.parts[0];
|
||||||
|
addr[1] = u.parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64_t
|
||||||
|
GET_I64_FROM_ADDR(uint32_t *addr)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
int64_t val;
|
||||||
|
uint32_t parts[2];
|
||||||
|
} u;
|
||||||
|
u.parts[0] = addr[0];
|
||||||
|
u.parts[1] = addr[1];
|
||||||
|
return u.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
GET_F64_FROM_ADDR(uint32_t *addr)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
double val;
|
||||||
|
uint32_t parts[2];
|
||||||
|
} u;
|
||||||
|
u.parts[0] = addr[0];
|
||||||
|
u.parts[1] = addr[1];
|
||||||
|
return u.val;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Instance struct {
|
||||||
|
_instance C.wasm_module_inst_t
|
||||||
|
_exec_env C.wasm_exec_env_t
|
||||||
|
_module *Module
|
||||||
|
_exportsCache map[string]C.wasm_function_inst_t
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create instance from the module */
|
||||||
|
func NewInstance(module *Module,
|
||||||
|
stackSize uint, heapSize uint) (*Instance, error) {
|
||||||
|
if (module == nil) {
|
||||||
|
return nil, fmt.Errorf("NewInstance error: invalid input")
|
||||||
|
}
|
||||||
|
|
||||||
|
errorBytes := make([]byte, 128)
|
||||||
|
errorPtr := (*C.char)(unsafe.Pointer(&errorBytes[0]))
|
||||||
|
errorLen := C.uint(len(errorBytes))
|
||||||
|
|
||||||
|
instance := C.wasm_runtime_instantiate(module.module, C.uint(stackSize),
|
||||||
|
C.uint(heapSize), errorPtr, errorLen)
|
||||||
|
if (instance == nil) {
|
||||||
|
return nil, fmt.Errorf("NewInstance Error: %s", string(errorBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
exec_env := C.wasm_runtime_create_exec_env(instance, C.uint(stackSize))
|
||||||
|
if (exec_env == nil) {
|
||||||
|
C.wasm_runtime_deinstantiate(instance)
|
||||||
|
return nil, fmt.Errorf("NewInstance Error: create exec_env failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
self := &Instance{
|
||||||
|
_instance: instance,
|
||||||
|
_exec_env: exec_env,
|
||||||
|
_module: module,
|
||||||
|
_exportsCache: make(map[string]C.wasm_function_inst_t),
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.SetFinalizer(self, func(self *Instance) {
|
||||||
|
self.Destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
return self, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy the instance */
|
||||||
|
func (self *Instance) Destroy() {
|
||||||
|
runtime.SetFinalizer(self, nil)
|
||||||
|
if (self._instance != nil) {
|
||||||
|
C.wasm_runtime_deinstantiate(self._instance)
|
||||||
|
}
|
||||||
|
if (self._exec_env != nil) {
|
||||||
|
C.wasm_runtime_destroy_exec_env(self._exec_env)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the wasm function with argument in the uint32 array, and store
|
||||||
|
the return values back into the array */
|
||||||
|
func (self *Instance) CallFunc(funcName string,
|
||||||
|
argc uint32, args []uint32) error {
|
||||||
|
_func := self._exportsCache[funcName]
|
||||||
|
if _func == nil {
|
||||||
|
cName := C.CString(funcName)
|
||||||
|
defer C.free(unsafe.Pointer(cName))
|
||||||
|
|
||||||
|
_func = C.wasm_runtime_lookup_function(self._instance,
|
||||||
|
cName, (*C.char)(C.NULL))
|
||||||
|
if _func == nil {
|
||||||
|
return fmt.Errorf("CallFunc error: lookup function failed")
|
||||||
|
}
|
||||||
|
self._exportsCache[funcName] = _func
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_env_inited := Runtime().ThreadEnvInited()
|
||||||
|
if (!thread_env_inited) {
|
||||||
|
Runtime().InitThreadEnv()
|
||||||
|
}
|
||||||
|
|
||||||
|
var args_C *C.uint32_t
|
||||||
|
if (argc > 0) {
|
||||||
|
args_C = (*C.uint32_t)(unsafe.Pointer(&args[0]))
|
||||||
|
}
|
||||||
|
if (!C.wasm_runtime_call_wasm(self._exec_env, _func,
|
||||||
|
C.uint(argc), args_C)) {
|
||||||
|
if (!thread_env_inited) {
|
||||||
|
Runtime().DestroyThreadEnv()
|
||||||
|
}
|
||||||
|
return fmt.Errorf("CallFunc error: %s", string(self.GetException()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!thread_env_inited) {
|
||||||
|
Runtime().DestroyThreadEnv()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the wasm function with variant arguments, and store the return
|
||||||
|
values back into the results array */
|
||||||
|
func (self *Instance) CallFuncV(funcName string,
|
||||||
|
num_results uint32, results []interface{},
|
||||||
|
args ... interface{}) error {
|
||||||
|
_func := self._exportsCache[funcName]
|
||||||
|
if _func == nil {
|
||||||
|
cName := C.CString(funcName)
|
||||||
|
defer C.free(unsafe.Pointer(cName))
|
||||||
|
|
||||||
|
_func = C.wasm_runtime_lookup_function(self._instance,
|
||||||
|
cName, (*C.char)(C.NULL))
|
||||||
|
if _func == nil {
|
||||||
|
return fmt.Errorf("CallFunc error: lookup function failed")
|
||||||
|
}
|
||||||
|
self._exportsCache[funcName] = _func
|
||||||
|
}
|
||||||
|
|
||||||
|
param_count := uint32(C.wasm_func_get_param_count(_func, self._instance))
|
||||||
|
result_count := uint32(C.wasm_func_get_result_count(_func, self._instance))
|
||||||
|
|
||||||
|
if (num_results < result_count) {
|
||||||
|
str := "CallFunc error: invalid result count %d, " +
|
||||||
|
"must be no smaller than %d"
|
||||||
|
return fmt.Errorf(str, num_results, result_count)
|
||||||
|
}
|
||||||
|
|
||||||
|
param_types := make([]C.uchar, param_count, param_count)
|
||||||
|
result_types := make([]C.uchar, result_count, result_count)
|
||||||
|
if (param_count > 0) {
|
||||||
|
C.wasm_func_get_param_types(_func, self._instance,
|
||||||
|
(*C.uchar)(unsafe.Pointer(¶m_types[0])))
|
||||||
|
}
|
||||||
|
if (result_count > 0) {
|
||||||
|
C.wasm_func_get_result_types(_func, self._instance,
|
||||||
|
(*C.uchar)(unsafe.Pointer(&result_types[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
argv_size := param_count * 2
|
||||||
|
if (result_count > param_count) {
|
||||||
|
argv_size = result_count * 2
|
||||||
|
}
|
||||||
|
argv := make([]uint32, argv_size, argv_size)
|
||||||
|
|
||||||
|
var i, argc uint32
|
||||||
|
for _, arg := range args {
|
||||||
|
if (i >= param_count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch arg.(type) {
|
||||||
|
case int32:
|
||||||
|
if (param_types[i] != C.WASM_I32 &&
|
||||||
|
param_types[i] != C.WASM_FUNCREF &&
|
||||||
|
param_types[i] != C.WASM_ANYREF) {
|
||||||
|
str := "CallFunc error: invalid param type %d, " +
|
||||||
|
"expect i32 but got other"
|
||||||
|
return fmt.Errorf(str, param_types[i])
|
||||||
|
}
|
||||||
|
argv[argc] = (uint32)(arg.(int32))
|
||||||
|
argc++
|
||||||
|
break
|
||||||
|
case int64:
|
||||||
|
if (param_types[i] != C.WASM_I64) {
|
||||||
|
str := "CallFunc error: invalid param type %d, " +
|
||||||
|
"expect i64 but got other"
|
||||||
|
return fmt.Errorf(str, param_types[i])
|
||||||
|
}
|
||||||
|
addr := (*C.uint32_t)(unsafe.Pointer(&argv[argc]))
|
||||||
|
C.PUT_I64_TO_ADDR(addr, (C.int64_t)(arg.(int64)))
|
||||||
|
argc += 2
|
||||||
|
break
|
||||||
|
case float32:
|
||||||
|
if (param_types[i] != C.WASM_F32) {
|
||||||
|
str := "CallFunc error: invalid param type %d, " +
|
||||||
|
"expect f32 but got other"
|
||||||
|
return fmt.Errorf(str, param_types[i])
|
||||||
|
}
|
||||||
|
*(*C.float)(unsafe.Pointer(&argv[argc])) = (C.float)(arg.(float32))
|
||||||
|
argc++
|
||||||
|
break
|
||||||
|
case float64:
|
||||||
|
if (param_types[i] != C.WASM_F64) {
|
||||||
|
str := "CallFunc error: invalid param type %d, " +
|
||||||
|
"expect f64 but got other"
|
||||||
|
return fmt.Errorf(str, param_types[i])
|
||||||
|
}
|
||||||
|
addr := (*C.uint32_t)(unsafe.Pointer(&argv[argc]))
|
||||||
|
C.PUT_F64_TO_ADDR(addr, (C.double)(arg.(float64)))
|
||||||
|
argc += 2
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("CallFunc error: unknown param type %d",
|
||||||
|
param_types[i])
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < param_count) {
|
||||||
|
str := "CallFunc error: invalid param count, " +
|
||||||
|
"must be no smaller than %d"
|
||||||
|
return fmt.Errorf(str, param_count)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := self.CallFunc(funcName, argc, argv)
|
||||||
|
if (err != nil) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
argc = 0
|
||||||
|
for i = 0; i < result_count; i++ {
|
||||||
|
switch result_types[i] {
|
||||||
|
case C.WASM_I32:
|
||||||
|
case C.WASM_FUNCREF:
|
||||||
|
case C.WASM_ANYREF:
|
||||||
|
i32 := (int32)(argv[argc])
|
||||||
|
results[i] = i32
|
||||||
|
argc++
|
||||||
|
break
|
||||||
|
case C.WASM_I64:
|
||||||
|
addr := (*C.uint32_t)(unsafe.Pointer(&argv[argc]))
|
||||||
|
results[i] = (int64)(C.GET_I64_FROM_ADDR(addr))
|
||||||
|
argc += 2
|
||||||
|
break
|
||||||
|
case C.WASM_F32:
|
||||||
|
addr := (*C.float)(unsafe.Pointer(&argv[argc]))
|
||||||
|
results[i] = (float32)(*addr)
|
||||||
|
argc++
|
||||||
|
break
|
||||||
|
case C.WASM_F64:
|
||||||
|
addr := (*C.uint32_t)(unsafe.Pointer(&argv[argc]))
|
||||||
|
results[i] = (float64)(C.GET_F64_FROM_ADDR(addr))
|
||||||
|
argc += 2
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get exception info of the instance */
|
||||||
|
func (self *Instance) GetException() string {
|
||||||
|
cStr := C.wasm_runtime_get_exception(self._instance)
|
||||||
|
goStr := C.GoString(cStr)
|
||||||
|
return goStr
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory from the heap of the instance */
|
||||||
|
func (self Instance) ModuleMalloc(size uint32) (uint32, *uint8) {
|
||||||
|
var offset C.uint32_t
|
||||||
|
native_addrs := make([]*uint8, 1, 1)
|
||||||
|
ptr := unsafe.Pointer(&native_addrs[0])
|
||||||
|
offset = C.wasm_runtime_module_malloc(self._instance, (C.uint32_t)(size),
|
||||||
|
(*unsafe.Pointer)(ptr))
|
||||||
|
return (uint32)(offset), native_addrs[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free memory to the heap of the instance */
|
||||||
|
func (self Instance) ModuleFree(offset uint32) {
|
||||||
|
C.wasm_runtime_module_free(self._instance, (C.uint32_t)(offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) ValidateAppAddr(app_offset uint32, size uint32) bool {
|
||||||
|
ret := C.wasm_runtime_validate_app_addr(self._instance,
|
||||||
|
(C.uint32_t)(app_offset),
|
||||||
|
(C.uint32_t)(size))
|
||||||
|
return (bool)(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) ValidateStrAddr(app_str_offset uint32) bool {
|
||||||
|
ret := C.wasm_runtime_validate_app_str_addr(self._instance,
|
||||||
|
(C.uint32_t)(app_str_offset))
|
||||||
|
return (bool)(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) ValidateNativeAddr(native_ptr *uint8, size uint32) bool {
|
||||||
|
native_ptr_C := (unsafe.Pointer)(native_ptr)
|
||||||
|
ret := C.wasm_runtime_validate_native_addr(self._instance,
|
||||||
|
native_ptr_C,
|
||||||
|
(C.uint32_t)(size))
|
||||||
|
return (bool)(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) AddrAppToNative(app_offset uint32) *uint8 {
|
||||||
|
native_ptr := C.wasm_runtime_addr_app_to_native(self._instance,
|
||||||
|
(C.uint32_t)(app_offset))
|
||||||
|
return (*uint8)(native_ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) AddrNativeToApp(native_ptr *uint8) uint32 {
|
||||||
|
native_ptr_C := (unsafe.Pointer)(native_ptr)
|
||||||
|
offset := C.wasm_runtime_addr_native_to_app(self._instance,
|
||||||
|
native_ptr_C)
|
||||||
|
return (uint32)(offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) GetAppAddrRange(app_offset uint32) (bool,
|
||||||
|
uint32,
|
||||||
|
uint32) {
|
||||||
|
var start_offset, end_offset C.uint32_t
|
||||||
|
ret := C.wasm_runtime_get_app_addr_range(self._instance,
|
||||||
|
(C.uint32_t)(app_offset),
|
||||||
|
&start_offset, &end_offset)
|
||||||
|
return (bool)(ret), (uint32)(start_offset), (uint32)(end_offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) GetNativeAddrRange(native_ptr *uint8) (bool,
|
||||||
|
*uint8,
|
||||||
|
*uint8) {
|
||||||
|
var start_addr, end_addr *C.uint8_t
|
||||||
|
native_ptr_C := (*C.uint8_t)((unsafe.Pointer)(native_ptr))
|
||||||
|
ret := C.wasm_runtime_get_native_addr_range(self._instance,
|
||||||
|
native_ptr_C,
|
||||||
|
&start_addr, &end_addr)
|
||||||
|
return (bool)(ret), (*uint8)(start_addr), (*uint8)(end_addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) DumpMemoryConsumption() {
|
||||||
|
C.wasm_runtime_dump_mem_consumption(self._exec_env)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Instance) DumpCallStack() {
|
||||||
|
C.wasm_runtime_dump_call_stack(self._exec_env)
|
||||||
|
}
|
19
language-bindings/go/wamr/instance_test.go
Normal file
19
language-bindings/go/wamr/instance_test.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wamr
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInstance(t *testing.T) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCallFunc(t *testing.T) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
134
language-bindings/go/wamr/module.go
Normal file
134
language-bindings/go/wamr/module.go
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wamr
|
||||||
|
|
||||||
|
// #include <wasm_export.h>
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
"runtime"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Module struct {
|
||||||
|
module C.wasm_module_t
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create WASM/AOT module from the memory buffer */
|
||||||
|
func NewModule(wasmBytes []byte) (*Module, error) {
|
||||||
|
if (wasmBytes == nil || len(wasmBytes) == 0) {
|
||||||
|
return nil, fmt.Errorf("NewModule error: invalid input")
|
||||||
|
}
|
||||||
|
|
||||||
|
wasmPtr := (*C.uint8_t)(unsafe.Pointer(&wasmBytes[0]))
|
||||||
|
wasmLen := C.uint(len(wasmBytes))
|
||||||
|
|
||||||
|
errorBytes := make([]byte, 128)
|
||||||
|
errorPtr := (*C.char)(unsafe.Pointer(&errorBytes[0]))
|
||||||
|
errorLen := C.uint(len(errorBytes))
|
||||||
|
|
||||||
|
m := C.wasm_runtime_load(wasmPtr, wasmLen, errorPtr, errorLen)
|
||||||
|
if (m == nil) {
|
||||||
|
return nil, fmt.Errorf("NewModule error: %s", string(errorBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
self := &Module{
|
||||||
|
module: m,
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.SetFinalizer(self, func(self *Module) {
|
||||||
|
self.Destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
return self, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy the module */
|
||||||
|
func (self *Module) Destroy() {
|
||||||
|
runtime.SetFinalizer(self, nil)
|
||||||
|
if (self.module != nil) {
|
||||||
|
C.wasm_runtime_unload(self.module)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set module's wasi arguments */
|
||||||
|
func (self *Module) SetWasiArgs(dirList [][]byte, mapDirList [][]byte,
|
||||||
|
env [][]byte, argv[][]byte) {
|
||||||
|
var dirPtr, mapDirPtr, envPtr, argvPtr **C.char
|
||||||
|
var dirCount, mapDirCount, envCount C.uint
|
||||||
|
var argc C.int
|
||||||
|
|
||||||
|
if (dirList != nil) {
|
||||||
|
dirPtr = (**C.char)(unsafe.Pointer(&dirList[0]))
|
||||||
|
dirCount = C.uint(len(dirList))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapDirList != nil) {
|
||||||
|
mapDirPtr = (**C.char)(unsafe.Pointer(&mapDirList[0]))
|
||||||
|
mapDirCount = C.uint(len(mapDirList))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env != nil) {
|
||||||
|
envPtr = (**C.char)(unsafe.Pointer(&env[0]))
|
||||||
|
envCount = C.uint(len(env))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv != nil) {
|
||||||
|
argvPtr = (**C.char)(unsafe.Pointer(&argv[0]))
|
||||||
|
argc = C.int(len(argv))
|
||||||
|
}
|
||||||
|
|
||||||
|
C.wasm_runtime_set_wasi_args(self.module, dirPtr, dirCount,
|
||||||
|
mapDirPtr, mapDirCount,
|
||||||
|
envPtr, envCount, argvPtr, argc)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set module's wasi arguments */
|
||||||
|
func (self *Module) SetWasiArgsEx(dirList [][]byte, mapDirList [][]byte,
|
||||||
|
env [][]byte, argv[][]byte,
|
||||||
|
stdinfd int, stdoutfd int, stderrfd int) {
|
||||||
|
var dirPtr, mapDirPtr, envPtr, argvPtr **C.char
|
||||||
|
var dirCount, mapDirCount, envCount C.uint
|
||||||
|
var argc C.int
|
||||||
|
|
||||||
|
if (dirList != nil) {
|
||||||
|
dirPtr = (**C.char)(unsafe.Pointer(&dirList[0]))
|
||||||
|
dirCount = C.uint(len(dirList))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapDirList != nil) {
|
||||||
|
mapDirPtr = (**C.char)(unsafe.Pointer(&mapDirList[0]))
|
||||||
|
mapDirCount = C.uint(len(mapDirList))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env != nil) {
|
||||||
|
envPtr = (**C.char)(unsafe.Pointer(&env[0]))
|
||||||
|
envCount = C.uint(len(env))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv != nil) {
|
||||||
|
argvPtr = (**C.char)(unsafe.Pointer(&argv[0]))
|
||||||
|
argc = C.int(len(argv))
|
||||||
|
}
|
||||||
|
|
||||||
|
C.wasm_runtime_set_wasi_args_ex(self.module, dirPtr, dirCount,
|
||||||
|
mapDirPtr, mapDirCount,
|
||||||
|
envPtr, envCount, argvPtr, argc,
|
||||||
|
C.int(stdinfd), C.int(stdoutfd),
|
||||||
|
C.int(stderrfd))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set module's wasi network address pool */
|
||||||
|
func (self *Module) SetWasiAddrPool(addrPool [][]byte) {
|
||||||
|
var addrPoolPtr **C.char
|
||||||
|
var addrPoolSize C.uint
|
||||||
|
|
||||||
|
if (addrPool != nil) {
|
||||||
|
addrPoolPtr = (**C.char)(unsafe.Pointer(&addrPool[0]))
|
||||||
|
addrPoolSize = C.uint(len(addrPool))
|
||||||
|
}
|
||||||
|
C.wasm_runtime_set_wasi_addr_pool(self.module, addrPoolPtr, addrPoolSize)
|
||||||
|
}
|
15
language-bindings/go/wamr/module_test.go
Normal file
15
language-bindings/go/wamr/module_test.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wamr
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestModule(t *testing.T) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
6
language-bindings/go/wamr/packaged/include/dummy.go
Normal file
6
language-bindings/go/wamr/packaged/include/dummy.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package include
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package darwin_amd64
|
6
language-bindings/go/wamr/packaged/lib/dummy.go
Normal file
6
language-bindings/go/wamr/packaged/lib/dummy.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package lib
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package linux_amd64
|
153
language-bindings/go/wamr/runtime.go
Normal file
153
language-bindings/go/wamr/runtime.go
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wamr
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <wasm_export.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
bh_log_set_verbose_level(uint32_t level);
|
||||||
|
|
||||||
|
bool
|
||||||
|
init_wamr_runtime(bool alloc_with_pool, uint8_t *heap_buf,
|
||||||
|
uint32_t heap_size, uint32_t max_thread_num)
|
||||||
|
{
|
||||||
|
RuntimeInitArgs init_args;
|
||||||
|
|
||||||
|
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||||
|
|
||||||
|
if (alloc_with_pool) {
|
||||||
|
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||||
|
init_args.mem_alloc_option.pool.heap_buf = heap_buf;
|
||||||
|
init_args.mem_alloc_option.pool.heap_size = heap_size;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
init_args.mem_alloc_type = Alloc_With_System_Allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wasm_runtime_full_init(&init_args);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LogLevel uint32
|
||||||
|
const (
|
||||||
|
LOG_LEVEL_FATAL LogLevel = 0
|
||||||
|
LOG_LEVEL_ERROR LogLevel = 1
|
||||||
|
LOG_LEVEL_WARNING LogLevel = 2
|
||||||
|
LOG_LEVEL_DEBUG LogLevel = 3
|
||||||
|
LOG_LEVEL_VERBOSE LogLevel = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
type NativeSymbol struct {
|
||||||
|
symbol string
|
||||||
|
func_ptr *uint8
|
||||||
|
signature string
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
type _Runtime struct {
|
||||||
|
initialized bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var _runtime_singleton *_Runtime
|
||||||
|
|
||||||
|
/* Return the runtime singleton */
|
||||||
|
func Runtime() *_Runtime {
|
||||||
|
if (_runtime_singleton == nil) {
|
||||||
|
self := &_Runtime{}
|
||||||
|
_runtime_singleton = self
|
||||||
|
}
|
||||||
|
return _runtime_singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the WASM runtime environment */
|
||||||
|
func (self *_Runtime) FullInit(alloc_with_pool bool, heap_buf []byte,
|
||||||
|
max_thread_num uint) error {
|
||||||
|
var heap_buf_C *C.uchar
|
||||||
|
|
||||||
|
if (self.initialized) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alloc_with_pool) {
|
||||||
|
if (heap_buf == nil) {
|
||||||
|
return fmt.Errorf("Failed to init WAMR runtime")
|
||||||
|
}
|
||||||
|
heap_buf_C = (*C.uchar)(unsafe.Pointer(&heap_buf[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!C.init_wamr_runtime((C.bool)(alloc_with_pool), heap_buf_C,
|
||||||
|
(C.uint)(len(heap_buf)),
|
||||||
|
(C.uint)(max_thread_num))) {
|
||||||
|
return fmt.Errorf("Failed to init WAMR runtime")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.initialized = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the WASM runtime environment */
|
||||||
|
func (self *_Runtime) Init() error {
|
||||||
|
return self.FullInit(false, nil, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy the WASM runtime environment */
|
||||||
|
func (self *_Runtime) Destroy() {
|
||||||
|
if (self.initialized) {
|
||||||
|
C.wasm_runtime_destroy()
|
||||||
|
self.initialized = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set log verbose level (0 to 5, default is 2),
|
||||||
|
larger level with more log */
|
||||||
|
func (self *_Runtime) SetLogLevel(level LogLevel) {
|
||||||
|
C.bh_log_set_verbose_level(C.uint32_t(level))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func (self *_Runtime) RegisterNatives(moduleName string,
|
||||||
|
nativeSymbols []NativeSymbol) {
|
||||||
|
}
|
||||||
|
*/ /* TODO */
|
||||||
|
|
||||||
|
func (self *_Runtime) InitThreadEnv() bool {
|
||||||
|
if (!C.wasm_runtime_init_thread_env()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *_Runtime) DestroyThreadEnv() {
|
||||||
|
C.wasm_runtime_destroy_thread_env();
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *_Runtime) ThreadEnvInited() bool {
|
||||||
|
if (!C.wasm_runtime_thread_env_inited()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory from runtime memory environment */
|
||||||
|
func (self *_Runtime) Malloc(size uint32) *uint8 {
|
||||||
|
ptr := C.wasm_runtime_malloc((C.uint32_t)(size))
|
||||||
|
return (*uint8)(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free memory to runtime memory environment */
|
||||||
|
func (self *_Runtime) Free(ptr *uint8) {
|
||||||
|
C.wasm_runtime_free((unsafe.Pointer)(ptr))
|
||||||
|
}
|
42
language-bindings/go/wamr/runtime_test.go
Normal file
42
language-bindings/go/wamr/runtime_test.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wamr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRuntime(t *testing.T) {
|
||||||
|
res := false
|
||||||
|
if (Runtime() != nil) {
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
assert.Equal(t, res, true)
|
||||||
|
|
||||||
|
err := Runtime().Init()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
Runtime().Destroy()
|
||||||
|
|
||||||
|
err = Runtime().FullInit(false, nil, 6)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
Runtime().Destroy()
|
||||||
|
|
||||||
|
err = Runtime().FullInit(false, nil, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
Runtime().Destroy()
|
||||||
|
|
||||||
|
heap_buf := make([]byte, 128 * 1024)
|
||||||
|
err = Runtime().FullInit(true, heap_buf, 4)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
Runtime().Destroy()
|
||||||
|
|
||||||
|
Runtime().FullInit(false, nil, 0)
|
||||||
|
err = Runtime().FullInit(false, nil, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
Runtime().Destroy()
|
||||||
|
Runtime().Destroy()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user