github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/engine/wazevo/wazevoapi/offsetdata.go (about) 1 package wazevoapi 2 3 import ( 4 "github.com/wasilibs/wazerox/internal/wasm" 5 ) 6 7 const ( 8 // FunctionInstanceSize is the size of wazevo.functionInstance. 9 FunctionInstanceSize = 24 10 // FunctionInstanceExecutableOffset is an offset of `executable` field in wazevo.functionInstance 11 FunctionInstanceExecutableOffset = 0 12 // FunctionInstanceModuleContextOpaquePtrOffset is an offset of `moduleContextOpaquePtr` field in wazevo.functionInstance 13 FunctionInstanceModuleContextOpaquePtrOffset = 8 14 // FunctionInstanceTypeIDOffset is an offset of `typeID` field in wazevo.functionInstance 15 FunctionInstanceTypeIDOffset = 16 16 ) 17 18 const ( 19 // ExecutionContextOffsetExitCodeOffset is an offset of `exitCode` field in wazevo.executionContext 20 ExecutionContextOffsetExitCodeOffset Offset = 0 21 // ExecutionContextOffsetCallerModuleContextPtr is an offset of `callerModuleContextPtr` field in wazevo.executionContext 22 ExecutionContextOffsetCallerModuleContextPtr Offset = 8 23 // ExecutionContextOffsetOriginalFramePointer is an offset of `originalFramePointer` field in wazevo.executionContext 24 ExecutionContextOffsetOriginalFramePointer Offset = 16 25 // ExecutionContextOffsetOriginalStackPointer is an offset of `originalStackPointer` field in wazevo.executionContext 26 ExecutionContextOffsetOriginalStackPointer Offset = 24 27 // ExecutionContextOffsetGoReturnAddress is an offset of `goReturnAddress` field in wazevo.executionContext 28 ExecutionContextOffsetGoReturnAddress Offset = 32 29 // ExecutionContextOffsetStackBottomPtr is an offset of `stackBottomPtr` field in wazevo.executionContext 30 ExecutionContextOffsetStackBottomPtr Offset = 40 31 // ExecutionContextOffsetGoCallReturnAddress is an offset of `goCallReturnAddress` field in wazevo.executionContext 32 ExecutionContextOffsetGoCallReturnAddress Offset = 48 33 // ExecutionContextOffsetStackPointerBeforeGoCall is an offset of `StackPointerBeforeGoCall` field in wazevo.executionContext 34 ExecutionContextOffsetStackPointerBeforeGoCall Offset = 56 35 // ExecutionContextOffsetStackGrowRequiredSize is an offset of `stackGrowRequiredSize` field in wazevo.executionContext 36 ExecutionContextOffsetStackGrowRequiredSize Offset = 64 37 // ExecutionContextOffsetMemoryGrowTrampolineAddress is an offset of `memoryGrowTrampolineAddress` field in wazevo.executionContext 38 ExecutionContextOffsetMemoryGrowTrampolineAddress Offset = 72 39 // ExecutionContextOffsetStackGrowCallTrampolineAddress is an offset of `stackGrowCallTrampolineAddress` field in wazevo.executionContext. 40 ExecutionContextOffsetStackGrowCallTrampolineAddress Offset = 80 41 // ExecutionContextOffsetCheckModuleExitCodeTrampolineAddress is an offset of `checkModuleExitCodeTrampolineAddress` field in wazevo.executionContext. 42 ExecutionContextOffsetCheckModuleExitCodeTrampolineAddress Offset = 88 43 // ExecutionContextOffsetSavedRegistersBegin is an offset of the first element of `savedRegisters` field in wazevo.executionContext 44 ExecutionContextOffsetSavedRegistersBegin Offset = 96 45 // ExecutionContextOffsetGoFunctionCallCalleeModuleContextOpaque is an offset of `goFunctionCallCalleeModuleContextOpaque` field in wazevo.executionContext 46 ExecutionContextOffsetGoFunctionCallCalleeModuleContextOpaque Offset = 1120 47 // ExecutionContextOffsetTableGrowTrampolineAddress is an offset of `tableGrowTrampolineAddress` field in wazevo.executionContext 48 ExecutionContextOffsetTableGrowTrampolineAddress Offset = 1128 49 // ExecutionContextOffsetRefFuncTrampolineAddress is an offset of `refFuncTrampolineAddress` field in wazevo.executionContext 50 ExecutionContextOffsetRefFuncTrampolineAddress Offset = 1136 51 ExecutionContextOffsetMemmoveAddress Offset = 1144 52 ) 53 54 // ModuleContextOffsetData allows the compilers to get the information about offsets to the fields of wazevo.moduleContextOpaque, 55 // This is unique per module. 56 type ModuleContextOffsetData struct { 57 TotalSize int 58 ModuleInstanceOffset, 59 LocalMemoryBegin, 60 ImportedMemoryBegin, 61 ImportedFunctionsBegin, 62 GlobalsBegin, 63 TypeIDs1stElement, 64 TablesBegin, 65 BeforeListenerTrampolines1stElement, 66 AfterListenerTrampolines1stElement, 67 DataInstances1stElement, 68 ElementInstances1stElement Offset 69 } 70 71 // ImportedFunctionOffset returns an offset of the i-th imported function. 72 // Each item is stored as wazevo.functionInstance whose size matches FunctionInstanceSize. 73 func (m *ModuleContextOffsetData) ImportedFunctionOffset(i wasm.Index) ( 74 executableOffset, moduleCtxOffset, typeIDOffset Offset, 75 ) { 76 base := m.ImportedFunctionsBegin + Offset(i)*FunctionInstanceSize 77 return base, base + 8, base + 16 78 } 79 80 // GlobalInstanceOffset returns an offset of the i-th global instance. 81 func (m *ModuleContextOffsetData) GlobalInstanceOffset(i wasm.Index) Offset { 82 return m.GlobalsBegin + Offset(i)*8 83 } 84 85 // Offset represents an offset of a field of a struct. 86 type Offset int32 87 88 // U32 encodes an Offset as uint32 for convenience. 89 func (o Offset) U32() uint32 { 90 return uint32(o) 91 } 92 93 // I64 encodes an Offset as int64 for convenience. 94 func (o Offset) I64() int64 { 95 return int64(o) 96 } 97 98 // U64 encodes an Offset as int64 for convenience. 99 func (o Offset) U64() uint64 { 100 return uint64(o) 101 } 102 103 // LocalMemoryBase returns an offset of the first byte of the local memory. 104 func (m *ModuleContextOffsetData) LocalMemoryBase() Offset { 105 return m.LocalMemoryBegin 106 } 107 108 // LocalMemoryLen returns an offset of the length of the local memory buffer. 109 func (m *ModuleContextOffsetData) LocalMemoryLen() Offset { 110 if l := m.LocalMemoryBegin; l >= 0 { 111 return l + 8 112 } 113 return -1 114 } 115 116 // TableOffset returns an offset of the i-th table instance. 117 func (m *ModuleContextOffsetData) TableOffset(tableIndex int) Offset { 118 return m.TablesBegin + Offset(tableIndex)*8 119 } 120 121 // NewModuleContextOffsetData creates a ModuleContextOffsetData determining the structure of moduleContextOpaque for the given Module. 122 // The structure is described in the comment of wazevo.moduleContextOpaque. 123 func NewModuleContextOffsetData(m *wasm.Module, withListener bool) ModuleContextOffsetData { 124 ret := ModuleContextOffsetData{} 125 var offset Offset 126 127 ret.ModuleInstanceOffset = 0 128 offset += 8 129 130 if m.MemorySection != nil { 131 ret.LocalMemoryBegin = offset 132 // buffer base + memory size. 133 const localMemorySizeInOpaqueModuleContext = 16 134 offset += localMemorySizeInOpaqueModuleContext 135 } else { 136 // Indicates that there's no local memory 137 ret.LocalMemoryBegin = -1 138 } 139 140 if m.ImportMemoryCount > 0 { 141 // *wasm.MemoryInstance + imported memory's owner (moduleContextOpaque) 142 const importedMemorySizeInOpaqueModuleContext = 16 143 ret.ImportedMemoryBegin = offset 144 offset += importedMemorySizeInOpaqueModuleContext 145 } else { 146 // Indicates that there's no imported memory 147 ret.ImportedMemoryBegin = -1 148 } 149 150 if m.ImportFunctionCount > 0 { 151 ret.ImportedFunctionsBegin = offset 152 // Each function is stored wazevo.functionInstance. 153 size := int(m.ImportFunctionCount) * FunctionInstanceSize 154 offset += Offset(size) 155 } else { 156 ret.ImportedFunctionsBegin = -1 157 } 158 159 if globals := int(m.ImportGlobalCount) + len(m.GlobalSection); globals > 0 { 160 ret.GlobalsBegin = offset 161 // Pointers to *wasm.GlobalInstance. 162 offset += Offset(globals) * 8 163 } else { 164 ret.GlobalsBegin = -1 165 } 166 167 if tables := len(m.TableSection) + int(m.ImportTableCount); tables > 0 { 168 ret.TypeIDs1stElement = offset 169 offset += 8 // First element of TypeIDs. 170 171 ret.TablesBegin = offset 172 // Pointers to *wasm.TableInstance. 173 offset += Offset(tables) * 8 174 } else { 175 ret.TypeIDs1stElement = -1 176 ret.TablesBegin = -1 177 } 178 179 if withListener { 180 ret.BeforeListenerTrampolines1stElement = offset 181 offset += 8 // First element of BeforeListenerTrampolines. 182 183 ret.AfterListenerTrampolines1stElement = offset 184 offset += 8 // First element of AfterListenerTrampolines. 185 } else { 186 ret.BeforeListenerTrampolines1stElement = -1 187 ret.AfterListenerTrampolines1stElement = -1 188 } 189 190 ret.DataInstances1stElement = offset 191 offset += 8 // First element of DataInstances. 192 193 ret.ElementInstances1stElement = offset 194 offset += 8 // First element of ElementInstances. 195 196 ret.TotalSize = int(offset) 197 return ret 198 }