wa-lang.org/wazero@v1.0.2/internal/wasm/binary/const_expr_test.go (about)

     1  package binary
     2  
     3  import (
     4  	"bytes"
     5  	"strconv"
     6  	"testing"
     7  
     8  	"wa-lang.org/wazero/api"
     9  	"wa-lang.org/wazero/internal/testing/require"
    10  	"wa-lang.org/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  			actual, err := decodeConstantExpression(bytes.NewReader(tc.in),
    88  				api.CoreFeatureBulkMemoryOperations|api.CoreFeatureSIMD)
    89  			require.NoError(t, err)
    90  			require.Equal(t, tc.exp, actual)
    91  		})
    92  	}
    93  }
    94  
    95  func TestDecodeConstantExpression_errors(t *testing.T) {
    96  	tests := []struct {
    97  		in          []byte
    98  		expectedErr string
    99  		features    api.CoreFeatures
   100  	}{
   101  		{
   102  			in: []byte{
   103  				wasm.OpcodeRefFunc,
   104  				0,
   105  			},
   106  			expectedErr: "look for end opcode: EOF",
   107  			features:    api.CoreFeatureBulkMemoryOperations,
   108  		},
   109  		{
   110  			in: []byte{
   111  				wasm.OpcodeRefNull,
   112  			},
   113  			expectedErr: "read reference type for ref.null: EOF",
   114  			features:    api.CoreFeatureBulkMemoryOperations,
   115  		},
   116  		{
   117  			in: []byte{
   118  				wasm.OpcodeRefNull,
   119  				0xff,
   120  				wasm.OpcodeEnd,
   121  			},
   122  			expectedErr: "invalid type for ref.null: 0xff",
   123  			features:    api.CoreFeatureBulkMemoryOperations,
   124  		},
   125  		{
   126  			in: []byte{
   127  				wasm.OpcodeRefNull,
   128  				wasm.RefTypeExternref,
   129  				wasm.OpcodeEnd,
   130  			},
   131  			expectedErr: "ref.null is not supported as feature \"bulk-memory-operations\" is disabled",
   132  			features:    api.CoreFeaturesV1,
   133  		},
   134  		{
   135  			in: []byte{
   136  				wasm.OpcodeRefFunc,
   137  				0x80, 0,
   138  				wasm.OpcodeEnd,
   139  			},
   140  			expectedErr: "ref.func is not supported as feature \"bulk-memory-operations\" is disabled",
   141  			features:    api.CoreFeaturesV1,
   142  		},
   143  		{
   144  			in: []byte{
   145  				wasm.OpcodeVecPrefix,
   146  				wasm.OpcodeVecV128Const,
   147  				1, 1, 1, 1, 1, 1, 1, 1,
   148  				1, 1, 1, 1, 1, 1, 1, 1,
   149  				wasm.OpcodeEnd,
   150  			},
   151  			expectedErr: "vector instructions are not supported as feature \"simd\" is disabled",
   152  			features:    api.CoreFeaturesV1,
   153  		},
   154  		{
   155  			in: []byte{
   156  				wasm.OpcodeVecPrefix,
   157  			},
   158  			expectedErr: "read vector instruction opcode suffix: EOF",
   159  			features:    api.CoreFeatureSIMD,
   160  		},
   161  		{
   162  			in: []byte{
   163  				wasm.OpcodeVecPrefix,
   164  				1, 1, 1, 1, 1, 1, 1, 1,
   165  				1, 1, 1, 1, 1, 1, 1, 1,
   166  				wasm.OpcodeEnd,
   167  			},
   168  			expectedErr: "invalid vector opcode for const expression: 0x1",
   169  			features:    api.CoreFeatureSIMD,
   170  		},
   171  		{
   172  			in: []byte{
   173  				wasm.OpcodeVecPrefix,
   174  				wasm.OpcodeVecV128Const,
   175  				1, 1, 1, 1, 1, 1, 1, 1,
   176  			},
   177  			expectedErr: "read vector const instruction immediates: needs 16 bytes but was 8 bytes",
   178  			features:    api.CoreFeatureSIMD,
   179  		},
   180  	}
   181  
   182  	for _, tt := range tests {
   183  		tc := tt
   184  		t.Run(tc.expectedErr, func(t *testing.T) {
   185  			_, err := decodeConstantExpression(bytes.NewReader(tc.in), tc.features)
   186  			require.EqualError(t, err, tc.expectedErr)
   187  		})
   188  	}
   189  }