tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testWasmRefSubtypes.cpp (8995B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "jsapi-tests/tests.h"
      6 
      7 #include "wasm/WasmValType.h"
      8 
      9 BEGIN_TEST(testWasmRefType_LUB) {
     10  using namespace js;
     11  using namespace wasm;
     12 
     13  struct TestCase {
     14    RefType a;
     15    RefType b;
     16    RefType lub;
     17  };
     18 
     19  // For the any hierarchy:
     20  //
     21  // s1     a1
     22  // │ └┐
     23  // s2 s3
     24 
     25  MutableTypeContext types = new TypeContext();
     26  MutableRecGroup recGroup = types->startRecGroup(4);
     27 
     28  TypeDef* tA1 = &recGroup->type(0);
     29  *tA1 = ArrayType(StorageType::I16, true);
     30 
     31  TypeDef* tS1 = &recGroup->type(1);
     32  *tS1 = StructType();
     33 
     34  TypeDef* tS2 = &recGroup->type(2);
     35  FieldTypeVector s2Fields;
     36  CHECK(s2Fields.append(FieldType(StorageType::I32, false)));
     37  *tS2 = StructType(std::move(s2Fields));
     38  tS2->setSuperTypeDef(tS1);
     39 
     40  TypeDef* tS3 = &recGroup->type(3);
     41  FieldTypeVector s3Fields;
     42  CHECK(s3Fields.append(FieldType(StorageType::I64, false)));
     43  *tS3 = StructType(std::move(s3Fields));
     44  tS3->setSuperTypeDef(tS1);
     45 
     46  CHECK(types->endRecGroup());
     47 
     48  RefType a1 = RefType::fromTypeDef(tA1, true);
     49  RefType s1 = RefType::fromTypeDef(tS1, true);
     50  RefType s2 = RefType::fromTypeDef(tS2, true);
     51  RefType s3 = RefType::fromTypeDef(tS3, true);
     52 
     53  TestCase testCases[] = {
     54      //
     55      // Tops and bottoms
     56      //
     57 
     58      // any, any -> any
     59      {RefType::any(), RefType::any(), RefType::any()},
     60      {RefType::any().asNonNullable(), RefType::any(), RefType::any()},
     61      {RefType::any().asNonNullable(), RefType::any().asNonNullable(),
     62       RefType::any().asNonNullable()},
     63 
     64      // none, none -> none
     65      {RefType::none(), RefType::none(), RefType::none()},
     66      {RefType::none().asNonNullable(), RefType::none(), RefType::none()},
     67      {RefType::none().asNonNullable(), RefType::none().asNonNullable(),
     68       RefType::none().asNonNullable()},
     69 
     70      // none, any -> any
     71      {RefType::none(), RefType::any(), RefType::any()},
     72      {RefType::none().asNonNullable(), RefType::any(), RefType::any()},
     73      {RefType::none(), RefType::any().asNonNullable(), RefType::any()},
     74      {RefType::none().asNonNullable(), RefType::any().asNonNullable(),
     75       RefType::any().asNonNullable()},
     76 
     77      // func, func -> func
     78      {RefType::func(), RefType::func(), RefType::func()},
     79      {RefType::func().asNonNullable(), RefType::func(), RefType::func()},
     80      {RefType::func().asNonNullable(), RefType::func().asNonNullable(),
     81       RefType::func().asNonNullable()},
     82 
     83      // nofunc, nofunc -> nofunc
     84      {RefType::nofunc(), RefType::nofunc(), RefType::nofunc()},
     85      {RefType::nofunc().asNonNullable(), RefType::nofunc(), RefType::nofunc()},
     86      {RefType::nofunc().asNonNullable(), RefType::nofunc().asNonNullable(),
     87       RefType::nofunc().asNonNullable()},
     88 
     89      // nofunc, func -> func
     90      {RefType::nofunc(), RefType::func(), RefType::func()},
     91      {RefType::nofunc().asNonNullable(), RefType::func(), RefType::func()},
     92      {RefType::nofunc(), RefType::func().asNonNullable(), RefType::func()},
     93      {RefType::nofunc().asNonNullable(), RefType::func().asNonNullable(),
     94       RefType::func().asNonNullable()},
     95 
     96      // extern, extern -> extern
     97      {RefType::extern_(), RefType::extern_(), RefType::extern_()},
     98      {RefType::extern_().asNonNullable(), RefType::extern_(),
     99       RefType::extern_()},
    100      {RefType::extern_().asNonNullable(), RefType::extern_().asNonNullable(),
    101       RefType::extern_().asNonNullable()},
    102 
    103      // noextern, noextern -> noextern
    104      {RefType::noextern(), RefType::noextern(), RefType::noextern()},
    105      {RefType::noextern().asNonNullable(), RefType::noextern(),
    106       RefType::noextern()},
    107      {RefType::noextern().asNonNullable(), RefType::noextern().asNonNullable(),
    108       RefType::noextern().asNonNullable()},
    109 
    110      // noextern, extern -> extern
    111      {RefType::noextern(), RefType::extern_(), RefType::extern_()},
    112      {RefType::noextern().asNonNullable(), RefType::extern_(),
    113       RefType::extern_()},
    114      {RefType::noextern(), RefType::extern_().asNonNullable(),
    115       RefType::extern_()},
    116      {RefType::noextern().asNonNullable(), RefType::extern_().asNonNullable(),
    117       RefType::extern_().asNonNullable()},
    118 
    119      // exn, exn -> exn
    120      {RefType::exn(), RefType::exn(), RefType::exn()},
    121      {RefType::exn().asNonNullable(), RefType::exn(), RefType::exn()},
    122      {RefType::exn().asNonNullable(), RefType::exn().asNonNullable(),
    123       RefType::exn().asNonNullable()},
    124 
    125      // noexn, noexn -> noexn
    126      {RefType::noexn(), RefType::noexn(), RefType::noexn()},
    127      {RefType::noexn().asNonNullable(), RefType::noexn(), RefType::noexn()},
    128      {RefType::noexn().asNonNullable(), RefType::noexn().asNonNullable(),
    129       RefType::noexn().asNonNullable()},
    130 
    131      // noexn, exn -> exn
    132      {RefType::noexn(), RefType::exn(), RefType::exn()},
    133      {RefType::noexn().asNonNullable(), RefType::exn(), RefType::exn()},
    134      {RefType::noexn(), RefType::exn().asNonNullable(), RefType::exn()},
    135      {RefType::noexn().asNonNullable(), RefType::exn().asNonNullable(),
    136       RefType::exn().asNonNullable()},
    137 
    138      //
    139      // concrete type, abstract types
    140      //
    141 
    142      // $a1, $a1 -> array
    143      {a1, a1, a1},
    144      {a1.asNonNullable(), a1, a1},
    145      {a1.asNonNullable(), a1.asNonNullable(), a1.asNonNullable()},
    146 
    147      // $a1, any -> any
    148      {a1, RefType::any(), RefType::any()},
    149      {a1, RefType::any().asNonNullable(), RefType::any()},
    150      {a1.asNonNullable(), RefType::any(), RefType::any()},
    151      {a1.asNonNullable(), RefType::any().asNonNullable(),
    152       RefType::any().asNonNullable()},
    153 
    154      // $a1, eq -> eq
    155      {a1, RefType::eq(), RefType::eq()},
    156      {a1.asNonNullable(), RefType::eq(), RefType::eq()},
    157      {a1, RefType::eq().asNonNullable(), RefType::eq()},
    158      {a1.asNonNullable(), RefType::eq().asNonNullable(),
    159       RefType::eq().asNonNullable()},
    160 
    161      // $a1, i31 -> eq
    162      {a1, RefType::i31(), RefType::eq()},
    163      {a1.asNonNullable(), RefType::i31(), RefType::eq()},
    164      {a1, RefType::i31().asNonNullable(), RefType::eq()},
    165      {a1.asNonNullable(), RefType::i31().asNonNullable(),
    166       RefType::eq().asNonNullable()},
    167 
    168      // $a1, struct -> eq
    169      {a1, RefType::struct_(), RefType::eq()},
    170      {a1.asNonNullable(), RefType::struct_(), RefType::eq()},
    171      {a1, RefType::struct_().asNonNullable(), RefType::eq()},
    172      {a1.asNonNullable(), RefType::struct_().asNonNullable(),
    173       RefType::eq().asNonNullable()},
    174 
    175      // $a1, array -> array
    176      {a1, RefType::array(), RefType::array()},
    177      {a1.asNonNullable(), RefType::array(), RefType::array()},
    178      {a1, RefType::array().asNonNullable(), RefType::array()},
    179      {a1.asNonNullable(), RefType::array().asNonNullable(),
    180       RefType::array().asNonNullable()},
    181 
    182      // $a1, none -> $a1
    183      {a1, RefType::none(), a1},
    184      {a1, RefType::none().asNonNullable(), a1},
    185      {a1.asNonNullable(), RefType::none(), a1},
    186      {a1.asNonNullable(), RefType::none().asNonNullable(), a1.asNonNullable()},
    187 
    188      //
    189      // concrete subtypes
    190      //
    191 
    192      // $s1, $s2 -> $s1
    193      {s1, s2, s1},
    194      {s1.asNonNullable(), s2, s1},
    195      {s1, s2.asNonNullable(), s1},
    196      {s1.asNonNullable(), s2.asNonNullable(), s1.asNonNullable()},
    197 
    198      //
    199      // concrete sibling types
    200      //
    201 
    202      // $s2, $s3 -> $s1
    203      {s2, s3, s1},
    204      {s2.asNonNullable(), s3, s1},
    205      {s2, s3.asNonNullable(), s1},
    206      {s2.asNonNullable(), s3.asNonNullable(), s1.asNonNullable()},
    207 
    208      //
    209      // unrelated concrete types
    210      //
    211 
    212      // $s1, $a1 -> eq
    213      {s1, a1, RefType::eq()},
    214      {s1.asNonNullable(), a1, RefType::eq()},
    215      {s1, a1.asNonNullable(), RefType::eq()},
    216      {s1.asNonNullable(), a1.asNonNullable(), RefType::eq().asNonNullable()},
    217  };
    218 
    219 #define CHECK_LUB(a, b, expected)                                          \
    220  do {                                                                     \
    221    RefType _actual = RefType::leastUpperBound((a), (b));                  \
    222    if (_actual != (expected)) {                                           \
    223      return fail(JSAPITestString("bad LUB of ") +                         \
    224                      wasm::ToString((a), types).get() + " and " +         \
    225                      wasm::ToString((b), types).get() + ": expected " +   \
    226                      wasm::ToString((expected), types).get() + ", got " + \
    227                      wasm::ToString(_actual, types).get(),                \
    228                  __FILE__, __LINE__);                                     \
    229    }                                                                      \
    230  } while (false)
    231 
    232  for (const TestCase& testCase : testCases) {
    233    // LUB is commutative.
    234    CHECK_LUB(testCase.a, testCase.b, testCase.lub);
    235    CHECK_LUB(testCase.b, testCase.a, testCase.lub);
    236  }
    237 
    238  return true;
    239 }
    240 END_TEST(testWasmRefType_LUB)