working commit
This commit is contained in:
+94
@@ -0,0 +1,94 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/tetratelabs/wabin/leb128"
|
||||
"github.com/tetratelabs/wabin/wasm"
|
||||
)
|
||||
|
||||
// dataSegmentPrefix represents three types of data segments.
|
||||
//
|
||||
// https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-section
|
||||
type dataSegmentPrefix = uint32
|
||||
|
||||
const (
|
||||
// dataSegmentPrefixActive is the prefix for the version 1.0 compatible
|
||||
// data segment, which is classified as "active" in 2.0.
|
||||
dataSegmentPrefixActive dataSegmentPrefix = 0x0
|
||||
// dataSegmentPrefixPassive prefixes the "passive" data segment as in
|
||||
// version 2.0 specification.
|
||||
dataSegmentPrefixPassive dataSegmentPrefix = 0x1
|
||||
// dataSegmentPrefixActiveWithMemoryIndex is the active prefix with memory
|
||||
//index encoded which is defined for future use as of 2.0.
|
||||
dataSegmentPrefixActiveWithMemoryIndex dataSegmentPrefix = 0x2
|
||||
)
|
||||
|
||||
func decodeDataSegment(r *bytes.Reader, features wasm.CoreFeatures) (*wasm.DataSegment, error) {
|
||||
dataSegmentPrefix, _, err := leb128.DecodeUint32(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read data segment prefix: %w", err)
|
||||
}
|
||||
|
||||
if dataSegmentPrefix != dataSegmentPrefixActive {
|
||||
if err := features.RequireEnabled(wasm.CoreFeatureBulkMemoryOperations); err != nil {
|
||||
return nil, fmt.Errorf("non-zero prefix for data segment is invalid as %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var expr *wasm.ConstantExpression
|
||||
switch dataSegmentPrefix {
|
||||
case dataSegmentPrefixActive,
|
||||
dataSegmentPrefixActiveWithMemoryIndex:
|
||||
// Active data segment as in
|
||||
// https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-section
|
||||
if dataSegmentPrefix == 0x2 {
|
||||
d, _, err := leb128.DecodeUint32(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read memory index: %v", err)
|
||||
} else if d != 0 {
|
||||
return nil, fmt.Errorf("memory index must be zero but was %d", d)
|
||||
}
|
||||
}
|
||||
|
||||
expr, err = decodeConstantExpression(r, features)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read offset expression: %v", err)
|
||||
}
|
||||
case dataSegmentPrefixPassive:
|
||||
// Passive data segment doesn't need const expr nor memory index encoded.
|
||||
// https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-section
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid data segment prefix: 0x%x", dataSegmentPrefix)
|
||||
}
|
||||
|
||||
vs, _, err := leb128.DecodeUint32(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get the size of vector: %v", err)
|
||||
}
|
||||
|
||||
b := make([]byte, vs)
|
||||
if _, err := io.ReadFull(r, b); err != nil {
|
||||
return nil, fmt.Errorf("read bytes for init: %v", err)
|
||||
}
|
||||
|
||||
return &wasm.DataSegment{
|
||||
OffsetExpression: expr,
|
||||
Init: b,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeDataSegment(d *wasm.DataSegment) (ret []byte) {
|
||||
if d.OffsetExpression == nil {
|
||||
ret = append(ret, leb128.EncodeInt32(int32(dataSegmentPrefixPassive))...)
|
||||
} else {
|
||||
// Currently multiple memories are not supported.
|
||||
ret = append(ret, leb128.EncodeInt32(int32(dataSegmentPrefixActive))...)
|
||||
ret = append(ret, encodeConstantExpression(d.OffsetExpression)...)
|
||||
}
|
||||
ret = append(ret, leb128.EncodeUint32(uint32(len(d.Init)))...)
|
||||
ret = append(ret, d.Init...)
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user