package wasmimport ()// Module is a WebAssembly binary representation.// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#modules%E2%91%A8//// Differences from the specification:// * NameSection is the only key ("name") decoded from the SectionIDCustom.// * ExportSection is represented as a map for lookup convenience.// * Code.GoFunc is contains any go `func`. It may be present when Code.Body is not.typeModulestruct {// TypeSection contains the unique FunctionType of functions imported or defined in this module. // // Note: Currently, there is no type ambiguity in the index as WebAssembly 1.0 only defines function type. // In the future, other types may be introduced to support CoreFeatures such as module linking. // // Note: In the Binary Format, this is SectionIDType. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#types%E2%91%A0%E2%91%A0 TypeSection []FunctionType// ImportSection contains imported functions, tables, memories or globals required for instantiation // (Store.Instantiate). // // Note: there are no unique constraints relating to the two-level namespace of Import.Module and Import.Name. // // Note: In the Binary Format, this is SectionIDImport. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#import-section%E2%91%A0 ImportSection []Import// ImportFunctionCount ImportGlobalCount ImportMemoryCount, and ImportTableCount are // the cached import count per ExternType set during decoding. ImportFunctionCount, ImportGlobalCount, ImportMemoryCount, ImportTableCount Index// ImportPerModule maps a module name to the list of Import to be imported from the module. // This is used to do fast import resolution during instantiation. ImportPerModule map[string][]*Import// FunctionSection contains the index in TypeSection of each function defined in this module. // // Note: The function Index space begins with imported functions and ends with those defined in this module. // For example, if there are two imported functions and one defined in this module, the function Index 3 is defined // in this module at FunctionSection[0]. // // Note: FunctionSection is index correlated with the CodeSection. If given the same position, e.g. 2, a function // type is at TypeSection[FunctionSection[2]], while its locals and body are at CodeSection[2]. // // Note: In the Binary Format, this is SectionIDFunction. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#function-section%E2%91%A0 FunctionSection []Index// TableSection contains each table defined in this module. // // Note: The table Index space begins with imported tables and ends with those defined in this module. // For example, if there are two imported tables and one defined in this module, the table Index 3 is defined in // this module at TableSection[0]. // // Note: Version 1.0 (20191205) of the WebAssembly spec allows at most one table definition per module, so the // length of the TableSection can be zero or one, and can only be one if there is no imported table. // // Note: In the Binary Format, this is SectionIDTable. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#table-section%E2%91%A0 TableSection []Table// MemorySection contains each memory defined in this module. // // Note: The memory Index space begins with imported memories and ends with those defined in this module. // For example, if there are two imported memories and one defined in this module, the memory Index 3 is defined in // this module at TableSection[0]. // // Note: Version 1.0 (20191205) of the WebAssembly spec allows at most one memory definition per module, so the // length of the MemorySection can be zero or one, and can only be one if there is no imported memory. // // Note: In the Binary Format, this is SectionIDMemory. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#memory-section%E2%91%A0 MemorySection *Memory// GlobalSection contains each global defined in this module. // // Global indexes are offset by any imported globals because the global index begins with imports, followed by // ones defined in this module. For example, if there are two imported globals and three defined in this module, the // global at index 3 is defined in this module at GlobalSection[0]. // // Note: In the Binary Format, this is SectionIDGlobal. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#global-section%E2%91%A0 GlobalSection []Global// ExportSection contains each export defined in this module. // // Note: In the Binary Format, this is SectionIDExport. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#exports%E2%91%A0 ExportSection []Export// Exports maps a name to Export, and is convenient for fast look up of exported instances at runtime. // Each item of this map points to an element of ExportSection. Exports map[string]*Export// StartSection is the index of a function to call before returning from Store.Instantiate. // // Note: The index here is not the position in the FunctionSection, rather in the function index, which // begins with imported functions. // // Note: In the Binary Format, this is SectionIDStart. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#start-section%E2%91%A0 StartSection *Index// Note: In the Binary Format, this is SectionIDElement. ElementSection []ElementSegment// CodeSection is index-correlated with FunctionSection and contains each // function's locals and body. // // When present, the HostFunctionSection of the same index must be nil. // // Note: In the Binary Format, this is SectionIDCode. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#code-section%E2%91%A0 CodeSection []Code// Note: In the Binary Format, this is SectionIDData. DataSection []DataSegment// NameSection is set when the SectionIDCustom "name" was successfully decoded from the binary format. // // Note: This is the only SectionIDCustom defined in the WebAssembly 1.0 (20191205) Binary Format. // Others are skipped as they are not used in wazero. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#name-section%E2%91%A0 // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#custom-section%E2%91%A0 NameSection *NameSection// CustomSections are set when the SectionIDCustom other than "name" were successfully decoded from the binary format. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#custom-section%E2%91%A0 CustomSections []*CustomSection// DataCountSection is the optional section and holds the number of data segments in the data section. // // Note: This may exist in WebAssembly 2.0 or WebAssembly 1.0 with CoreFeatureBulkMemoryOperations. // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-count-section // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/appendix/changes.html#bulk-memory-and-table-instructions DataCountSection *uint32// ID is the sha256 value of the source wasm plus the configurations which affect the runtime representation of // Wasm binary. This is only used for caching. ID ModuleID// IsHostModule true if this is the host module, false otherwise. IsHostModule bool// functionDefinitionSectionInitOnce guards FunctionDefinitionSection so that it is initialized exactly once. functionDefinitionSectionInitOnce sync.Once// FunctionDefinitionSection is a wazero-specific section. FunctionDefinitionSection []FunctionDefinition// MemoryDefinitionSection is a wazero-specific section. MemoryDefinitionSection []MemoryDefinition// DWARFLines is used to emit DWARF based stack trace. This is created from the multiple custom sections // as described in https://yurydelendik.github.io/webassembly-dwarf/, though it is not specified in the Wasm // specification: https://github.com/WebAssembly/debugging/issues/1 DWARFLines *wasmdebug.DWARFLines}// ModuleID represents sha256 hash value uniquely assigned to Module.typeModuleID = [sha256.Size]byte// The wazero specific limitation described at RATIONALE.md.// TL;DR; We multiply by 8 (to get offsets in bytes) and the multiplication result must be less than 32bit maxconst (MaximumGlobals = uint32(1 << 27)MaximumFunctionIndex = uint32(1 << 27)MaximumTableIndex = uint32(1 << 27))// AssignModuleID calculates a sha256 checksum on `wasm` and other args, and set Module.ID to the result.// See the doc on Module.ID on what it's used for.func ( *Module) ( []byte, []experimental.FunctionListener, bool) { := sha256.New() .Write()// Use the pre-allocated space backed by m.ID below.// Write the existence of listeners to the checksum per function.for , := range {binary.LittleEndian.PutUint32(.ID[:], uint32()) .ID[4] = boolToByte( != nil) .Write(.ID[:5]) }// Write the flag of ensureTermination to the checksum. .ID[0] = boolToByte() .Write(.ID[:1])// Get checksum by passing the slice underlying m.ID. .Sum(.ID[:0])}func boolToByte( bool) ( byte) {if { = 1 }return}// typeOfFunction returns the wasm.FunctionType for the given function space index or nil.func ( *Module) ( Index) *FunctionType { , := uint32(len(.TypeSection)), .ImportFunctionCountif < {// Imports are not exclusively functions. This is the current function index in the loop. := Index(0)for := range .ImportSection { := &.ImportSection[]if .Type != ExternTypeFunc {continue }if == {if .DescFunc >= {returnnil }return &.TypeSection[.DescFunc] } ++ } } := - .ImportFunctionCountif >= uint32(len(.FunctionSection)) {returnnil } := .FunctionSection[]if >= {returnnil }return &.TypeSection[]}func ( *Module) ( api.CoreFeatures) error {for := range .TypeSection { := &.TypeSection[] .CacheNumInUint64() }if := .validateStartSection(); != nil {return } , , , , := .AllDeclarations()if != nil {return }if = .validateImports(); != nil {return }if = .validateGlobals(, uint32(len()), MaximumGlobals); != nil {return }if = .validateMemory(, , ); != nil {return }if = .validateExports(, , , , ); != nil {return }if .CodeSection != nil {if = .validateFunctions(, , , , , MaximumFunctionIndex); != nil {return } } // No need to validate host functions as NewHostModule validatesif = .validateTable(, , MaximumTableIndex); != nil {return }if = .validateDataCountSection(); != nil {return }returnnil}func ( *Module) () error {// Check the start function is valid. // TODO: this should be verified during decode so that errors have the correct source positionsif .StartSection != nil { := *.StartSection := .typeOfFunction()if == nil { // TODO: move this check to decoder so that a module can never be decoded invalidlyreturnfmt.Errorf("invalid start function: func[%d] has an invalid type", ) }iflen(.Params) > 0 || len(.Results) > 0 {returnfmt.Errorf("invalid start function: func[%d] must have an empty (nullary) signature: %s", , ) } }returnnil}func ( *Module) ( []GlobalType, , uint32) error {ifuint32(len()) > {returnfmt.Errorf("too many globals in a module") }// Global initialization constant expression can only reference the imported globals. // See the note on https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#constant-expressions%E2%91%A0 := [:.ImportGlobalCount]for := range .GlobalSection { := &.GlobalSection[]if := validateConstExpression(, , &.Init, .Type.ValType); != nil {return } }returnnil}func ( *Module) ( api.CoreFeatures, []Index, []GlobalType, *Memory, []Table, uint32) error {ifuint32(len()) > {returnfmt.Errorf("too many functions (%d) in a module", len()) } := .SectionElementCount(SectionIDFunction) := .SectionElementCount(SectionIDCode)if == 0 && == 0 {returnnil } := .SectionElementCount(SectionIDType)if != {returnfmt.Errorf("code count (%d) != function count (%d)", , ) } , := .declaredFunctionIndexes()if != nil {return }// Create bytes.Reader once as it causes allocation, and // we frequently need it (e.g. on every If instruction). := bytes.NewReader(nil)// Also, we reuse the stacks across multiple function validations to reduce allocations. := &stacks{}for , := range .FunctionSection {if >= {returnfmt.Errorf("invalid %s: type section index %d out of range", .funcDesc(SectionIDFunction, Index()), ) } := &.CodeSection[]if .GoFunc != nil {continue }if = .validateFunction(, , Index(), , , , , , ); != nil {returnfmt.Errorf("invalid %s: %w", .funcDesc(SectionIDFunction, Index()), ) } }returnnil}// declaredFunctionIndexes returns a set of function indexes that can be used as an immediate for OpcodeRefFunc instruction.//// The criteria for which function indexes can be available for that instruction is vague in the spec://// - "References: the list of function indices that occur in the module outside functions and can hence be used to form references inside them."// - https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/valid/conventions.html#contexts// - "Ref is the set funcidx(module with functions=ε, start=ε) , i.e., the set of function indices occurring in the module, except in its functions or start function."// - https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/valid/modules.html#valid-module//// To clarify, we reverse-engineer logic required to pass the WebAssembly Core specification 2.0 test suite:// https://github.com/WebAssembly/spec/blob/d39195773112a22b245ffbe864bab6d1182ccb06/test/core/ref_func.wast#L78-L115//// To summarize, the function indexes OpcodeRefFunc can refer include:// - existing in an element section regardless of its mode (active, passive, declarative).// - defined as globals whose value type is ValueRefFunc.// - used as an exported function.//// See https://github.com/WebAssembly/reference-types/issues/31// See https://github.com/WebAssembly/reference-types/issues/76func ( *Module) () ( map[Index]struct{}, error) { = map[uint32]struct{}{}for := range .ExportSection { := &.ExportSection[]if .Type == ExternTypeFunc { [.Index] = struct{}{} } }for := range .GlobalSection { := &.GlobalSection[]if .Init.Opcode == OpcodeRefFunc {varuint32 , _, = leb128.LoadUint32(.Init.Data)if != nil { = fmt.Errorf("%s[%d] failed to initialize: %w", SectionIDName(SectionIDGlobal), , )return } [] = struct{}{} } }for := range .ElementSection { := &.ElementSection[]for , := range .Init {if != ElementInitNullReference { [] = struct{}{} } } }return}func ( *Module) ( SectionID, Index) string {// Try to improve the error message by collecting any exports:var []string := + .ImportFunctionCountfor := range .ExportSection { := &.ExportSection[]if .Index == && .Type == ExternTypeFunc { = append(, fmt.Sprintf("%q", .Name)) } } := SectionIDName()if == nil {returnfmt.Sprintf("%s[%d]", , ) }sort.Strings() // go map keys do not iterate consistentlyreturnfmt.Sprintf("%s[%d] export[%s]", , , strings.Join(, ","))}func ( *Module) ( *Memory, []GlobalType, api.CoreFeatures) error {varintfor := range .DataSection { := &.DataSection[]if !.IsPassive() { ++ } }if > 0 && == nil {returnfmt.Errorf("unknown memory") }// Constant expression can only reference imported globals. // https://github.com/WebAssembly/spec/blob/5900d839f38641989a9d8df2df4aee0513365d39/test/core/data.wast#L84-L91 := [:.ImportGlobalCount]for := range .DataSection { := &.DataSection[]if !.IsPassive() {if := validateConstExpression(, 0, &.OffsetExpression, ValueTypeI32); != nil {returnfmt.Errorf("calculate offset: %w", ) } } }returnnil}func ( *Module) ( api.CoreFeatures) error {for := range .ImportSection { := &.ImportSection[]if .Module == "" {returnfmt.Errorf("import[%d] has an empty module name", ) }switch .Type {caseExternTypeFunc:ifint(.DescFunc) >= len(.TypeSection) {returnfmt.Errorf("invalid import[%q.%q] function: type index out of range", .Module, .Name) }caseExternTypeGlobal:if !.DescGlobal.Mutable {continue }if := .RequireEnabled(api.CoreFeatureMutableGlobal); != nil {returnfmt.Errorf("invalid import[%q.%q] global: %w", .Module, .Name, ) } } }returnnil}func ( *Module) ( api.CoreFeatures, []Index, []GlobalType, *Memory, []Table) error {for := range .ExportSection { := &.ExportSection[] := .Indexswitch .Type {caseExternTypeFunc:if >= uint32(len()) {returnfmt.Errorf("unknown function for export[%q]", .Name) }caseExternTypeGlobal:if >= uint32(len()) {returnfmt.Errorf("unknown global for export[%q]", .Name) }if ![].Mutable {continue }if := .RequireEnabled(api.CoreFeatureMutableGlobal); != nil {returnfmt.Errorf("invalid export[%q] global[%d]: %w", .Name, , ) }caseExternTypeMemory:if > 0 || == nil {returnfmt.Errorf("memory for export[%q] out of range", .Name) }caseExternTypeTable:if >= uint32(len()) {returnfmt.Errorf("table for export[%q] out of range", .Name) } } }returnnil}func validateConstExpression( []GlobalType, uint32, *ConstantExpression, ValueType) ( error) {varValueTypeswitch .Opcode {caseOpcodeI32Const:// Treat constants as signed as their interpretation is not yet known per /RATIONALE.md _, _, = leb128.LoadInt32(.Data)if != nil {returnfmt.Errorf("read i32: %w", ) } = ValueTypeI32caseOpcodeI64Const:// Treat constants as signed as their interpretation is not yet known per /RATIONALE.md _, _, = leb128.LoadInt64(.Data)if != nil {returnfmt.Errorf("read i64: %w", ) } = ValueTypeI64caseOpcodeF32Const: _, = ieee754.DecodeFloat32(.Data)if != nil {returnfmt.Errorf("read f32: %w", ) } = ValueTypeF32caseOpcodeF64Const: _, = ieee754.DecodeFloat64(.Data)if != nil {returnfmt.Errorf("read f64: %w", ) } = ValueTypeF64caseOpcodeGlobalGet: , , := leb128.LoadUint32(.Data)if != nil {returnfmt.Errorf("read index of global: %w", ) }ifuint32(len()) <= {returnfmt.Errorf("global index out of range") } = [].ValTypecaseOpcodeRefNull:iflen(.Data) == 0 {returnfmt.Errorf("read reference type for ref.null: %w", io.ErrShortBuffer) } := .Data[0]if != RefTypeFuncref && != RefTypeExternref {returnfmt.Errorf("invalid type for ref.null: 0x%x", ) } = caseOpcodeRefFunc: , , := leb128.LoadUint32(.Data)if != nil {returnfmt.Errorf("read i32: %w", ) } elseif >= {returnfmt.Errorf("ref.func index out of range [%d] with length %d", , -1) } = ValueTypeFuncrefcaseOpcodeVecV128Const:iflen(.Data) != 16 {returnfmt.Errorf("%s needs 16 bytes but was %d bytes", OpcodeVecV128ConstName, len(.Data)) } = ValueTypeV128default:returnfmt.Errorf("invalid opcode for const expression: 0x%x", .Opcode) }if != {returnfmt.Errorf("const expression type mismatch expected %s but got %s",ValueTypeName(), ValueTypeName()) }returnnil}func ( *Module) () ( error) {if .DataCountSection != nil && int(*.DataCountSection) != len(.DataSection) { = fmt.Errorf("data count section (%d) doesn't match the length of data section (%d)", *.DataCountSection, len(.DataSection)) }return}func ( *ModuleInstance) ( *Module, func( Index) Reference) { := .Globals[:.ImportGlobalCount] := .Engine := .OwnsGlobals()for := Index(0); < Index(len(.GlobalSection)); ++ { := &.GlobalSection[] := &GlobalInstance{}if { .Me = .Index = + .ImportGlobalCount } .Globals[+.ImportGlobalCount] = .Type = .Type .initialize(, &.Init, ) }}func paramNames( IndirectNameMap, uint32, int) []string {for := range { := &[]// Only build parameter names if we have one for each.if .Index != || len(.NameMap) < {continue } := make([]string, )for := range .NameMap { := &.NameMap[]ifint(.Index) < { [.Index] = .Name } }return }returnnil}func ( *ModuleInstance) ( *Module, experimental.MemoryAllocator) { := .MemorySectionif != nil { .MemoryInstance = NewMemoryInstance(, , .Engine) .MemoryInstance.definition = &.MemoryDefinitionSection[0] }}// Index is the offset in an index, not necessarily an absolute position in a Module section. This is because// indexs are often preceded by a corresponding type in the Module.ImportSection.//// For example, the function index starts with any ExternTypeFunc in the Module.ImportSection followed by// the Module.FunctionSection//// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-indextypeIndex = uint32// FunctionType is a possibly empty function signature.//// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#function-types%E2%91%A0typeFunctionTypestruct {// Params are the possibly empty sequence of value types accepted by a function with this signature. Params []ValueType// Results are the possibly empty sequence of value types returned by a function with this signature. // // Note: In WebAssembly 1.0 (20191205), there can be at most one result. // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#result-types%E2%91%A0 Results []ValueType// string is cached as it is used both for String and key string string// ParamNumInUint64 is the number of uint64 values requires to represent the Wasm param type. ParamNumInUint64 int// ResultsNumInUint64 is the number of uint64 values requires to represent the Wasm result type. ResultNumInUint64 int}func ( *FunctionType) () {if .ParamNumInUint64 == 0 {for , := range .Params { .ParamNumInUint64++if == ValueTypeV128 { .ParamNumInUint64++ } } }if .ResultNumInUint64 == 0 {for , := range .Results { .ResultNumInUint64++if == ValueTypeV128 { .ResultNumInUint64++ } } }}// EqualsSignature returns true if the function type has the same parameters and results.func ( *FunctionType) ( []ValueType, []ValueType) bool {returnbytes.Equal(.Params, ) && bytes.Equal(.Results, )}// key gets or generates the key for Store.typeIDs. e.g. "i32_v" for one i32 parameter and no (void) result.func ( *FunctionType) () string {if .string != "" {return .string }varstringfor , := range .Params { += ValueTypeName() }iflen(.Params) == 0 { += "v_" } else { += "_" }for , := range .Results { += ValueTypeName() }iflen(.Results) == 0 { += "v" } .string = return}// String implements fmt.Stringer.func ( *FunctionType) () string {return .key()}// Import is the binary representation of an import indicated by Type// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-importtypeImportstruct { Type ExternType// Module is the possibly empty primary namespace of this import Module string// Module is the possibly empty secondary namespace of this import Name string// DescFunc is the index in Module.TypeSection when Type equals ExternTypeFunc DescFunc Index// DescTable is the inlined Table when Type equals ExternTypeTable DescTable Table// DescMem is the inlined Memory when Type equals ExternTypeMemory DescMem *Memory// DescGlobal is the inlined GlobalType when Type equals ExternTypeGlobal DescGlobal GlobalType// IndexPerType has the index of this import per ExternType. IndexPerType Index}// Memory describes the limits of pages (64KB) in a memory.typeMemorystruct { Min, Cap, Max uint32// IsMaxEncoded true if the Max is encoded in the original binary. IsMaxEncoded bool// IsShared true if the memory is shared for access from multiple agents. IsShared bool}// Validate ensures values assigned to Min, Cap and Max are within valid thresholds.func ( *Memory) ( uint32) error { , , := .Min, .Cap, .Maxif > {returnfmt.Errorf("max %d pages (%s) over limit of %d pages (%s)", , PagesToUnitOfBytes(), , PagesToUnitOfBytes()) } elseif > {returnfmt.Errorf("min %d pages (%s) over limit of %d pages (%s)", , PagesToUnitOfBytes(), , PagesToUnitOfBytes()) } elseif > {returnfmt.Errorf("min %d pages (%s) > max %d pages (%s)", , PagesToUnitOfBytes(), , PagesToUnitOfBytes()) } elseif < {returnfmt.Errorf("capacity %d pages (%s) less than minimum %d pages (%s)", , PagesToUnitOfBytes(), , PagesToUnitOfBytes()) } elseif > {returnfmt.Errorf("capacity %d pages (%s) over limit of %d pages (%s)", , PagesToUnitOfBytes(), , PagesToUnitOfBytes()) }returnnil}typeGlobalTypestruct { ValType ValueType Mutable bool}typeGlobalstruct { Type GlobalType Init ConstantExpression}typeConstantExpressionstruct { Opcode Opcode Data []byte}// Export is the binary representation of an export indicated by Type// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-exporttypeExportstruct { Type ExternType// Name is what the host refers to this definition as. Name string// Index is the index of the definition to export, the index is by Type // e.g. If ExternTypeFunc, this is a position in the function index. Index Index}// Code is an entry in the Module.CodeSection containing the locals and body of the function.// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-codetypeCodestruct {// LocalTypes are any function-scoped variables in insertion order. // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-local LocalTypes []ValueType// Body is a sequence of expressions ending in OpcodeEnd // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-expr Body []byte// GoFunc is non-nil when IsHostFunction and defined in go, either // api.GoFunction or api.GoModuleFunction. When present, LocalTypes and Body must // be nil. // // Note: This has no serialization format, so is not encodable. // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#host-functions%E2%91%A2 GoFunc interface{}// BodyOffsetInCodeSection is the offset of the beginning of the body in the code section. // This is used for DWARF based stack trace where a program counter represents an offset in code section. BodyOffsetInCodeSection uint64}typeDataSegmentstruct { OffsetExpression ConstantExpression Init []byte Passive bool}// IsPassive returns true if this data segment is "passive" in the sense that memory offset and// index is determined at runtime and used by OpcodeMemoryInitName instruction in the bulk memory// operations proposal.//// See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/appendix/changes.html#bulk-memory-and-table-instructionsfunc ( *DataSegment) () bool {return .Passive}// NameSection represent the known custom name subsections defined in the WebAssembly Binary Format//// Note: This can be nil if no names were decoded for any reason including configuration.// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#name-section%E2%91%A0typeNameSectionstruct {// ModuleName is the symbolic identifier for a module. e.g. math // // Note: This can be empty for any reason including configuration. ModuleName string// FunctionNames is an association of a function index to its symbolic identifier. e.g. add // // * the key (idx) is in the function index, where module defined functions are preceded by imported ones. // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#functions%E2%91%A7 // // For example, assuming the below text format is the second import, you would expect FunctionNames[1] = "mul" // (import "Math" "Mul" (func $mul (param $x f32) (param $y f32) (result f32))) // // Note: FunctionNames are only used for debugging. At runtime, functions are called based on raw numeric index. // Note: This can be nil for any reason including configuration. FunctionNames NameMap// LocalNames contains symbolic names for function parameters or locals that have one. // // Note: In the Text Format, function local names can inherit parameter // names from their type. Here are some examples: // * (module (import (func (param $x i32) (param i32))) (func (type 0))) = [{0, {x,0}}] // * (module (import (func (param i32) (param $y i32))) (func (type 0) (local $z i32))) = [0, [{y,1},{z,2}]] // * (module (func (param $x i32) (local $y i32) (local $z i32))) = [{x,0},{y,1},{z,2}] // // Note: LocalNames are only used for debugging. At runtime, locals are called based on raw numeric index. // Note: This can be nil for any reason including configuration. LocalNames IndirectNameMap// ResultNames is a wazero-specific mechanism to store result names. ResultNames IndirectNameMap}// CustomSection contains the name and raw data of a custom section.typeCustomSectionstruct { Name string Data []byte}// NameMap associates an index with any associated names.//// Note: Often the index bridges multiple sections. For example, the function index starts with any// ExternTypeFunc in the Module.ImportSection followed by the Module.FunctionSection//// Note: NameMap is unique by NameAssoc.Index, but NameAssoc.Name needn't be unique.// Note: When encoding in the Binary format, this must be ordered by NameAssoc.Index// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-namemaptypeNameMap []NameAssoctypeNameAssocstruct { Index Index Name string}// IndirectNameMap associates an index with an association of names.//// Note: IndirectNameMap is unique by NameMapAssoc.Index, but NameMapAssoc.NameMap needn't be unique.// Note: When encoding in the Binary format, this must be ordered by NameMapAssoc.Index// https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-indirectnamemaptypeIndirectNameMap []NameMapAssoctypeNameMapAssocstruct { Index Index NameMap NameMap}// AllDeclarations returns all declarations for functions, globals, memories and tables in a module including imported ones.func ( *Module) () ( []Index, []GlobalType, *Memory, []Table, error) {for := range .ImportSection { := &.ImportSection[]switch .Type {caseExternTypeFunc: = append(, .DescFunc)caseExternTypeGlobal: = append(, .DescGlobal)caseExternTypeMemory: = .DescMemcaseExternTypeTable: = append(, .DescTable) } } = append(, .FunctionSection...)for := range .GlobalSection { := &.GlobalSection[] = append(, .Type) }if .MemorySection != nil {if != nil { // shouldn't be possible due to Validate = errors.New("at most one table allowed in module")return } = .MemorySection }if .TableSection != nil { = append(, .TableSection...) }return}// SectionID identifies the sections of a Module in the WebAssembly 1.0 (20191205) Binary Format.//// Note: these are defined in the wasm package, instead of the binary package, as a key per section is needed regardless// of format, and deferring to the binary type avoids confusion.//// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#sections%E2%91%A0typeSectionID = byteconst (// SectionIDCustom includes the standard defined NameSection and possibly others not defined in the standard.SectionIDCustomSectionID = iota// don't add anything not in https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#sections%E2%91%A0SectionIDTypeSectionIDImportSectionIDFunctionSectionIDTableSectionIDMemorySectionIDGlobalSectionIDExportSectionIDStartSectionIDElementSectionIDCodeSectionIDData// SectionIDDataCount may exist in WebAssembly 2.0 or WebAssembly 1.0 with CoreFeatureBulkMemoryOperations enabled. // // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-count-section // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/appendix/changes.html#bulk-memory-and-table-instructionsSectionIDDataCount)// SectionIDName returns the canonical name of a module section.// https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#sections%E2%91%A0func ( SectionID) string {switch {caseSectionIDCustom:return"custom"caseSectionIDType:return"type"caseSectionIDImport:return"import"caseSectionIDFunction:return"function"caseSectionIDTable:return"table"caseSectionIDMemory:return"memory"caseSectionIDGlobal:return"global"caseSectionIDExport:return"export"caseSectionIDStart:return"start"caseSectionIDElement:return"element"caseSectionIDCode:return"code"caseSectionIDData:return"data"caseSectionIDDataCount:return"data_count" }return"unknown"}// ValueType is an alias of api.ValueType defined to simplify imports.typeValueType = api.ValueTypeconst (ValueTypeI32 = api.ValueTypeI32ValueTypeI64 = api.ValueTypeI64ValueTypeF32 = api.ValueTypeF32ValueTypeF64 = api.ValueTypeF64// TODO: ValueTypeV128 is not exposed in the api pkg yet.ValueTypeV128ValueType = 0x7b// TODO: ValueTypeFuncref is not exposed in the api pkg yet.ValueTypeFuncrefValueType = 0x70ValueTypeExternref = api.ValueTypeExternref)// ValueTypeName is an alias of api.ValueTypeName defined to simplify imports.func ( ValueType) string {if == ValueTypeFuncref {return"funcref" } elseif == ValueTypeV128 {return"v128" }returnapi.ValueTypeName()}func isReferenceValueType( ValueType) bool {return == ValueTypeExternref || == ValueTypeFuncref}// ExternType is an alias of api.ExternType defined to simplify imports.typeExternType = api.ExternTypeconst (ExternTypeFunc = api.ExternTypeFuncExternTypeFuncName = api.ExternTypeFuncNameExternTypeTable = api.ExternTypeTableExternTypeTableName = api.ExternTypeTableNameExternTypeMemory = api.ExternTypeMemoryExternTypeMemoryName = api.ExternTypeMemoryNameExternTypeGlobal = api.ExternTypeGlobalExternTypeGlobalName = api.ExternTypeGlobalName)// ExternTypeName is an alias of api.ExternTypeName defined to simplify imports.func ( ValueType) string {returnapi.ExternTypeName()}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.