add relase call
parent
0072b5c1a3
commit
e56a2c5a85
50
bridge.go
50
bridge.go
|
@ -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.
|
@ -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_")
|
||||
}
|
||||
|
|
16
imports.go
16
imports.go
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue