true bidirctional

pull/2/head
vedhavyas 2019-08-20 12:20:20 -07:00
parent 9a613261cb
commit 803f7df155
No known key found for this signature in database
GPG Key ID: 317BF0923E3EB7E5
5 changed files with 56 additions and 21 deletions

View File

@ -78,7 +78,7 @@ func BridgeFromFile(name, file string, imports *wasmer.Imports) (*Bridge, error)
func (b *Bridge) addValues() { func (b *Bridge) addValues() {
var goObj *object var goObj *object
goObj = propObject("jsGo", map[string]interface{}{ goObj = propObject("jsGo", map[string]interface{}{
"_makeFuncWrapper": wasmFunc(func(args []interface{}) (interface{}, error) { "_makeFuncWrapper": Func(func(args []interface{}) (interface{}, error) {
return &funcWrapper{id: args[0]}, nil return &funcWrapper{id: args[0]}, nil
}), }),
"_pendingEvent": nil, "_pendingEvent": nil,
@ -112,7 +112,7 @@ func (b *Bridge) addValues() {
"O_EXCL": syscall.O_EXCL, "O_EXCL": syscall.O_EXCL,
}), }),
"write": wasmFunc(func(args []interface{}) (interface{}, error) { "write": Func(func(args []interface{}) (interface{}, error) {
fd := int(args[0].(float64)) fd := int(args[0].(float64))
offset := int(args[2].(float64)) offset := int(args[2].(float64))
length := int(args[3].(float64)) length := int(args[3].(float64))
@ -311,6 +311,11 @@ func (b *Bridge) storeValue(addr int32, v interface{}) {
return return
} }
rv := reflect.TypeOf(v)
if rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
ref, ok := b.refs[v] ref, ok := b.refs[v]
if !ok { if !ok {
ref = len(b.values) ref = len(b.values)
@ -319,18 +324,15 @@ func (b *Bridge) storeValue(addr int32, v interface{}) {
} }
typeFlag := 0 typeFlag := 0
rv := reflect.TypeOf(v)
if rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
switch rv.Kind() { switch rv.Kind() {
case reflect.String: case reflect.String:
typeFlag = 1 typeFlag = 1
case reflect.Struct, reflect.Slice: //TODO symbol maybe? case reflect.Struct, reflect.Slice:
typeFlag = 2 typeFlag = 2
case reflect.Func:
typeFlag = 3
default: default:
panic(fmt.Sprintf("unknown type: %T", v)) panic(fmt.Sprintf("unknown type: %T", v))
// TODO function
} }
b.setUint32(addr+4, uint32(nanHead|typeFlag)) b.setUint32(addr+4, uint32(nanHead|typeFlag))
b.setUint32(addr, uint32(ref)) b.setUint32(addr, uint32(ref))
@ -372,7 +374,7 @@ type buffer struct {
data []byte data []byte
} }
type wasmFunc func(args []interface{}) (interface{}, error) type Func func(args []interface{}) (interface{}, error)
func (b *Bridge) resume() error { func (b *Bridge) resume() error {
res := b.instance.Exports["resume"] res := b.instance.Exports["resume"]
@ -402,11 +404,17 @@ func (b *Bridge) makeFuncWrapper(id, this interface{}, args *[]interface{}) (int
} }
// TODO cheeck if the wasm is still running // TODO cheeck if the wasm is still running
func (b *Bridge) CallFunc(fn string, args *[]interface{}) (interface{}, error) { func (b *Bridge) CallFunc(fn string, args []interface{}) (interface{}, error) {
fw, ok := b.values[5].(*object).props[fn] fw, ok := b.values[5].(*object).props[fn]
if !ok { if !ok {
return nil, fmt.Errorf("missing function: %v", fn) return nil, fmt.Errorf("missing function: %v", fn)
} }
return b.makeFuncWrapper(fw.(*funcWrapper).id, b.values[7], args) return b.makeFuncWrapper(fw.(*funcWrapper).id, b.values[7], &args)
}
// TODO check if wasm is still running
func (b *Bridge) SetFunc(fname string, fn Func) error {
b.values[5].(*object).props[fname] = &fn
return nil
} }

View File

@ -157,7 +157,7 @@ func valueCall(ctx unsafe.Pointer, sp int32) {
v := b.loadValue(sp + 8) v := b.loadValue(sp + 8)
str := b.loadString(sp + 16) str := b.loadString(sp + 16)
args := b.loadSliceOfValues(sp + 32) args := b.loadSliceOfValues(sp + 32)
f, ok := v.(*object).props[str].(wasmFunc) f, ok := v.(*object).props[str].(Func)
if !ok { if !ok {
panic(fmt.Sprintln("valueCall: prop not found in ", v, str)) panic(fmt.Sprintln("valueCall: prop not found in ", v, str))
} }
@ -176,7 +176,19 @@ func valueCall(ctx unsafe.Pointer, sp int32) {
//export valueInvoke //export valueInvoke
func valueInvoke(ctx unsafe.Pointer, sp int32) { func valueInvoke(ctx unsafe.Pointer, sp int32) {
panic("valueInvoke") b := getBridge(ctx)
val := *(b.loadValue(sp + 8).(*Func))
args := b.loadSliceOfValues(sp + 16)
res, err := val(args)
sp = b.getSP()
if err != nil {
b.storeValue(sp+40, err)
b.setUint8(sp+48, 0)
return
}
b.storeValue(sp+40, res)
b.setUint8(sp+48, 1)
} }
//export valueNew //export valueNew

View File

@ -7,12 +7,24 @@ import (
wasmgo "github.com/vedhavyas/wasm" wasmgo "github.com/vedhavyas/wasm"
) )
func proxy(b *wasmgo.Bridge) wasmgo.Func {
return func(args []interface{}) (i interface{}, e error) {
fmt.Println("In Go", args)
return b.CallFunc("addition", args)
}
}
func main() { func main() {
b, err := wasmgo.BridgeFromFile("test", "./simple/prog/main.wasm", nil) b, err := wasmgo.BridgeFromFile("test", "./simple/prog/main.wasm", nil)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
err = b.SetFunc("proxy", proxy(b))
if err != nil {
panic(err)
}
init, done := make(chan error), make(chan bool) init, done := make(chan error), make(chan bool)
go b.Run(init, done) go b.Run(init, done)
err = <-init err = <-init
@ -20,8 +32,6 @@ func main() {
panic(err) panic(err)
} }
res, err := b.CallFunc("printWasm", &[]interface{}{"Hello from Go"})
fmt.Println(res, err)
<-done <-done
fmt.Println("wasm exited", err) fmt.Println("wasm exited", err)
} }

View File

@ -8,17 +8,22 @@ import (
) )
// TODO: log seems to cause an issue // TODO: log seems to cause an issue
func printWasm(this js.Value, v []js.Value) interface{} { func addition(this js.Value, args []js.Value) interface{} {
fmt.Println(v[0].String()) fmt.Println("In WASM", args)
return "Hello from WASM" this.Set()
this.SetIndex()
a, b := args[0].Int(), args[1].Int()
return a + b
} }
func main() { func main() {
ch := make(chan bool) ch := make(chan bool)
fmt.Println("WASM-Go Initialized")
// register functions // register functions
fun := js.FuncOf(printWasm) fun := js.FuncOf(addition)
js.Global().Set("printWasm", fun) js.Global().Set("addition", fun)
res := js.Global().Get("proxy").Invoke(1, 2)
fmt.Printf("1 + 2 = %d\n", res.Int())
<-ch <-ch
} }

Binary file not shown.