chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.h

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

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_SET_RETURN_VALUE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_SET_RETURN_VALUE_H_

#include <optional>
#include <type_traits>

#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/enumeration_base.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/bindings/v8_value_cache.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "v8/include/v8-function-callback.h"
#include "v8/include/v8.h"

namespace blink::bindings {

// `V8SetReturnValue()` sets a return value in a V8 callback function.  The
// first two arguments are fixed as either `v8::FunctionCallbackInfo<T>` or
// `v8::PropertyCallbackInfo<T>` and the actual return value. The function may
// take more arguments as optimization hints depending on the return value type.

template <template <typename...> class Template, typename T>
struct IsSpecializationOf : std::false_type {};

IsSpecializationOf<Template, Template<Args...>>;

FunctionCallbackInfoOrPropertyCallbackInfo;

struct V8ReturnValue {};

// V8 handle types
template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo,
          typename S,
          typename... ExtraArgs>
void V8SetReturnValue(const CallbackInfo& info,
                      const v8::Local<S> value,
                      ExtraArgs... extra_args) {}

// Property descriptor
PLATFORM_EXPORT v8::Local<v8::Object> CreatePropertyDescriptorObject(
    v8::Isolate* isolate,
    const v8::PropertyDescriptor& desc);

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const v8::PropertyDescriptor& value) {}

// Indexed properties and named properties
PLATFORM_EXPORT inline void V8SetReturnValue(
    const v8::FunctionCallbackInfo<v8::Value>& info,
    IndexedPropertySetterResult value) {}

PLATFORM_EXPORT inline void V8SetReturnValue(
    const v8::PropertyCallbackInfo<void>& info,
    IndexedPropertySetterResult value) {}

PLATFORM_EXPORT inline void V8SetReturnValue(
    const v8::FunctionCallbackInfo<v8::Value>& info,
    NamedPropertySetterResult value) {}

PLATFORM_EXPORT inline void V8SetReturnValue(
    const v8::PropertyCallbackInfo<void>& info,
    NamedPropertySetterResult value) {}

PLATFORM_EXPORT inline void V8SetReturnValue(
    const v8::PropertyCallbackInfo<void>& info,
    NamedPropertyDeleterResult value) {}

PLATFORM_EXPORT inline void V8SetReturnValue(
    const v8::PropertyCallbackInfo<v8::Boolean>& info,
    NamedPropertyDeleterResult value) {}

// nullptr
template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, std::nullptr_t) {}

// Primitive types
template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, bool value) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, int16_t value) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, uint16_t value) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, int32_t value) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, uint32_t value) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, int64_t value) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, uint64_t value) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info, double value) {}

// Primitive types with IDL type
//
// |IdlType| represents a C++ type corresponding to an IDL type, and |value| is
// passed from Blink implementation and its type occasionally does not match
// the IDL type because Blink is not always respectful to IDL types.  These
// functions fix such a type mismatch.
template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo,
          typename BlinkType,
          typename IdlType>
inline typename std::enable_if_t<std::is_arithmetic<BlinkType>::value ||
                                 std::is_enum<BlinkType>::value>
V8SetReturnValue(const CallbackInfo& info,
                 BlinkType value,
                 V8ReturnValue::PrimitiveType<IdlType>) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo,
          typename BlinkType>
inline void V8SetReturnValue(const CallbackInfo& info,
                             BlinkType* value,
                             V8ReturnValue::PrimitiveType<bool>) {}

// String types
template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const AtomicString& string,
                      v8::Isolate* isolate,
                      V8ReturnValue::NonNullable) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const String& string,
                      v8::Isolate* isolate,
                      V8ReturnValue::NonNullable) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const WebString& string,
                      v8::Isolate* isolate,
                      V8ReturnValue::NonNullable) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const AtomicString& string,
                      v8::Isolate* isolate,
                      V8ReturnValue::Nullable) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const String& string,
                      v8::Isolate* isolate,
                      V8ReturnValue::Nullable) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const WebString& string,
                      v8::Isolate* isolate,
                      V8ReturnValue::Nullable) {}

// ScriptWrappable
template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const ScriptWrappable* value,
                      V8ReturnValue::MainWorld) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const ScriptWrappable& value,
                      V8ReturnValue::MainWorld) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const ScriptWrappable* value,
                      const ScriptWrappable* receiver) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const ScriptWrappable& value,
                      const ScriptWrappable* receiver) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const ScriptWrappable* value,
                      const ScriptWrappable* receiver,
                      V8ReturnValue::MaybeCrossOrigin) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const ScriptWrappable& value,
                      const ScriptWrappable* receiver,
                      V8ReturnValue::MaybeCrossOrigin) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      const ScriptWrappable* value,
                      v8::Local<v8::Context> creation_context) {}

template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
                      ScriptWrappable& value,
                      v8::Local<v8::Context> creation_context) {}

// EnumerationBase
template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo,
          typename... ExtraArgs>
void V8SetReturnValue(const CallbackInfo& info,
                      const bindings::EnumerationBase& value,
                      v8::Isolate* isolate,
                      ExtraArgs... extra_args) {}

// Nullable types
template <FunctionCallbackInfoOrPropertyCallbackInfo CallbackInfo,
          typename T,
          typename... ExtraArgs>
void V8SetReturnValue(const CallbackInfo& info,
                      std::optional<T> value,
                      ExtraArgs... extra_args) {}

// Exposed objects
PLATFORM_EXPORT v8::Local<v8::Value> GetExposedInterfaceObject(
    v8::Isolate* isolate,
    v8::Local<v8::Object> creation_context,
    const WrapperTypeInfo* wrapper_type_info);

PLATFORM_EXPORT v8::Local<v8::Value> GetExposedNamespaceObject(
    v8::Isolate* isolate,
    v8::Local<v8::Object> creation_context,
    const WrapperTypeInfo* wrapper_type_info);

inline void V8SetReturnValue(const v8::PropertyCallbackInfo<v8::Value>& info,
                             const WrapperTypeInfo* wrapper_type_info,
                             V8ReturnValue::InterfaceObject) {}

inline void V8SetReturnValue(const v8::PropertyCallbackInfo<v8::Value>& info,
                             const WrapperTypeInfo* wrapper_type_info,
                             V8ReturnValue::NamespaceObject) {}

}  // namespace blink::bindings

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_SET_RETURN_VALUE_H_