From a9e6c0b5bb07f3bd7af52ae04c8d03db8cc36891 Mon Sep 17 00:00:00 2001 From: gram Date: Mon, 25 Mar 2024 11:29:45 +0100 Subject: [PATCH 1/5] Tinygo support for internal/wasm Signed-off-by: gram --- internal/wasm/memory.go | 2 +- internal/wasm/memory_go.go | 7 +++++++ internal/wasm/memory_tinygo.go | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 internal/wasm/memory_go.go create mode 100644 internal/wasm/memory_tinygo.go diff --git a/internal/wasm/memory.go b/internal/wasm/memory.go index 1dc276574a..87465ec830 100644 --- a/internal/wasm/memory.go +++ b/internal/wasm/memory.go @@ -271,7 +271,7 @@ func (m *MemoryInstance) Grow(delta uint32) (result uint32, ok bool) { // Use atomic write to ensure new length is visible across threads. atomic.StoreUintptr((*uintptr)(unsafe.Pointer(&sp.Len)), uintptr(MemoryPagesToBytesNum(newPages))) } else { - sp.Len = int(MemoryPagesToBytesNum(newPages)) + sp.Len = lengthMemoryPages(newPages) } return currentPages, true } diff --git a/internal/wasm/memory_go.go b/internal/wasm/memory_go.go new file mode 100644 index 0000000000..1b8b79505b --- /dev/null +++ b/internal/wasm/memory_go.go @@ -0,0 +1,7 @@ +//go:build !tinygo + +package wasm + +func lengthMemoryPages(newPage uint32) int { + return int(MemoryPagesToBytesNum(newPage)) +} diff --git a/internal/wasm/memory_tinygo.go b/internal/wasm/memory_tinygo.go new file mode 100644 index 0000000000..14302ab0f6 --- /dev/null +++ b/internal/wasm/memory_tinygo.go @@ -0,0 +1,7 @@ +//go:build tinygo + +package wasm + +func lengthMemoryPages(newPage uint32) uintptr { + return uintptr(MemoryPagesToBytesNum(newPage)) +} From 05a09fd3f20dfbe8de635a6068911e5db9c4d557 Mon Sep 17 00:00:00 2001 From: gram Date: Mon, 25 Mar 2024 11:33:32 +0100 Subject: [PATCH 2/5] Tinygo support for reflect.SliceHeader uses Signed-off-by: gram --- .../engine/wazevo/backend/isa/amd64/reflect_go.go | 11 +++++++++++ .../engine/wazevo/backend/isa/amd64/reflect_tinygo.go | 11 +++++++++++ internal/engine/wazevo/backend/isa/amd64/stack.go | 8 ++------ internal/engine/wazevo/call_engine.go | 9 +++------ internal/engine/wazevo/hostmodule.go | 3 +-- internal/engine/wazevo/reflect_go.go | 11 +++++++++++ internal/engine/wazevo/reflect_tinygo.go | 11 +++++++++++ 7 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 internal/engine/wazevo/backend/isa/amd64/reflect_go.go create mode 100644 internal/engine/wazevo/backend/isa/amd64/reflect_tinygo.go create mode 100644 internal/engine/wazevo/reflect_go.go create mode 100644 internal/engine/wazevo/reflect_tinygo.go diff --git a/internal/engine/wazevo/backend/isa/amd64/reflect_go.go b/internal/engine/wazevo/backend/isa/amd64/reflect_go.go new file mode 100644 index 0000000000..5219837e35 --- /dev/null +++ b/internal/engine/wazevo/backend/isa/amd64/reflect_go.go @@ -0,0 +1,11 @@ +//go:build !tinygo + +package amd64 + +import "reflect" + +// setSliceLimits sets both Cap and Len for the given reflected slice. +func setSliceLimits(s *reflect.SliceHeader, limit uintptr) { + s.Len = int(limit) + s.Cap = int(limit) +} diff --git a/internal/engine/wazevo/backend/isa/amd64/reflect_tinygo.go b/internal/engine/wazevo/backend/isa/amd64/reflect_tinygo.go new file mode 100644 index 0000000000..df4cf46ec5 --- /dev/null +++ b/internal/engine/wazevo/backend/isa/amd64/reflect_tinygo.go @@ -0,0 +1,11 @@ +//go:build tinygo + +package amd64 + +import "reflect" + +// setSliceLimits sets both Cap and Len for the given reflected slice. +func setSliceLimits(s *reflect.SliceHeader, limit uintptr) { + s.Len = limit + s.Len = limit +} diff --git a/internal/engine/wazevo/backend/isa/amd64/stack.go b/internal/engine/wazevo/backend/isa/amd64/stack.go index f0a54d3497..f863dda8fe 100644 --- a/internal/engine/wazevo/backend/isa/amd64/stack.go +++ b/internal/engine/wazevo/backend/isa/amd64/stack.go @@ -9,14 +9,11 @@ import ( ) func stackView(rbp, top uintptr) []byte { - l := int(top - rbp) var stackBuf []byte { // TODO: use unsafe.Slice after floor version is set to Go 1.20. hdr := (*reflect.SliceHeader)(unsafe.Pointer(&stackBuf)) - hdr.Data = rbp - hdr.Len = l - hdr.Cap = l + setSliceLimits(hdr, top-rbp) } return stackBuf } @@ -79,8 +76,7 @@ func GoCallStackView(stackPointerBeforeGoCall *uint64) []uint64 { { sh := (*reflect.SliceHeader)(unsafe.Pointer(&view)) sh.Data = uintptr(unsafe.Pointer(stackPointerBeforeGoCall)) + 8 // skips the(sliceSize. - sh.Len = int(size) - sh.Cap = int(size) + setSliceLimits(sh, uintptr(size)) } return view } diff --git a/internal/engine/wazevo/call_engine.go b/internal/engine/wazevo/call_engine.go index 0d0ef0286c..e5a419855f 100644 --- a/internal/engine/wazevo/call_engine.go +++ b/internal/engine/wazevo/call_engine.go @@ -528,8 +528,7 @@ func opaqueViewFromPtr(ptr uintptr) []byte { var opaque []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&opaque)) sh.Data = ptr - sh.Len = 24 - sh.Cap = 24 + setSliceLimits(sh, 24, 24) return opaque } @@ -574,8 +573,7 @@ func (c *callEngine) cloneStack(l uintptr) (newSP, newFP, newTop uintptr, newSta { sh := (*reflect.SliceHeader)(unsafe.Pointer(&prevStackAligned)) sh.Data = c.stackTop - relSp - sh.Len = int(relSp) - sh.Cap = int(relSp) + setSliceLimits(sh, relSp, relSp) } newTop = alignedStackTop(newStack) { @@ -583,8 +581,7 @@ func (c *callEngine) cloneStack(l uintptr) (newSP, newFP, newTop uintptr, newSta newFP = newTop - relFp sh := (*reflect.SliceHeader)(unsafe.Pointer(&newStackAligned)) sh.Data = newSP - sh.Len = int(relSp) - sh.Cap = int(relSp) + setSliceLimits(sh, relSp, relSp) } copy(newStackAligned, prevStackAligned) return diff --git a/internal/engine/wazevo/hostmodule.go b/internal/engine/wazevo/hostmodule.go index c01b4fe148..8da7347a9f 100644 --- a/internal/engine/wazevo/hostmodule.go +++ b/internal/engine/wazevo/hostmodule.go @@ -53,8 +53,7 @@ func hostModuleListenersSliceFromOpaque(opaqueBegin uintptr) []experimental.Func var ret []experimental.FunctionListener sh = (*reflect.SliceHeader)(unsafe.Pointer(&ret)) sh.Data = uintptr(b) - sh.Len = int(l) - sh.Cap = int(c) + setSliceLimits(sh, uintptr(l), uintptr(c)) return ret } diff --git a/internal/engine/wazevo/reflect_go.go b/internal/engine/wazevo/reflect_go.go new file mode 100644 index 0000000000..6a03fc65c7 --- /dev/null +++ b/internal/engine/wazevo/reflect_go.go @@ -0,0 +1,11 @@ +//go:build !tinygo + +package wazevo + +import "reflect" + +// setSliceLimits sets both Cap and Len for the given reflected slice. +func setSliceLimits(s *reflect.SliceHeader, l, c uintptr) { + s.Len = int(l) + s.Cap = int(c) +} diff --git a/internal/engine/wazevo/reflect_tinygo.go b/internal/engine/wazevo/reflect_tinygo.go new file mode 100644 index 0000000000..eda3e706ac --- /dev/null +++ b/internal/engine/wazevo/reflect_tinygo.go @@ -0,0 +1,11 @@ +//go:build tinygo + +package wazevo + +import "reflect" + +// setSliceLimits sets both Cap and Len for the given reflected slice. +func setSliceLimits(s *reflect.SliceHeader, l, c uintptr) { + s.Len = l + s.Cap = c +} From 4505f6677bd7b38d8fe18e0eef48d1163366e5d3 Mon Sep 17 00:00:00 2001 From: gram Date: Mon, 25 Mar 2024 12:17:17 +0100 Subject: [PATCH 3/5] Restore accidentally removed hdr.Data Signed-off-by: gram --- internal/engine/wazevo/backend/isa/amd64/stack.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/engine/wazevo/backend/isa/amd64/stack.go b/internal/engine/wazevo/backend/isa/amd64/stack.go index f863dda8fe..ef08805840 100644 --- a/internal/engine/wazevo/backend/isa/amd64/stack.go +++ b/internal/engine/wazevo/backend/isa/amd64/stack.go @@ -13,6 +13,7 @@ func stackView(rbp, top uintptr) []byte { { // TODO: use unsafe.Slice after floor version is set to Go 1.20. hdr := (*reflect.SliceHeader)(unsafe.Pointer(&stackBuf)) + hdr.Data = rbp setSliceLimits(hdr, top-rbp) } return stackBuf From 2310fd7895ade88a7fb95bdef565290192d16be8 Mon Sep 17 00:00:00 2001 From: gram Date: Thu, 28 Mar 2024 10:32:58 +0100 Subject: [PATCH 4/5] Apply suggestions Signed-off-by: gram --- internal/engine/wazevo/backend/isa/amd64/stack.go | 9 ++------- internal/wasm/memory.go | 4 ++-- internal/wasm/memory_go.go | 7 ------- internal/wasm/memory_tinygo.go | 7 ------- 4 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 internal/wasm/memory_go.go delete mode 100644 internal/wasm/memory_tinygo.go diff --git a/internal/engine/wazevo/backend/isa/amd64/stack.go b/internal/engine/wazevo/backend/isa/amd64/stack.go index ef08805840..05ba5f027e 100644 --- a/internal/engine/wazevo/backend/isa/amd64/stack.go +++ b/internal/engine/wazevo/backend/isa/amd64/stack.go @@ -72,14 +72,9 @@ func GoCallStackView(stackPointerBeforeGoCall *uint64) []uint64 { // | SizeInBytes | // +-----------------+ <---- stackPointerBeforeGoCall // (low address) + data := unsafe.Pointer(uintptr(unsafe.Pointer(stackPointerBeforeGoCall)) + 8) size := *stackPointerBeforeGoCall / 8 - var view []uint64 - { - sh := (*reflect.SliceHeader)(unsafe.Pointer(&view)) - sh.Data = uintptr(unsafe.Pointer(stackPointerBeforeGoCall)) + 8 // skips the(sliceSize. - setSliceLimits(sh, uintptr(size)) - } - return view + return unsafe.Slice((*uint64)(data), int(size)) } func AdjustClonedStack(oldRsp, oldTop, rsp, rbp, top uintptr) { diff --git a/internal/wasm/memory.go b/internal/wasm/memory.go index 87465ec830..0162ccc0db 100644 --- a/internal/wasm/memory.go +++ b/internal/wasm/memory.go @@ -266,12 +266,12 @@ func (m *MemoryInstance) Grow(delta uint32) (result uint32, ok bool) { m.Cap = newPages return currentPages, true } else { // We already have the capacity we need. - sp := (*reflect.SliceHeader)(unsafe.Pointer(&m.Buffer)) if m.Shared { + sp := (*reflect.SliceHeader)(unsafe.Pointer(&m.Buffer)) // Use atomic write to ensure new length is visible across threads. atomic.StoreUintptr((*uintptr)(unsafe.Pointer(&sp.Len)), uintptr(MemoryPagesToBytesNum(newPages))) } else { - sp.Len = lengthMemoryPages(newPages) + m.Buffer = m.Buffer[:MemoryPagesToBytesNum(newPages)] } return currentPages, true } diff --git a/internal/wasm/memory_go.go b/internal/wasm/memory_go.go deleted file mode 100644 index 1b8b79505b..0000000000 --- a/internal/wasm/memory_go.go +++ /dev/null @@ -1,7 +0,0 @@ -//go:build !tinygo - -package wasm - -func lengthMemoryPages(newPage uint32) int { - return int(MemoryPagesToBytesNum(newPage)) -} diff --git a/internal/wasm/memory_tinygo.go b/internal/wasm/memory_tinygo.go deleted file mode 100644 index 14302ab0f6..0000000000 --- a/internal/wasm/memory_tinygo.go +++ /dev/null @@ -1,7 +0,0 @@ -//go:build tinygo - -package wasm - -func lengthMemoryPages(newPage uint32) uintptr { - return uintptr(MemoryPagesToBytesNum(newPage)) -} From 57b20b52fcd5a27001f69cac230400c2ec07e5f1 Mon Sep 17 00:00:00 2001 From: gram Date: Thu, 28 Mar 2024 11:18:38 +0100 Subject: [PATCH 5/5] Rename reflect_go to reflect Signed-off-by: gram --- .../engine/wazevo/backend/isa/amd64/{reflect_go.go => reflect.go} | 0 internal/engine/wazevo/{reflect_go.go => reflect.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename internal/engine/wazevo/backend/isa/amd64/{reflect_go.go => reflect.go} (100%) rename internal/engine/wazevo/{reflect_go.go => reflect.go} (100%) diff --git a/internal/engine/wazevo/backend/isa/amd64/reflect_go.go b/internal/engine/wazevo/backend/isa/amd64/reflect.go similarity index 100% rename from internal/engine/wazevo/backend/isa/amd64/reflect_go.go rename to internal/engine/wazevo/backend/isa/amd64/reflect.go diff --git a/internal/engine/wazevo/reflect_go.go b/internal/engine/wazevo/reflect.go similarity index 100% rename from internal/engine/wazevo/reflect_go.go rename to internal/engine/wazevo/reflect.go