github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/api/features.go (about) 1 package api 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 // CoreFeatures is a bit flag of WebAssembly Core specification features. See 9 // https://github.com/WebAssembly/proposals for proposals and their status. 10 // 11 // Constants define individual features, such as CoreFeatureMultiValue, or 12 // groups of "finished" features, assigned to a WebAssembly Core Specification 13 // version, e.g. CoreFeaturesV1 or CoreFeaturesV2. 14 // 15 // Note: Numeric values are not intended to be interpreted except as bit flags. 16 type CoreFeatures uint64 17 18 // CoreFeaturesV1 are features included in the WebAssembly Core Specification 19 // 1.0. As of late 2022, this is the only version that is a Web Standard (W3C 20 // Recommendation). 21 // 22 // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/ 23 const CoreFeaturesV1 = CoreFeatureMutableGlobal 24 25 // CoreFeaturesV2 are features included in the WebAssembly Core Specification 26 // 2.0 (20220419). As of late 2022, version 2.0 is a W3C working draft, not yet 27 // a Web Standard (W3C Recommendation). 28 // 29 // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/appendix/changes.html#release-1-1 30 const CoreFeaturesV2 = CoreFeaturesV1 | 31 CoreFeatureBulkMemoryOperations | 32 CoreFeatureMultiValue | 33 CoreFeatureNonTrappingFloatToIntConversion | 34 CoreFeatureReferenceTypes | 35 CoreFeatureSignExtensionOps | 36 CoreFeatureSIMD 37 38 const ( 39 // CoreFeatureBulkMemoryOperations adds instructions modify ranges of 40 // memory or table entries ("bulk-memory-operations"). This is included in 41 // CoreFeaturesV2, but not CoreFeaturesV1. 42 // 43 // Here are the notable effects: 44 // - Adds `memory.fill`, `memory.init`, `memory.copy` and `data.drop` 45 // instructions. 46 // - Adds `table.init`, `table.copy` and `elem.drop` instructions. 47 // - Introduces a "passive" form of element and data segments. 48 // - Stops checking "active" element and data segment boundaries at 49 // compile-time, meaning they can error at runtime. 50 // 51 // Note: "bulk-memory-operations" is mixed with the "reference-types" 52 // proposal due to the WebAssembly Working Group merging them 53 // "mutually dependent". Therefore, enabling this feature requires enabling 54 // CoreFeatureReferenceTypes, and vice-versa. 55 // 56 // See https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/bulk-memory-operations/Overview.md 57 // https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/reference-types/Overview.md and 58 // https://github.com/WebAssembly/spec/pull/1287 59 CoreFeatureBulkMemoryOperations CoreFeatures = 1 << iota 60 61 // CoreFeatureMultiValue enables multiple values ("multi-value"). This is 62 // included in CoreFeaturesV2, but not CoreFeaturesV1. 63 // 64 // Here are the notable effects: 65 // - Function (`func`) types allow more than one result. 66 // - Block types (`block`, `loop` and `if`) can be arbitrary function 67 // types. 68 // 69 // See https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/multi-value/Overview.md 70 CoreFeatureMultiValue 71 72 // CoreFeatureMutableGlobal allows globals to be mutable. This is included 73 // in both CoreFeaturesV1 and CoreFeaturesV2. 74 // 75 // When false, an api.Global can never be cast to an api.MutableGlobal, and 76 // any wasm that includes global vars will fail to parse. 77 CoreFeatureMutableGlobal 78 79 // CoreFeatureNonTrappingFloatToIntConversion enables non-trapping 80 // float-to-int conversions ("nontrapping-float-to-int-conversion"). This 81 // is included in CoreFeaturesV2, but not CoreFeaturesV1. 82 // 83 // The only effect of enabling is allowing the following instructions, 84 // which return 0 on NaN instead of panicking. 85 // - `i32.trunc_sat_f32_s` 86 // - `i32.trunc_sat_f32_u` 87 // - `i32.trunc_sat_f64_s` 88 // - `i32.trunc_sat_f64_u` 89 // - `i64.trunc_sat_f32_s` 90 // - `i64.trunc_sat_f32_u` 91 // - `i64.trunc_sat_f64_s` 92 // - `i64.trunc_sat_f64_u` 93 // 94 // See https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/nontrapping-float-to-int-conversion/Overview.md 95 CoreFeatureNonTrappingFloatToIntConversion 96 97 // CoreFeatureReferenceTypes enables various instructions and features 98 // related to table and new reference types. This is included in 99 // CoreFeaturesV2, but not CoreFeaturesV1. 100 // 101 // - Introduction of new value types: `funcref` and `externref`. 102 // - Support for the following new instructions: 103 // - `ref.null` 104 // - `ref.func` 105 // - `ref.is_null` 106 // - `table.fill` 107 // - `table.get` 108 // - `table.grow` 109 // - `table.set` 110 // - `table.size` 111 // - Support for multiple tables per module: 112 // - `call_indirect`, `table.init`, `table.copy` and `elem.drop` 113 // - Support for instructions can take non-zero table index. 114 // - Element segments can take non-zero table index. 115 // 116 // Note: "reference-types" is mixed with the "bulk-memory-operations" 117 // proposal due to the WebAssembly Working Group merging them 118 // "mutually dependent". Therefore, enabling this feature requires enabling 119 // CoreFeatureBulkMemoryOperations, and vice-versa. 120 // 121 // See https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/bulk-memory-operations/Overview.md 122 // https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/reference-types/Overview.md and 123 // https://github.com/WebAssembly/spec/pull/1287 124 CoreFeatureReferenceTypes 125 126 // CoreFeatureSignExtensionOps enables sign extension instructions 127 // ("sign-extension-ops"). This is included in CoreFeaturesV2, but not 128 // CoreFeaturesV1. 129 // 130 // Adds instructions: 131 // - `i32.extend8_s` 132 // - `i32.extend16_s` 133 // - `i64.extend8_s` 134 // - `i64.extend16_s` 135 // - `i64.extend32_s` 136 // 137 // See https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/sign-extension-ops/Overview.md 138 CoreFeatureSignExtensionOps 139 140 // CoreFeatureSIMD enables the vector value type and vector instructions 141 // (aka SIMD). This is included in CoreFeaturesV2, but not CoreFeaturesV1. 142 // 143 // Note: The instruction list is too long to enumerate in godoc. 144 // See https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md 145 CoreFeatureSIMD 146 147 // Update experimental/features.go when adding elements here. 148 ) 149 150 // SetEnabled enables or disables the feature or group of features. 151 func (f CoreFeatures) SetEnabled(feature CoreFeatures, val bool) CoreFeatures { 152 if val { 153 return f | feature 154 } 155 return f &^ feature 156 } 157 158 // IsEnabled returns true if the feature (or group of features) is enabled. 159 func (f CoreFeatures) IsEnabled(feature CoreFeatures) bool { 160 return f&feature != 0 161 } 162 163 // RequireEnabled returns an error if the feature (or group of features) is not 164 // enabled. 165 func (f CoreFeatures) RequireEnabled(feature CoreFeatures) error { 166 if f&feature == 0 { 167 return fmt.Errorf("feature %q is disabled", feature) 168 } 169 return nil 170 } 171 172 // String implements fmt.Stringer by returning each enabled feature. 173 func (f CoreFeatures) String() string { 174 var builder strings.Builder 175 for i := 0; i <= 63; i++ { // cycle through all bits to reduce code and maintenance 176 target := CoreFeatures(1 << i) 177 if f.IsEnabled(target) { 178 if name := featureName(target); name != "" { 179 if builder.Len() > 0 { 180 builder.WriteByte('|') 181 } 182 builder.WriteString(name) 183 } 184 } 185 } 186 return builder.String() 187 } 188 189 func featureName(f CoreFeatures) string { 190 switch f { 191 case CoreFeatureMutableGlobal: 192 // match https://github.com/WebAssembly/mutable-global 193 return "mutable-global" 194 case CoreFeatureSignExtensionOps: 195 // match https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/sign-extension-ops/Overview.md 196 return "sign-extension-ops" 197 case CoreFeatureMultiValue: 198 // match https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/multi-value/Overview.md 199 return "multi-value" 200 case CoreFeatureNonTrappingFloatToIntConversion: 201 // match https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/nontrapping-float-to-int-conversion/Overview.md 202 return "nontrapping-float-to-int-conversion" 203 case CoreFeatureBulkMemoryOperations: 204 // match https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/bulk-memory-operations/Overview.md 205 return "bulk-memory-operations" 206 case CoreFeatureReferenceTypes: 207 // match https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/reference-types/Overview.md 208 return "reference-types" 209 case CoreFeatureSIMD: 210 // match https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md 211 return "simd" 212 case CoreFeatureSIMD << 1: // Defined in experimental/features.go 213 // match https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md 214 return "threads" 215 } 216 return "" 217 }