// 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 "vm/compiler/ffi/unit_test.h"

#include "platform/syslog.h"
#include "vm/compiler/ffi/native_type.h"
#include "vm/compiler/runtime_api.h"

namespace dart {
namespace compiler {
namespace ffi {

const NativeCompoundType& RunStructTest(dart::Zone* zone,
                                        const char* name,
                                        const NativeTypes& member_types) {
  const auto& struct_type =
      NativeCompoundType::FromNativeTypes(zone, member_types);

  const char* test_result = struct_type.ToCString(zone, /*multi_line=*/true);

  const int kFilePathLength = 100;
  char expectation_file_path[kFilePathLength];
  Utils::SNPrint(expectation_file_path, kFilePathLength,
                 "runtime/vm/compiler/ffi/unit_tests/%s/%s_%s.expect", name,
                 kArch, kOs);

  if (TestCaseBase::update_expectations) {
    Syslog::Print("Updating %s\n", expectation_file_path);
    WriteToFile(expectation_file_path, test_result);
  }

  char* expectation_file_contents = nullptr;
  ReadFromFile(expectation_file_path, &expectation_file_contents);
  EXPECT_NOTNULL(expectation_file_contents);
  if (expectation_file_contents != nullptr) {
    EXPECT_STREQ(expectation_file_contents, test_result);
    free(expectation_file_contents);
  }

  return struct_type;
}

UNIT_TEST_CASE_WITH_ZONE(NativeType) {
  const auto& native_type = *new (Z) NativePrimitiveType(kInt8);

  EXPECT_EQ(1, native_type.SizeInBytes());
  EXPECT(native_type.IsInt());
  EXPECT(native_type.IsPrimitive());

  EXPECT_STREQ("int8", native_type.ToCString(Z));
}

UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_int8x10) {
  const auto& int8type = *new (Z) NativePrimitiveType(kInt8);

  auto& members = *new (Z) NativeTypes(Z, 10);
  members.Add(&int8type);
  members.Add(&int8type);
  members.Add(&int8type);
  members.Add(&int8type);
  members.Add(&int8type);
  members.Add(&int8type);
  members.Add(&int8type);
  members.Add(&int8type);
  members.Add(&int8type);
  members.Add(&int8type);

  const auto& struct_type = RunStructTest(Z, "struct_int8x10", members);

  EXPECT(!struct_type.ContainsHomogenuousFloats());
  EXPECT(!struct_type.ContainsOnlyFloats(Range::StartAndEnd(0, 8)));
  EXPECT_EQ(0, struct_type.NumberOfWordSizeChunksOnlyFloat());
  EXPECT_EQ(
      Utils::RoundUp(struct_type.SizeInBytes(), compiler::target::kWordSize) /
          compiler::target::kWordSize,
      struct_type.NumberOfWordSizeChunksNotOnlyFloat());
}

UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_floatx4) {
  const auto& float_type = *new (Z) NativePrimitiveType(kFloat);

  auto& members = *new (Z) NativeTypes(Z, 4);
  members.Add(&float_type);
  members.Add(&float_type);
  members.Add(&float_type);
  members.Add(&float_type);

  const auto& struct_type = RunStructTest(Z, "struct_floatx4", members);

  // This is a homogenous float in the arm and arm64 ABIs.
  //
  // On Arm64 iOS stack alignment of homogenous floats is not word size see
  // runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_ios.expect.
  EXPECT(struct_type.ContainsHomogenuousFloats());

  // On x64, 8-byte parts of the chunks contain only floats and will be passed
  // in FPU registers.
  EXPECT(struct_type.ContainsOnlyFloats(Range::StartAndEnd(0, 8)));
  EXPECT(struct_type.ContainsOnlyFloats(Range::StartAndEnd(8, 16)));
  EXPECT_EQ(struct_type.SizeInBytes() / compiler::target::kWordSize,
            struct_type.NumberOfWordSizeChunksOnlyFloat());
  EXPECT_EQ(0, struct_type.NumberOfWordSizeChunksNotOnlyFloat());
}

// A struct designed to exercise all kinds of alignment rules.
// Note that offset32A (System V ia32, iOS arm) aligns doubles on 4 bytes while
// offset32B (Arm 32 bit and MSVC ia32) aligns on 8 bytes.
// TODO(37271): Support nested structs.
// TODO(37470): Add uncommon primitive data types when we want to support them.
struct VeryLargeStruct {
  //                             size32 size64 offset32A offset32B offset64
  int8_t a;                   // 1              0         0         0
  int16_t b;                  // 2              2         2         2
  int32_t c;                  // 4              4         4         4
  int64_t d;                  // 8              8         8         8
  uint8_t e;                  // 1             16        16        16
  uint16_t f;                 // 2             18        18        18
  uint32_t g;                 // 4             20        20        20
  uint64_t h;                 // 8             24        24        24
  intptr_t i;                 // 4      8      32        32        32
  double j;                   // 8             36        40        40
  float k;                    // 4             44        48        48
  VeryLargeStruct* parent;    // 4      8      48        52        56
  intptr_t numChildren;       // 4      8      52        56        64
  VeryLargeStruct* children;  // 4      8      56        60        72
  int8_t smallLastField;      // 1             60        64        80
                              // sizeof        64        72        88
};

UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_VeryLargeStruct) {
  const auto& intptr_type = *new (Z) NativePrimitiveType(
      compiler::target::kWordSize == 4 ? kInt32 : kInt64);

  auto& members = *new (Z) NativeTypes(Z, 15);
  members.Add(new (Z) NativePrimitiveType(kInt8));
  members.Add(new (Z) NativePrimitiveType(kInt16));
  members.Add(new (Z) NativePrimitiveType(kInt32));
  members.Add(new (Z) NativePrimitiveType(kInt64));
  members.Add(new (Z) NativePrimitiveType(kUint8));
  members.Add(new (Z) NativePrimitiveType(kUint16));
  members.Add(new (Z) NativePrimitiveType(kUint32));
  members.Add(new (Z) NativePrimitiveType(kUint64));
  members.Add(&intptr_type);
  members.Add(new (Z) NativePrimitiveType(kDouble));
  members.Add(new (Z) NativePrimitiveType(kFloat));
  members.Add(&intptr_type);
  members.Add(&intptr_type);
  members.Add(&intptr_type);
  members.Add(new (Z) NativePrimitiveType(kInt8));

  RunStructTest(Z, "struct_VeryLargeStruct", members);
}

UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_int8array) {
  const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
  const auto& array_type = *new (Z) NativeArrayType(int8type, 8);

  auto& members = *new (Z) NativeTypes(Z, 1);
  members.Add(&array_type);

  const auto& struct_type = RunStructTest(Z, "struct_int8array", members);

  EXPECT_EQ(8, struct_type.SizeInBytes());
  EXPECT(!struct_type.ContainsHomogenuousFloats());
  EXPECT(!struct_type.ContainsOnlyFloats(Range::StartAndEnd(0, 8)));
  EXPECT_EQ(0, struct_type.NumberOfWordSizeChunksOnlyFloat());
  EXPECT_EQ(
      Utils::RoundUp(struct_type.SizeInBytes(), compiler::target::kWordSize) /
          compiler::target::kWordSize,
      struct_type.NumberOfWordSizeChunksNotOnlyFloat());
}

UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_floatarray) {
  const auto& float_type = *new (Z) NativePrimitiveType(kFloat);

  const auto& inner_array_type = *new (Z) NativeArrayType(float_type, 2);

  auto& inner_struct_members = *new (Z) NativeTypes(Z, 1);
  inner_struct_members.Add(&inner_array_type);
  const auto& inner_struct =
      NativeCompoundType::FromNativeTypes(Z, inner_struct_members);

  const auto& array_type = *new (Z) NativeArrayType(inner_struct, 2);

  auto& members = *new (Z) NativeTypes(Z, 1);
  members.Add(&array_type);

  const auto& struct_type = RunStructTest(Z, "struct_floatarray", members);

  EXPECT_EQ(16, struct_type.SizeInBytes());
  EXPECT(struct_type.ContainsHomogenuousFloats());
  EXPECT(struct_type.ContainsOnlyFloats(Range::StartAndEnd(0, 8)));
  EXPECT_EQ(16 / compiler::target::kWordSize,
            struct_type.NumberOfWordSizeChunksOnlyFloat());
}

}  // namespace ffi
}  // namespace compiler
}  // namespace dart
