github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/arch_tinygowasm.go (about) 1 //go:build tinygo.wasm 2 3 package runtime 4 5 import ( 6 "unsafe" 7 ) 8 9 const GOARCH = "wasm" 10 11 // The bitness of the CPU (e.g. 8, 32, 64). 12 const TargetBits = 32 13 14 const deferExtraRegs = 0 15 16 const callInstSize = 1 // unknown and irrelevant (llvm.returnaddress doesn't work), so make something up 17 18 //go:extern __heap_base 19 var heapStartSymbol [0]byte 20 21 //go:extern __global_base 22 var globalsStartSymbol [0]byte 23 24 const ( 25 // wasmMemoryIndex is always zero until the multi-memory feature is used. 26 // 27 // See https://github.com/WebAssembly/multi-memory 28 wasmMemoryIndex = 0 29 30 // wasmPageSize is the size of a page in WebAssembly's 32-bit memory. This 31 // is also its only unit of change. 32 // 33 // See https://www.w3.org/TR/wasm-core-1/#page-size 34 wasmPageSize = 64 * 1024 35 ) 36 37 // wasm_memory_size invokes the "memory.size" instruction, which returns the 38 // current size to the memory at the given index (always wasmMemoryIndex), in 39 // pages. 40 // 41 //export llvm.wasm.memory.size.i32 42 func wasm_memory_size(index int32) int32 43 44 // wasm_memory_grow invokes the "memory.grow" instruction, which attempts to 45 // increase the size of the memory at the given index (always wasmMemoryIndex), 46 // by the delta (in pages). This returns the previous size on success of -1 on 47 // failure. 48 // 49 //export llvm.wasm.memory.grow.i32 50 func wasm_memory_grow(index int32, delta int32) int32 51 52 var ( 53 // heapStart is the current memory offset which starts the heap. The heap 54 // extends from this offset until heapEnd (exclusive). 55 heapStart = uintptr(unsafe.Pointer(&heapStartSymbol)) 56 57 // heapEnd is the current memory length in bytes. 58 heapEnd = uintptr(wasm_memory_size(wasmMemoryIndex) * wasmPageSize) 59 60 globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol)) 61 globalsEnd = uintptr(unsafe.Pointer(&heapStartSymbol)) 62 63 stackTop = uintptr(unsafe.Pointer(&globalsStartSymbol)) 64 ) 65 66 func align(ptr uintptr) uintptr { 67 // Align to 16, which is the alignment of max_align_t: 68 // https://godbolt.org/z/dYqTsWrGq 69 const heapAlign = 16 70 return (ptr + heapAlign - 1) &^ (heapAlign - 1) 71 } 72 73 //export tinygo_getCurrentStackPointer 74 func getCurrentStackPointer() uintptr 75 76 // growHeap tries to grow the heap size. It returns true if it succeeds, false 77 // otherwise. 78 func growHeap() bool { 79 // Grow memory by the available size, which means the heap size is doubled. 80 memorySize := wasm_memory_size(wasmMemoryIndex) 81 result := wasm_memory_grow(wasmMemoryIndex, memorySize) 82 if result == -1 { 83 // Grow failed. 84 return false 85 } 86 87 setHeapEnd(uintptr(wasm_memory_size(wasmMemoryIndex) * wasmPageSize)) 88 89 // Heap has grown successfully. 90 return true 91 }