add store value
parent
4aefd0446f
commit
771a2d95cf
210
bridge.go
210
bridge.go
|
@ -3,8 +3,10 @@ package wasm
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/wasmerio/go-ext-wasm/wasmer"
|
"github.com/wasmerio/go-ext-wasm/wasmer"
|
||||||
|
@ -13,11 +15,9 @@ import (
|
||||||
var undefined = &struct{}{}
|
var undefined = &struct{}{}
|
||||||
var bridges = map[string]*Bridge{}
|
var bridges = map[string]*Bridge{}
|
||||||
var mu sync.RWMutex // to protect bridges
|
var mu sync.RWMutex // to protect bridges
|
||||||
|
type context struct{ n string }
|
||||||
|
|
||||||
type context struct {
|
// TODO ensure it wont override the another context with same name.
|
||||||
n string
|
|
||||||
}
|
|
||||||
|
|
||||||
func setBridge(b *Bridge) unsafe.Pointer {
|
func setBridge(b *Bridge) unsafe.Pointer {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
|
@ -38,9 +38,12 @@ type Bridge struct {
|
||||||
instance wasmer.Instance
|
instance wasmer.Instance
|
||||||
vmExit bool
|
vmExit bool
|
||||||
exitCode int
|
exitCode int
|
||||||
|
values []interface{}
|
||||||
|
refs map[interface{}]int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bridge) InitWASMBytes(name string, bytes []byte, imports *wasmer.Imports) error {
|
func BridgeFromBytes(name string, bytes []byte, imports *wasmer.Imports) (*Bridge, error) {
|
||||||
|
b := new(Bridge)
|
||||||
if imports == nil {
|
if imports == nil {
|
||||||
imports = wasmer.NewImports()
|
imports = wasmer.NewImports()
|
||||||
}
|
}
|
||||||
|
@ -48,26 +51,70 @@ func (b *Bridge) InitWASMBytes(name string, bytes []byte, imports *wasmer.Import
|
||||||
b.name = name
|
b.name = name
|
||||||
err := b.addImports(imports)
|
err := b.addImports(imports)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
inst, err := wasmer.NewInstanceWithImports(bytes, imports)
|
inst, err := wasmer.NewInstanceWithImports(bytes, imports)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
b.instance = inst
|
b.instance = inst
|
||||||
inst.SetContextData(setBridge(b))
|
inst.SetContextData(setBridge(b))
|
||||||
return nil
|
b.addValues()
|
||||||
|
b.refs = make(map[interface{}]int)
|
||||||
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bridge) InitWASM(name, file string, imports *wasmer.Imports) (err error) {
|
func BridgeFromFile(name, file string, imports *wasmer.Imports) (*Bridge, error) {
|
||||||
bytes, err := wasmer.ReadBytes(file)
|
bytes, err := wasmer.ReadBytes(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.InitWASMBytes(name, bytes, imports)
|
return BridgeFromBytes(name, bytes, imports)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bridge) addValues() {
|
||||||
|
b.values = []interface{}{
|
||||||
|
math.NaN(),
|
||||||
|
float64(0),
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&object{
|
||||||
|
props: map[string]interface{}{
|
||||||
|
"Object": &object{name: "Object", props: map[string]interface{}{}},
|
||||||
|
"Array": &object{name: "Array", props: map[string]interface{}{}},
|
||||||
|
"Int8Array": typedArray("Int8Array"),
|
||||||
|
"Int16Array": typedArray("Int16Array"),
|
||||||
|
"Int32Array": typedArray("Int32Array"),
|
||||||
|
"Uint8Array": typedArray("Uint8Array"),
|
||||||
|
"Uint16Array": typedArray("Uint16Array"),
|
||||||
|
"Uint32Array": typedArray("Uint32Array"),
|
||||||
|
"Float32Array": typedArray("Float32Array"),
|
||||||
|
"Float64Array": typedArray("Float64Array"),
|
||||||
|
"process": &object{name: "process", props: map[string]interface{}{}},
|
||||||
|
"fs": &object{name: "fs", props: map[string]interface{}{
|
||||||
|
"constants": &object{name: "constants", props: map[string]interface{}{
|
||||||
|
"O_WRONLY": syscall.O_WRONLY,
|
||||||
|
"O_RDWR": syscall.O_RDWR,
|
||||||
|
"O_CREAT": syscall.O_CREAT,
|
||||||
|
"O_TRUNC": syscall.O_TRUNC,
|
||||||
|
"O_APPEND": syscall.O_APPEND,
|
||||||
|
"O_EXCL": syscall.O_EXCL,
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}, //global
|
||||||
|
&object{
|
||||||
|
name: "mem",
|
||||||
|
props: map[string]interface{}{
|
||||||
|
"buffer": &arrayBuffer{data: b.mem()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&object{name: "jsGo", props: map[string]interface{}{}}, // jsGo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run start the wasm instance.
|
// Run start the wasm instance.
|
||||||
|
@ -96,57 +143,172 @@ func (b *Bridge) mem() []byte {
|
||||||
return b.instance.Memory.Data()
|
return b.instance.Memory.Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) setInt64(offset int32, v int64) {
|
func (b *Bridge) getSP() int32 {
|
||||||
|
spFunc := b.instance.Exports["getsp"]
|
||||||
|
val, err := spFunc()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to get sp", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return val.ToI32()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bridge) setInt64(offset int32, v int64) {
|
||||||
mem := b.mem()
|
mem := b.mem()
|
||||||
binary.LittleEndian.PutUint64(mem[offset:], uint64(v))
|
binary.LittleEndian.PutUint64(mem[offset:], uint64(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) setUint64(offset int32, v uint64) {
|
func (b *Bridge) getInt64(offset int32) int64 {
|
||||||
|
mem := b.mem()
|
||||||
|
return int64(binary.LittleEndian.Uint64(mem[offset:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bridge) setUint32(offset int32, v uint32) {
|
||||||
|
mem := b.mem()
|
||||||
|
binary.LittleEndian.PutUint32(mem[offset:], v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bridge) setUint64(offset int32, v uint64) {
|
||||||
mem := b.mem()
|
mem := b.mem()
|
||||||
binary.LittleEndian.PutUint64(mem[offset:], v)
|
binary.LittleEndian.PutUint64(mem[offset:], v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) getUnit64(offset int32) uint64 {
|
func (b *Bridge) getUnit64(offset int32) uint64 {
|
||||||
mem := b.mem()
|
mem := b.mem()
|
||||||
return binary.LittleEndian.Uint64(mem[offset+0:])
|
return binary.LittleEndian.Uint64(mem[offset+0:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) setFloat64(offset int32, v float64) {
|
func (b *Bridge) setFloat64(offset int32, v float64) {
|
||||||
uf := math.Float64bits(v)
|
uf := math.Float64bits(v)
|
||||||
b.setUint64(offset, uf)
|
b.setUint64(offset, uf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) getFloat64(offset int32) float64 {
|
func (b *Bridge) getFloat64(offset int32) float64 {
|
||||||
uf := b.getUnit64(offset)
|
uf := b.getUnit64(offset)
|
||||||
return math.Float64frombits(uf)
|
return math.Float64frombits(uf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) getUint32(offset int32) uint32 {
|
func (b *Bridge) getUint32(offset int32) uint32 {
|
||||||
return binary.LittleEndian.Uint32(b.mem()[offset+0:])
|
return binary.LittleEndian.Uint32(b.mem()[offset+0:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) loadSlice(addr int32) []byte {
|
func (b *Bridge) loadSlice(addr int32) []byte {
|
||||||
mem := b.mem()
|
mem := b.mem()
|
||||||
array := binary.LittleEndian.Uint64(mem[addr+0:])
|
array := binary.LittleEndian.Uint64(mem[addr+0:])
|
||||||
length := binary.LittleEndian.Uint64(mem[addr+8:])
|
length := binary.LittleEndian.Uint64(mem[addr+8:])
|
||||||
return mem[array : array+length]
|
return mem[array : array+length]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) loadString(addr int32) string {
|
func (b *Bridge) loadString(addr int32) string {
|
||||||
d := b.loadSlice(addr)
|
d := b.loadSlice(addr)
|
||||||
return string(d)
|
return string(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bridge) loadValue(addr int32) interface{} {
|
func (b *Bridge) loadSliceOfValues(addr int32) []interface{} {
|
||||||
|
arr := int(b.getInt64(addr + 0))
|
||||||
|
arrLen := int(b.getInt64(addr + 8))
|
||||||
|
vals := make([]interface{}, arrLen, arrLen)
|
||||||
|
for i := 0; i < int(arrLen); i++ {
|
||||||
|
_, vals[i] = b.loadValue(int32(arr + i*8))
|
||||||
|
}
|
||||||
|
|
||||||
|
return vals
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO remove id once debugging is done
|
||||||
|
func (b *Bridge) loadValue(addr int32) (uint32, interface{}) {
|
||||||
f := b.getFloat64(addr)
|
f := b.getFloat64(addr)
|
||||||
if f == 0 {
|
if f == 0 {
|
||||||
return undefined
|
return 0, undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
if !math.IsNaN(f) {
|
if !math.IsNaN(f) {
|
||||||
return f
|
return 0, f
|
||||||
}
|
}
|
||||||
|
|
||||||
// return value instead of uint32
|
id := b.getUint32(addr)
|
||||||
return b.getUint32(addr)
|
return id, b.values[id]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bridge) storeValue(addr int32, v interface{}) {
|
||||||
|
const nanHead = 0x7FF80000
|
||||||
|
|
||||||
|
if i, ok := v.(int); ok {
|
||||||
|
v = float64(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if i, ok := v.(uint); ok {
|
||||||
|
v = float64(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := v.(float64); ok {
|
||||||
|
if math.IsNaN(v) {
|
||||||
|
b.setUint32(addr+4, nanHead)
|
||||||
|
b.setUint32(addr, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v == 0 {
|
||||||
|
b.setUint32(addr+4, nanHead)
|
||||||
|
b.setUint32(addr, 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
b.setFloat64(addr, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v {
|
||||||
|
case undefined:
|
||||||
|
b.setFloat64(addr, 0)
|
||||||
|
return
|
||||||
|
case nil:
|
||||||
|
b.setUint32(addr+4, nanHead)
|
||||||
|
b.setUint32(addr, 2)
|
||||||
|
return
|
||||||
|
case true:
|
||||||
|
b.setUint32(addr+4, nanHead)
|
||||||
|
b.setUint32(addr, 3)
|
||||||
|
return
|
||||||
|
case false:
|
||||||
|
b.setUint32(addr+4, nanHead)
|
||||||
|
b.setUint32(addr, 4)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ref, ok := b.refs[v]
|
||||||
|
if !ok {
|
||||||
|
ref = len(b.values)
|
||||||
|
b.values = append(b.values, v)
|
||||||
|
b.refs[v] = ref
|
||||||
|
}
|
||||||
|
|
||||||
|
typeFlag := 0
|
||||||
|
switch v.(type) {
|
||||||
|
case string:
|
||||||
|
typeFlag = 1
|
||||||
|
case *object, *arrayBuffer: //TODO symbol maybe?
|
||||||
|
typeFlag = 2
|
||||||
|
default:
|
||||||
|
log.Fatalf("unknown type: %T", v)
|
||||||
|
// TODO function
|
||||||
|
}
|
||||||
|
b.setUint32(addr+4, uint32(nanHead|typeFlag))
|
||||||
|
b.setUint32(addr, uint32(ref))
|
||||||
|
}
|
||||||
|
|
||||||
|
type object struct {
|
||||||
|
name string // TODO for debugging
|
||||||
|
props map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func typedArray(name string) *object {
|
||||||
|
return &object{
|
||||||
|
name: name,
|
||||||
|
props: map[string]interface{}{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type arrayBuffer struct {
|
||||||
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
61
imports.go
61
imports.go
|
@ -28,7 +28,6 @@ extern void clearTimeoutEvent(void *context, int32_t a);
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
@ -46,13 +45,12 @@ func debug(ctx unsafe.Pointer, sp int32) {
|
||||||
func wexit(ctx unsafe.Pointer, sp int32) {
|
func wexit(ctx unsafe.Pointer, sp int32) {
|
||||||
b := getBridge(ctx)
|
b := getBridge(ctx)
|
||||||
b.vmExit = true
|
b.vmExit = true
|
||||||
mem := b.mem()
|
b.exitCode = int(b.getUint32(sp + 8))
|
||||||
b.exitCode = int(binary.LittleEndian.Uint32(mem[sp+8:]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//export wwrite
|
//export wwrite
|
||||||
func wwrite(ctx unsafe.Pointer, sp int32) {
|
func wwrite(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("wasm write", sp)
|
log.Fatal("wasm write", sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export nanotime
|
//export nanotime
|
||||||
|
@ -63,97 +61,114 @@ func nanotime(ctx unsafe.Pointer, sp int32) {
|
||||||
|
|
||||||
//export walltime
|
//export walltime
|
||||||
func walltime(ctx unsafe.Pointer, sp int32) {
|
func walltime(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("wall time")
|
log.Fatal("wall time")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export scheduleCallback
|
//export scheduleCallback
|
||||||
func scheduleCallback(ctx unsafe.Pointer, sp int32) {
|
func scheduleCallback(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("schedule callback")
|
log.Fatal("schedule callback")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export clearScheduledCallback
|
//export clearScheduledCallback
|
||||||
func clearScheduledCallback(ctx unsafe.Pointer, sp int32) {
|
func clearScheduledCallback(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("clear scheduled callback")
|
log.Fatal("clear scheduled callback")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export getRandomData
|
//export getRandomData
|
||||||
func getRandomData(ctx unsafe.Pointer, sp int32) {
|
func getRandomData(ctx unsafe.Pointer, sp int32) {
|
||||||
s := getBridge(ctx).loadSlice(sp + 8)
|
s := getBridge(ctx).loadSlice(sp + 8)
|
||||||
_, err := rand.Read(s)
|
_, err := rand.Read(s)
|
||||||
|
// TODO how to pass error?
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("failed: getRandomData", err)
|
log.Fatal("failed: getRandomData", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//export stringVal
|
//export stringVal
|
||||||
func stringVal(ctx unsafe.Pointer, sp int32) {
|
func stringVal(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("stringVal")
|
log.Fatal("stringVal")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueGet
|
//export valueGet
|
||||||
func valueGet(ctx unsafe.Pointer, sp int32) {
|
func valueGet(ctx unsafe.Pointer, sp int32) {
|
||||||
b := getBridge(ctx)
|
b := getBridge(ctx)
|
||||||
str := b.loadString(sp + 16)
|
str := b.loadString(sp + 16)
|
||||||
val := b.loadValue(sp + 8)
|
id, val := b.loadValue(sp + 8)
|
||||||
fmt.Println("valueGet", str, val)
|
sp = b.getSP()
|
||||||
|
obj, ok := val.(*object)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("valueGet", str, id)
|
||||||
|
b.storeValue(sp+32, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, ok := obj.props[str]
|
||||||
|
if !ok {
|
||||||
|
// TODO
|
||||||
|
log.Fatal("missing property", val, str)
|
||||||
|
}
|
||||||
|
fmt.Println("valueGet", str, id, obj.name)
|
||||||
|
b.storeValue(sp+32, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueSet
|
//export valueSet
|
||||||
func valueSet(ctx unsafe.Pointer, sp int32) {
|
func valueSet(ctx unsafe.Pointer, sp int32) {
|
||||||
str := getBridge(ctx).loadString(sp + 16)
|
str := getBridge(ctx).loadString(sp + 16)
|
||||||
fmt.Println("valueSet", str)
|
log.Fatal("valueSet", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueIndex
|
//export valueIndex
|
||||||
func valueIndex(ctx unsafe.Pointer, sp int32) {
|
func valueIndex(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("valueIndex")
|
log.Fatal("valueIndex")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueSetIndex
|
//export valueSetIndex
|
||||||
func valueSetIndex(ctx unsafe.Pointer, sp int32) {
|
func valueSetIndex(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("valueSetIndex")
|
log.Fatal("valueSetIndex")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueCall
|
//export valueCall
|
||||||
func valueCall(ctx unsafe.Pointer, sp int32) {
|
func valueCall(ctx unsafe.Pointer, sp int32) {
|
||||||
str := getBridge(ctx).loadString(sp + 16)
|
str := getBridge(ctx).loadString(sp + 16)
|
||||||
fmt.Println("valueCall", str)
|
log.Fatal("valueCall", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueInvoke
|
//export valueInvoke
|
||||||
func valueInvoke(ctx unsafe.Pointer, sp int32) {
|
func valueInvoke(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("valueInvoke")
|
log.Fatal("valueInvoke")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueNew
|
//export valueNew
|
||||||
func valueNew(ctx unsafe.Pointer, sp int32) {
|
func valueNew(ctx unsafe.Pointer, sp int32) {
|
||||||
str := getBridge(ctx).loadString(sp + 16)
|
b := getBridge(ctx)
|
||||||
fmt.Println("valueNew", str)
|
id, val := b.loadValue(sp + 8)
|
||||||
|
args := b.loadSliceOfValues(sp + 16)
|
||||||
|
log.Fatal("valueNew ", id, val, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueLength
|
//export valueLength
|
||||||
func valueLength(ctx unsafe.Pointer, sp int32) {
|
func valueLength(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("valueLength")
|
log.Fatal("valueLength")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valuePrepareString
|
//export valuePrepareString
|
||||||
func valuePrepareString(ctx unsafe.Pointer, sp int32) {
|
func valuePrepareString(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("valuePrepareString")
|
log.Fatal("valuePrepareString")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export valueLoadString
|
//export valueLoadString
|
||||||
func valueLoadString(ctx unsafe.Pointer, sp int32) {
|
func valueLoadString(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("valueLoadString")
|
log.Fatal("valueLoadString")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export scheduleTimeoutEvent
|
//export scheduleTimeoutEvent
|
||||||
func scheduleTimeoutEvent(ctx unsafe.Pointer, sp int32) {
|
func scheduleTimeoutEvent(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("scheduleTimeoutEvent")
|
log.Fatal("scheduleTimeoutEvent")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export clearTimeoutEvent
|
//export clearTimeoutEvent
|
||||||
func clearTimeoutEvent(ctx unsafe.Pointer, sp int32) {
|
func clearTimeoutEvent(ctx unsafe.Pointer, sp int32) {
|
||||||
fmt.Println("clearTimeoutEvent")
|
log.Fatal("clearTimeoutEvent")
|
||||||
}
|
}
|
||||||
|
|
||||||
// addImports adds go Bridge imports in "go" namespace.
|
// addImports adds go Bridge imports in "go" namespace.
|
||||||
|
|
|
@ -7,8 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
b := wasmgo.Bridge{}
|
b, err := wasmgo.BridgeFromFile("test", "./simple/prog/main.wasm", nil)
|
||||||
err := b.InitWASM("test", "./simple/prog/main.wasm", nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue