true bidirctional
parent
9a613261cb
commit
803f7df155
30
bridge.go
30
bridge.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
16
imports.go
16
imports.go
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
Loading…
Reference in New Issue