11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <type_traits> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "cppgc/type-traits.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cinamespace cppgc { 131cb0ef41Sopenharmony_cinamespace internal { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciusing FinalizationCallback = void (*)(void*); 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_citemplate <typename T, typename = void> 181cb0ef41Sopenharmony_cistruct HasFinalizeGarbageCollectedObject : std::false_type {}; 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_citemplate <typename T> 211cb0ef41Sopenharmony_cistruct HasFinalizeGarbageCollectedObject< 221cb0ef41Sopenharmony_ci T, 231cb0ef41Sopenharmony_ci std::void_t<decltype(std::declval<T>().FinalizeGarbageCollectedObject())>> 241cb0ef41Sopenharmony_ci : std::true_type {}; 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci// The FinalizerTraitImpl specifies how to finalize objects. 271cb0ef41Sopenharmony_citemplate <typename T, bool isFinalized> 281cb0ef41Sopenharmony_cistruct FinalizerTraitImpl; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_citemplate <typename T> 311cb0ef41Sopenharmony_cistruct FinalizerTraitImpl<T, true> { 321cb0ef41Sopenharmony_ci private: 331cb0ef41Sopenharmony_ci // Dispatch to custom FinalizeGarbageCollectedObject(). 341cb0ef41Sopenharmony_ci struct Custom { 351cb0ef41Sopenharmony_ci static void Call(void* obj) { 361cb0ef41Sopenharmony_ci static_cast<T*>(obj)->FinalizeGarbageCollectedObject(); 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci }; 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci // Dispatch to regular destructor. 411cb0ef41Sopenharmony_ci struct Destructor { 421cb0ef41Sopenharmony_ci static void Call(void* obj) { static_cast<T*>(obj)->~T(); } 431cb0ef41Sopenharmony_ci }; 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci using FinalizeImpl = 461cb0ef41Sopenharmony_ci std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value, Custom, 471cb0ef41Sopenharmony_ci Destructor>; 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci public: 501cb0ef41Sopenharmony_ci static void Finalize(void* obj) { 511cb0ef41Sopenharmony_ci static_assert(sizeof(T), "T must be fully defined"); 521cb0ef41Sopenharmony_ci FinalizeImpl::Call(obj); 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci}; 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_citemplate <typename T> 571cb0ef41Sopenharmony_cistruct FinalizerTraitImpl<T, false> { 581cb0ef41Sopenharmony_ci static void Finalize(void* obj) { 591cb0ef41Sopenharmony_ci static_assert(sizeof(T), "T must be fully defined"); 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci}; 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci// The FinalizerTrait is used to determine if a type requires finalization and 641cb0ef41Sopenharmony_ci// what finalization means. 651cb0ef41Sopenharmony_citemplate <typename T> 661cb0ef41Sopenharmony_cistruct FinalizerTrait { 671cb0ef41Sopenharmony_ci private: 681cb0ef41Sopenharmony_ci // Object has a finalizer if it has 691cb0ef41Sopenharmony_ci // - a custom FinalizeGarbageCollectedObject method, or 701cb0ef41Sopenharmony_ci // - a destructor. 711cb0ef41Sopenharmony_ci static constexpr bool kNonTrivialFinalizer = 721cb0ef41Sopenharmony_ci internal::HasFinalizeGarbageCollectedObject<T>::value || 731cb0ef41Sopenharmony_ci !std::is_trivially_destructible<typename std::remove_cv<T>::type>::value; 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci static void Finalize(void* obj) { 761cb0ef41Sopenharmony_ci internal::FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj); 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci public: 801cb0ef41Sopenharmony_ci static constexpr bool HasFinalizer() { return kNonTrivialFinalizer; } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci // The callback used to finalize an object of type T. 831cb0ef41Sopenharmony_ci static constexpr FinalizationCallback kCallback = 841cb0ef41Sopenharmony_ci kNonTrivialFinalizer ? Finalize : nullptr; 851cb0ef41Sopenharmony_ci}; 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_citemplate <typename T> 881cb0ef41Sopenharmony_ciconstexpr FinalizationCallback FinalizerTrait<T>::kCallback; 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci} // namespace internal 911cb0ef41Sopenharmony_ci} // namespace cppgc 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci#endif // INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_ 94