| #! /usr/bin/python3 |
| |
| ''' |
| Generate test modules with all interesting casts |
| ''' |
| |
| import argparse |
| import itertools |
| |
| interesting_pairs = [('$super', '$super', 'cast-to-self-nonfinal'), |
| ('$sub-final', '$sub-final', 'cast-to-self-final'), |
| ('$sub', '$super', 'cast-to-super'), |
| ('$super', '$sub', 'cast-to-sub'), |
| ('$sub-final', '$sub', 'cast-to-sibling'), |
| ('$super', 'none', 'cast-to-bottom'), |
| ('none', '$super', 'cast-from-bottom')] |
| |
| |
| def gen_test_configs(args): |
| for src_heap, cast_heap, heap_name in interesting_pairs: |
| for src_nullable, src_exact, cast_nullable, cast_exact in \ |
| itertools.product([True, False], repeat=4): |
| if src_exact and src_heap == 'none': |
| continue |
| if cast_exact and cast_heap == 'none': |
| continue |
| if args.enable_descs != cast_exact: |
| continue |
| yield heap_name, src_heap, cast_heap, src_nullable, cast_nullable, \ |
| src_exact, cast_exact |
| |
| |
| def print_test(config): |
| heap_name, src_heap, cast_heap, src_nullable, cast_nullable, src_exact, \ |
| cast_exact = config |
| |
| src_nullable_name = 'null' if src_nullable else 'non-null' |
| cast_nullable_name = 'null' if cast_nullable else 'non-null' |
| |
| src_exact_name = 'exact' if src_exact else 'inexact' |
| cast_exact_name = 'exact' if cast_exact else 'inexact' |
| |
| test_name = f'{heap_name}-{src_nullable_name}-{src_exact_name}-to-' + \ |
| f'{cast_nullable_name}-{cast_exact_name}' |
| |
| src_nullable_type = ' null' if src_nullable else '' |
| cast_nullable_type = ' null' if cast_nullable else '' |
| |
| src_heap_type = f'(exact {src_heap})' if src_exact else src_heap |
| cast_heap_type = f'(exact {cast_heap})' if cast_exact else cast_heap |
| |
| src_type = f'(ref{src_nullable_type} {src_heap_type})' |
| cast_type = f'(ref{cast_nullable_type} {cast_heap_type})' |
| |
| test = f''' |
| (func ${test_name} (param {src_type}) (result {cast_type}) |
| (local anyref) |
| (ref.cast {cast_type} |
| (local.tee 1 |
| (local.get 0) |
| ) |
| ) |
| )''' |
| print(test) |
| |
| |
| def print_tests(args): |
| for config in gen_test_configs(args): |
| print_test(config) |
| |
| |
| def print_header(args): |
| flags = '' |
| if args.enable_descs: |
| flags = ' --enable-custom-descs' |
| header = f''';; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. |
| ;; NOTE: Test has been generated by scripts/test/gen-cast-test.py{flags}. Do not edit manually. |
| |
| ;; Exhaustively test optimization of all interesting casts. |
| ''' |
| |
| if args.enable_descs: |
| header += ''' |
| ;; RUN: wasm-opt %s -all --optimize-instructions -S -o - | filecheck %s |
| ''' |
| else: |
| header += ''' |
| ;; RUN: wasm-opt %s -all --optimize-instructions -S -o - | filecheck %s |
| ;; RUN: wasm-opt %s -all --disable-custom-descriptors --optimize-instructions -S -o - | filecheck %s --check-prefix=NO_CD |
| ''' |
| |
| header += ''' |
| (module |
| (type $super (sub (struct))) |
| (type $sub (sub $super (struct))) |
| (type $sub-final (sub final $super (struct)))''' |
| |
| print(header) |
| |
| |
| def print_footer(): |
| print(')') |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser(description=__doc__) |
| parser.add_argument('--enable-custom-descs', action='store_true', dest='enable_descs') |
| args = parser.parse_args() |
| print_header(args) |
| print_tests(args) |
| print_footer() |
| |
| |
| if __name__ == '__main__': |
| main() |