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  }