package binary
import (
"bytes"
"fmt"
"io"
"github.com/tetratelabs/wazero/internal/leb128"
"github.com/tetratelabs/wazero/internal/wasm"
)
const (
subsectionIDModuleName = uint8 (0 )
subsectionIDFunctionNames = uint8 (1 )
subsectionIDLocalNames = uint8 (2 )
)
func decodeNameSection(r *bytes .Reader , limit uint64 ) (result *wasm .NameSection , err error ) {
result = &wasm .NameSection {}
var subsectionID uint8
var subsectionSize uint32
var bytesRead uint64
for limit > 0 {
if subsectionID , err = r .ReadByte (); err != nil {
if err == io .EOF {
return result , nil
}
return nil , fmt .Errorf ("failed to read a subsection ID: %w" , err )
}
limit --
if subsectionSize , bytesRead , err = leb128 .DecodeUint32 (r ); err != nil {
return nil , fmt .Errorf ("failed to read the size of subsection[%d]: %w" , subsectionID , err )
}
limit -= bytesRead
switch subsectionID {
case subsectionIDModuleName :
if result .ModuleName , _, err = decodeUTF8 (r , "module name" ); err != nil {
return nil , err
}
case subsectionIDFunctionNames :
if result .FunctionNames , err = decodeFunctionNames (r ); err != nil {
return nil , err
}
case subsectionIDLocalNames :
if result .LocalNames , err = decodeLocalNames (r ); err != nil {
return nil , err
}
default :
if _, err = io .CopyN (io .Discard , r , int64 (subsectionSize )); err != nil {
return nil , fmt .Errorf ("failed to skip subsection[%d]: %w" , subsectionID , err )
}
}
limit -= uint64 (subsectionSize )
}
return
}
func decodeFunctionNames(r *bytes .Reader ) (wasm .NameMap , error ) {
functionCount , err := decodeFunctionCount (r , subsectionIDFunctionNames )
if err != nil {
return nil , err
}
result := make (wasm .NameMap , functionCount )
for i := uint32 (0 ); i < functionCount ; i ++ {
functionIndex , err := decodeFunctionIndex (r , subsectionIDFunctionNames )
if err != nil {
return nil , err
}
name , _ , err := decodeUTF8 (r , "function[%d] name" , functionIndex )
if err != nil {
return nil , err
}
result [i ] = wasm .NameAssoc {Index : functionIndex , Name : name }
}
return result , nil
}
func decodeLocalNames(r *bytes .Reader ) (wasm .IndirectNameMap , error ) {
functionCount , err := decodeFunctionCount (r , subsectionIDLocalNames )
if err != nil {
return nil , err
}
result := make (wasm .IndirectNameMap , functionCount )
for i := uint32 (0 ); i < functionCount ; i ++ {
functionIndex , err := decodeFunctionIndex (r , subsectionIDLocalNames )
if err != nil {
return nil , err
}
localCount , _ , err := leb128 .DecodeUint32 (r )
if err != nil {
return nil , fmt .Errorf ("failed to read the local count for function[%d]: %w" , functionIndex , err )
}
locals := make (wasm .NameMap , localCount )
for j := uint32 (0 ); j < localCount ; j ++ {
localIndex , _ , err := leb128 .DecodeUint32 (r )
if err != nil {
return nil , fmt .Errorf ("failed to read a local index of function[%d]: %w" , functionIndex , err )
}
name , _ , err := decodeUTF8 (r , "function[%d] local[%d] name" , functionIndex , localIndex )
if err != nil {
return nil , err
}
locals [j ] = wasm .NameAssoc {Index : localIndex , Name : name }
}
result [i ] = wasm .NameMapAssoc {Index : functionIndex , NameMap : locals }
}
return result , nil
}
func decodeFunctionIndex(r *bytes .Reader , subsectionID uint8 ) (uint32 , error ) {
functionIndex , _ , err := leb128 .DecodeUint32 (r )
if err != nil {
return 0 , fmt .Errorf ("failed to read a function index in subsection[%d]: %w" , subsectionID , err )
}
return functionIndex , nil
}
func decodeFunctionCount(r *bytes .Reader , subsectionID uint8 ) (uint32 , error ) {
functionCount , _ , err := leb128 .DecodeUint32 (r )
if err != nil {
return 0 , fmt .Errorf ("failed to read the function count of subsection[%d]: %w" , subsectionID , err )
}
return functionCount , 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 .