chromium/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_TO_V8_TRAITS_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_TO_V8_TRAITS_H_

#include <optional>

#include "base/numerics/safe_conversions.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_deque.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
#include "v8/include/v8.h"

namespace blink {

class CallbackFunctionBase;
class CallbackInterfaceBase;
class ScriptWrappable;

template <typename IDLType>
class FrozenArray;

namespace bindings {

class DictionaryBase;
class EnumerationBase;
class UnionBase;

}  // namespace bindings

// ToV8Traits provides C++ -> V8 conversion.
// Currently, you can use ToV8() which is defined in to_v8.h for this
// conversion, but it cannot throw an exception when an error occurs.
// We will solve this problem and replace ToV8() in to_v8.h with
// ToV8Traits::ToV8().
// TODO(canonmukai): Replace existing ToV8() with ToV8Traits<>.

// Primary template for ToV8Traits.
template <typename T, typename SFINAEHelper = void>
struct ToV8Traits;

// Used only for allowing a ScriptPromiseProperty to specify that it will
// resolve/reject with v8::Undefined.
struct ToV8UndefinedGenerator {};

// undefined
template <>
struct ToV8Traits<IDLUndefined> {};

// Any
template <>
struct ToV8Traits<IDLAny> {};

// Boolean
template <>
struct ToV8Traits<IDLBoolean> {};

// Bigint
template <>
struct ToV8Traits<IDLBigint> {};

// Integer
// int8_t
ToV8Traits<IDLIntegerTypeBase<int8_t, mode>>;

// int16_t
ToV8Traits<IDLIntegerTypeBase<int16_t, mode>>;

// int32_t
ToV8Traits<IDLIntegerTypeBase<int32_t, mode>>;

// int64_t
ToV8Traits<IDLIntegerTypeBase<int64_t, mode>>;

// uint8_t
ToV8Traits<IDLIntegerTypeBase<uint8_t, mode>>;

// uint16_t
ToV8Traits<IDLIntegerTypeBase<uint16_t, mode>>;

// uint32_t
ToV8Traits<IDLIntegerTypeBase<uint32_t, mode>>;

// uint64_t
ToV8Traits<IDLIntegerTypeBase<uint64_t, mode>>;

// Floating Point Number
ToV8Traits<IDLFloatingPointNumberTypeBase<T, mode>>;

// String
ToV8Traits<T, std::enable_if_t<std::is_base_of<IDLStringTypeBase, T>::value>>;

// Object
template <>
struct ToV8Traits<IDLObject> {};

// Promise
template <>
struct ToV8Traits<IDLPromise> {};

// ScriptWrappable
ToV8Traits<T, std::enable_if_t<std::is_base_of<ScriptWrappable, T>::value>>;

// Dictionary
ToV8Traits<T, std::enable_if_t<std::is_base_of<bindings::DictionaryBase, T>::value>>;

// Callback function
ToV8Traits<T, std::enable_if_t<std::is_base_of<CallbackFunctionBase, T>::value>>;

// Callback interface
ToV8Traits<T, std::enable_if_t<std::is_base_of<CallbackInterfaceBase, T>::value>>;

// Enumeration
ToV8Traits<T, std::enable_if_t<std::is_base_of<bindings::EnumerationBase, T>::value>>;

// NotShared
ToV8Traits<NotShared<T>>;

// MaybeShared
ToV8Traits<MaybeShared<T>>;

// Array

namespace bindings {

// Helper function for IDLSequence
template <typename ElementIDLType, typename ContainerType>
[[nodiscard]] inline v8::Local<v8::Value> ToV8HelperSequence(
    ScriptState* script_state,
    const ContainerType& sequence) {}

// Helper function for IDLSequence in order to reduce code size. This avoids
// template instantiation of ToV8HelperSequence<T> where T is a subclass of
// bindings::DictionaryBase, or ScriptWrappable.
// Since these base classes are the leftmost base class,
// HeapVector<Member<TheBase>> has the same binary representation with
// HeapVector<Member<T>>. We leverage this fact to reduce the APK size.
//
// This hack reduces the APK size by 4 Kbytes as of 2021 March.
template <typename BaseClassOfT, typename T>
[[nodiscard]] inline v8::Local<v8::Value> ToV8HelperSequenceWithMemberUpcast(
    ScriptState* script_state,
    const HeapVector<Member<T>>& sequence) {}

template <typename BaseClassOfT, typename T>
[[nodiscard]] inline v8::Local<v8::Value> ToV8HelperSequenceWithMemberUpcast(
    ScriptState* script_state,
    const HeapDeque<Member<T>>& sequence) {}

// Helper function for IDLRecord
template <typename ValueIDLType, typename ContainerType>
[[nodiscard]] inline v8::Local<v8::Value> ToV8HelperRecord(
    ScriptState* script_state,
    const ContainerType& record) {}

}  // namespace bindings

// IDLSequence
ToV8Traits<IDLSequence<T>, std::enable_if_t<std::is_base_of<bindings::DictionaryBase, T>::value>>;

ToV8Traits<IDLSequence<T>, std::enable_if_t<std::is_base_of<ScriptWrappable, T>::value>>;

ToV8Traits<IDLSequence<T>, std::enable_if_t<!std::is_base_of<bindings::DictionaryBase, T>::value && !std::is_base_of<ScriptWrappable, T>::value>>;

// IDLArray
ToV8Traits<IDLArray<T>>;

// IDLRecord
// K must be based of IDL String types.
ToV8Traits<IDLRecord<K, V>>;

// Nullable

// IDLNullable<IDLNullable<T>> must not be used.
ToV8Traits<IDLNullable<IDLNullable<T>>>;

// Nullable Boolean
template <>
struct ToV8Traits<IDLNullable<IDLBoolean>> {};

// Nullable Integers
ToV8Traits<IDLNullable<IDLIntegerTypeBase<T, mode>>>;

// Nullable Bigints
template <>
struct ToV8Traits<IDLNullable<IDLBigint>> {};

// Nullable Floating Point Number
ToV8Traits<IDLNullable<IDLFloatingPointNumberTypeBase<T, mode>>>;

// Nullable Strings
ToV8Traits<IDLNullable<T>, std::enable_if_t<std::is_base_of<IDLStringTypeBase, T>::value>>;

// Nullable Object
template <>
struct ToV8Traits<IDLNullable<IDLObject>> {};

// Nullable ScriptWrappable
ToV8Traits<IDLNullable<T>, std::enable_if_t<std::is_base_of<ScriptWrappable, T>::value>>;

// Nullable Dictionary
ToV8Traits<IDLNullable<T>, std::enable_if_t<std::is_base_of<bindings::DictionaryBase, T>::value>>;

// Nullable Callback function
ToV8Traits<IDLNullable<T>, std::enable_if_t<std::is_base_of<CallbackFunctionBase, T>::value>>;

// Nullable Callback interface
ToV8Traits<IDLNullable<T>, std::enable_if_t<std::is_base_of<CallbackInterfaceBase, T>::value>>;

// Nullable Enumeration
ToV8Traits<IDLNullable<T>, std::enable_if_t<std::is_base_of<bindings::EnumerationBase, T>::value>>;

// Nullable NotShared
ToV8Traits<IDLNullable<NotShared<T>>>;

// Nullable MaybeShared
ToV8Traits<IDLNullable<MaybeShared<T>>>;

// Nullable Sequence
ToV8Traits<IDLNullable<IDLSequence<T>>>;

// Nullable Frozen Array
ToV8Traits<IDLNullable<IDLArray<T>>>;

// Nullable Record
ToV8Traits<IDLNullable<IDLRecord<K, V>>>;

// Nullable Date
// IDLDate must be used as IDLNullable<IDLDate>.
template <>
struct ToV8Traits<IDLNullable<IDLDate>> {};

// Union types

ToV8Traits<T, std::enable_if_t<std::is_base_of<bindings::UnionBase, T>::value>>;

ToV8Traits<IDLNullable<T>, std::enable_if_t<std::is_base_of<bindings::UnionBase, T>::value>>;

// Optional
ToV8Traits<IDLOptional<T>>;

template <typename IDLType, typename BlinkType>
ScriptPromise<IDLType> ToResolvedPromise(ScriptState* script_state,
                                         BlinkType value) {}

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_TO_V8_TRAITS_H_