summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/hostmodule.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/hostmodule.go')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/hostmodule.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/hostmodule.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/hostmodule.go
new file mode 100644
index 000000000..8da7347a9
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/hostmodule.go
@@ -0,0 +1,82 @@
+package wazevo
+
+import (
+ "encoding/binary"
+ "reflect"
+ "unsafe"
+
+ "github.com/tetratelabs/wazero/experimental"
+ "github.com/tetratelabs/wazero/internal/wasm"
+)
+
+func buildHostModuleOpaque(m *wasm.Module, listeners []experimental.FunctionListener) moduleContextOpaque {
+ size := len(m.CodeSection)*16 + 32
+ ret := newAlignedOpaque(size)
+
+ binary.LittleEndian.PutUint64(ret[0:], uint64(uintptr(unsafe.Pointer(m))))
+
+ if len(listeners) > 0 {
+ sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&listeners))
+ binary.LittleEndian.PutUint64(ret[8:], uint64(sliceHeader.Data))
+ binary.LittleEndian.PutUint64(ret[16:], uint64(sliceHeader.Len))
+ binary.LittleEndian.PutUint64(ret[24:], uint64(sliceHeader.Cap))
+ }
+
+ offset := 32
+ for i := range m.CodeSection {
+ goFn := m.CodeSection[i].GoFunc
+ writeIface(goFn, ret[offset:])
+ offset += 16
+ }
+ return ret
+}
+
+func hostModuleFromOpaque(opaqueBegin uintptr) *wasm.Module {
+ var opaqueViewOverSlice []byte
+ sh := (*reflect.SliceHeader)(unsafe.Pointer(&opaqueViewOverSlice))
+ sh.Data = opaqueBegin
+ sh.Len = 32
+ sh.Cap = 32
+ return *(**wasm.Module)(unsafe.Pointer(&opaqueViewOverSlice[0]))
+}
+
+func hostModuleListenersSliceFromOpaque(opaqueBegin uintptr) []experimental.FunctionListener {
+ var opaqueViewOverSlice []byte
+ sh := (*reflect.SliceHeader)(unsafe.Pointer(&opaqueViewOverSlice))
+ sh.Data = opaqueBegin
+ sh.Len = 32
+ sh.Cap = 32
+
+ b := binary.LittleEndian.Uint64(opaqueViewOverSlice[8:])
+ l := binary.LittleEndian.Uint64(opaqueViewOverSlice[16:])
+ c := binary.LittleEndian.Uint64(opaqueViewOverSlice[24:])
+ var ret []experimental.FunctionListener
+ sh = (*reflect.SliceHeader)(unsafe.Pointer(&ret))
+ sh.Data = uintptr(b)
+ setSliceLimits(sh, uintptr(l), uintptr(c))
+ return ret
+}
+
+func hostModuleGoFuncFromOpaque[T any](index int, opaqueBegin uintptr) T {
+ offset := uintptr(index*16) + 32
+ ptr := opaqueBegin + offset
+
+ var opaqueViewOverFunction []byte
+ sh := (*reflect.SliceHeader)(unsafe.Pointer(&opaqueViewOverFunction))
+ sh.Data = ptr
+ sh.Len = 16
+ sh.Cap = 16
+ return readIface(opaqueViewOverFunction).(T)
+}
+
+func writeIface(goFn interface{}, buf []byte) {
+ goFnIface := *(*[2]uint64)(unsafe.Pointer(&goFn))
+ binary.LittleEndian.PutUint64(buf, goFnIface[0])
+ binary.LittleEndian.PutUint64(buf[8:], goFnIface[1])
+}
+
+func readIface(buf []byte) interface{} {
+ b := binary.LittleEndian.Uint64(buf)
+ s := binary.LittleEndian.Uint64(buf[8:])
+ return *(*interface{})(unsafe.Pointer(&[2]uint64{b, s}))
+}