github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/wasm/binary/data.go (about) 1 package binary 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 8 "github.com/wasilibs/wazerox/api" 9 "github.com/wasilibs/wazerox/internal/leb128" 10 "github.com/wasilibs/wazerox/internal/wasm" 11 ) 12 13 // dataSegmentPrefix represents three types of data segments. 14 // 15 // https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-section 16 type dataSegmentPrefix = uint32 17 18 const ( 19 // dataSegmentPrefixActive is the prefix for the version 1.0 compatible data segment, which is classified as "active" in 2.0. 20 dataSegmentPrefixActive dataSegmentPrefix = 0x0 21 // dataSegmentPrefixPassive prefixes the "passive" data segment as in version 2.0 specification. 22 dataSegmentPrefixPassive dataSegmentPrefix = 0x1 23 // dataSegmentPrefixActiveWithMemoryIndex is the active prefix with memory index encoded which is defined for futur use as of 2.0. 24 dataSegmentPrefixActiveWithMemoryIndex dataSegmentPrefix = 0x2 25 ) 26 27 func decodeDataSegment(r *bytes.Reader, enabledFeatures api.CoreFeatures, ret *wasm.DataSegment) (err error) { 28 dataSegmentPrefx, _, err := leb128.DecodeUint32(r) 29 if err != nil { 30 err = fmt.Errorf("read data segment prefix: %w", err) 31 return 32 } 33 34 if dataSegmentPrefx != dataSegmentPrefixActive { 35 if err = enabledFeatures.RequireEnabled(api.CoreFeatureBulkMemoryOperations); err != nil { 36 err = fmt.Errorf("non-zero prefix for data segment is invalid as %w", err) 37 return 38 } 39 } 40 41 switch dataSegmentPrefx { 42 case dataSegmentPrefixActive, 43 dataSegmentPrefixActiveWithMemoryIndex: 44 // Active data segment as in 45 // https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-section 46 if dataSegmentPrefx == 0x2 { 47 d, _, err := leb128.DecodeUint32(r) 48 if err != nil { 49 return fmt.Errorf("read memory index: %v", err) 50 } else if d != 0 { 51 return fmt.Errorf("memory index must be zero but was %d", d) 52 } 53 } 54 55 err = decodeConstantExpression(r, enabledFeatures, &ret.OffsetExpression) 56 if err != nil { 57 return fmt.Errorf("read offset expression: %v", err) 58 } 59 case dataSegmentPrefixPassive: 60 // Passive data segment doesn't need const expr nor memory index encoded. 61 // https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-section 62 ret.Passive = true 63 default: 64 err = fmt.Errorf("invalid data segment prefix: 0x%x", dataSegmentPrefx) 65 return 66 } 67 68 vs, _, err := leb128.DecodeUint32(r) 69 if err != nil { 70 err = fmt.Errorf("get the size of vector: %v", err) 71 return 72 } 73 74 ret.Init = make([]byte, vs) 75 if _, err = io.ReadFull(r, ret.Init); err != nil { 76 err = fmt.Errorf("read bytes for init: %v", err) 77 } 78 return 79 }