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/**
61cb0ef41Sopenharmony_ci * This file provides additional API on top of the default one for making
71cb0ef41Sopenharmony_ci * API calls, which come from embedder C++ functions. The functions are being
81cb0ef41Sopenharmony_ci * called directly from optimized code, doing all the necessary typechecks
91cb0ef41Sopenharmony_ci * in the compiler itself, instead of on the embedder side. Hence the "fast"
101cb0ef41Sopenharmony_ci * in the name. Example usage might look like:
111cb0ef41Sopenharmony_ci *
121cb0ef41Sopenharmony_ci * \code
131cb0ef41Sopenharmony_ci *    void FastMethod(int param, bool another_param);
141cb0ef41Sopenharmony_ci *
151cb0ef41Sopenharmony_ci *    v8::FunctionTemplate::New(isolate, SlowCallback, data,
161cb0ef41Sopenharmony_ci *                              signature, length, constructor_behavior
171cb0ef41Sopenharmony_ci *                              side_effect_type,
181cb0ef41Sopenharmony_ci *                              &v8::CFunction::Make(FastMethod));
191cb0ef41Sopenharmony_ci * \endcode
201cb0ef41Sopenharmony_ci *
211cb0ef41Sopenharmony_ci * By design, fast calls are limited by the following requirements, which
221cb0ef41Sopenharmony_ci * the embedder should enforce themselves:
231cb0ef41Sopenharmony_ci *   - they should not allocate on the JS heap;
241cb0ef41Sopenharmony_ci *   - they should not trigger JS execution.
251cb0ef41Sopenharmony_ci * To enforce them, the embedder could use the existing
261cb0ef41Sopenharmony_ci * v8::Isolate::DisallowJavascriptExecutionScope and a utility similar to
271cb0ef41Sopenharmony_ci * Blink's NoAllocationScope:
281cb0ef41Sopenharmony_ci * https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/platform/heap/thread_state_scopes.h;l=16
291cb0ef41Sopenharmony_ci *
301cb0ef41Sopenharmony_ci * Due to these limitations, it's not directly possible to report errors by
311cb0ef41Sopenharmony_ci * throwing a JS exception or to otherwise do an allocation. There is an
321cb0ef41Sopenharmony_ci * alternative way of creating fast calls that supports falling back to the
331cb0ef41Sopenharmony_ci * slow call and then performing the necessary allocation. When one creates
341cb0ef41Sopenharmony_ci * the fast method by using CFunction::MakeWithFallbackSupport instead of
351cb0ef41Sopenharmony_ci * CFunction::Make, the fast callback gets as last parameter an output variable,
361cb0ef41Sopenharmony_ci * through which it can request falling back to the slow call. So one might
371cb0ef41Sopenharmony_ci * declare their method like:
381cb0ef41Sopenharmony_ci *
391cb0ef41Sopenharmony_ci * \code
401cb0ef41Sopenharmony_ci *    void FastMethodWithFallback(int param, FastApiCallbackOptions& options);
411cb0ef41Sopenharmony_ci * \endcode
421cb0ef41Sopenharmony_ci *
431cb0ef41Sopenharmony_ci * If the callback wants to signal an error condition or to perform an
441cb0ef41Sopenharmony_ci * allocation, it must set options.fallback to true and do an early return from
451cb0ef41Sopenharmony_ci * the fast method. Then V8 checks the value of options.fallback and if it's
461cb0ef41Sopenharmony_ci * true, falls back to executing the SlowCallback, which is capable of reporting
471cb0ef41Sopenharmony_ci * the error (either by throwing a JS exception or logging to the console) or
481cb0ef41Sopenharmony_ci * doing the allocation. It's the embedder's responsibility to ensure that the
491cb0ef41Sopenharmony_ci * fast callback is idempotent up to the point where error and fallback
501cb0ef41Sopenharmony_ci * conditions are checked, because otherwise executing the slow callback might
511cb0ef41Sopenharmony_ci * produce visible side-effects twice.
521cb0ef41Sopenharmony_ci *
531cb0ef41Sopenharmony_ci * An example for custom embedder type support might employ a way to wrap/
541cb0ef41Sopenharmony_ci * unwrap various C++ types in JSObject instances, e.g:
551cb0ef41Sopenharmony_ci *
561cb0ef41Sopenharmony_ci * \code
571cb0ef41Sopenharmony_ci *
581cb0ef41Sopenharmony_ci *    // Helper method with a check for field count.
591cb0ef41Sopenharmony_ci *    template <typename T, int offset>
601cb0ef41Sopenharmony_ci *    inline T* GetInternalField(v8::Local<v8::Object> wrapper) {
611cb0ef41Sopenharmony_ci *      assert(offset < wrapper->InternalFieldCount());
621cb0ef41Sopenharmony_ci *      return reinterpret_cast<T*>(
631cb0ef41Sopenharmony_ci *          wrapper->GetAlignedPointerFromInternalField(offset));
641cb0ef41Sopenharmony_ci *    }
651cb0ef41Sopenharmony_ci *
661cb0ef41Sopenharmony_ci *    class CustomEmbedderType {
671cb0ef41Sopenharmony_ci *     public:
681cb0ef41Sopenharmony_ci *      // Returns the raw C object from a wrapper JS object.
691cb0ef41Sopenharmony_ci *      static CustomEmbedderType* Unwrap(v8::Local<v8::Object> wrapper) {
701cb0ef41Sopenharmony_ci *        return GetInternalField<CustomEmbedderType,
711cb0ef41Sopenharmony_ci *                                kV8EmbedderWrapperObjectIndex>(wrapper);
721cb0ef41Sopenharmony_ci *      }
731cb0ef41Sopenharmony_ci *      static void FastMethod(v8::Local<v8::Object> receiver_obj, int param) {
741cb0ef41Sopenharmony_ci *        CustomEmbedderType* receiver = static_cast<CustomEmbedderType*>(
751cb0ef41Sopenharmony_ci *          receiver_obj->GetAlignedPointerFromInternalField(
761cb0ef41Sopenharmony_ci *            kV8EmbedderWrapperObjectIndex));
771cb0ef41Sopenharmony_ci *
781cb0ef41Sopenharmony_ci *        // Type checks are already done by the optimized code.
791cb0ef41Sopenharmony_ci *        // Then call some performance-critical method like:
801cb0ef41Sopenharmony_ci *        // receiver->Method(param);
811cb0ef41Sopenharmony_ci *      }
821cb0ef41Sopenharmony_ci *
831cb0ef41Sopenharmony_ci *      static void SlowMethod(
841cb0ef41Sopenharmony_ci *          const v8::FunctionCallbackInfo<v8::Value>& info) {
851cb0ef41Sopenharmony_ci *        v8::Local<v8::Object> instance =
861cb0ef41Sopenharmony_ci *          v8::Local<v8::Object>::Cast(info.Holder());
871cb0ef41Sopenharmony_ci *        CustomEmbedderType* receiver = Unwrap(instance);
881cb0ef41Sopenharmony_ci *        // TODO: Do type checks and extract {param}.
891cb0ef41Sopenharmony_ci *        receiver->Method(param);
901cb0ef41Sopenharmony_ci *      }
911cb0ef41Sopenharmony_ci *    };
921cb0ef41Sopenharmony_ci *
931cb0ef41Sopenharmony_ci *    // TODO(mslekova): Clean-up these constants
941cb0ef41Sopenharmony_ci *    // The constants kV8EmbedderWrapperTypeIndex and
951cb0ef41Sopenharmony_ci *    // kV8EmbedderWrapperObjectIndex describe the offsets for the type info
961cb0ef41Sopenharmony_ci *    // struct and the native object, when expressed as internal field indices
971cb0ef41Sopenharmony_ci *    // within a JSObject. The existance of this helper function assumes that
981cb0ef41Sopenharmony_ci *    // all embedder objects have their JSObject-side type info at the same
991cb0ef41Sopenharmony_ci *    // offset, but this is not a limitation of the API itself. For a detailed
1001cb0ef41Sopenharmony_ci *    // use case, see the third example.
1011cb0ef41Sopenharmony_ci *    static constexpr int kV8EmbedderWrapperTypeIndex = 0;
1021cb0ef41Sopenharmony_ci *    static constexpr int kV8EmbedderWrapperObjectIndex = 1;
1031cb0ef41Sopenharmony_ci *
1041cb0ef41Sopenharmony_ci *    // The following setup function can be templatized based on
1051cb0ef41Sopenharmony_ci *    // the {embedder_object} argument.
1061cb0ef41Sopenharmony_ci *    void SetupCustomEmbedderObject(v8::Isolate* isolate,
1071cb0ef41Sopenharmony_ci *                                   v8::Local<v8::Context> context,
1081cb0ef41Sopenharmony_ci *                                   CustomEmbedderType* embedder_object) {
1091cb0ef41Sopenharmony_ci *      isolate->set_embedder_wrapper_type_index(
1101cb0ef41Sopenharmony_ci *        kV8EmbedderWrapperTypeIndex);
1111cb0ef41Sopenharmony_ci *      isolate->set_embedder_wrapper_object_index(
1121cb0ef41Sopenharmony_ci *        kV8EmbedderWrapperObjectIndex);
1131cb0ef41Sopenharmony_ci *
1141cb0ef41Sopenharmony_ci *      v8::CFunction c_func =
1151cb0ef41Sopenharmony_ci *        MakeV8CFunction(CustomEmbedderType::FastMethod);
1161cb0ef41Sopenharmony_ci *
1171cb0ef41Sopenharmony_ci *      Local<v8::FunctionTemplate> method_template =
1181cb0ef41Sopenharmony_ci *        v8::FunctionTemplate::New(
1191cb0ef41Sopenharmony_ci *          isolate, CustomEmbedderType::SlowMethod, v8::Local<v8::Value>(),
1201cb0ef41Sopenharmony_ci *          v8::Local<v8::Signature>(), 1, v8::ConstructorBehavior::kAllow,
1211cb0ef41Sopenharmony_ci *          v8::SideEffectType::kHasSideEffect, &c_func);
1221cb0ef41Sopenharmony_ci *
1231cb0ef41Sopenharmony_ci *      v8::Local<v8::ObjectTemplate> object_template =
1241cb0ef41Sopenharmony_ci *        v8::ObjectTemplate::New(isolate);
1251cb0ef41Sopenharmony_ci *      object_template->SetInternalFieldCount(
1261cb0ef41Sopenharmony_ci *        kV8EmbedderWrapperObjectIndex + 1);
1271cb0ef41Sopenharmony_ci *      object_template->Set(isolate, "method", method_template);
1281cb0ef41Sopenharmony_ci *
1291cb0ef41Sopenharmony_ci *      // Instantiate the wrapper JS object.
1301cb0ef41Sopenharmony_ci *      v8::Local<v8::Object> object =
1311cb0ef41Sopenharmony_ci *          object_template->NewInstance(context).ToLocalChecked();
1321cb0ef41Sopenharmony_ci *      object->SetAlignedPointerInInternalField(
1331cb0ef41Sopenharmony_ci *        kV8EmbedderWrapperObjectIndex,
1341cb0ef41Sopenharmony_ci *        reinterpret_cast<void*>(embedder_object));
1351cb0ef41Sopenharmony_ci *
1361cb0ef41Sopenharmony_ci *      // TODO: Expose {object} where it's necessary.
1371cb0ef41Sopenharmony_ci *    }
1381cb0ef41Sopenharmony_ci * \endcode
1391cb0ef41Sopenharmony_ci *
1401cb0ef41Sopenharmony_ci * For instance if {object} is exposed via a global "obj" variable,
1411cb0ef41Sopenharmony_ci * one could write in JS:
1421cb0ef41Sopenharmony_ci *   function hot_func() {
1431cb0ef41Sopenharmony_ci *     obj.method(42);
1441cb0ef41Sopenharmony_ci *   }
1451cb0ef41Sopenharmony_ci * and once {hot_func} gets optimized, CustomEmbedderType::FastMethod
1461cb0ef41Sopenharmony_ci * will be called instead of the slow version, with the following arguments:
1471cb0ef41Sopenharmony_ci *   receiver := the {embedder_object} from above
1481cb0ef41Sopenharmony_ci *   param := 42
1491cb0ef41Sopenharmony_ci *
1501cb0ef41Sopenharmony_ci * Currently supported return types:
1511cb0ef41Sopenharmony_ci *   - void
1521cb0ef41Sopenharmony_ci *   - bool
1531cb0ef41Sopenharmony_ci *   - int32_t
1541cb0ef41Sopenharmony_ci *   - uint32_t
1551cb0ef41Sopenharmony_ci *   - float32_t
1561cb0ef41Sopenharmony_ci *   - float64_t
1571cb0ef41Sopenharmony_ci * Currently supported argument types:
1581cb0ef41Sopenharmony_ci *  - pointer to an embedder type
1591cb0ef41Sopenharmony_ci *  - JavaScript array of primitive types
1601cb0ef41Sopenharmony_ci *  - bool
1611cb0ef41Sopenharmony_ci *  - int32_t
1621cb0ef41Sopenharmony_ci *  - uint32_t
1631cb0ef41Sopenharmony_ci *  - int64_t
1641cb0ef41Sopenharmony_ci *  - uint64_t
1651cb0ef41Sopenharmony_ci *  - float32_t
1661cb0ef41Sopenharmony_ci *  - float64_t
1671cb0ef41Sopenharmony_ci *
1681cb0ef41Sopenharmony_ci * The 64-bit integer types currently have the IDL (unsigned) long long
1691cb0ef41Sopenharmony_ci * semantics: https://heycam.github.io/webidl/#abstract-opdef-converttoint
1701cb0ef41Sopenharmony_ci * In the future we'll extend the API to also provide conversions from/to
1711cb0ef41Sopenharmony_ci * BigInt to preserve full precision.
1721cb0ef41Sopenharmony_ci * The floating point types currently have the IDL (unrestricted) semantics,
1731cb0ef41Sopenharmony_ci * which is the only one used by WebGL. We plan to add support also for
1741cb0ef41Sopenharmony_ci * restricted floats/doubles, similarly to the BigInt conversion policies.
1751cb0ef41Sopenharmony_ci * We also differ from the specific NaN bit pattern that WebIDL prescribes
1761cb0ef41Sopenharmony_ci * (https://heycam.github.io/webidl/#es-unrestricted-float) in that Blink
1771cb0ef41Sopenharmony_ci * passes NaN values as-is, i.e. doesn't normalize them.
1781cb0ef41Sopenharmony_ci *
1791cb0ef41Sopenharmony_ci * To be supported types:
1801cb0ef41Sopenharmony_ci *  - TypedArrays and ArrayBuffers
1811cb0ef41Sopenharmony_ci *  - arrays of embedder types
1821cb0ef41Sopenharmony_ci *
1831cb0ef41Sopenharmony_ci *
1841cb0ef41Sopenharmony_ci * The API offers a limited support for function overloads:
1851cb0ef41Sopenharmony_ci *
1861cb0ef41Sopenharmony_ci * \code
1871cb0ef41Sopenharmony_ci *    void FastMethod_2Args(int param, bool another_param);
1881cb0ef41Sopenharmony_ci *    void FastMethod_3Args(int param, bool another_param, int third_param);
1891cb0ef41Sopenharmony_ci *
1901cb0ef41Sopenharmony_ci *    v8::CFunction fast_method_2args_c_func =
1911cb0ef41Sopenharmony_ci *         MakeV8CFunction(FastMethod_2Args);
1921cb0ef41Sopenharmony_ci *    v8::CFunction fast_method_3args_c_func =
1931cb0ef41Sopenharmony_ci *         MakeV8CFunction(FastMethod_3Args);
1941cb0ef41Sopenharmony_ci *    const v8::CFunction fast_method_overloads[] = {fast_method_2args_c_func,
1951cb0ef41Sopenharmony_ci *                                                   fast_method_3args_c_func};
1961cb0ef41Sopenharmony_ci *    Local<v8::FunctionTemplate> method_template =
1971cb0ef41Sopenharmony_ci *        v8::FunctionTemplate::NewWithCFunctionOverloads(
1981cb0ef41Sopenharmony_ci *            isolate, SlowCallback, data, signature, length,
1991cb0ef41Sopenharmony_ci *            constructor_behavior, side_effect_type,
2001cb0ef41Sopenharmony_ci *            {fast_method_overloads, 2});
2011cb0ef41Sopenharmony_ci * \endcode
2021cb0ef41Sopenharmony_ci *
2031cb0ef41Sopenharmony_ci * In this example a single FunctionTemplate is associated to multiple C++
2041cb0ef41Sopenharmony_ci * functions. The overload resolution is currently only based on the number of
2051cb0ef41Sopenharmony_ci * arguments passed in a call. For example, if this method_template is
2061cb0ef41Sopenharmony_ci * registered with a wrapper JS object as described above, a call with two
2071cb0ef41Sopenharmony_ci * arguments:
2081cb0ef41Sopenharmony_ci *    obj.method(42, true);
2091cb0ef41Sopenharmony_ci * will result in a fast call to FastMethod_2Args, while a call with three or
2101cb0ef41Sopenharmony_ci * more arguments:
2111cb0ef41Sopenharmony_ci *    obj.method(42, true, 11);
2121cb0ef41Sopenharmony_ci * will result in a fast call to FastMethod_3Args. Instead a call with less than
2131cb0ef41Sopenharmony_ci * two arguments, like:
2141cb0ef41Sopenharmony_ci *    obj.method(42);
2151cb0ef41Sopenharmony_ci * would not result in a fast call but would fall back to executing the
2161cb0ef41Sopenharmony_ci * associated SlowCallback.
2171cb0ef41Sopenharmony_ci */
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci#ifndef INCLUDE_V8_FAST_API_CALLS_H_
2201cb0ef41Sopenharmony_ci#define INCLUDE_V8_FAST_API_CALLS_H_
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci#include <stddef.h>
2231cb0ef41Sopenharmony_ci#include <stdint.h>
2241cb0ef41Sopenharmony_ci
2251cb0ef41Sopenharmony_ci#include <tuple>
2261cb0ef41Sopenharmony_ci#include <type_traits>
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci#include "v8-internal.h"      // NOLINT(build/include_directory)
2291cb0ef41Sopenharmony_ci#include "v8-local-handle.h"  // NOLINT(build/include_directory)
2301cb0ef41Sopenharmony_ci#include "v8-typed-array.h"   // NOLINT(build/include_directory)
2311cb0ef41Sopenharmony_ci#include "v8-value.h"         // NOLINT(build/include_directory)
2321cb0ef41Sopenharmony_ci#include "v8config.h"         // NOLINT(build/include_directory)
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_cinamespace v8 {
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ciclass Isolate;
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ciclass CTypeInfo {
2391cb0ef41Sopenharmony_ci public:
2401cb0ef41Sopenharmony_ci  enum class Type : uint8_t {
2411cb0ef41Sopenharmony_ci    kVoid,
2421cb0ef41Sopenharmony_ci    kBool,
2431cb0ef41Sopenharmony_ci    kInt32,
2441cb0ef41Sopenharmony_ci    kUint32,
2451cb0ef41Sopenharmony_ci    kInt64,
2461cb0ef41Sopenharmony_ci    kUint64,
2471cb0ef41Sopenharmony_ci    kFloat32,
2481cb0ef41Sopenharmony_ci    kFloat64,
2491cb0ef41Sopenharmony_ci    kV8Value,
2501cb0ef41Sopenharmony_ci    kApiObject,  // This will be deprecated once all users have
2511cb0ef41Sopenharmony_ci                 // migrated from v8::ApiObject to v8::Local<v8::Value>.
2521cb0ef41Sopenharmony_ci    kAny,        // This is added to enable untyped representation of fast
2531cb0ef41Sopenharmony_ci                 // call arguments for test purposes. It can represent any of
2541cb0ef41Sopenharmony_ci                 // the other types stored in the same memory as a union (see
2551cb0ef41Sopenharmony_ci                 // the AnyCType struct declared below). This allows for
2561cb0ef41Sopenharmony_ci                 // uniform passing of arguments w.r.t. their location
2571cb0ef41Sopenharmony_ci                 // (in a register or on the stack), independent of their
2581cb0ef41Sopenharmony_ci                 // actual type. It's currently used by the arm64 simulator
2591cb0ef41Sopenharmony_ci                 // and can be added to the other simulators as well when fast
2601cb0ef41Sopenharmony_ci                 // calls having both GP and FP params need to be supported.
2611cb0ef41Sopenharmony_ci  };
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ci  // kCallbackOptionsType is not part of the Type enum
2641cb0ef41Sopenharmony_ci  // because it is only used internally. Use value 255 that is larger
2651cb0ef41Sopenharmony_ci  // than any valid Type enum.
2661cb0ef41Sopenharmony_ci  static constexpr Type kCallbackOptionsType = Type(255);
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci  enum class SequenceType : uint8_t {
2691cb0ef41Sopenharmony_ci    kScalar,
2701cb0ef41Sopenharmony_ci    kIsSequence,    // sequence<T>
2711cb0ef41Sopenharmony_ci    kIsTypedArray,  // TypedArray of T or any ArrayBufferView if T
2721cb0ef41Sopenharmony_ci                    // is void
2731cb0ef41Sopenharmony_ci    kIsArrayBuffer  // ArrayBuffer
2741cb0ef41Sopenharmony_ci  };
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  enum class Flags : uint8_t {
2771cb0ef41Sopenharmony_ci    kNone = 0,
2781cb0ef41Sopenharmony_ci    kAllowSharedBit = 1 << 0,   // Must be an ArrayBuffer or TypedArray
2791cb0ef41Sopenharmony_ci    kEnforceRangeBit = 1 << 1,  // T must be integral
2801cb0ef41Sopenharmony_ci    kClampBit = 1 << 2,         // T must be integral
2811cb0ef41Sopenharmony_ci    kIsRestrictedBit = 1 << 3,  // T must be float or double
2821cb0ef41Sopenharmony_ci  };
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci  explicit constexpr CTypeInfo(
2851cb0ef41Sopenharmony_ci      Type type, SequenceType sequence_type = SequenceType::kScalar,
2861cb0ef41Sopenharmony_ci      Flags flags = Flags::kNone)
2871cb0ef41Sopenharmony_ci      : type_(type), sequence_type_(sequence_type), flags_(flags) {}
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci  typedef uint32_t Identifier;
2901cb0ef41Sopenharmony_ci  explicit constexpr CTypeInfo(Identifier identifier)
2911cb0ef41Sopenharmony_ci      : CTypeInfo(static_cast<Type>(identifier >> 16),
2921cb0ef41Sopenharmony_ci                  static_cast<SequenceType>((identifier >> 8) & 255),
2931cb0ef41Sopenharmony_ci                  static_cast<Flags>(identifier & 255)) {}
2941cb0ef41Sopenharmony_ci  constexpr Identifier GetId() const {
2951cb0ef41Sopenharmony_ci    return static_cast<uint8_t>(type_) << 16 |
2961cb0ef41Sopenharmony_ci           static_cast<uint8_t>(sequence_type_) << 8 |
2971cb0ef41Sopenharmony_ci           static_cast<uint8_t>(flags_);
2981cb0ef41Sopenharmony_ci  }
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci  constexpr Type GetType() const { return type_; }
3011cb0ef41Sopenharmony_ci  constexpr SequenceType GetSequenceType() const { return sequence_type_; }
3021cb0ef41Sopenharmony_ci  constexpr Flags GetFlags() const { return flags_; }
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  static constexpr bool IsIntegralType(Type type) {
3051cb0ef41Sopenharmony_ci    return type == Type::kInt32 || type == Type::kUint32 ||
3061cb0ef41Sopenharmony_ci           type == Type::kInt64 || type == Type::kUint64;
3071cb0ef41Sopenharmony_ci  }
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci  static constexpr bool IsFloatingPointType(Type type) {
3101cb0ef41Sopenharmony_ci    return type == Type::kFloat32 || type == Type::kFloat64;
3111cb0ef41Sopenharmony_ci  }
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci  static constexpr bool IsPrimitive(Type type) {
3141cb0ef41Sopenharmony_ci    return IsIntegralType(type) || IsFloatingPointType(type) ||
3151cb0ef41Sopenharmony_ci           type == Type::kBool;
3161cb0ef41Sopenharmony_ci  }
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci private:
3191cb0ef41Sopenharmony_ci  Type type_;
3201cb0ef41Sopenharmony_ci  SequenceType sequence_type_;
3211cb0ef41Sopenharmony_ci  Flags flags_;
3221cb0ef41Sopenharmony_ci};
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_cistruct FastApiTypedArrayBase {
3251cb0ef41Sopenharmony_ci public:
3261cb0ef41Sopenharmony_ci  // Returns the length in number of elements.
3271cb0ef41Sopenharmony_ci  size_t V8_EXPORT length() const { return length_; }
3281cb0ef41Sopenharmony_ci  // Checks whether the given index is within the bounds of the collection.
3291cb0ef41Sopenharmony_ci  void V8_EXPORT ValidateIndex(size_t index) const;
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ci protected:
3321cb0ef41Sopenharmony_ci  size_t length_ = 0;
3331cb0ef41Sopenharmony_ci};
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_citemplate <typename T>
3361cb0ef41Sopenharmony_cistruct FastApiTypedArray : public FastApiTypedArrayBase {
3371cb0ef41Sopenharmony_ci public:
3381cb0ef41Sopenharmony_ci  V8_INLINE T get(size_t index) const {
3391cb0ef41Sopenharmony_ci#ifdef DEBUG
3401cb0ef41Sopenharmony_ci    ValidateIndex(index);
3411cb0ef41Sopenharmony_ci#endif  // DEBUG
3421cb0ef41Sopenharmony_ci    T tmp;
3431cb0ef41Sopenharmony_ci    memcpy(&tmp, reinterpret_cast<T*>(data_) + index, sizeof(T));
3441cb0ef41Sopenharmony_ci    return tmp;
3451cb0ef41Sopenharmony_ci  }
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci  bool getStorageIfAligned(T** elements) const {
3481cb0ef41Sopenharmony_ci    if (reinterpret_cast<uintptr_t>(data_) % alignof(T) != 0) {
3491cb0ef41Sopenharmony_ci      return false;
3501cb0ef41Sopenharmony_ci    }
3511cb0ef41Sopenharmony_ci    *elements = reinterpret_cast<T*>(data_);
3521cb0ef41Sopenharmony_ci    return true;
3531cb0ef41Sopenharmony_ci  }
3541cb0ef41Sopenharmony_ci
3551cb0ef41Sopenharmony_ci private:
3561cb0ef41Sopenharmony_ci  // This pointer should include the typed array offset applied.
3571cb0ef41Sopenharmony_ci  // It's not guaranteed that it's aligned to sizeof(T), it's only
3581cb0ef41Sopenharmony_ci  // guaranteed that it's 4-byte aligned, so for 8-byte types we need to
3591cb0ef41Sopenharmony_ci  // provide a special implementation for reading from it, which hides
3601cb0ef41Sopenharmony_ci  // the possibly unaligned read in the `get` method.
3611cb0ef41Sopenharmony_ci  void* data_;
3621cb0ef41Sopenharmony_ci};
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ci// Any TypedArray. It uses kTypedArrayBit with base type void
3651cb0ef41Sopenharmony_ci// Overloaded args of ArrayBufferView and TypedArray are not supported
3661cb0ef41Sopenharmony_ci// (for now) because the generic “any” ArrayBufferView doesn’t have its
3671cb0ef41Sopenharmony_ci// own instance type. It could be supported if we specify that
3681cb0ef41Sopenharmony_ci// TypedArray<T> always has precedence over the generic ArrayBufferView,
3691cb0ef41Sopenharmony_ci// but this complicates overload resolution.
3701cb0ef41Sopenharmony_cistruct FastApiArrayBufferView {
3711cb0ef41Sopenharmony_ci  void* data;
3721cb0ef41Sopenharmony_ci  size_t byte_length;
3731cb0ef41Sopenharmony_ci};
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_cistruct FastApiArrayBuffer {
3761cb0ef41Sopenharmony_ci  void* data;
3771cb0ef41Sopenharmony_ci  size_t byte_length;
3781cb0ef41Sopenharmony_ci};
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_ciclass V8_EXPORT CFunctionInfo {
3811cb0ef41Sopenharmony_ci public:
3821cb0ef41Sopenharmony_ci  // Construct a struct to hold a CFunction's type information.
3831cb0ef41Sopenharmony_ci  // |return_info| describes the function's return type.
3841cb0ef41Sopenharmony_ci  // |arg_info| is an array of |arg_count| CTypeInfos describing the
3851cb0ef41Sopenharmony_ci  //   arguments. Only the last argument may be of the special type
3861cb0ef41Sopenharmony_ci  //   CTypeInfo::kCallbackOptionsType.
3871cb0ef41Sopenharmony_ci  CFunctionInfo(const CTypeInfo& return_info, unsigned int arg_count,
3881cb0ef41Sopenharmony_ci                const CTypeInfo* arg_info);
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci  const CTypeInfo& ReturnInfo() const { return return_info_; }
3911cb0ef41Sopenharmony_ci
3921cb0ef41Sopenharmony_ci  // The argument count, not including the v8::FastApiCallbackOptions
3931cb0ef41Sopenharmony_ci  // if present.
3941cb0ef41Sopenharmony_ci  unsigned int ArgumentCount() const {
3951cb0ef41Sopenharmony_ci    return HasOptions() ? arg_count_ - 1 : arg_count_;
3961cb0ef41Sopenharmony_ci  }
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci  // |index| must be less than ArgumentCount().
3991cb0ef41Sopenharmony_ci  //  Note: if the last argument passed on construction of CFunctionInfo
4001cb0ef41Sopenharmony_ci  //  has type CTypeInfo::kCallbackOptionsType, it is not included in
4011cb0ef41Sopenharmony_ci  //  ArgumentCount().
4021cb0ef41Sopenharmony_ci  const CTypeInfo& ArgumentInfo(unsigned int index) const;
4031cb0ef41Sopenharmony_ci
4041cb0ef41Sopenharmony_ci  bool HasOptions() const {
4051cb0ef41Sopenharmony_ci    // The options arg is always the last one.
4061cb0ef41Sopenharmony_ci    return arg_count_ > 0 && arg_info_[arg_count_ - 1].GetType() ==
4071cb0ef41Sopenharmony_ci                                 CTypeInfo::kCallbackOptionsType;
4081cb0ef41Sopenharmony_ci  }
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ci private:
4111cb0ef41Sopenharmony_ci  const CTypeInfo return_info_;
4121cb0ef41Sopenharmony_ci  const unsigned int arg_count_;
4131cb0ef41Sopenharmony_ci  const CTypeInfo* arg_info_;
4141cb0ef41Sopenharmony_ci};
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_cistruct FastApiCallbackOptions;
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci// Provided for testing.
4191cb0ef41Sopenharmony_cistruct AnyCType {
4201cb0ef41Sopenharmony_ci  AnyCType() : int64_value(0) {}
4211cb0ef41Sopenharmony_ci
4221cb0ef41Sopenharmony_ci  union {
4231cb0ef41Sopenharmony_ci    bool bool_value;
4241cb0ef41Sopenharmony_ci    int32_t int32_value;
4251cb0ef41Sopenharmony_ci    uint32_t uint32_value;
4261cb0ef41Sopenharmony_ci    int64_t int64_value;
4271cb0ef41Sopenharmony_ci    uint64_t uint64_value;
4281cb0ef41Sopenharmony_ci    float float_value;
4291cb0ef41Sopenharmony_ci    double double_value;
4301cb0ef41Sopenharmony_ci    Local<Object> object_value;
4311cb0ef41Sopenharmony_ci    Local<Array> sequence_value;
4321cb0ef41Sopenharmony_ci    const FastApiTypedArray<int32_t>* int32_ta_value;
4331cb0ef41Sopenharmony_ci    const FastApiTypedArray<uint32_t>* uint32_ta_value;
4341cb0ef41Sopenharmony_ci    const FastApiTypedArray<int64_t>* int64_ta_value;
4351cb0ef41Sopenharmony_ci    const FastApiTypedArray<uint64_t>* uint64_ta_value;
4361cb0ef41Sopenharmony_ci    const FastApiTypedArray<float>* float_ta_value;
4371cb0ef41Sopenharmony_ci    const FastApiTypedArray<double>* double_ta_value;
4381cb0ef41Sopenharmony_ci    FastApiCallbackOptions* options_value;
4391cb0ef41Sopenharmony_ci  };
4401cb0ef41Sopenharmony_ci};
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_cistatic_assert(
4431cb0ef41Sopenharmony_ci    sizeof(AnyCType) == 8,
4441cb0ef41Sopenharmony_ci    "The AnyCType struct should have size == 64 bits, as this is assumed "
4451cb0ef41Sopenharmony_ci    "by EffectControlLinearizer.");
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_ciclass V8_EXPORT CFunction {
4481cb0ef41Sopenharmony_ci public:
4491cb0ef41Sopenharmony_ci  constexpr CFunction() : address_(nullptr), type_info_(nullptr) {}
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_ci  const CTypeInfo& ReturnInfo() const { return type_info_->ReturnInfo(); }
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_ci  const CTypeInfo& ArgumentInfo(unsigned int index) const {
4541cb0ef41Sopenharmony_ci    return type_info_->ArgumentInfo(index);
4551cb0ef41Sopenharmony_ci  }
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci  unsigned int ArgumentCount() const { return type_info_->ArgumentCount(); }
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_ci  const void* GetAddress() const { return address_; }
4601cb0ef41Sopenharmony_ci  const CFunctionInfo* GetTypeInfo() const { return type_info_; }
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ci  enum class OverloadResolution { kImpossible, kAtRuntime, kAtCompileTime };
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_ci  // Returns whether an overload between this and the given CFunction can
4651cb0ef41Sopenharmony_ci  // be resolved at runtime by the RTTI available for the arguments or at
4661cb0ef41Sopenharmony_ci  // compile time for functions with different number of arguments.
4671cb0ef41Sopenharmony_ci  OverloadResolution GetOverloadResolution(const CFunction* other) {
4681cb0ef41Sopenharmony_ci    // Runtime overload resolution can only deal with functions with the
4691cb0ef41Sopenharmony_ci    // same number of arguments. Functions with different arity are handled
4701cb0ef41Sopenharmony_ci    // by compile time overload resolution though.
4711cb0ef41Sopenharmony_ci    if (ArgumentCount() != other->ArgumentCount()) {
4721cb0ef41Sopenharmony_ci      return OverloadResolution::kAtCompileTime;
4731cb0ef41Sopenharmony_ci    }
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci    // The functions can only differ by a single argument position.
4761cb0ef41Sopenharmony_ci    int diff_index = -1;
4771cb0ef41Sopenharmony_ci    for (unsigned int i = 0; i < ArgumentCount(); ++i) {
4781cb0ef41Sopenharmony_ci      if (ArgumentInfo(i).GetSequenceType() !=
4791cb0ef41Sopenharmony_ci          other->ArgumentInfo(i).GetSequenceType()) {
4801cb0ef41Sopenharmony_ci        if (diff_index >= 0) {
4811cb0ef41Sopenharmony_ci          return OverloadResolution::kImpossible;
4821cb0ef41Sopenharmony_ci        }
4831cb0ef41Sopenharmony_ci        diff_index = i;
4841cb0ef41Sopenharmony_ci
4851cb0ef41Sopenharmony_ci        // We only support overload resolution between sequence types.
4861cb0ef41Sopenharmony_ci        if (ArgumentInfo(i).GetSequenceType() ==
4871cb0ef41Sopenharmony_ci                CTypeInfo::SequenceType::kScalar ||
4881cb0ef41Sopenharmony_ci            other->ArgumentInfo(i).GetSequenceType() ==
4891cb0ef41Sopenharmony_ci                CTypeInfo::SequenceType::kScalar) {
4901cb0ef41Sopenharmony_ci          return OverloadResolution::kImpossible;
4911cb0ef41Sopenharmony_ci        }
4921cb0ef41Sopenharmony_ci      }
4931cb0ef41Sopenharmony_ci    }
4941cb0ef41Sopenharmony_ci
4951cb0ef41Sopenharmony_ci    return OverloadResolution::kAtRuntime;
4961cb0ef41Sopenharmony_ci  }
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ci  template <typename F>
4991cb0ef41Sopenharmony_ci  static CFunction Make(F* func) {
5001cb0ef41Sopenharmony_ci    return ArgUnwrap<F*>::Make(func);
5011cb0ef41Sopenharmony_ci  }
5021cb0ef41Sopenharmony_ci
5031cb0ef41Sopenharmony_ci  // Provided for testing purposes.
5041cb0ef41Sopenharmony_ci  template <typename R, typename... Args, typename R_Patch,
5051cb0ef41Sopenharmony_ci            typename... Args_Patch>
5061cb0ef41Sopenharmony_ci  static CFunction Make(R (*func)(Args...),
5071cb0ef41Sopenharmony_ci                        R_Patch (*patching_func)(Args_Patch...)) {
5081cb0ef41Sopenharmony_ci    CFunction c_func = ArgUnwrap<R (*)(Args...)>::Make(func);
5091cb0ef41Sopenharmony_ci    static_assert(
5101cb0ef41Sopenharmony_ci        sizeof...(Args_Patch) == sizeof...(Args),
5111cb0ef41Sopenharmony_ci        "The patching function must have the same number of arguments.");
5121cb0ef41Sopenharmony_ci    c_func.address_ = reinterpret_cast<void*>(patching_func);
5131cb0ef41Sopenharmony_ci    return c_func;
5141cb0ef41Sopenharmony_ci  }
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci  CFunction(const void* address, const CFunctionInfo* type_info);
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci private:
5191cb0ef41Sopenharmony_ci  const void* address_;
5201cb0ef41Sopenharmony_ci  const CFunctionInfo* type_info_;
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci  template <typename F>
5231cb0ef41Sopenharmony_ci  class ArgUnwrap {
5241cb0ef41Sopenharmony_ci    static_assert(sizeof(F) != sizeof(F),
5251cb0ef41Sopenharmony_ci                  "CFunction must be created from a function pointer.");
5261cb0ef41Sopenharmony_ci  };
5271cb0ef41Sopenharmony_ci
5281cb0ef41Sopenharmony_ci  template <typename R, typename... Args>
5291cb0ef41Sopenharmony_ci  class ArgUnwrap<R (*)(Args...)> {
5301cb0ef41Sopenharmony_ci   public:
5311cb0ef41Sopenharmony_ci    static CFunction Make(R (*func)(Args...));
5321cb0ef41Sopenharmony_ci  };
5331cb0ef41Sopenharmony_ci};
5341cb0ef41Sopenharmony_ci
5351cb0ef41Sopenharmony_ci/**
5361cb0ef41Sopenharmony_ci * A struct which may be passed to a fast call callback, like so:
5371cb0ef41Sopenharmony_ci * \code
5381cb0ef41Sopenharmony_ci *    void FastMethodWithOptions(int param, FastApiCallbackOptions& options);
5391cb0ef41Sopenharmony_ci * \endcode
5401cb0ef41Sopenharmony_ci */
5411cb0ef41Sopenharmony_cistruct FastApiCallbackOptions {
5421cb0ef41Sopenharmony_ci  /**
5431cb0ef41Sopenharmony_ci   * Creates a new instance of FastApiCallbackOptions for testing purpose.  The
5441cb0ef41Sopenharmony_ci   * returned instance may be filled with mock data.
5451cb0ef41Sopenharmony_ci   */
5461cb0ef41Sopenharmony_ci  static FastApiCallbackOptions CreateForTesting(Isolate* isolate) {
5471cb0ef41Sopenharmony_ci    return {false, {0}};
5481cb0ef41Sopenharmony_ci  }
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci  /**
5511cb0ef41Sopenharmony_ci   * If the callback wants to signal an error condition or to perform an
5521cb0ef41Sopenharmony_ci   * allocation, it must set options.fallback to true and do an early return
5531cb0ef41Sopenharmony_ci   * from the fast method. Then V8 checks the value of options.fallback and if
5541cb0ef41Sopenharmony_ci   * it's true, falls back to executing the SlowCallback, which is capable of
5551cb0ef41Sopenharmony_ci   * reporting the error (either by throwing a JS exception or logging to the
5561cb0ef41Sopenharmony_ci   * console) or doing the allocation. It's the embedder's responsibility to
5571cb0ef41Sopenharmony_ci   * ensure that the fast callback is idempotent up to the point where error and
5581cb0ef41Sopenharmony_ci   * fallback conditions are checked, because otherwise executing the slow
5591cb0ef41Sopenharmony_ci   * callback might produce visible side-effects twice.
5601cb0ef41Sopenharmony_ci   */
5611cb0ef41Sopenharmony_ci  bool fallback;
5621cb0ef41Sopenharmony_ci
5631cb0ef41Sopenharmony_ci  /**
5641cb0ef41Sopenharmony_ci   * The `data` passed to the FunctionTemplate constructor, or `undefined`.
5651cb0ef41Sopenharmony_ci   * `data_ptr` allows for default constructing FastApiCallbackOptions.
5661cb0ef41Sopenharmony_ci   */
5671cb0ef41Sopenharmony_ci  union {
5681cb0ef41Sopenharmony_ci    uintptr_t data_ptr;
5691cb0ef41Sopenharmony_ci    v8::Value data;
5701cb0ef41Sopenharmony_ci  };
5711cb0ef41Sopenharmony_ci};
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_cinamespace internal {
5741cb0ef41Sopenharmony_ci
5751cb0ef41Sopenharmony_ci// Helper to count the number of occurances of `T` in `List`
5761cb0ef41Sopenharmony_citemplate <typename T, typename... List>
5771cb0ef41Sopenharmony_cistruct count : std::integral_constant<int, 0> {};
5781cb0ef41Sopenharmony_citemplate <typename T, typename... Args>
5791cb0ef41Sopenharmony_cistruct count<T, T, Args...>
5801cb0ef41Sopenharmony_ci    : std::integral_constant<std::size_t, 1 + count<T, Args...>::value> {};
5811cb0ef41Sopenharmony_citemplate <typename T, typename U, typename... Args>
5821cb0ef41Sopenharmony_cistruct count<T, U, Args...> : count<T, Args...> {};
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_citemplate <typename RetBuilder, typename... ArgBuilders>
5851cb0ef41Sopenharmony_ciclass CFunctionInfoImpl : public CFunctionInfo {
5861cb0ef41Sopenharmony_ci  static constexpr int kOptionsArgCount =
5871cb0ef41Sopenharmony_ci      count<FastApiCallbackOptions&, ArgBuilders...>();
5881cb0ef41Sopenharmony_ci  static constexpr int kReceiverCount = 1;
5891cb0ef41Sopenharmony_ci
5901cb0ef41Sopenharmony_ci  static_assert(kOptionsArgCount == 0 || kOptionsArgCount == 1,
5911cb0ef41Sopenharmony_ci                "Only one options parameter is supported.");
5921cb0ef41Sopenharmony_ci
5931cb0ef41Sopenharmony_ci  static_assert(sizeof...(ArgBuilders) >= kOptionsArgCount + kReceiverCount,
5941cb0ef41Sopenharmony_ci                "The receiver or the options argument is missing.");
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci public:
5971cb0ef41Sopenharmony_ci  constexpr CFunctionInfoImpl()
5981cb0ef41Sopenharmony_ci      : CFunctionInfo(RetBuilder::Build(), sizeof...(ArgBuilders),
5991cb0ef41Sopenharmony_ci                      arg_info_storage_),
6001cb0ef41Sopenharmony_ci        arg_info_storage_{ArgBuilders::Build()...} {
6011cb0ef41Sopenharmony_ci    constexpr CTypeInfo::Type kReturnType = RetBuilder::Build().GetType();
6021cb0ef41Sopenharmony_ci    static_assert(kReturnType == CTypeInfo::Type::kVoid ||
6031cb0ef41Sopenharmony_ci                      kReturnType == CTypeInfo::Type::kBool ||
6041cb0ef41Sopenharmony_ci                      kReturnType == CTypeInfo::Type::kInt32 ||
6051cb0ef41Sopenharmony_ci                      kReturnType == CTypeInfo::Type::kUint32 ||
6061cb0ef41Sopenharmony_ci                      kReturnType == CTypeInfo::Type::kFloat32 ||
6071cb0ef41Sopenharmony_ci                      kReturnType == CTypeInfo::Type::kFloat64 ||
6081cb0ef41Sopenharmony_ci                      kReturnType == CTypeInfo::Type::kAny,
6091cb0ef41Sopenharmony_ci                  "64-bit int and api object values are not currently "
6101cb0ef41Sopenharmony_ci                  "supported return types.");
6111cb0ef41Sopenharmony_ci  }
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ci private:
6141cb0ef41Sopenharmony_ci  const CTypeInfo arg_info_storage_[sizeof...(ArgBuilders)];
6151cb0ef41Sopenharmony_ci};
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_citemplate <typename T>
6181cb0ef41Sopenharmony_cistruct TypeInfoHelper {
6191cb0ef41Sopenharmony_ci  static_assert(sizeof(T) != sizeof(T), "This type is not supported");
6201cb0ef41Sopenharmony_ci};
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci#define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR(T, Enum)                          \
6231cb0ef41Sopenharmony_ci  template <>                                                                 \
6241cb0ef41Sopenharmony_ci  struct TypeInfoHelper<T> {                                                  \
6251cb0ef41Sopenharmony_ci    static constexpr CTypeInfo::Flags Flags() {                               \
6261cb0ef41Sopenharmony_ci      return CTypeInfo::Flags::kNone;                                         \
6271cb0ef41Sopenharmony_ci    }                                                                         \
6281cb0ef41Sopenharmony_ci                                                                              \
6291cb0ef41Sopenharmony_ci    static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
6301cb0ef41Sopenharmony_ci    static constexpr CTypeInfo::SequenceType SequenceType() {                 \
6311cb0ef41Sopenharmony_ci      return CTypeInfo::SequenceType::kScalar;                                \
6321cb0ef41Sopenharmony_ci    }                                                                         \
6331cb0ef41Sopenharmony_ci  };
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_citemplate <CTypeInfo::Type type>
6361cb0ef41Sopenharmony_cistruct CTypeInfoTraits {};
6371cb0ef41Sopenharmony_ci
6381cb0ef41Sopenharmony_ci#define DEFINE_TYPE_INFO_TRAITS(CType, Enum)      \
6391cb0ef41Sopenharmony_ci  template <>                                     \
6401cb0ef41Sopenharmony_ci  struct CTypeInfoTraits<CTypeInfo::Type::Enum> { \
6411cb0ef41Sopenharmony_ci    using ctype = CType;                          \
6421cb0ef41Sopenharmony_ci  };
6431cb0ef41Sopenharmony_ci
6441cb0ef41Sopenharmony_ci#define PRIMITIVE_C_TYPES(V) \
6451cb0ef41Sopenharmony_ci  V(bool, kBool)             \
6461cb0ef41Sopenharmony_ci  V(int32_t, kInt32)         \
6471cb0ef41Sopenharmony_ci  V(uint32_t, kUint32)       \
6481cb0ef41Sopenharmony_ci  V(int64_t, kInt64)         \
6491cb0ef41Sopenharmony_ci  V(uint64_t, kUint64)       \
6501cb0ef41Sopenharmony_ci  V(float, kFloat32)         \
6511cb0ef41Sopenharmony_ci  V(double, kFloat64)
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ci// Same as above, but includes deprecated types for compatibility.
6541cb0ef41Sopenharmony_ci#define ALL_C_TYPES(V)               \
6551cb0ef41Sopenharmony_ci  PRIMITIVE_C_TYPES(V)               \
6561cb0ef41Sopenharmony_ci  V(void, kVoid)                     \
6571cb0ef41Sopenharmony_ci  V(v8::Local<v8::Value>, kV8Value)  \
6581cb0ef41Sopenharmony_ci  V(v8::Local<v8::Object>, kV8Value) \
6591cb0ef41Sopenharmony_ci  V(AnyCType, kAny)
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci// ApiObject was a temporary solution to wrap the pointer to the v8::Value.
6621cb0ef41Sopenharmony_ci// Please use v8::Local<v8::Value> in new code for the arguments and
6631cb0ef41Sopenharmony_ci// v8::Local<v8::Object> for the receiver, as ApiObject will be deprecated.
6641cb0ef41Sopenharmony_ci
6651cb0ef41Sopenharmony_ciALL_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR)
6661cb0ef41Sopenharmony_ciPRIMITIVE_C_TYPES(DEFINE_TYPE_INFO_TRAITS)
6671cb0ef41Sopenharmony_ci
6681cb0ef41Sopenharmony_ci#undef PRIMITIVE_C_TYPES
6691cb0ef41Sopenharmony_ci#undef ALL_C_TYPES
6701cb0ef41Sopenharmony_ci
6711cb0ef41Sopenharmony_ci#define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA(T, Enum)                       \
6721cb0ef41Sopenharmony_ci  template <>                                                                 \
6731cb0ef41Sopenharmony_ci  struct TypeInfoHelper<const FastApiTypedArray<T>&> {                        \
6741cb0ef41Sopenharmony_ci    static constexpr CTypeInfo::Flags Flags() {                               \
6751cb0ef41Sopenharmony_ci      return CTypeInfo::Flags::kNone;                                         \
6761cb0ef41Sopenharmony_ci    }                                                                         \
6771cb0ef41Sopenharmony_ci                                                                              \
6781cb0ef41Sopenharmony_ci    static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
6791cb0ef41Sopenharmony_ci    static constexpr CTypeInfo::SequenceType SequenceType() {                 \
6801cb0ef41Sopenharmony_ci      return CTypeInfo::SequenceType::kIsTypedArray;                          \
6811cb0ef41Sopenharmony_ci    }                                                                         \
6821cb0ef41Sopenharmony_ci  };
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci#define TYPED_ARRAY_C_TYPES(V) \
6851cb0ef41Sopenharmony_ci  V(int32_t, kInt32)           \
6861cb0ef41Sopenharmony_ci  V(uint32_t, kUint32)         \
6871cb0ef41Sopenharmony_ci  V(int64_t, kInt64)           \
6881cb0ef41Sopenharmony_ci  V(uint64_t, kUint64)         \
6891cb0ef41Sopenharmony_ci  V(float, kFloat32)           \
6901cb0ef41Sopenharmony_ci  V(double, kFloat64)
6911cb0ef41Sopenharmony_ci
6921cb0ef41Sopenharmony_ciTYPED_ARRAY_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA)
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_ci#undef TYPED_ARRAY_C_TYPES
6951cb0ef41Sopenharmony_ci
6961cb0ef41Sopenharmony_citemplate <>
6971cb0ef41Sopenharmony_cistruct TypeInfoHelper<v8::Local<v8::Array>> {
6981cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
6991cb0ef41Sopenharmony_ci
7001cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::kVoid; }
7011cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::SequenceType SequenceType() {
7021cb0ef41Sopenharmony_ci    return CTypeInfo::SequenceType::kIsSequence;
7031cb0ef41Sopenharmony_ci  }
7041cb0ef41Sopenharmony_ci};
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_citemplate <>
7071cb0ef41Sopenharmony_cistruct TypeInfoHelper<v8::Local<v8::Uint32Array>> {
7081cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
7091cb0ef41Sopenharmony_ci
7101cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::kUint32; }
7111cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::SequenceType SequenceType() {
7121cb0ef41Sopenharmony_ci    return CTypeInfo::SequenceType::kIsTypedArray;
7131cb0ef41Sopenharmony_ci  }
7141cb0ef41Sopenharmony_ci};
7151cb0ef41Sopenharmony_ci
7161cb0ef41Sopenharmony_citemplate <>
7171cb0ef41Sopenharmony_cistruct TypeInfoHelper<FastApiCallbackOptions&> {
7181cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
7191cb0ef41Sopenharmony_ci
7201cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::Type Type() {
7211cb0ef41Sopenharmony_ci    return CTypeInfo::kCallbackOptionsType;
7221cb0ef41Sopenharmony_ci  }
7231cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::SequenceType SequenceType() {
7241cb0ef41Sopenharmony_ci    return CTypeInfo::SequenceType::kScalar;
7251cb0ef41Sopenharmony_ci  }
7261cb0ef41Sopenharmony_ci};
7271cb0ef41Sopenharmony_ci
7281cb0ef41Sopenharmony_ci#define STATIC_ASSERT_IMPLIES(COND, ASSERTION, MSG) \
7291cb0ef41Sopenharmony_ci  static_assert(((COND) == 0) || (ASSERTION), MSG)
7301cb0ef41Sopenharmony_ci
7311cb0ef41Sopenharmony_ci}  // namespace internal
7321cb0ef41Sopenharmony_ci
7331cb0ef41Sopenharmony_citemplate <typename T, CTypeInfo::Flags... Flags>
7341cb0ef41Sopenharmony_ciclass V8_EXPORT CTypeInfoBuilder {
7351cb0ef41Sopenharmony_ci public:
7361cb0ef41Sopenharmony_ci  using BaseType = T;
7371cb0ef41Sopenharmony_ci
7381cb0ef41Sopenharmony_ci  static constexpr CTypeInfo Build() {
7391cb0ef41Sopenharmony_ci    constexpr CTypeInfo::Flags kFlags =
7401cb0ef41Sopenharmony_ci        MergeFlags(internal::TypeInfoHelper<T>::Flags(), Flags...);
7411cb0ef41Sopenharmony_ci    constexpr CTypeInfo::Type kType = internal::TypeInfoHelper<T>::Type();
7421cb0ef41Sopenharmony_ci    constexpr CTypeInfo::SequenceType kSequenceType =
7431cb0ef41Sopenharmony_ci        internal::TypeInfoHelper<T>::SequenceType();
7441cb0ef41Sopenharmony_ci
7451cb0ef41Sopenharmony_ci    STATIC_ASSERT_IMPLIES(
7461cb0ef41Sopenharmony_ci        uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kAllowSharedBit),
7471cb0ef41Sopenharmony_ci        (kSequenceType == CTypeInfo::SequenceType::kIsTypedArray ||
7481cb0ef41Sopenharmony_ci         kSequenceType == CTypeInfo::SequenceType::kIsArrayBuffer),
7491cb0ef41Sopenharmony_ci        "kAllowSharedBit is only allowed for TypedArrays and ArrayBuffers.");
7501cb0ef41Sopenharmony_ci    STATIC_ASSERT_IMPLIES(
7511cb0ef41Sopenharmony_ci        uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kEnforceRangeBit),
7521cb0ef41Sopenharmony_ci        CTypeInfo::IsIntegralType(kType),
7531cb0ef41Sopenharmony_ci        "kEnforceRangeBit is only allowed for integral types.");
7541cb0ef41Sopenharmony_ci    STATIC_ASSERT_IMPLIES(
7551cb0ef41Sopenharmony_ci        uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kClampBit),
7561cb0ef41Sopenharmony_ci        CTypeInfo::IsIntegralType(kType),
7571cb0ef41Sopenharmony_ci        "kClampBit is only allowed for integral types.");
7581cb0ef41Sopenharmony_ci    STATIC_ASSERT_IMPLIES(
7591cb0ef41Sopenharmony_ci        uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kIsRestrictedBit),
7601cb0ef41Sopenharmony_ci        CTypeInfo::IsFloatingPointType(kType),
7611cb0ef41Sopenharmony_ci        "kIsRestrictedBit is only allowed for floating point types.");
7621cb0ef41Sopenharmony_ci    STATIC_ASSERT_IMPLIES(kSequenceType == CTypeInfo::SequenceType::kIsSequence,
7631cb0ef41Sopenharmony_ci                          kType == CTypeInfo::Type::kVoid,
7641cb0ef41Sopenharmony_ci                          "Sequences are only supported from void type.");
7651cb0ef41Sopenharmony_ci    STATIC_ASSERT_IMPLIES(
7661cb0ef41Sopenharmony_ci        kSequenceType == CTypeInfo::SequenceType::kIsTypedArray,
7671cb0ef41Sopenharmony_ci        CTypeInfo::IsPrimitive(kType) || kType == CTypeInfo::Type::kVoid,
7681cb0ef41Sopenharmony_ci        "TypedArrays are only supported from primitive types or void.");
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_ci    // Return the same type with the merged flags.
7711cb0ef41Sopenharmony_ci    return CTypeInfo(internal::TypeInfoHelper<T>::Type(),
7721cb0ef41Sopenharmony_ci                     internal::TypeInfoHelper<T>::SequenceType(), kFlags);
7731cb0ef41Sopenharmony_ci  }
7741cb0ef41Sopenharmony_ci
7751cb0ef41Sopenharmony_ci private:
7761cb0ef41Sopenharmony_ci  template <typename... Rest>
7771cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::Flags MergeFlags(CTypeInfo::Flags flags,
7781cb0ef41Sopenharmony_ci                                               Rest... rest) {
7791cb0ef41Sopenharmony_ci    return CTypeInfo::Flags(uint8_t(flags) | uint8_t(MergeFlags(rest...)));
7801cb0ef41Sopenharmony_ci  }
7811cb0ef41Sopenharmony_ci  static constexpr CTypeInfo::Flags MergeFlags() { return CTypeInfo::Flags(0); }
7821cb0ef41Sopenharmony_ci};
7831cb0ef41Sopenharmony_ci
7841cb0ef41Sopenharmony_cinamespace internal {
7851cb0ef41Sopenharmony_citemplate <typename RetBuilder, typename... ArgBuilders>
7861cb0ef41Sopenharmony_ciclass CFunctionBuilderWithFunction {
7871cb0ef41Sopenharmony_ci public:
7881cb0ef41Sopenharmony_ci  explicit constexpr CFunctionBuilderWithFunction(const void* fn) : fn_(fn) {}
7891cb0ef41Sopenharmony_ci
7901cb0ef41Sopenharmony_ci  template <CTypeInfo::Flags... Flags>
7911cb0ef41Sopenharmony_ci  constexpr auto Ret() {
7921cb0ef41Sopenharmony_ci    return CFunctionBuilderWithFunction<
7931cb0ef41Sopenharmony_ci        CTypeInfoBuilder<typename RetBuilder::BaseType, Flags...>,
7941cb0ef41Sopenharmony_ci        ArgBuilders...>(fn_);
7951cb0ef41Sopenharmony_ci  }
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci  template <unsigned int N, CTypeInfo::Flags... Flags>
7981cb0ef41Sopenharmony_ci  constexpr auto Arg() {
7991cb0ef41Sopenharmony_ci    // Return a copy of the builder with the Nth arg builder merged with
8001cb0ef41Sopenharmony_ci    // template parameter pack Flags.
8011cb0ef41Sopenharmony_ci    return ArgImpl<N, Flags...>(
8021cb0ef41Sopenharmony_ci        std::make_index_sequence<sizeof...(ArgBuilders)>());
8031cb0ef41Sopenharmony_ci  }
8041cb0ef41Sopenharmony_ci
8051cb0ef41Sopenharmony_ci  auto Build() {
8061cb0ef41Sopenharmony_ci    static CFunctionInfoImpl<RetBuilder, ArgBuilders...> instance;
8071cb0ef41Sopenharmony_ci    return CFunction(fn_, &instance);
8081cb0ef41Sopenharmony_ci  }
8091cb0ef41Sopenharmony_ci
8101cb0ef41Sopenharmony_ci private:
8111cb0ef41Sopenharmony_ci  template <bool Merge, unsigned int N, CTypeInfo::Flags... Flags>
8121cb0ef41Sopenharmony_ci  struct GetArgBuilder;
8131cb0ef41Sopenharmony_ci
8141cb0ef41Sopenharmony_ci  // Returns the same ArgBuilder as the one at index N, including its flags.
8151cb0ef41Sopenharmony_ci  // Flags in the template parameter pack are ignored.
8161cb0ef41Sopenharmony_ci  template <unsigned int N, CTypeInfo::Flags... Flags>
8171cb0ef41Sopenharmony_ci  struct GetArgBuilder<false, N, Flags...> {
8181cb0ef41Sopenharmony_ci    using type =
8191cb0ef41Sopenharmony_ci        typename std::tuple_element<N, std::tuple<ArgBuilders...>>::type;
8201cb0ef41Sopenharmony_ci  };
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci  // Returns an ArgBuilder with the same base type as the one at index N,
8231cb0ef41Sopenharmony_ci  // but merges the flags with the flags in the template parameter pack.
8241cb0ef41Sopenharmony_ci  template <unsigned int N, CTypeInfo::Flags... Flags>
8251cb0ef41Sopenharmony_ci  struct GetArgBuilder<true, N, Flags...> {
8261cb0ef41Sopenharmony_ci    using type = CTypeInfoBuilder<
8271cb0ef41Sopenharmony_ci        typename std::tuple_element<N,
8281cb0ef41Sopenharmony_ci                                    std::tuple<ArgBuilders...>>::type::BaseType,
8291cb0ef41Sopenharmony_ci        std::tuple_element<N, std::tuple<ArgBuilders...>>::type::Build()
8301cb0ef41Sopenharmony_ci            .GetFlags(),
8311cb0ef41Sopenharmony_ci        Flags...>;
8321cb0ef41Sopenharmony_ci  };
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci  // Return a copy of the CFunctionBuilder, but merges the Flags on
8351cb0ef41Sopenharmony_ci  // ArgBuilder index N with the new Flags passed in the template parameter
8361cb0ef41Sopenharmony_ci  // pack.
8371cb0ef41Sopenharmony_ci  template <unsigned int N, CTypeInfo::Flags... Flags, size_t... I>
8381cb0ef41Sopenharmony_ci  constexpr auto ArgImpl(std::index_sequence<I...>) {
8391cb0ef41Sopenharmony_ci    return CFunctionBuilderWithFunction<
8401cb0ef41Sopenharmony_ci        RetBuilder, typename GetArgBuilder<N == I, I, Flags...>::type...>(fn_);
8411cb0ef41Sopenharmony_ci  }
8421cb0ef41Sopenharmony_ci
8431cb0ef41Sopenharmony_ci  const void* fn_;
8441cb0ef41Sopenharmony_ci};
8451cb0ef41Sopenharmony_ci
8461cb0ef41Sopenharmony_ciclass CFunctionBuilder {
8471cb0ef41Sopenharmony_ci public:
8481cb0ef41Sopenharmony_ci  constexpr CFunctionBuilder() {}
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ci  template <typename R, typename... Args>
8511cb0ef41Sopenharmony_ci  constexpr auto Fn(R (*fn)(Args...)) {
8521cb0ef41Sopenharmony_ci    return CFunctionBuilderWithFunction<CTypeInfoBuilder<R>,
8531cb0ef41Sopenharmony_ci                                        CTypeInfoBuilder<Args>...>(
8541cb0ef41Sopenharmony_ci        reinterpret_cast<const void*>(fn));
8551cb0ef41Sopenharmony_ci  }
8561cb0ef41Sopenharmony_ci};
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci}  // namespace internal
8591cb0ef41Sopenharmony_ci
8601cb0ef41Sopenharmony_ci// static
8611cb0ef41Sopenharmony_citemplate <typename R, typename... Args>
8621cb0ef41Sopenharmony_ciCFunction CFunction::ArgUnwrap<R (*)(Args...)>::Make(R (*func)(Args...)) {
8631cb0ef41Sopenharmony_ci  return internal::CFunctionBuilder().Fn(func).Build();
8641cb0ef41Sopenharmony_ci}
8651cb0ef41Sopenharmony_ci
8661cb0ef41Sopenharmony_ciusing CFunctionBuilder = internal::CFunctionBuilder;
8671cb0ef41Sopenharmony_ci
8681cb0ef41Sopenharmony_cistatic constexpr CTypeInfo kTypeInfoInt32 = CTypeInfo(CTypeInfo::Type::kInt32);
8691cb0ef41Sopenharmony_cistatic constexpr CTypeInfo kTypeInfoFloat64 =
8701cb0ef41Sopenharmony_ci    CTypeInfo(CTypeInfo::Type::kFloat64);
8711cb0ef41Sopenharmony_ci
8721cb0ef41Sopenharmony_ci/**
8731cb0ef41Sopenharmony_ci * Copies the contents of this JavaScript array to a C++ buffer with
8741cb0ef41Sopenharmony_ci * a given max_length. A CTypeInfo is passed as an argument,
8751cb0ef41Sopenharmony_ci * instructing different rules for conversion (e.g. restricted float/double).
8761cb0ef41Sopenharmony_ci * The element type T of the destination array must match the C type
8771cb0ef41Sopenharmony_ci * corresponding to the CTypeInfo (specified by CTypeInfoTraits).
8781cb0ef41Sopenharmony_ci * If the array length is larger than max_length or the array is of
8791cb0ef41Sopenharmony_ci * unsupported type, the operation will fail, returning false. Generally, an
8801cb0ef41Sopenharmony_ci * array which contains objects, undefined, null or anything not convertible
8811cb0ef41Sopenharmony_ci * to the requested destination type, is considered unsupported. The operation
8821cb0ef41Sopenharmony_ci * returns true on success. `type_info` will be used for conversions.
8831cb0ef41Sopenharmony_ci */
8841cb0ef41Sopenharmony_citemplate <const CTypeInfo* type_info, typename T>
8851cb0ef41Sopenharmony_ciV8_DEPRECATED(
8861cb0ef41Sopenharmony_ci    "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
8871cb0ef41Sopenharmony_cibool V8_EXPORT V8_WARN_UNUSED_RESULT
8881cb0ef41Sopenharmony_ci    TryCopyAndConvertArrayToCppBuffer(Local<Array> src, T* dst,
8891cb0ef41Sopenharmony_ci                                      uint32_t max_length);
8901cb0ef41Sopenharmony_ci
8911cb0ef41Sopenharmony_citemplate <>
8921cb0ef41Sopenharmony_ciV8_DEPRECATED(
8931cb0ef41Sopenharmony_ci    "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
8941cb0ef41Sopenharmony_ciinline bool V8_WARN_UNUSED_RESULT
8951cb0ef41Sopenharmony_ci    TryCopyAndConvertArrayToCppBuffer<&kTypeInfoInt32, int32_t>(
8961cb0ef41Sopenharmony_ci        Local<Array> src, int32_t* dst, uint32_t max_length) {
8971cb0ef41Sopenharmony_ci  return false;
8981cb0ef41Sopenharmony_ci}
8991cb0ef41Sopenharmony_ci
9001cb0ef41Sopenharmony_citemplate <>
9011cb0ef41Sopenharmony_ciV8_DEPRECATED(
9021cb0ef41Sopenharmony_ci    "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
9031cb0ef41Sopenharmony_ciinline bool V8_WARN_UNUSED_RESULT
9041cb0ef41Sopenharmony_ci    TryCopyAndConvertArrayToCppBuffer<&kTypeInfoFloat64, double>(
9051cb0ef41Sopenharmony_ci        Local<Array> src, double* dst, uint32_t max_length) {
9061cb0ef41Sopenharmony_ci  return false;
9071cb0ef41Sopenharmony_ci}
9081cb0ef41Sopenharmony_ci
9091cb0ef41Sopenharmony_citemplate <CTypeInfo::Identifier type_info_id, typename T>
9101cb0ef41Sopenharmony_cibool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(
9111cb0ef41Sopenharmony_ci    Local<Array> src, T* dst, uint32_t max_length);
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_citemplate <>
9141cb0ef41Sopenharmony_cibool V8_EXPORT V8_WARN_UNUSED_RESULT
9151cb0ef41Sopenharmony_ciTryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<int32_t>::Build().GetId(),
9161cb0ef41Sopenharmony_ci                                    int32_t>(Local<Array> src, int32_t* dst,
9171cb0ef41Sopenharmony_ci                                             uint32_t max_length);
9181cb0ef41Sopenharmony_ci
9191cb0ef41Sopenharmony_citemplate <>
9201cb0ef41Sopenharmony_cibool V8_EXPORT V8_WARN_UNUSED_RESULT
9211cb0ef41Sopenharmony_ciTryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<uint32_t>::Build().GetId(),
9221cb0ef41Sopenharmony_ci                                    uint32_t>(Local<Array> src, uint32_t* dst,
9231cb0ef41Sopenharmony_ci                                              uint32_t max_length);
9241cb0ef41Sopenharmony_ci
9251cb0ef41Sopenharmony_citemplate <>
9261cb0ef41Sopenharmony_cibool V8_EXPORT V8_WARN_UNUSED_RESULT
9271cb0ef41Sopenharmony_ciTryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<float>::Build().GetId(),
9281cb0ef41Sopenharmony_ci                                    float>(Local<Array> src, float* dst,
9291cb0ef41Sopenharmony_ci                                           uint32_t max_length);
9301cb0ef41Sopenharmony_ci
9311cb0ef41Sopenharmony_citemplate <>
9321cb0ef41Sopenharmony_cibool V8_EXPORT V8_WARN_UNUSED_RESULT
9331cb0ef41Sopenharmony_ciTryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<double>::Build().GetId(),
9341cb0ef41Sopenharmony_ci                                    double>(Local<Array> src, double* dst,
9351cb0ef41Sopenharmony_ci                                            uint32_t max_length);
9361cb0ef41Sopenharmony_ci
9371cb0ef41Sopenharmony_ci}  // namespace v8
9381cb0ef41Sopenharmony_ci
9391cb0ef41Sopenharmony_ci#endif  // INCLUDE_V8_FAST_API_CALLS_H_
940