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"
|
"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.
|
@ -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_")
|
||||||
|
}
|
||||||
|
|
16
imports.go
16
imports.go
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue