github.com/taubyte/vm-wasm-utils@v1.0.2/features.go (about) 1 package wasm 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 // Features are the currently enabled features. 9 // 10 // Note: This is a bit flag until we have too many (>63). Flags are simpler to manage in multiple places than a map. 11 type Features uint64 12 13 // Features20191205 include those finished in WebAssembly 1.0 (20191205). 14 // 15 // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205 16 const Features20191205 = FeatureMutableGlobal 17 18 // Features20220419 include those finished in WebAssembly 2.0 (20220419). 19 // 20 // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/appendix/changes.html#release-1-1 21 const Features20220419 = Features20191205 | 22 FeatureBulkMemoryOperations | 23 FeatureMultiValue | 24 FeatureNonTrappingFloatToIntConversion | 25 FeatureReferenceTypes | 26 FeatureSignExtensionOps | 27 FeatureSIMD 28 29 const ( 30 // FeatureBulkMemoryOperations decides if parsing should succeed on the following instructions: 31 // 32 // * [ OpcodeMiscPrefix, OpcodeMiscMemoryInit] 33 // * [ OpcodeMiscPrefix, OpcodeMiscDataDrop] 34 // * [ OpcodeMiscPrefix, OpcodeMiscMemoryCopy] 35 // * [ OpcodeMiscPrefix, OpcodeMiscMemoryFill] 36 // * [ OpcodeMiscPrefix, OpcodeMiscTableInit] 37 // * [ OpcodeMiscPrefix, OpcodeMiscElemDrop] 38 // * [ OpcodeMiscPrefix, OpcodeMiscTableCopy] 39 // 40 // Also, if the parsing should succeed with the presence of SectionIDDataCount. 41 // 42 // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/appendix/changes.html#bulk-memory-and-table-instructions 43 FeatureBulkMemoryOperations Features = 1 << iota 44 45 // FeatureMultiValue decides if parsing should succeed on the following: 46 // 47 // * FunctionType.Results length greater than one. 48 // * `block`, `loop` and `if` can be arbitrary function types. 49 // 50 // See https://github.com/WebAssembly/spec/blob/main/proposals/multi-value/Overview.md 51 FeatureMultiValue 52 53 // FeatureMutableGlobal decides if global vars are allowed to be imported or exported (ExternTypeGlobal) 54 // See https://github.com/WebAssembly/mutable-global 55 FeatureMutableGlobal 56 57 // FeatureNonTrappingFloatToIntConversion decides if parsing should succeed on the following instructions: 58 // 59 // * [ OpcodeMiscPrefix, OpcodeMiscI32TruncSatF32S] 60 // * [ OpcodeMiscPrefix, OpcodeMiscI32TruncSatF32U] 61 // * [ OpcodeMiscPrefix, OpcodeMiscI64TruncSatF32S] 62 // * [ OpcodeMiscPrefix, OpcodeMiscI64TruncSatF32U] 63 // * [ OpcodeMiscPrefix, OpcodeMiscI32TruncSatF64S] 64 // * [ OpcodeMiscPrefix, OpcodeMiscI32TruncSatF64U] 65 // * [ OpcodeMiscPrefix, OpcodeMiscI64TruncSatF64S] 66 // * [ OpcodeMiscPrefix, OpcodeMiscI64TruncSatF64U] 67 // 68 // See https://github.com/WebAssembly/spec/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md 69 FeatureNonTrappingFloatToIntConversion 70 71 // FeatureReferenceTypes enables various features related to reference types and tables. 72 // * Introduction of new values types: RefTypeFuncref and RefTypeExternref 73 // * Support for the following opcodes: 74 // * OpcodeRefNull 75 // * OpcodeRefIsNull 76 // * OpcodeRefFunc 77 // * OpcodeTableGet 78 // * OpcodeTableSet 79 // * [ OpcodeMiscPrefix, OpcodeMiscTableFill] 80 // * [ OpcodeMiscPrefix, OpcodeMiscTableGrow] 81 // * [ OpcodeMiscPrefix, OpcodeMiscTableSize] 82 // * Support for multiple tables per module: 83 // * OpcodeCallIndirect, OpcodeTableInit, and OpcodeElemDrop can take non-zero table indexes. 84 // * Element segments can take non-zero table index. 85 // 86 // See https://github.com/WebAssembly/spec/blob/main/proposals/reference-types/Overview.md 87 FeatureReferenceTypes 88 89 // FeatureSignExtensionOps decides if parsing should succeed on the following instructions: 90 // 91 // * OpcodeI32Extend8S 92 // * OpcodeI32Extend16S 93 // * OpcodeI64Extend8S 94 // * OpcodeI64Extend16S 95 // * OpcodeI64Extend32S 96 // 97 // See https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md 98 FeatureSignExtensionOps 99 100 // FeatureSIMD enables the vector value type and vector instructions. 101 // 102 // See https://github.com/WebAssembly/spec/blob/main/proposals/simd/SIMD.md 103 FeatureSIMD 104 ) 105 106 // Set assigns the value for the given feature. 107 func (f Features) Set(feature Features, val bool) Features { 108 if val { 109 return f | feature 110 } 111 return f &^ feature 112 } 113 114 // Get returns the value of the given feature. 115 func (f Features) Get(feature Features) bool { 116 return f&feature != 0 117 } 118 119 // Require fails with a configuration error if the given feature is not enabled 120 func (f Features) Require(feature Features) error { 121 if f&feature == 0 { 122 return fmt.Errorf("feature %q is disabled", feature) 123 } 124 return nil 125 } 126 127 // String implements fmt.Stringer by returning each enabled feature. 128 func (f Features) String() string { 129 var builder strings.Builder 130 for i := 0; i <= 63; i++ { // cycle through all bits to reduce code and maintenance 131 target := Features(1 << i) 132 if f.Get(target) { 133 if name := featureName(target); name != "" { 134 if builder.Len() > 0 { 135 builder.WriteByte('|') 136 } 137 builder.WriteString(name) 138 } 139 } 140 } 141 return builder.String() 142 } 143 144 func featureName(f Features) string { 145 switch f { 146 case FeatureMutableGlobal: 147 // match https://github.com/WebAssembly/mutable-global 148 return "mutable-global" 149 case FeatureSignExtensionOps: 150 // match https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md 151 return "sign-extension-ops" 152 case FeatureMultiValue: 153 // match https://github.com/WebAssembly/spec/blob/main/proposals/multi-value/Overview.md 154 return "multi-value" 155 case FeatureNonTrappingFloatToIntConversion: 156 // match https://github.com/WebAssembly/spec/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md 157 return "nontrapping-float-to-int-conversion" 158 case FeatureBulkMemoryOperations: 159 // match https://github.com/WebAssembly/spec/blob/main/proposals/bulk-memory-operations/Overview.md 160 return "bulk-memory-operations" 161 case FeatureReferenceTypes: 162 // match https://github.com/WebAssembly/spec/blob/main/proposals/reference-types/Overview.md 163 return "reference-types" 164 case FeatureSIMD: 165 // match https://github.com/WebAssembly/spec/blob/main/proposals/simd/SIMD.md 166 return "simd" 167 } 168 return "" 169 }