add relase call

pull/2/head
vedhavyas 2019-09-23 23:23:27 +02:00
parent 0072b5c1a3
commit e56a2c5a85
No known key found for this signature in database
GPG Key ID: 317BF0923E3EB7E5
4 changed files with 65 additions and 9 deletions

View File

@ -18,9 +18,14 @@ import (
"github.com/wasmerio/go-ext-wasm/wasmer" "github.com/wasmerio/go-ext-wasm/wasmer"
) )
var undefined = &struct{}{} const release_call = "_release_"
var bridges = map[string]*Bridge{}
var mu sync.RWMutex // to protect bridges var (
undefined = &struct{}{}
bridges = map[string]*Bridge{}
mu sync.RWMutex // to protect bridges
)
type bctx struct{ n string } type bctx struct{ n string }
func getCtxData(b *Bridge) (unsafe.Pointer, error) { func getCtxData(b *Bridge) (unsafe.Pointer, error) {
@ -55,6 +60,30 @@ type Bridge struct {
cancF context.CancelFunc cancF context.CancelFunc
} }
// releaseRef removes the ref from the refs.
// Returns the idx and true if remove was successful.
func (b *Bridge) releaseRef(v interface{}) (int, bool) {
idx, ok := b.refs[v]
if !ok {
return 0, false
}
delete(b.refs, v)
return idx, true
}
// releaseVal removes val from the valueMap
// Returns the value and true if remove was successful
func (b *Bridge) releaseVal(idx int) (interface{}, bool) {
v, ok := b.valueMap[idx]
if !ok {
return nil, false
}
delete(b.valueMap, idx)
return v, true
}
func BridgeFromBytes(name string, bytes []byte, imports *wasmer.Imports) (*Bridge, error) { func BridgeFromBytes(name string, bytes []byte, imports *wasmer.Imports) (*Bridge, error) {
b := new(Bridge) b := new(Bridge)
if imports == nil { if imports == nil {
@ -513,6 +542,21 @@ func (b *Bridge) SetFunc(fname string, fn Func) error {
return nil return nil
} }
func (b *Bridge) releaseFunc(v interface{}) Func {
return Func(func(args []interface{}) (interface{}, error) {
b.valuesMu.Lock()
defer b.valuesMu.Unlock()
idx, ok := b.releaseRef(v)
if !ok {
return nil, nil
}
b.releaseVal(idx)
return nil, nil
})
}
func Bytes(v interface{}) ([]byte, error) { func Bytes(v interface{}) ([]byte, error) {
arr, ok := v.(*array) arr, ok := v.(*array)
if !ok { if !ok {

Binary file not shown.

View File

@ -7,8 +7,14 @@ import "syscall/js"
func ToBytes(v js.Value) []byte { func ToBytes(v js.Value) []byte {
buf := make([]byte, v.Length(), v.Length()) buf := make([]byte, v.Length(), v.Length())
for i := 0; i < v.Length(); i++ { for i := 0; i < v.Length(); i++ {
buf[i] = byte(v.Index(i).Int()) sv := v.Index(i)
buf[i] = byte(sv.Int())
} }
return buf return buf
} }
// Free frees the value for GC
func free(v js.Value) {
v.Call("_release_")
}

View File

@ -156,13 +156,19 @@ func valueSetIndex(_ unsafe.Pointer, _ int32) {
func valueCall(ctx unsafe.Pointer, sp int32) { func valueCall(ctx unsafe.Pointer, sp int32) {
b := getBridge(ctx) b := getBridge(ctx)
v := b.loadValue(sp + 8) v := b.loadValue(sp + 8)
var f Func
var args []interface{}
str := b.loadString(sp + 16) str := b.loadString(sp + 16)
args := b.loadSliceOfValues(sp + 32) if str == release_call {
f, ok := v.(*object).props[str].(Func) f = b.releaseFunc(v)
if !ok { } else {
panic(fmt.Sprintln("valueCall: prop not found in ", v, str)) args = b.loadSliceOfValues(sp + 32)
var ok bool
f, ok = v.(*object).props[str].(Func)
if !ok {
panic(fmt.Sprintln("valueCall: prop not found in ", v, str))
}
} }
sp = b.getSP() sp = b.getSP()
res, err := f(args) res, err := f(args)
if err != nil { if err != nil {