function.go

 1package binary
 2
 3import (
 4	"bytes"
 5	"fmt"
 6
 7	"github.com/tetratelabs/wazero/api"
 8	"github.com/tetratelabs/wazero/internal/leb128"
 9	"github.com/tetratelabs/wazero/internal/wasm"
10)
11
12func decodeFunctionType(enabledFeatures api.CoreFeatures, r *bytes.Reader, ret *wasm.FunctionType) (err error) {
13	b, err := r.ReadByte()
14	if err != nil {
15		return fmt.Errorf("read leading byte: %w", err)
16	}
17
18	if b != 0x60 {
19		return fmt.Errorf("%w: %#x != 0x60", ErrInvalidByte, b)
20	}
21
22	paramCount, _, err := leb128.DecodeUint32(r)
23	if err != nil {
24		return fmt.Errorf("could not read parameter count: %w", err)
25	}
26
27	paramTypes, err := decodeValueTypes(r, paramCount)
28	if err != nil {
29		return fmt.Errorf("could not read parameter types: %w", err)
30	}
31
32	resultCount, _, err := leb128.DecodeUint32(r)
33	if err != nil {
34		return fmt.Errorf("could not read result count: %w", err)
35	}
36
37	// Guard >1.0 feature multi-value
38	if resultCount > 1 {
39		if err = enabledFeatures.RequireEnabled(api.CoreFeatureMultiValue); err != nil {
40			return fmt.Errorf("multiple result types invalid as %v", err)
41		}
42	}
43
44	resultTypes, err := decodeValueTypes(r, resultCount)
45	if err != nil {
46		return fmt.Errorf("could not read result types: %w", err)
47	}
48
49	ret.Params = paramTypes
50	ret.Results = resultTypes
51
52	// cache the key for the function type
53	_ = ret.String()
54
55	return nil
56}