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:
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()
|
||||
}
|
||||
Reference in New Issue
Block a user