// Copyright 2023 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <new>

#include "base/allocator/partition_allocator/partition_alloc.h"
#include "build/build_config.h"
#include "third_party/base/no_destructor.h"

#if !defined(PDF_USE_PARTITION_ALLOC)
#error "Malloc shim must use partition alloc."
#endif

namespace {

constexpr partition_alloc::PartitionOptions kOptions = {
    partition_alloc::PartitionOptions::AlignedAlloc::kDisallowed,
    partition_alloc::PartitionOptions::ThreadCache::kDisabled,
    partition_alloc::PartitionOptions::Quarantine::kDisallowed,
    partition_alloc::PartitionOptions::Cookie::kAllowed,
#if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
    partition_alloc::PartitionOptions::BackupRefPtr::kEnabled,
    partition_alloc::PartitionOptions::BackupRefPtrZapping::kEnabled,
#else
    partition_alloc::PartitionOptions::BackupRefPtr::kDisabled,
    partition_alloc::PartitionOptions::BackupRefPtrZapping::kDisabled,
#endif
    partition_alloc::PartitionOptions::UseConfigurablePool::kNo,
};

#if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
void DanglingDetected(uintptr_t id) {
  abort();  // Must die for unit test death tests.
}
#endif

partition_alloc::PartitionAllocator& GetTestBrpPartitionAllocator() {
  static bool s_allocator_initialized = false;
  static pdfium::base::NoDestructor<partition_alloc::PartitionAllocator>
      s_allocator;

  if (!s_allocator_initialized) {
    s_allocator_initialized = true;  // Set flag first ...
    s_allocator->init(kOptions);     // ... may re-enter.
#if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
    partition_alloc::SetDanglingRawPtrDetectedFn(DanglingDetected);
    partition_alloc::SetUnretainedDanglingRawPtrDetectedFn(DanglingDetected);
    partition_alloc::SetUnretainedDanglingRawPtrCheckEnabled(true);
#endif
  }
  return *s_allocator;
}

void* TestBrpPartitionNewOrDie(size_t size) noexcept {
  return GetTestBrpPartitionAllocator().root()->AllocWithFlags(0, size,
                                                               "BRP Partition");
}

void TestBrpPartitionDelete(void* p) noexcept {
  GetTestBrpPartitionAllocator().root()->Free(p);
}

}  // namespace

void* operator new(size_t size) {
  return TestBrpPartitionNewOrDie(size);
}

void* operator new[](size_t size) {
  return TestBrpPartitionNewOrDie(size);
}

void operator delete(void* p) {
  TestBrpPartitionDelete(p);
}

void operator delete[](void* p) {
  TestBrpPartitionDelete(p);
}

void* operator new(size_t size, const std::nothrow_t&) noexcept {
  return TestBrpPartitionNewOrDie(size);
}

void* operator new[](size_t size, const std::nothrow_t&) noexcept {
  return TestBrpPartitionNewOrDie(size);
}

void operator delete(void* p, const std::nothrow_t&) noexcept {
  TestBrpPartitionDelete(p);
}

void operator delete[](void* p, const std::nothrow_t&) noexcept {
  TestBrpPartitionDelete(p);
}
