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:
Wenyong Huang 2022-06-01 11:35:05 +08:00 committed by GitHub
parent 3d34a91f0b
commit 5b1dcf2fa2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1482 additions and 9 deletions

View File

@ -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.");

View File

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

View File

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

View File

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

View File

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

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

View 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

View 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=

View 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

View 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

View 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()
}

View 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"

View 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;
}

View 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 (
)

View 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(&param_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)
}

View 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 */
}

View 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)
}

View 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 */
}

View File

@ -0,0 +1,6 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
package include

View File

@ -0,0 +1,6 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
package darwin_amd64

View File

@ -0,0 +1,6 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
package lib

View File

@ -0,0 +1,6 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
package linux_amd64

View 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))
}

View 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()
}