github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/wasm/binary/const_expr_test.go (about)

     1  package binary
     2  
     3  import (
     4  	"bytes"
     5  	"strconv"
     6  	"testing"
     7  
     8  	"github.com/bananabytelabs/wazero/api"
     9  	"github.com/bananabytelabs/wazero/internal/testing/require"
    10  	"github.com/bananabytelabs/wazero/internal/wasm"
    11  )
    12  
    13  func TestDecodeConstantExpression(t *testing.T) {
    14  	tests := []struct {
    15  		in  []byte
    16  		exp wasm.ConstantExpression
    17  	}{
    18  		{
    19  			in: []byte{
    20  				wasm.OpcodeRefFunc,
    21  				0x80, 0, // Multi byte zero.
    22  				wasm.OpcodeEnd,
    23  			},
    24  			exp: wasm.ConstantExpression{
    25  				Opcode: wasm.OpcodeRefFunc,
    26  				Data:   []byte{0x80, 0},
    27  			},
    28  		},
    29  		{
    30  			in: []byte{
    31  				wasm.OpcodeRefFunc,
    32  				0x80, 0x80, 0x80, 0x4f, // 165675008 in varint encoding.
    33  				wasm.OpcodeEnd,
    34  			},
    35  			exp: wasm.ConstantExpression{
    36  				Opcode: wasm.OpcodeRefFunc,
    37  				Data:   []byte{0x80, 0x80, 0x80, 0x4f},
    38  			},
    39  		},
    40  		{
    41  			in: []byte{
    42  				wasm.OpcodeRefNull,
    43  				wasm.RefTypeFuncref,
    44  				wasm.OpcodeEnd,
    45  			},
    46  			exp: wasm.ConstantExpression{
    47  				Opcode: wasm.OpcodeRefNull,
    48  				Data: []byte{
    49  					wasm.RefTypeFuncref,
    50  				},
    51  			},
    52  		},
    53  		{
    54  			in: []byte{
    55  				wasm.OpcodeRefNull,
    56  				wasm.RefTypeExternref,
    57  				wasm.OpcodeEnd,
    58  			},
    59  			exp: wasm.ConstantExpression{
    60  				Opcode: wasm.OpcodeRefNull,
    61  				Data: []byte{
    62  					wasm.RefTypeExternref,
    63  				},
    64  			},
    65  		},
    66  		{
    67  			in: []byte{
    68  				wasm.OpcodeVecPrefix,
    69  				wasm.OpcodeVecV128Const,
    70  				1, 1, 1, 1, 1, 1, 1, 1,
    71  				1, 1, 1, 1, 1, 1, 1, 1,
    72  				wasm.OpcodeEnd,
    73  			},
    74  			exp: wasm.ConstantExpression{
    75  				Opcode: wasm.OpcodeVecV128Const,
    76  				Data: []byte{
    77  					1, 1, 1, 1, 1, 1, 1, 1,
    78  					1, 1, 1, 1, 1, 1, 1, 1,
    79  				},
    80  			},
    81  		},
    82  	}
    83  
    84  	for i, tt := range tests {
    85  		tc := tt
    86  		t.Run(strconv.Itoa(i), func(t *testing.T) {
    87  			var actual wasm.ConstantExpression
    88  			err := decodeConstantExpression(bytes.NewReader(tc.in),
    89  				api.CoreFeatureBulkMemoryOperations|api.CoreFeatureSIMD, &actual)
    90  			require.NoError(t, err)
    91  			require.Equal(t, tc.exp, actual)
    92  		})
    93  	}
    94  }
    95  
    96  func TestDecodeConstantExpression_errors(t *testing.T) {
    97  	tests := []struct {
    98  		in          []byte
    99  		expectedErr string
   100  		features    api.CoreFeatures
   101  	}{
   102  		{
   103  			in: []byte{
   104  				wasm.OpcodeRefFunc,
   105  				0,
   106  			},
   107  			expectedErr: "look for end opcode: EOF",
   108  			features:    api.CoreFeatureBulkMemoryOperations,
   109  		},
   110  		{
   111  			in: []byte{
   112  				wasm.OpcodeRefNull,
   113  			},
   114  			expectedErr: "read reference type for ref.null: EOF",
   115  			features:    api.CoreFeatureBulkMemoryOperations,
   116  		},
   117  		{
   118  			in: []byte{
   119  				wasm.OpcodeRefNull,
   120  				0xff,
   121  				wasm.OpcodeEnd,
   122  			},
   123  			expectedErr: "invalid type for ref.null: 0xff",
   124  			features:    api.CoreFeatureBulkMemoryOperations,
   125  		},
   126  		{
   127  			in: []byte{
   128  				wasm.OpcodeRefNull,
   129  				wasm.RefTypeExternref,
   130  				wasm.OpcodeEnd,
   131  			},
   132  			expectedErr: "ref.null is not supported as feature \"bulk-memory-operations\" is disabled",
   133  			features:    api.CoreFeaturesV1,
   134  		},
   135  		{
   136  			in: []byte{
   137  				wasm.OpcodeRefFunc,
   138  				0x80, 0,
   139  				wasm.OpcodeEnd,
   140  			},
   141  			expectedErr: "ref.func is not supported as feature \"bulk-memory-operations\" is disabled",
   142  			features:    api.CoreFeaturesV1,
   143  		},
   144  		{
   145  			in: []byte{
   146  				wasm.OpcodeVecPrefix,
   147  				wasm.OpcodeVecV128Const,
   148  				1, 1, 1, 1, 1, 1, 1, 1,
   149  				1, 1, 1, 1, 1, 1, 1, 1,
   150  				wasm.OpcodeEnd,
   151  			},
   152  			expectedErr: "vector instructions are not supported as feature \"simd\" is disabled",
   153  			features:    api.CoreFeaturesV1,
   154  		},
   155  		{
   156  			in: []byte{
   157  				wasm.OpcodeVecPrefix,
   158  			},
   159  			expectedErr: "read vector instruction opcode suffix: EOF",
   160  			features:    api.CoreFeatureSIMD,
   161  		},
   162  		{
   163  			in: []byte{
   164  				wasm.OpcodeVecPrefix,
   165  				1, 1, 1, 1, 1, 1, 1, 1,
   166  				1, 1, 1, 1, 1, 1, 1, 1,
   167  				wasm.OpcodeEnd,
   168  			},
   169  			expectedErr: "invalid vector opcode for const expression: 0x1",
   170  			features:    api.CoreFeatureSIMD,
   171  		},
   172  		{
   173  			in: []byte{
   174  				wasm.OpcodeVecPrefix,
   175  				wasm.OpcodeVecV128Const,
   176  				1, 1, 1, 1, 1, 1, 1, 1,
   177  			},
   178  			expectedErr: "read vector const instruction immediates: needs 16 bytes but was 8 bytes",
   179  			features:    api.CoreFeatureSIMD,
   180  		},
   181  	}
   182  
   183  	for _, tt := range tests {
   184  		tc := tt
   185  		t.Run(tc.expectedErr, func(t *testing.T) {
   186  			var actual wasm.ConstantExpression
   187  			err := decodeConstantExpression(bytes.NewReader(tc.in), tc.features, &actual)
   188  			require.EqualError(t, err, tc.expectedErr)
   189  		})
   190  	}
   191  }