package binary
import (
"bytes"
"fmt"
"io"
"math"
"github.com/tetratelabs/wazero/internal/leb128"
"github.com/tetratelabs/wazero/internal/wasm"
)
func decodeCode(r *bytes .Reader , codeSectionStart uint64 , ret *wasm .Code ) (err error ) {
ss , _ , err := leb128 .DecodeUint32 (r )
if err != nil {
return fmt .Errorf ("get the size of code: %w" , err )
}
remaining := int64 (ss )
ls , bytesRead , err := leb128 .DecodeUint32 (r )
remaining -= int64 (bytesRead )
if err != nil {
return fmt .Errorf ("get the size locals: %v" , err )
} else if remaining < 0 {
return io .EOF
}
bytesRead = 0
var sum uint64
for i := uint32 (0 ); i < ls ; i ++ {
num , n , err := leb128 .DecodeUint32 (r )
if err != nil {
return fmt .Errorf ("read n of locals: %v" , err )
} else if remaining < 0 {
return io .EOF
}
sum += uint64 (num )
b , err := r .ReadByte ()
if err != nil {
return fmt .Errorf ("read type of local: %v" , err )
}
bytesRead += n + 1
switch vt := b ; vt {
case wasm .ValueTypeI32 , wasm .ValueTypeF32 , wasm .ValueTypeI64 , wasm .ValueTypeF64 ,
wasm .ValueTypeFuncref , wasm .ValueTypeExternref , wasm .ValueTypeV128 :
default :
return fmt .Errorf ("invalid local type: 0x%x" , vt )
}
}
if sum > math .MaxUint32 {
return fmt .Errorf ("too many locals: %d" , sum )
}
_, err = r .Seek (-int64 (bytesRead ), io .SeekCurrent )
if err != nil {
return err
}
localTypes := make ([]wasm .ValueType , 0 , sum )
for i := uint32 (0 ); i < ls ; i ++ {
num , bytesRead , err := leb128 .DecodeUint32 (r )
remaining -= int64 (bytesRead ) + 1
if err != nil {
return fmt .Errorf ("read n of locals: %v" , err )
} else if remaining < 0 {
return io .EOF
}
b , err := r .ReadByte ()
if err != nil {
return fmt .Errorf ("read type of local: %v" , err )
}
for j := uint32 (0 ); j < num ; j ++ {
localTypes = append (localTypes , b )
}
}
bodyOffsetInCodeSection := codeSectionStart - uint64 (r .Len ())
body := make ([]byte , remaining )
if _, err = io .ReadFull (r , body ); err != nil {
return fmt .Errorf ("read body: %w" , err )
}
if endIndex := len (body ) - 1 ; endIndex < 0 || body [endIndex ] != wasm .OpcodeEnd {
return fmt .Errorf ("expr not end with OpcodeEnd" )
}
ret .BodyOffsetInCodeSection = bodyOffsetInCodeSection
ret .LocalTypes = localTypes
ret .Body = body
return nil
}
The pages are generated with Golds v0.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 .