2019-08-06 16:03:11 +03:00
|
|
|
package wasm
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
extern void debug(void *context, int32_t a);
|
|
|
|
extern void wexit(void *context, int32_t a);
|
|
|
|
extern void wwrite(void *context, int32_t a);
|
|
|
|
extern void nanotime(void *context, int32_t a);
|
|
|
|
extern void walltime(void *context, int32_t a);
|
|
|
|
extern void scheduleCallback(void *context, int32_t a);
|
|
|
|
extern void clearScheduledCallback(void *context, int32_t a);
|
|
|
|
extern void getRandomData(void *context, int32_t a);
|
|
|
|
extern void stringVal(void *context, int32_t a);
|
|
|
|
extern void valueGet(void *context, int32_t a);
|
|
|
|
extern void valueSet(void *context, int32_t a);
|
|
|
|
extern void valueIndex(void *context, int32_t a);
|
|
|
|
extern void valueSetIndex(void *context, int32_t a);
|
|
|
|
extern void valueCall(void *context, int32_t a);
|
|
|
|
extern void valueInvoke(void *context, int32_t a);
|
|
|
|
extern void valueNew(void *context, int32_t a);
|
|
|
|
extern void valueLength(void *context, int32_t a);
|
|
|
|
extern void valuePrepareString(void *context, int32_t a);
|
|
|
|
extern void valueLoadString(void *context, int32_t a);
|
2019-08-07 13:47:59 +03:00
|
|
|
extern void scheduleTimeoutEvent(void *context, int32_t a);
|
|
|
|
extern void clearTimeoutEvent(void *context, int32_t a);
|
2019-08-06 16:03:11 +03:00
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
import (
|
2019-08-07 13:47:59 +03:00
|
|
|
"crypto/rand"
|
2019-08-06 16:03:11 +03:00
|
|
|
"fmt"
|
|
|
|
"log"
|
2019-08-07 13:47:59 +03:00
|
|
|
"time"
|
2019-08-06 16:03:11 +03:00
|
|
|
"unsafe"
|
|
|
|
|
|
|
|
"github.com/wasmerio/go-ext-wasm/wasmer"
|
|
|
|
)
|
|
|
|
|
|
|
|
//export debug
|
2019-08-13 18:11:23 +03:00
|
|
|
func debug(ctx unsafe.Pointer, sp int32) {
|
|
|
|
log.Println(sp)
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export wexit
|
2019-08-13 18:11:23 +03:00
|
|
|
func wexit(ctx unsafe.Pointer, sp int32) {
|
|
|
|
b := getBridge(ctx)
|
|
|
|
b.vmExit = true
|
2019-08-15 21:12:20 +03:00
|
|
|
b.exitCode = int(b.getUint32(sp + 8))
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export wwrite
|
2019-08-13 18:11:23 +03:00
|
|
|
func wwrite(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("wasm write", sp)
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export nanotime
|
2019-08-13 18:11:23 +03:00
|
|
|
func nanotime(ctx unsafe.Pointer, sp int32) {
|
2019-08-07 13:47:59 +03:00
|
|
|
n := time.Now().UnixNano()
|
2019-08-13 18:11:23 +03:00
|
|
|
getBridge(ctx).setInt64(sp+8, n)
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export walltime
|
2019-08-13 18:11:23 +03:00
|
|
|
func walltime(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("wall time")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export scheduleCallback
|
2019-08-13 18:11:23 +03:00
|
|
|
func scheduleCallback(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("schedule callback")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export clearScheduledCallback
|
2019-08-13 18:11:23 +03:00
|
|
|
func clearScheduledCallback(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("clear scheduled callback")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export getRandomData
|
2019-08-13 18:11:23 +03:00
|
|
|
func getRandomData(ctx unsafe.Pointer, sp int32) {
|
|
|
|
s := getBridge(ctx).loadSlice(sp + 8)
|
2019-08-07 13:47:59 +03:00
|
|
|
_, err := rand.Read(s)
|
2019-08-15 21:12:20 +03:00
|
|
|
// TODO how to pass error?
|
2019-08-07 13:47:59 +03:00
|
|
|
if err != nil {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("failed: getRandomData", err)
|
2019-08-07 13:47:59 +03:00
|
|
|
}
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export stringVal
|
2019-08-13 18:11:23 +03:00
|
|
|
func stringVal(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("stringVal")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueGet
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueGet(ctx unsafe.Pointer, sp int32) {
|
|
|
|
b := getBridge(ctx)
|
|
|
|
str := b.loadString(sp + 16)
|
2019-08-15 21:12:20 +03:00
|
|
|
id, val := b.loadValue(sp + 8)
|
|
|
|
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)
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueSet
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueSet(ctx unsafe.Pointer, sp int32) {
|
|
|
|
str := getBridge(ctx).loadString(sp + 16)
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("valueSet", str)
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueIndex
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueIndex(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("valueIndex")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueSetIndex
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueSetIndex(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("valueSetIndex")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueCall
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueCall(ctx unsafe.Pointer, sp int32) {
|
|
|
|
str := getBridge(ctx).loadString(sp + 16)
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("valueCall", str)
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueInvoke
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueInvoke(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("valueInvoke")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueNew
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueNew(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
b := getBridge(ctx)
|
|
|
|
id, val := b.loadValue(sp + 8)
|
|
|
|
args := b.loadSliceOfValues(sp + 16)
|
|
|
|
log.Fatal("valueNew ", id, val, args)
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueLength
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueLength(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("valueLength")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valuePrepareString
|
2019-08-13 18:11:23 +03:00
|
|
|
func valuePrepareString(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("valuePrepareString")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export valueLoadString
|
2019-08-13 18:11:23 +03:00
|
|
|
func valueLoadString(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("valueLoadString")
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
|
2019-08-07 13:47:59 +03:00
|
|
|
//export scheduleTimeoutEvent
|
2019-08-13 18:11:23 +03:00
|
|
|
func scheduleTimeoutEvent(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("scheduleTimeoutEvent")
|
2019-08-07 13:47:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//export clearTimeoutEvent
|
2019-08-13 18:11:23 +03:00
|
|
|
func clearTimeoutEvent(ctx unsafe.Pointer, sp int32) {
|
2019-08-15 21:12:20 +03:00
|
|
|
log.Fatal("clearTimeoutEvent")
|
2019-08-07 13:47:59 +03:00
|
|
|
}
|
|
|
|
|
2019-08-13 18:11:23 +03:00
|
|
|
// addImports adds go Bridge imports in "go" namespace.
|
|
|
|
func (b *Bridge) addImports(imps *wasmer.Imports) error {
|
2019-08-07 13:47:59 +03:00
|
|
|
imps = imps.Namespace("go")
|
2019-08-06 16:03:11 +03:00
|
|
|
var is = []struct {
|
|
|
|
name string
|
|
|
|
imp interface{}
|
|
|
|
cgo unsafe.Pointer
|
|
|
|
}{
|
|
|
|
{"debug", debug, C.debug},
|
|
|
|
{"runtime.wasmExit", wexit, C.wexit},
|
|
|
|
{"runtime.wasmWrite", wwrite, C.wwrite},
|
|
|
|
{"runtime.nanotime", nanotime, C.nanotime},
|
|
|
|
{"runtime.walltime", walltime, C.walltime},
|
|
|
|
{"runtime.scheduleCallback", scheduleCallback, C.scheduleCallback},
|
|
|
|
{"runtime.clearScheduledCallback", clearScheduledCallback, C.clearScheduledCallback},
|
|
|
|
{"runtime.getRandomData", getRandomData, C.getRandomData},
|
2019-08-07 13:47:59 +03:00
|
|
|
{"runtime.scheduleTimeoutEvent", scheduleTimeoutEvent, C.scheduleTimeoutEvent},
|
|
|
|
{"runtime.clearTimeoutEvent", clearTimeoutEvent, C.clearTimeoutEvent},
|
2019-08-06 16:03:11 +03:00
|
|
|
{"syscall/js.stringVal", stringVal, C.stringVal},
|
|
|
|
{"syscall/js.valueGet", valueGet, C.valueGet},
|
|
|
|
{"syscall/js.valueSet", valueSet, C.valueSet},
|
|
|
|
{"syscall/js.valueIndex", valueIndex, C.valueIndex},
|
|
|
|
{"syscall/js.valueSetIndex", valueSetIndex, C.valueSetIndex},
|
|
|
|
{"syscall/js.valueCall", valueCall, C.valueCall},
|
|
|
|
{"syscall/js.valueInvoke", valueInvoke, C.valueInvoke},
|
|
|
|
{"syscall/js.valueNew", valueNew, C.valueNew},
|
|
|
|
{"syscall/js.valueLength", valueLength, C.valueLength},
|
|
|
|
{"syscall/js.valuePrepareString", valuePrepareString, C.valuePrepareString},
|
|
|
|
{"syscall/js.valueLoadString", valueLoadString, C.valueLoadString},
|
|
|
|
}
|
|
|
|
|
|
|
|
var err error
|
|
|
|
for _, imp := range is {
|
|
|
|
imps, err = imps.Append(imp.name, imp.imp, imp.cgo)
|
|
|
|
if err != nil {
|
2019-08-07 13:47:59 +03:00
|
|
|
return err
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-07 13:47:59 +03:00
|
|
|
return nil
|
2019-08-06 16:03:11 +03:00
|
|
|
}
|