mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +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,
|
||||
uint8 *orig_file_buf,
|
||||
uint32 orig_file_buf_size,
|
||||
char *error_buf, uint32_t error_buf_size)
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMRegisteredModule *node = NULL;
|
||||
|
||||
|
@ -500,7 +500,7 @@ wasm_runtime_register_module_internal(const char *module_name,
|
|||
|
||||
bool
|
||||
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) {
|
||||
LOG_ERROR("error buffer is required");
|
||||
|
@ -823,7 +823,7 @@ wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
|||
|
||||
WASMModuleCommon *
|
||||
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;
|
||||
|
||||
|
@ -980,6 +980,23 @@ wasm_runtime_destroy_thread_env(void)
|
|||
#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)
|
||||
void
|
||||
wasm_runtime_dump_module_mem_consumption(const WASMModuleCommon *module)
|
||||
|
@ -1222,8 +1239,81 @@ wasm_runtime_lookup_function(WASMModuleInstanceCommon *const module_inst,
|
|||
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
|
||||
/* (uintptr_t)externref -> (uint32_t)index */
|
||||
/* (uintptr_t)externref -> (uint32)index */
|
||||
/* argv -> *ret_argv */
|
||||
static bool
|
||||
wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
||||
|
@ -1321,7 +1411,7 @@ wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* (uintptr_t)externref <- (uint32_t)index */
|
||||
/* (uintptr_t)externref <- (uint32)index */
|
||||
/* argv <- new_argv */
|
||||
static bool
|
||||
wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
||||
|
@ -3952,8 +4042,8 @@ fail:
|
|||
|| defined(BUILD_TARGET_RISCV64_LP64) */
|
||||
|
||||
bool
|
||||
wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32_t element_indices,
|
||||
uint32_t argc, uint32_t argv[])
|
||||
wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_indices,
|
||||
uint32 argc, uint32 argv[])
|
||||
{
|
||||
if (!wasm_runtime_exec_env_check(exec_env)) {
|
||||
LOG_ERROR("Invalid exec env stack info.");
|
||||
|
|
|
@ -471,6 +471,28 @@ WASMType *
|
|||
wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
|
||||
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 */
|
||||
WASM_RUNTIME_API_EXTERN WASMExecEnv *
|
||||
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,
|
||||
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.
|
||||
*
|
||||
|
@ -449,7 +497,7 @@ WASM_RUNTIME_API_EXTERN uint32_t
|
|||
wasm_runtime_start_debug_instance(wasm_exec_env_t exec_env);
|
||||
|
||||
/**
|
||||
* Initialize thread environment.
|
||||
* Initialize the thread environment.
|
||||
* Note:
|
||||
* If developer creates a child thread by himself to call the
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Destroy thread environment
|
||||
* Destroy the thread environment
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN 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
|
||||
*
|
||||
|
|
|
@ -107,6 +107,12 @@ os_thread_env_init();
|
|||
void
|
||||
os_thread_env_destroy();
|
||||
|
||||
/**
|
||||
* Whether the thread environment is initialized
|
||||
*/
|
||||
bool
|
||||
os_thread_env_inited();
|
||||
|
||||
/**
|
||||
* Suspend execution of the calling thread for (at least)
|
||||
* 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
|
||||
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