From c1f1bd57f6d99bff890a412e850dac85fe921f38 Mon Sep 17 00:00:00 2001 From: Luca Burgazzoli Date: Thu, 4 May 2023 09:39:15 +0200 Subject: [PATCH] examples(allocation): ensures data used in host functions isn't freed before invocation Signed-off-by: Luca Burgazzoli --- examples/allocation/tinygo/testdata/greet.go | 25 ++++++++++++++---- .../allocation/tinygo/testdata/greet.wasm | Bin 54254 -> 54228 bytes 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/examples/allocation/tinygo/testdata/greet.go b/examples/allocation/tinygo/testdata/greet.go index 2eb717d5652..85c161850e7 100644 --- a/examples/allocation/tinygo/testdata/greet.go +++ b/examples/allocation/tinygo/testdata/greet.go @@ -6,6 +6,7 @@ import "C" import ( "fmt" "reflect" + "runtime" "unsafe" ) @@ -21,6 +22,11 @@ func greet(name string) { func log(message string) { ptr, size := stringToPtr(message) _log(ptr, size) + + // the stringToPtr returns a pointer to the underlying bytes + // of the message it must be ensured that the string is not + // freed + runtime.KeepAlive(message) } // _log is a WebAssembly import which prints a string (linear memory offset, @@ -72,13 +78,22 @@ func ptrToString(ptr uint32, size uint32) string { })) } -// stringToPtr returns a pointer and size pair for the given string in a way -// compatible with WebAssembly numeric types. +// stringToPtr returns a pointer and size pair to the underlying bytes of the given +// string in a way compatible with WebAssembly numeric types. Since Go strings are +// immutable, the pointer returned by stringToPtr must not be modified. func stringToPtr(s string) (uint32, uint32) { - buf := []byte(s) - ptr := &buf[0] + // for an empty string the return value by TinyGo 0.27 is nil, however the + // subsequent are still safe and result in the method returning pointer = 0 + // and size = 0 + // + // Note that: + // - we assume that the given string is never empty so there is no special + // handling for such case + // - this method does not keep the given string alive, hence it is the + // responsibility of the caller to ensure the string is kept alive + ptr := unsafe.StringData(s) unsafePtr := uintptr(unsafe.Pointer(ptr)) - return uint32(unsafePtr), uint32(len(buf)) + return uint32(unsafePtr), uint32(len(s)) } // stringToLeakedPtr returns a pointer and size pair for the given string in a way diff --git a/examples/allocation/tinygo/testdata/greet.wasm b/examples/allocation/tinygo/testdata/greet.wasm index 6a7fa97869035863d6a1e667bc231392334ce9b9..cc2fe35ddac45efcaf5317667b5e270bcd31e632 100755 GIT binary patch delta 217 zcmaF2ocYRf<_&U8jPo|jGjUa=HZd`>)+;kOUSP;pVp3sHU~;s`Qet*uFlPp_9kP{J zVeAtOSxRh<3}#F~36PipP@dh4Nk@T60VrtT_+~n*1`~rK3y1-f(#Qga!^@X)tjpfvsW%DFoUGqFfY! W3=Jk80f-$ylR<90u-U10O&9=M=q0}Z delta 263 zcmXAkJqp4=5JqQbB8DVIS{q$fg%k>@7K;>FRIsqH5V7zC@dl#g1~wL2*xL$e1h3%% zascrJ7S6iW8{Y2xe6JgQZgg*>cvKw>cH=7wD!X86*edLSL=$NoFw(++Nxva02^v#Y z?{gzTP@cxb)@+hOBb<)=VV{g22MQ!<^dv~Z-ZhRKGK*8aZt3YRc16mh^RJ6u*j DPf9IG