github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/wasm/binary/table_test.go (about)

     1  package binary
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/wasilibs/wazerox/api"
     9  	"github.com/wasilibs/wazerox/experimental"
    10  	"github.com/wasilibs/wazerox/internal/testing/binaryencoding"
    11  	"github.com/wasilibs/wazerox/internal/testing/require"
    12  	"github.com/wasilibs/wazerox/internal/wasm"
    13  )
    14  
    15  func TestTableType(t *testing.T) {
    16  	zero := uint32(0)
    17  	max := wasm.MaximumFunctionIndex
    18  
    19  	tests := []struct {
    20  		name     string
    21  		input    wasm.Table
    22  		expected []byte
    23  	}{
    24  		{
    25  			name:     "min 0 - funcref",
    26  			input:    wasm.Table{Type: wasm.RefTypeFuncref},
    27  			expected: []byte{wasm.RefTypeFuncref, 0x0, 0},
    28  		},
    29  		{
    30  			name:     "min 0 - externref",
    31  			input:    wasm.Table{Type: wasm.RefTypeExternref},
    32  			expected: []byte{wasm.RefTypeExternref, 0x0, 0},
    33  		},
    34  		{
    35  			name:     "min 0, max 0",
    36  			input:    wasm.Table{Max: &zero, Type: wasm.RefTypeFuncref},
    37  			expected: []byte{wasm.RefTypeFuncref, 0x1, 0, 0},
    38  		},
    39  		{
    40  			name:     "min largest",
    41  			input:    wasm.Table{Min: max, Type: wasm.RefTypeFuncref},
    42  			expected: []byte{wasm.RefTypeFuncref, 0x0, 0x80, 0x80, 0x80, 0x40},
    43  		},
    44  		{
    45  			name:     "min 0, max largest",
    46  			input:    wasm.Table{Max: &max, Type: wasm.RefTypeFuncref},
    47  			expected: []byte{wasm.RefTypeFuncref, 0x1, 0, 0x80, 0x80, 0x80, 0x40},
    48  		},
    49  		{
    50  			name:     "min largest max largest",
    51  			input:    wasm.Table{Min: max, Max: &max, Type: wasm.RefTypeFuncref},
    52  			expected: []byte{wasm.RefTypeFuncref, 0x1, 0x80, 0x80, 0x80, 0x40, 0x80, 0x80, 0x80, 0x40},
    53  		},
    54  	}
    55  
    56  	for _, tt := range tests {
    57  		tc := tt
    58  
    59  		b := binaryencoding.EncodeTable(&tc.input)
    60  		t.Run(fmt.Sprintf("encode - %s", tc.name), func(t *testing.T) {
    61  			require.Equal(t, tc.expected, b)
    62  		})
    63  
    64  		t.Run(fmt.Sprintf("decode - %s", tc.name), func(t *testing.T) {
    65  			var decoded wasm.Table
    66  			err := decodeTable(bytes.NewReader(b), api.CoreFeatureReferenceTypes, &decoded)
    67  			require.NoError(t, err)
    68  			require.Equal(t, decoded, tc.input)
    69  		})
    70  	}
    71  }
    72  
    73  func TestDecodeTableType_Errors(t *testing.T) {
    74  	tests := []struct {
    75  		name        string
    76  		input       []byte
    77  		expectedErr string
    78  		features    api.CoreFeatures
    79  	}{
    80  		{
    81  			name:        "not func ref",
    82  			input:       []byte{0x50, 0x1, 0x80, 0x80, 0x4, 0},
    83  			expectedErr: "table type funcref is invalid: feature \"reference-types\" is disabled",
    84  		},
    85  		{
    86  			name:        "max < min",
    87  			input:       []byte{wasm.RefTypeFuncref, 0x1, 0x80, 0x80, 0x4, 0},
    88  			expectedErr: "table size minimum must not be greater than maximum",
    89  			features:    api.CoreFeatureReferenceTypes,
    90  		},
    91  		{
    92  			name:        "min > limit",
    93  			input:       []byte{wasm.RefTypeFuncref, 0x0, 0xff, 0xff, 0xff, 0xff, 0xf},
    94  			expectedErr: "table min must be at most 134217728",
    95  			features:    api.CoreFeatureReferenceTypes,
    96  		},
    97  		{
    98  			name:        "shared",
    99  			input:       []byte{wasm.RefTypeFuncref, 0x2, 0},
   100  			expectedErr: "tables cannot be marked as shared",
   101  			// Shared tables are an error even if threads are enabled.
   102  			features: experimental.CoreFeaturesThreads,
   103  		},
   104  	}
   105  
   106  	for _, tt := range tests {
   107  		tc := tt
   108  		t.Run(tc.name, func(t *testing.T) {
   109  			var decoded wasm.Table
   110  			err := decodeTable(bytes.NewReader(tc.input), tc.features, &decoded)
   111  			require.EqualError(t, err, tc.expectedErr)
   112  		})
   113  	}
   114  }