// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <functional>

#include "platform/assert.h"

#include "vm/class_finalizer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/symbols.h"
#include "vm/type_testing_stubs.h"
#include "vm/type_testing_stubs_test.h"
#include "vm/unit_test.h"

#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_ARM) ||                  \
    defined(TARGET_ARCH_X64)

namespace dart {

static void FinalizeAndCanonicalize(const Class& klass, AbstractType* type) {
  *type = ClassFinalizer::FinalizeType(klass, *type);
  ASSERT(type->IsCanonical());
}

static void CanonicalizeTAV(TypeArguments* tav) {
  *tav = tav->Canonicalize();
}

static void RunTTSTest(
    const Object& instance,
    const AbstractType& dst_type,
    const TypeArguments& instantiator_tav,
    const TypeArguments& function_tav,
    std::function<void(const Object& result, const SubtypeTestCache& stc)> lazy,
    std::function<void(const Object& result,
                       const SubtypeTestCache& stc,
                       const Bool& abi_regs_modified,
                       const Bool& rest_regs_modified)> nonlazy) {
  ASSERT(instantiator_tav.IsNull() || instantiator_tav.IsCanonical());
  ASSERT(function_tav.IsNull() || function_tav.IsCanonical());
  auto thread = Thread::Current();

  // Build a stub which will do calling conversion to call TTS stubs.
  const auto& klass =
      Class::Handle(thread->isolate()->class_table()->At(kInstanceCid));
  const auto& symbol = String::Handle(
      Symbols::New(thread, OS::SCreate(thread->zone(), "TTSTest")));
  const auto& function = Function::Handle(
      Function::New(symbol, FunctionLayout::kRegularFunction, false, false,
                    false, false, false, klass, TokenPosition::kNoSource));
  compiler::ObjectPoolBuilder pool_builder;
  const auto& invoke_tts = Code::Handle(
      StubCode::Generate("InvokeTTS", &pool_builder, &GenerateInvokeTTSStub));
  const auto& pool =
      ObjectPool::Handle(ObjectPool::NewFromBuilder(pool_builder));
  invoke_tts.set_object_pool(pool.raw());
  invoke_tts.set_owner(function);
  invoke_tts.set_exception_handlers(
      ExceptionHandlers::Handle(ExceptionHandlers::New(0)));

  EXPECT(pool.Length() == 2);
  const intptr_t kSubtypeTestCacheIndex = 0;

  const auto& arguments_descriptor =
      Array::Handle(ArgumentsDescriptor::NewBoxed(0, 6));
  const auto& arguments = Array::Handle(Array::New(6));
  const auto& abi_regs_modified_box = Array::Handle(Array::New(1));
  const auto& rest_regs_modified_box = Array::Handle(Array::New(1));
  arguments.SetAt(0, abi_regs_modified_box);
  arguments.SetAt(1, rest_regs_modified_box);
  arguments.SetAt(2, instance);
  arguments.SetAt(3, instantiator_tav);
  arguments.SetAt(4, function_tav);
  arguments.SetAt(5, dst_type);

  // Ensure we have a) uninitialized TTS b) no/empty SubtypeTestCache.
  auto& instantiated_dst_type = AbstractType::Handle(dst_type.raw());
  if (dst_type.IsTypeParameter()) {
    instantiated_dst_type = TypeParameter::Cast(dst_type).GetFromTypeArguments(
        instantiator_tav, function_tav);
  }
  instantiated_dst_type.SetTypeTestingStub(StubCode::LazySpecializeTypeTest());
  EXPECT(instantiated_dst_type.type_test_stub() ==
         StubCode::LazySpecializeTypeTest().raw());
  EXPECT(pool.ObjectAt(kSubtypeTestCacheIndex) == Object::null());

  auto& result = Object::Handle();
  auto& result2 = Object::Handle();
  auto& abi_regs_modified = Bool::Handle();
  auto& rest_regs_modified = Bool::Handle();
  auto& tts = Code::Handle();
  auto& tts2 = Code::Handle();
  auto& stc = SubtypeTestCache::Handle();
  auto& stc2 = SubtypeTestCache::Handle();

  // First invocation will a) specialize the TTS b) may create SubtypeTestCache
  result = DartEntry::InvokeCode(invoke_tts, arguments_descriptor, arguments,
                                 thread);
  stc ^= pool.ObjectAt(kSubtypeTestCacheIndex);
  tts = instantiated_dst_type.type_test_stub();
  if (!result.IsError()) {
    EXPECT(tts.raw() != StubCode::LazySpecializeTypeTest().raw());
  }
  lazy(result, stc);

  // Second invocation will a) keep TTS b) keep optional SubtypeTestCache
  result2 = DartEntry::InvokeCode(invoke_tts, arguments_descriptor, arguments,
                                  thread);
  stc2 ^= pool.ObjectAt(kSubtypeTestCacheIndex);
  tts2 = instantiated_dst_type.type_test_stub();
  abi_regs_modified ^= abi_regs_modified_box.At(0);
  rest_regs_modified ^= rest_regs_modified_box.At(0);
  EXPECT(result2.IsError() || !abi_regs_modified.IsNull());
  EXPECT(tts2.raw() == tts.raw());
  EXPECT(stc2.raw() == stc.raw());
  nonlazy(result2, stc2, abi_regs_modified, rest_regs_modified);

  // Third invocation will a) explicitly install TTS beforehand b) keep optional
  // SubtypeTestCache
  // (This is to simulate AOT where we don't use lazy specialization but
  // precompile the TTS)
  TypeTestingStubGenerator::SpecializeStubFor(thread, instantiated_dst_type);
  tts = instantiated_dst_type.type_test_stub();

  result2 = DartEntry::InvokeCode(invoke_tts, arguments_descriptor, arguments,
                                  thread);
  stc2 ^= pool.ObjectAt(kSubtypeTestCacheIndex);
  tts2 = instantiated_dst_type.type_test_stub();
  abi_regs_modified ^= abi_regs_modified_box.At(0);
  rest_regs_modified ^= rest_regs_modified_box.At(0);
  EXPECT(result2.IsError() || !abi_regs_modified.IsNull());
  EXPECT(tts2.raw() == tts.raw());
  EXPECT(stc2.raw() == stc.raw());
  nonlazy(result2, stc2, abi_regs_modified, rest_regs_modified);
}

static void ExpectLazilyHandledViaTTS(const Object& result,
                                      const SubtypeTestCache& stc) {
  // Ensure the type test succeeded.
  EXPECT(result.IsNull());
  // Ensure we didn't fall back to the subtype test cache.
  EXPECT(stc.IsNull());
}

static void ExpectHandledViaTTS(const Object& result,
                                const SubtypeTestCache& stc,
                                const Bool& abi_regs_modified,
                                const Bool& rest_regs_modified) {
  ExpectLazilyHandledViaTTS(result, stc);
  // Ensure the TTS abi registers were preserved.
  EXPECT(!abi_regs_modified.value());
  // Ensure the non-TTS abi registers were preserved.
  EXPECT(!rest_regs_modified.value());
}

static void ExpectLazilyHandledViaSTC(const Object& result,
                                      const SubtypeTestCache& stc) {
  // Ensure the type test succeeded.
  EXPECT(result.IsNull());
  // Ensure we did fall back to the subtype test cache.
  EXPECT(!stc.IsNull());
  // Ensure the test is marked as succeeding in the STC.
  EXPECT(stc.NumberOfChecks() == 1);
  SubtypeTestCacheTable entries(Array::Handle(stc.cache()));
  EXPECT(entries[0].Get<SubtypeTestCache::kTestResult>() ==
         Object::bool_true().raw());
}

static void ExpectHandledViaSTC(const Object& result,
                                const SubtypeTestCache& stc,
                                const Bool& abi_regs_modified,
                                const Bool& rest_regs_modified) {
  ExpectLazilyHandledViaSTC(result, stc);
  // Ensure the TTS/STC abi registers were preserved.
  EXPECT(!abi_regs_modified.value());
}

static void ExpectLazilyFailedViaTTS(const Object& result,
                                     const SubtypeTestCache& stc) {
  // Ensure we have not updated STC (which we shouldn't do in case the type test
  // fails, i.e. an exception is thrown).
  EXPECT(stc.IsNull());
  // Ensure we get a proper exception for the type test.
  EXPECT(result.IsUnhandledException());
  const auto& error =
      Instance::Handle(UnhandledException::Cast(result).exception());
  EXPECT(strstr(error.ToCString(), "_TypeError"));
}

static void ExpectFailedViaTTS(const Object& result,
                               const SubtypeTestCache& stc,
                               const Bool& abi_regs_modified,
                               const Bool& rest_regs_modified) {
  ExpectLazilyFailedViaTTS(result, stc);
}

static void ExpectLazilyFailedViaSTC(const Object& result,
                                     const SubtypeTestCache& stc) {
  // Ensure we have not updated STC (which we shouldn't do in case the type test
  // fails, i.e. an exception is thrown).
  EXPECT(stc.IsNull());
  // Ensure we get a proper exception for the type test.
  EXPECT(result.IsUnhandledException());
  const auto& error =
      Instance::Handle(UnhandledException::Cast(result).exception());
  EXPECT(strstr(error.ToCString(), "_TypeError"));
}

static void ExpectFailedViaSTC(const Object& result,
                               const SubtypeTestCache& stc,
                               const Bool& abi_regs_modified,
                               const Bool& rest_regs_modified) {
  ExpectLazilyFailedViaSTC(result, stc);
}

const char* kSubtypeRangeCheckScript =
    R"(
      class I<T, U> {}
      class I2 {}

      class Base<T> {}

      class A extends Base<int> {}
      class A1 extends A implements I2 {}
      class A2<T> extends A implements I<int, T> {}

      class B extends Base<String> {}
      class B1 extends B implements I2 {}
      class B2<T> extends B implements I<T, String> {}

      genericFun<A, B>() {}

      createI() => I<int, String>();
      createI2() => I2();
      createBaseInt() => Base<int>();
      createA() => A();
      createA1() => A1();
      createA2() => A2<int>();
      createB() => B();
      createB1() => B1();
      createB2() => B2<int>();
      createBaseIStringDouble() => Base<I<String, double>>();
      createBaseA2Int() => Base<A2<int>>();
      createBaseA2A1() => Base<A2<A1>>();
      createBaseB2Int() => Base<B2<int>>();
)";

ISOLATE_UNIT_TEST_CASE(TTS_SubtypeRangeCheck) {
  const auto& root_library =
      Library::Handle(LoadTestScript(kSubtypeRangeCheckScript));
  const auto& class_a = Class::Handle(GetClass(root_library, "A"));
  const auto& class_base = Class::Handle(GetClass(root_library, "Base"));
  const auto& class_i = Class::Handle(GetClass(root_library, "I"));
  const auto& class_i2 = Class::Handle(GetClass(root_library, "I2"));
  const auto& class_null = Class::Handle(Class::null());

  const auto& obj_i = Object::Handle(Invoke(root_library, "createI"));
  const auto& obj_i2 = Object::Handle(Invoke(root_library, "createI2"));
  const auto& obj_baseint =
      Object::Handle(Invoke(root_library, "createBaseInt"));
  const auto& obj_a = Object::Handle(Invoke(root_library, "createA"));
  const auto& obj_a1 = Object::Handle(Invoke(root_library, "createA1"));
  const auto& obj_a2 = Object::Handle(Invoke(root_library, "createA2"));
  const auto& obj_b = Object::Handle(Invoke(root_library, "createB"));
  const auto& obj_b1 = Object::Handle(Invoke(root_library, "createB1"));
  const auto& obj_b2 = Object::Handle(Invoke(root_library, "createB2"));

  const auto& type_dynamic = Type::Handle(Type::DynamicType());
  auto& type_object = Type::Handle(Type::ObjectType());
  type_object = type_object.ToNullability(Nullability::kNullable, Heap::kNew);

  const auto& tav_null = TypeArguments::Handle(TypeArguments::null());

  auto& tav_object = TypeArguments::Handle(TypeArguments::New(1));
  tav_object.SetTypeAt(0, type_object);
  CanonicalizeTAV(&tav_object);

  auto& tav_object_dynamic = TypeArguments::Handle(TypeArguments::New(2));
  tav_object_dynamic.SetTypeAt(0, type_object);
  tav_object_dynamic.SetTypeAt(1, type_dynamic);
  CanonicalizeTAV(&tav_object_dynamic);

  auto& tav_dynamic_t = TypeArguments::Handle(TypeArguments::New(2));
  tav_dynamic_t.SetTypeAt(0, type_dynamic);
  tav_dynamic_t.SetTypeAt(
      1, TypeParameter::Handle(GetClassTypeParameter(class_base, "T")));
  CanonicalizeTAV(&tav_dynamic_t);

  // We will generate specialized TTS for instantiated interface types
  // where there are no type arguments or the type arguments are top
  // types.
  //
  //   obj as A                  // Subclass ranges
  //   obj as Base<Object>       // Subclass ranges with top-type tav
  //   obj as I2                 // Subtype ranges
  //   obj as I<Object, dynamic> // Subtype ranges with top-type tav
  //

  // <...> as A
  const auto& type_a = AbstractType::Handle(class_a.RareType());
  RunTTSTest(obj_i, type_a, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_i2, type_a, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_baseint, type_a, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_a, type_a, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_a1, type_a, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_a2, type_a, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_b, type_a, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_b1, type_a, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_b2, type_a, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);

  // <...> as Base<Object>
  auto& type_base = AbstractType::Handle(
      Type::New(class_base, tav_object, TokenPosition::kNoSource));
  FinalizeAndCanonicalize(class_null, &type_base);
  RunTTSTest(obj_i, type_base, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_i2, type_base, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_baseint, type_base, tav_null, tav_null,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(obj_a, type_base, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_a1, type_base, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_a2, type_base, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_b, type_base, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_b1, type_base, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_b2, type_base, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);

  // <...> as I2
  const auto& type_i2 = AbstractType::Handle(class_i2.RareType());
  RunTTSTest(obj_i, type_i2, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_i2, type_i2, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_baseint, type_i2, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_a, type_i2, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_a1, type_i2, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_a2, type_i2, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_b, type_i2, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
  RunTTSTest(obj_b1, type_i2, tav_null, tav_null, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);
  RunTTSTest(obj_b2, type_i2, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);

  // <...> as I<Object, dynamic>
  auto& type_i_object_dynamic = AbstractType::Handle(
      Type::New(class_i, tav_object_dynamic, TokenPosition::kNoSource));
  FinalizeAndCanonicalize(class_null, &type_i_object_dynamic);
  RunTTSTest(obj_i, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(obj_i2, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_baseint, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_a, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_a1, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_a2, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(obj_b, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_b1, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_b2, type_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);

  // We do not generate TTS for uninstantiated types if we would need to use
  // subtype range checks for the class of the interface type.
  //
  //   obj as I<dynamic, T>
  //
  auto& type_dynamic_t = AbstractType::Handle(
      Type::New(class_i, tav_dynamic_t, TokenPosition::kNoSource));
  FinalizeAndCanonicalize(class_base, &type_dynamic_t);
  RunTTSTest(obj_i, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyHandledViaSTC, ExpectHandledViaSTC);
  RunTTSTest(obj_i2, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);
  RunTTSTest(obj_baseint, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);
  RunTTSTest(obj_a, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);
  RunTTSTest(obj_a1, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);
  RunTTSTest(obj_a2, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyHandledViaSTC, ExpectHandledViaSTC);
  RunTTSTest(obj_b, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);
  RunTTSTest(obj_b1, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);
  RunTTSTest(obj_b2, type_dynamic_t, tav_object, tav_null,
             ExpectLazilyHandledViaSTC, ExpectHandledViaSTC);

  // obj as Object (with null safety)
  Isolate* isolate = Isolate::Current();
  if (isolate->null_safety()) {
    auto& type_non_nullable_object =
        Type::Handle(isolate->object_store()->non_nullable_object_type());
    RunTTSTest(obj_a, type_non_nullable_object, tav_null, tav_null,
               ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
    RunTTSTest(Object::null_object(), type_non_nullable_object, tav_null,
               tav_null, ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  }
}

ISOLATE_UNIT_TEST_CASE(TTS_GenericSubtypeRangeCheck) {
  const auto& root_library =
      Library::Handle(LoadTestScript(kSubtypeRangeCheckScript));
  const auto& class_a1 = Class::Handle(GetClass(root_library, "A1"));
  const auto& class_a2 = Class::Handle(GetClass(root_library, "A2"));
  const auto& class_base = Class::Handle(GetClass(root_library, "Base"));
  const auto& class_i = Class::Handle(GetClass(root_library, "I"));
  const auto& fun_generic =
      Function::Handle(GetFunction(root_library, "genericFun"));
  const auto& class_null = Class::Handle(Class::null());

  const auto& obj_i = Object::Handle(Invoke(root_library, "createI"));
  const auto& obj_i2 = Object::Handle(Invoke(root_library, "createI2"));
  const auto& obj_baseint =
      Object::Handle(Invoke(root_library, "createBaseInt"));
  const auto& obj_a = Object::Handle(Invoke(root_library, "createA"));
  const auto& obj_a1 = Object::Handle(Invoke(root_library, "createA1"));
  const auto& obj_a2 = Object::Handle(Invoke(root_library, "createA2"));
  const auto& obj_b = Object::Handle(Invoke(root_library, "createB"));
  const auto& obj_b1 = Object::Handle(Invoke(root_library, "createB1"));
  const auto& obj_b2 = Object::Handle(Invoke(root_library, "createB2"));
  const auto& obj_basea2int =
      Object::Handle(Invoke(root_library, "createBaseA2Int"));
  const auto& obj_basea2a1 =
      Object::Handle(Invoke(root_library, "createBaseA2A1"));
  const auto& obj_baseb2int =
      Object::Handle(Invoke(root_library, "createBaseB2Int"));
  const auto& obj_baseistringdouble =
      Object::Handle(Invoke(root_library, "createBaseIStringDouble"));

  const auto& type_dynamic = Type::Handle(Type::DynamicType());
  auto& type_int = Type::Handle(Type::IntType());
  if (!TestCase::IsNNBD()) {
    type_int = type_int.ToNullability(Nullability::kLegacy, Heap::kNew);
  }
  auto& type_string = Type::Handle(Type::StringType());
  if (!TestCase::IsNNBD()) {
    type_string = type_string.ToNullability(Nullability::kLegacy, Heap::kNew);
  }
  auto& type_object = Type::Handle(Type::ObjectType());
  type_object = type_object.ToNullability(
      TestCase::IsNNBD() ? Nullability::kNullable : Nullability::kLegacy,
      Heap::kNew);
  auto& type_a1 = Type::Handle(class_a1.DeclarationType());
  if (!TestCase::IsNNBD()) {
    type_a1 = type_a1.ToNullability(Nullability::kLegacy, Heap::kNew);
  }
  FinalizeAndCanonicalize(class_null, &type_a1);

  const auto& tav_null = TypeArguments::Handle(TypeArguments::null());

  auto& tav_object_dynamic = TypeArguments::Handle(TypeArguments::New(2));
  tav_object_dynamic.SetTypeAt(0, type_object);
  tav_object_dynamic.SetTypeAt(1, type_dynamic);
  CanonicalizeTAV(&tav_object_dynamic);

  auto& tav_dynamic_int = TypeArguments::Handle(TypeArguments::New(2));
  tav_dynamic_int.SetTypeAt(0, type_dynamic);
  tav_dynamic_int.SetTypeAt(1, type_int);
  CanonicalizeTAV(&tav_dynamic_int);

  auto& tav_dynamic_string = TypeArguments::Handle(TypeArguments::New(2));
  tav_dynamic_string.SetTypeAt(0, type_dynamic);
  tav_dynamic_string.SetTypeAt(1, type_string);
  CanonicalizeTAV(&tav_dynamic_string);

  auto& tav_int = TypeArguments::Handle(TypeArguments::New(1));
  tav_int.SetTypeAt(0, type_int);
  CanonicalizeTAV(&tav_int);

  auto& type_i_object_dynamic = AbstractType::Handle(
      Type::New(class_i, tav_object_dynamic, TokenPosition::kNoSource));
  FinalizeAndCanonicalize(class_null, &type_i_object_dynamic);
  const auto& tav_iod = TypeArguments::Handle(TypeArguments::New(1));
  tav_iod.SetTypeAt(0, type_i_object_dynamic);

  // We will generate specialized TTS for instantiated interface types
  // where there are no type arguments or the type arguments are top
  // types.
  //
  //   obj as Base<I<Object, dynamic>>   // Subclass ranges for Base, subtype
  //                                     // ranges tav arguments.
  //   obj as Base<T>                    // Subclass ranges for Base, type
  //                                     // equality for instantiator type arg T
  //   obj as Base<B>                    // Subclass ranges for Base, type
  //                                     // equality for function type arg B.
  //

  // <...> as Base<I<Object, dynamic>>
  auto& type_base_i_object_dynamic = AbstractType::Handle(
      Type::New(class_base, tav_iod, TokenPosition::kNoSource));
  FinalizeAndCanonicalize(class_null, &type_base_i_object_dynamic);
  RunTTSTest(obj_baseb2int, type_base_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(obj_baseistringdouble, type_base_i_object_dynamic, tav_null,
             tav_null, ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(obj_a, type_base_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_a1, type_base_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_a2, type_base_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_b, type_base_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_b1, type_base_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  RunTTSTest(obj_b2, type_base_i_object_dynamic, tav_null, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);

  // <...> as Base<T>  with T instantiantiator type parameter (T == int)
  const auto& tav_baset = TypeArguments::Handle(TypeArguments::New(1));
  tav_baset.SetTypeAt(
      0, TypeParameter::Handle(GetClassTypeParameter(class_base, "T")));
  auto& type_base_t = AbstractType::Handle(
      Type::New(class_base, tav_baset, TokenPosition::kNoSource));
  FinalizeAndCanonicalize(class_base, &type_base_t);
  RunTTSTest(obj_baseint, type_base_t, tav_int, tav_null,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(obj_baseistringdouble, type_base_t, tav_int, tav_null,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);

  // <...> as Base<B>  with B function type parameter
  const auto& tav_baseb = TypeArguments::Handle(TypeArguments::New(1));
  tav_baseb.SetTypeAt(
      0, TypeParameter::Handle(GetFunctionTypeParameter(fun_generic, "B")));
  auto& type_base_b = AbstractType::Handle(
      Type::New(class_base, tav_baseb, TokenPosition::kNoSource));
  FinalizeAndCanonicalize(class_null, &type_base_b);
  // With B == int
  RunTTSTest(obj_baseint, type_base_b, tav_null, tav_dynamic_int,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(obj_baseistringdouble, type_base_b, tav_null, tav_dynamic_int,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
  // With B == dynamic (null vector)
  RunTTSTest(obj_baseint, type_base_b, tav_null, tav_null,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(obj_i2, type_base_b, tav_null, tav_null, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);

  // We do not generate TTS for uninstantiated types if we would need to use
  // subtype range checks for the class of the interface type.
  //
  //   obj as I<dynamic, String>       // I is generic & implemented.
  //   obj as Base<A2<T>>              // A2<T> is not instantiated.
  //   obj as Base<A2<A1>>             // A2<A1> is not a rare type.
  //

  //   <...> as I<dynamic, String>
  RELEASE_ASSERT(class_i.is_implemented());
  auto& type_i_dynamic_string = Type::Handle(
      Type::New(class_i, tav_dynamic_string, TokenPosition::kNoSource));
  type_i_dynamic_string = type_i_dynamic_string.ToNullability(
      Nullability::kNonNullable, Heap::kNew);
  FinalizeAndCanonicalize(class_null, &type_i_dynamic_string);
  RunTTSTest(obj_i, type_i_dynamic_string, tav_null, tav_null,
             ExpectLazilyHandledViaSTC, ExpectHandledViaSTC);
  RunTTSTest(obj_baseint, type_i_dynamic_string, tav_null, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);

  //   <...> as Base<A2<T>>
  const auto& tav_t = TypeArguments::Handle(TypeArguments::New(1));
  tav_t.SetTypeAt(
      0, TypeParameter::Handle(GetClassTypeParameter(class_base, "T")));
  auto& type_a2_t =
      Type::Handle(Type::New(class_a2, tav_t, TokenPosition::kNoSource));
  type_a2_t = type_a2_t.ToNullability(Nullability::kLegacy, Heap::kNew);
  FinalizeAndCanonicalize(class_null, &type_a2_t);
  const auto& tav_a2_t = TypeArguments::Handle(TypeArguments::New(1));
  tav_a2_t.SetTypeAt(0, type_a2_t);
  auto& type_base_a2_t =
      Type::Handle(Type::New(class_base, tav_a2_t, TokenPosition::kNoSource));
  type_base_a2_t =
      type_base_a2_t.ToNullability(Nullability::kNonNullable, Heap::kNew);
  FinalizeAndCanonicalize(class_null, &type_base_a2_t);
  RunTTSTest(obj_basea2int, type_base_a2_t, tav_null, tav_null,
             ExpectLazilyHandledViaSTC, ExpectHandledViaSTC);
  RunTTSTest(obj_baseint, type_base_a2_t, tav_null, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);

  //   <...> as Base<A2<A1>>
  const auto& tav_a1 = TypeArguments::Handle(TypeArguments::New(1));
  tav_a1.SetTypeAt(0, type_a1);
  auto& type_a2_a1 =
      Type::Handle(Type::New(class_a2, tav_a1, TokenPosition::kNoSource));
  type_a2_a1 = type_a2_a1.ToNullability(Nullability::kLegacy, Heap::kNew);
  FinalizeAndCanonicalize(class_null, &type_a2_a1);
  const auto& tav_a2_a1 = TypeArguments::Handle(TypeArguments::New(1));
  tav_a2_a1.SetTypeAt(0, type_a2_a1);
  auto& type_base_a2_a1 =
      Type::Handle(Type::New(class_base, tav_a2_a1, TokenPosition::kNoSource));
  type_base_a2_a1 =
      type_base_a2_a1.ToNullability(Nullability::kNonNullable, Heap::kNew);
  FinalizeAndCanonicalize(class_null, &type_base_a2_a1);
  RunTTSTest(obj_basea2a1, type_base_a2_a1, tav_null, tav_null,
             ExpectLazilyHandledViaSTC, ExpectHandledViaSTC);
  RunTTSTest(obj_basea2int, type_base_a2_a1, tav_null, tav_null,
             ExpectLazilyFailedViaSTC, ExpectFailedViaSTC);
}

ISOLATE_UNIT_TEST_CASE(TTS_Regress40964) {
  const char* kScript =
      R"(
          class A<T> {
            test(x) => x as B<T>;
          }
          class B<T> {}
          class C<T> {}

          createACint() => A<C<int>>();
          createBCint() => B<C<int>>();
          createBCnum() => B<C<num>>();
  )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& class_b = Class::Handle(GetClass(root_library, "B"));
  const auto& class_null = Class::Handle(Class::null());

  const auto& acint = Object::Handle(Invoke(root_library, "createACint"));
  const auto& bcint = Object::Handle(Invoke(root_library, "createBCint"));
  const auto& bcnum = Object::Handle(Invoke(root_library, "createBCnum"));

  // dst_type = B<T>
  const auto& dst_tav = TypeArguments::Handle(TypeArguments::New(1));
  dst_tav.SetTypeAt(0,
                    TypeParameter::Handle(GetClassTypeParameter(class_b, "T")));
  auto& dst_type =
      Type::Handle(Type::New(class_b, dst_tav, TokenPosition::kNoSource));
  FinalizeAndCanonicalize(class_null, &dst_type);
  const auto& cint_tav =
      TypeArguments::Handle(Instance::Cast(acint).GetTypeArguments());
  const auto& function_tav = TypeArguments::Handle();

  // a as B<T> -- a==B<C<int>, T==<C<int>>
  RunTTSTest(bcint, dst_type, cint_tav, function_tav, ExpectLazilyHandledViaTTS,
             ExpectHandledViaTTS);

  // a as B<T> -- a==B<C<num>, T==<C<int>>
  RunTTSTest(bcnum, dst_type, cint_tav, function_tav, ExpectLazilyFailedViaTTS,
             ExpectFailedViaTTS);
}

ISOLATE_UNIT_TEST_CASE(TTS_TypeParameter) {
  const char* kScript =
      R"(
          class A<T> {
            T test(dynamic x) => x as T;
          }
          H genericFun<H>(dynamic x) => x as H;

          createAInt() => A<int>();
          createAString() => A<String>();
  )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& class_a = Class::Handle(GetClass(root_library, "A"));
  const auto& fun_generic =
      Function::Handle(GetFunction(root_library, "genericFun"));

  const auto& dst_type_t =
      TypeParameter::Handle(GetClassTypeParameter(class_a, "T"));
  const auto& dst_type_h =
      TypeParameter::Handle(GetFunctionTypeParameter(fun_generic, "H"));

  const auto& aint = Object::Handle(Invoke(root_library, "createAInt"));
  const auto& astring = Object::Handle(Invoke(root_library, "createAString"));

  const auto& int_tav =
      TypeArguments::Handle(Instance::Cast(aint).GetTypeArguments());
  const auto& string_tav =
      TypeArguments::Handle(Instance::Cast(astring).GetTypeArguments());

  const auto& int_instance = Integer::Handle(Integer::New(1));
  const auto& string_instance = String::Handle(String::New("foo"));

  RunTTSTest(int_instance, dst_type_t, int_tav, string_tav,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(string_instance, dst_type_t, int_tav, string_tav,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);

  RunTTSTest(string_instance, dst_type_h, int_tav, string_tav,
             ExpectLazilyHandledViaTTS, ExpectHandledViaTTS);
  RunTTSTest(int_instance, dst_type_h, int_tav, string_tav,
             ExpectLazilyFailedViaTTS, ExpectFailedViaTTS);
}

}  // namespace dart

#endif  // defined(TARGET_ARCH_ARM64) ||  defined(TARGET_ARCH_ARM) ||          \
        // defined(TARGET_ARCH_X64)
