// Copyright (c) 2019, 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 <vector>

#include "vm/closure_functions_cache.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/call_specializer.h"
#include "vm/compiler/compiler_pass.h"
#include "vm/object.h"
#include "vm/unit_test.h"

namespace dart {

#if defined(DART_PRECOMPILER)

// This test asserts that we are inlining accesses to typed data interfaces
// (e.g. Uint8List) if there are no instantiated 3rd party classes.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_Inlining) {
  const char* kScript =
      R"(
      import 'dart:typed_data';

      foo(Uint8List list, int from) {
        if (from >= list.length) {
          return list[from];
        }
      }
      )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "foo"));

  TestPipeline pipeline(function, CompilerPass::kAOT);
  FlowGraph* flow_graph = pipeline.RunPasses({});

  auto entry = flow_graph->graph_entry()->normal_entry();
  EXPECT(entry != nullptr);

  CheckNullInstr* check_null = nullptr;
  LoadFieldInstr* load_field = nullptr;
  GenericCheckBoundInstr* bounds_check = nullptr;
  Instruction* load_untagged = nullptr;
  LoadIndexedInstr* load_indexed = nullptr;

  ILMatcher cursor(flow_graph, entry);
  if (IsolateGroup::Current()->null_safety()) {
    RELEASE_ASSERT(cursor.TryMatch({
        kMoveGlob,
        {kMatchAndMoveLoadField, &load_field},
        kMoveGlob,
        kMatchAndMoveBranchTrue,
        kMoveGlob,
        {kMatchAndMoveGenericCheckBound, &bounds_check},
        {kMatchAndMoveLoadUntagged, &load_untagged},
        kMoveParallelMoves,
        {kMatchAndMoveLoadIndexed, &load_indexed},
        kMoveGlob,
        kMatchReturn,
    }));
  } else {
    RELEASE_ASSERT(cursor.TryMatch({
        kMoveGlob,
        {kMatchAndMoveCheckNull, &check_null},
        {kMatchAndMoveLoadField, &load_field},
        kMoveGlob,
        kMatchAndMoveBranchTrue,
        kMoveGlob,
        {kMatchAndMoveGenericCheckBound, &bounds_check},
        {kMatchAndMoveLoadUntagged, &load_untagged},
        kMoveParallelMoves,
        {kMatchAndMoveLoadIndexed, &load_indexed},
        kMoveGlob,
        kMatchReturn,
    }));
  }

  EXPECT(load_field->InputAt(0)->definition()->IsParameter());
  EXPECT(bounds_check->length()
             ->definition()
             ->OriginalDefinitionIgnoreBoxingAndConstraints() == load_field);
  EXPECT(load_untagged->InputAt(0)->definition()->IsParameter());
  EXPECT(load_indexed->InputAt(0)->definition() == load_untagged);
}

// This test asserts that we are inlining get:length, [] and []= for all typed
// data interfaces.  It also ensures that the asserted IR actually works by
// exercising it.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalGetSet) {
  const char* kTemplate =
      R"(
      import 'dart:typed_data';

      void reverse%s(%s list) {
        final length = list.length;
        final halfLength = length >> 1;
        for (int i = 0; i < halfLength; ++i) {
          final tmp = list[length-i-1];
          list[length-i-1] = list[i];
          list[i] = tmp;
        }
      }
      )";

  char script_buffer[1024];
  char uri_buffer[1024];
  char function_name[1024];
  auto& lib = Library::Handle();
  auto& function = Function::Handle();

  auto check_il = [&](const char* name) {
    // Fill in the template with the [name].
    Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name);
    Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///reverse-%s.dart",
                   name);
    Utils::SNPrint(function_name, sizeof(function_name), "reverse%s", name);

    // Create a new library, load the function and compile it using our AOT
    // pipeline.
    lib = LoadTestScript(script_buffer, nullptr, uri_buffer);
    function = GetFunction(lib, function_name);
    TestPipeline pipeline(function, CompilerPass::kAOT);
    FlowGraph* flow_graph = pipeline.RunPasses({});
    auto entry = flow_graph->graph_entry()->normal_entry();

    // Ensure the IL matches what we expect.
    ILMatcher cursor(flow_graph, entry);
    if (IsolateGroup::Current()->null_safety()) {
      EXPECT(cursor.TryMatch({
          // Before loop
          kMoveGlob,
          kMatchAndMoveLoadField,
          kMoveGlob,
          kMatchAndMoveBranchTrue,

          // Loop
          kMoveGlob,
          // Load 1
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Load 2
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Store 1
          kMatchAndMoveCheckWritable,
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,
          // Store 2
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,

          // Exit the loop.
          kMatchAndMoveBranchFalse,
          kMoveGlob,
          kMatchReturn,
      }));
    } else {
      EXPECT(cursor.TryMatch({
          // Before loop
          kMoveGlob,
          kMatchAndMoveCheckNull,
          kMatchAndMoveLoadField,
          kMoveGlob,
          kMatchAndMoveBranchTrue,

          // Loop
          kMoveGlob,
          // Load 1
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Load 2
          kMatchAndMoveGenericCheckBound,
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveLoadIndexed,
          kMoveGlob,
          // Store 1
          kMatchAndMoveCheckWritable,
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,
          // Store 2
          kMoveParallelMoves,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,
          kMoveGlob,

          // Exit the loop.
          kMatchAndMoveBranchFalse,
          kMoveGlob,
          kMatchReturn,
      }));
    }
  };

  check_il("Uint8List");
  check_il("Int8List");
  check_il("Uint8ClampedList");
  check_il("Int16List");
  check_il("Uint16List");
  check_il("Int32List");
  check_il("Uint32List");
  check_il("Int64List");
  check_il("Uint64List");
  check_il("Float32List");
  check_il("Float64List");
}

// This test asserts that we get errors if receiver, index or value are null.
ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalIndexError) {
  const char* kTemplate =
      R"(
      import 'dart:typed_data';
      void set%s(%s list, int index, %s value) {
        list[index] = value;
      }
      )";

  char script_buffer[1024];
  char uri_buffer[1024];
  char function_name[1024];
  auto& lib = Library::Handle();
  auto& function = Function::Handle();
  auto& arguments = Array::Handle();
  auto& result = Object::Handle();

  const intptr_t kIndex = 1;
  const intptr_t kLastStage = 3;

  auto run_test = [&](const char* name, const char* type,
                      const TypedDataBase& data, const Object& value,
                      int stage) {
    // Fill in the template with the [name].
    Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name,
                   type);
    Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///set-%s.dart", name);
    Utils::SNPrint(function_name, sizeof(function_name), "set%s", name);

    // Create a new library, load the function and compile it using our AOT
    // pipeline.
    lib = LoadTestScript(script_buffer, nullptr, uri_buffer);
    function = GetFunction(lib, function_name);
    TestPipeline pipeline(function, CompilerPass::kAOT);
    FlowGraph* flow_graph = pipeline.RunPasses({});
    auto entry = flow_graph->graph_entry()->normal_entry();

    // Ensure the IL matches what we expect.
    ILMatcher cursor(flow_graph, entry, /*trace=*/true);
    if (IsolateGroup::Current()->null_safety()) {
      EXPECT(cursor.TryMatch({
          // LoadField length
          kMoveGlob,
          kMatchAndMoveLoadField,

          // Bounds check
          kMoveGlob,
          kMatchAndMoveGenericCheckBound,

          // Store value.
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveOptionalUnbox,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,

          // Return
          kMoveGlob,
          kMatchReturn,
      }));
    } else {
      EXPECT(cursor.TryMatch({
          // Receiver null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // Index null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // Value null check
          kMoveGlob,
          kMatchAndMoveCheckNull,

          // LoadField length
          kMoveGlob,
          kMatchAndMoveLoadField,

          // Bounds check
          kMoveGlob,
          kMatchAndMoveGenericCheckBound,

          // Store value.
          kMoveGlob,
          kMatchAndMoveLoadUntagged,
          kMoveParallelMoves,
          kMatchAndMoveOptionalUnbox,
          kMoveParallelMoves,
          kMatchAndMoveStoreIndexed,

          // Return
          kMoveGlob,
          kMatchReturn,
      }));
    }

    // Compile the graph and attach the code.
    pipeline.CompileGraphAndAttachFunction();

    arguments = Array::New(3);
    arguments.SetAt(0, stage == 0 ? Object::null_object() : data);
    arguments.SetAt(
        1, stage == 1 ? Object::null_object() : Smi::Handle(Smi::New(kIndex)));
    arguments.SetAt(2, stage == 2 ? Object::null_object() : value);
    result = DartEntry::InvokeFunction(function, arguments);

    // Ensure we didn't deoptimize to unoptimized code.
    EXPECT(function.unoptimized_code() == Code::null());

    if (stage == kLastStage) {
      // The last stage must be successful
      EXPECT(result.IsNull());
    } else {
      // Ensure we get an error.
      EXPECT(result.IsUnhandledException());
      result = UnhandledException::Cast(result).exception();
    }
  };

  const auto& uint8_list =
      TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, 16));
  const auto& uint8c_list =
      TypedData::Handle(TypedData::New(kTypedDataUint8ClampedArrayCid, 16));
  const auto& int16_list =
      TypedData::Handle(TypedData::New(kTypedDataInt16ArrayCid, 16));
  const auto& uint16_list =
      TypedData::Handle(TypedData::New(kTypedDataUint16ArrayCid, 16));
  const auto& int32_list =
      TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 16));
  const auto& uint32_list =
      TypedData::Handle(TypedData::New(kTypedDataUint32ArrayCid, 16));
  const auto& int64_list =
      TypedData::Handle(TypedData::New(kTypedDataInt64ArrayCid, 16));
  const auto& uint64_list =
      TypedData::Handle(TypedData::New(kTypedDataUint64ArrayCid, 16));
  const auto& float32_list =
      TypedData::Handle(TypedData::New(kTypedDataFloat32ArrayCid, 16));
  const auto& float64_list =
      TypedData::Handle(TypedData::New(kTypedDataFloat64ArrayCid, 16));
  const auto& int8_list =
      TypedData::Handle(TypedData::New(kTypedDataInt8ArrayCid, 16));
  const auto& int_value = Integer::Handle(Integer::New(42));
  const auto& float_value = Double::Handle(Double::New(4.2));
  // With null safety nulls cannot be passed as non-nullable arguments, so
  // skip all error stages and only run the last stage.
  const intptr_t first_stage =
      IsolateGroup::Current()->null_safety() ? kLastStage : 0;
  for (intptr_t stage = first_stage; stage <= kLastStage; ++stage) {
    run_test("Uint8List", "int", int8_list, int_value, stage);
    run_test("Int8List", "int", uint8_list, int_value, stage);
    run_test("Uint8ClampedList", "int", uint8c_list, int_value, stage);
    run_test("Int16List", "int", int16_list, int_value, stage);
    run_test("Uint16List", "int", uint16_list, int_value, stage);
    run_test("Int32List", "int", int32_list, int_value, stage);
    run_test("Uint32List", "int", uint32_list, int_value, stage);
    run_test("Int64List", "int", int64_list, int_value, stage);
    run_test("Uint64List", "int", uint64_list, int_value, stage);
    run_test("Float32List", "double", float32_list, float_value, stage);
    run_test("Float64List", "double", float64_list, float_value, stage);
  }
}

#endif  // defined(DART_PRECOMPILER)

}  // namespace dart
