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"
)
var undefined = &struct{}{}
var bridges = map[string]*Bridge{}
var mu sync.RWMutex // to protect bridges
const release_call = "_release_"
var (
undefined = &struct{}{}
bridges = map[string]*Bridge{}
mu sync.RWMutex // to protect bridges
)
type bctx struct{ n string }
func getCtxData(b *Bridge) (unsafe.Pointer, error) {
@ -55,6 +60,30 @@ type Bridge struct {
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) {
b := new(Bridge)
if imports == nil {
@ -513,6 +542,21 @@ func (b *Bridge) SetFunc(fname string, fn Func) error {
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) {
arr, ok := v.(*array)
if !ok {

Binary file not shown.

View File

@ -7,8 +7,14 @@ import "syscall/js"
func ToBytes(v js.Value) []byte {
buf := make([]byte, v.Length(), v.Length())
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
}
// 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) {
b := getBridge(ctx)
v := b.loadValue(sp + 8)
var f Func
var args []interface{}
str := b.loadString(sp + 16)
args := b.loadSliceOfValues(sp + 32)
f, ok := v.(*object).props[str].(Func)
if !ok {
panic(fmt.Sprintln("valueCall: prop not found in ", v, str))
if str == release_call {
f = b.releaseFunc(v)
} else {
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()
res, err := f(args)
if err != nil {