From a58216158b155038d1816d344175876d69b74a3d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 18 Sep 2020 10:38:35 +0200 Subject: [PATCH] feat: Implement `Module`. --- wasmer/error.go | 2 +- wasmer/module.go | 35 +++++++++++++++++++++++++++-------- wasmer/store.go | 1 - 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/wasmer/error.go b/wasmer/error.go index a60898de..a6f80709 100644 --- a/wasmer/error.go +++ b/wasmer/error.go @@ -29,7 +29,7 @@ func newError() *Error { } return &Error{ - message: C.GoString(errorMessagePointer), + message: C.GoStringN(errorMessagePointer, errorLength), } } diff --git a/wasmer/module.go b/wasmer/module.go index b5e9c594..97eafbbe 100644 --- a/wasmer/module.go +++ b/wasmer/module.go @@ -1,8 +1,22 @@ package wasmer // #include +// +// // We can't create a `wasm_byte_vec_t` directly in Go otherwise cgo +// // complains with “Go pointer to Go pointer”. The hack consists at +// // creating the `wasm_byte_vec_t` directly in C. +// own wasm_module_t* go_wasm_module_new(wasm_store_t *store, uint8_t *bytes, size_t bytes_length) { +// wasm_byte_vec_t wasm_bytes; +// wasm_bytes.size = bytes_length; +// wasm_bytes.data = (wasm_byte_t*) bytes; +// +// return wasm_module_new(store, &wasm_bytes); +// } import "C" -import "unsafe" +import ( + "runtime" + "unsafe" +) // A WebAssembly module contains stateless WebAssembly code that has // already been compiled and can be instantiated multiple times. @@ -23,23 +37,28 @@ type Module struct { } func NewModule(store *Store, bytes []byte) (*Module, error) { - var bytes_ptr *C.char + var bytesPtr *C.uint8_t if len(bytes) > 0 { - bytes_ptr = (*C.char)(unsafe.Pointer(&bytes[0])) + bytesPtr = (*C.uint8_t)(unsafe.Pointer(&bytes[0])) } - var wasm_bytes C.wasm_byte_vec_t - wasm_bytes.size = C.size_t(len(bytes)) - wasm_bytes.data = (*C.wasm_byte_t)(bytes_ptr) - module := &Module{ - _inner: C.wasm_module_new(store.inner(), &wasm_bytes), + _inner: C.go_wasm_module_new(store.inner(), bytesPtr, C.size_t(len(bytes))), } + runtime.KeepAlive(bytes) + runtime.SetFinalizer(module, func(module *Module) { + C.wasm_module_delete(module.inner()) + }) + if module == nil { return nil, newError() } return module, nil } + +func (module *Module) inner() *C.wasm_module_t { + return module._inner +} diff --git a/wasmer/store.go b/wasmer/store.go index 6959bc34..d78cb072 100644 --- a/wasmer/store.go +++ b/wasmer/store.go @@ -25,7 +25,6 @@ func NewStore(engine *Engine) *Store { Engine: engine, } - runtime.KeepAlive(engine) runtime.SetFinalizer(store, func(store *Store) { C.wasm_store_delete(store.inner()) })