github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/examples/allocation/tinygo/testdata/greet.go (about) 1 package main 2 3 // #include <stdlib.h> 4 import "C" 5 6 import ( 7 "fmt" 8 "runtime" 9 "unsafe" 10 ) 11 12 // main is required for TinyGo to compile to Wasm. 13 func main() {} 14 15 // greet prints a greeting to the console. 16 func greet(name string) { 17 log(fmt.Sprint("wasm >> ", greeting(name))) 18 } 19 20 // log a message to the console using _log. 21 func log(message string) { 22 ptr, size := stringToPtr(message) 23 _log(ptr, size) 24 runtime.KeepAlive(message) // keep message alive until ptr is no longer needed. 25 } 26 27 // _log is a WebAssembly import which prints a string (linear memory offset, 28 // byteCount) to the console. 29 // 30 //go:wasmimport env log 31 func _log(ptr, size uint32) 32 33 // greeting gets a greeting for the name. 34 func greeting(name string) string { 35 return fmt.Sprint("Hello, ", name, "!") 36 } 37 38 // _greet is a WebAssembly export that accepts a string pointer (linear memory 39 // offset) and calls greet. 40 // 41 //export greet 42 func _greet(ptr, size uint32) { 43 name := ptrToString(ptr, size) 44 greet(name) 45 } 46 47 // _greeting is a WebAssembly export that accepts a string pointer (linear memory 48 // offset) and returns a pointer/size pair packed into a uint64. 49 // 50 // Note: This uses a uint64 instead of two result values for compatibility with 51 // WebAssembly 1.0. 52 // 53 //export greeting 54 func _greeting(ptr, size uint32) (ptrSize uint64) { 55 name := ptrToString(ptr, size) 56 g := greeting(name) 57 ptr, size = stringToLeakedPtr(g) 58 return (uint64(ptr) << uint64(32)) | uint64(size) 59 } 60 61 // ptrToString returns a string from WebAssembly compatible numeric types 62 // representing its pointer and length. 63 func ptrToString(ptr uint32, size uint32) string { 64 return unsafe.String((*byte)(unsafe.Pointer(uintptr(ptr))), size) 65 } 66 67 // stringToPtr returns a pointer and size pair for the given string in a way 68 // compatible with WebAssembly numeric types. 69 // The returned pointer aliases the string hence the string must be kept alive 70 // until ptr is no longer needed. 71 func stringToPtr(s string) (uint32, uint32) { 72 ptr := unsafe.Pointer(unsafe.StringData(s)) 73 return uint32(uintptr(ptr)), uint32(len(s)) 74 } 75 76 // stringToLeakedPtr returns a pointer and size pair for the given string in a way 77 // compatible with WebAssembly numeric types. 78 // The pointer is not automatically managed by TinyGo hence it must be freed by the host. 79 func stringToLeakedPtr(s string) (uint32, uint32) { 80 size := C.ulong(len(s)) 81 ptr := unsafe.Pointer(C.malloc(size)) 82 copy(unsafe.Slice((*byte)(ptr), size), s) 83 return uint32(uintptr(ptr)), uint32(size) 84 }