219#ifndef INCLUDE_V8_FAST_API_CALLS_H_
220#define INCLUDE_V8_FAST_API_CALLS_H_
226#include <type_traits>
290 : type_(type), sequence_type_(sequence_type), flags_(flags) {}
296 static_cast<
Flags>(identifier & 255)) {}
298 return static_cast<uint8_t
>(type_) << 16 |
299 static_cast<uint8_t
>(sequence_type_) << 8 |
300 static_cast<uint8_t
>(flags_);
347 memcpy(&tmp,
static_cast<void*
>(
reinterpret_cast<T*
>(data_) + index),
353 if (
reinterpret_cast<uintptr_t
>(data_) %
alignof(T) != 0) {
356 *elements =
reinterpret_cast<T*
>(data_);
411 return HasOptions() ? arg_count_ - 1 : arg_count_;
424 return arg_count_ > 0 && arg_info_[arg_count_ - 1].GetType() ==
425 CTypeInfo::kCallbackOptionsType;
430 const Int64Representation repr_;
431 const unsigned int arg_count_;
435struct FastApiCallbackOptions;
441#if defined(V8_ENABLE_LOCAL_OFF_STACK_CHECK) && V8_HAS_ATTRIBUTE_TRIVIAL_ABI
445 AnyCType& operator=(
const AnyCType& other) {
446 int64_value = other.int64_value;
474 "The union AnyCType should have size == 64 bits, as this is assumed "
475 "by EffectControlLinearizer.");
479 constexpr CFunction() : address_(nullptr), type_info_(nullptr) {}
484 return type_info_->ArgumentInfo(index);
491 return type_info_->GetInt64Representation();
505 return OverloadResolution::kAtCompileTime;
510 for (
unsigned int i = 0; i < ArgumentCount(); ++i) {
511 if (ArgumentInfo(i).GetSequenceType() !=
513 if (diff_index >= 0) {
514 return OverloadResolution::kImpossible;
519 if (ArgumentInfo(i).GetSequenceType() ==
520 CTypeInfo::SequenceType::kScalar ||
522 CTypeInfo::SequenceType::kScalar) {
523 return OverloadResolution::kImpossible;
528 return OverloadResolution::kAtRuntime;
531 template <
typename F>
533 return ArgUnwrap<F*>::Make(func);
537 template <
typename R,
typename... Args,
typename R_Patch,
538 typename... Args_Patch>
540 R_Patch (*patching_func)(Args_Patch...)) {
541 CFunction c_func = ArgUnwrap<R (*)(Args...)>::Make(func);
543 sizeof...(Args_Patch) ==
sizeof...(Args),
544 "The patching function must have the same number of arguments.");
545 c_func.address_ =
reinterpret_cast<void*
>(patching_func);
552 const void* address_;
555 template <
typename F>
557 static_assert(
sizeof(F) !=
sizeof(F),
558 "CFunction must be created from a function pointer.");
561 template <
typename R,
typename... Args>
562 class ArgUnwrap<R (*)(Args...)> {
564 static CFunction Make(R (*func)(Args...));
580 return {
false, {0},
nullptr};
614template <
typename T,
typename... List>
615struct count : std::integral_constant<int, 0> {};
616template <
typename T,
typename... Args>
618 : std::integral_constant<std::size_t, 1 + count<T, Args...>::value> {};
619template <
typename T,
typename U,
typename... Args>
623 typename RetBuilder,
typename... ArgBuilders>
625 static constexpr int kOptionsArgCount =
627 static constexpr int kReceiverCount = 1;
629 static_assert(kOptionsArgCount == 0 || kOptionsArgCount == 1,
630 "Only one options parameter is supported.");
632 static_assert(
sizeof...(ArgBuilders) >= kOptionsArgCount + kReceiverCount,
633 "The receiver or the options argument is missing.");
638 arg_info_storage_, Representation),
639 arg_info_storage_{ArgBuilders::Build()...} {
651 "String and api object values are not currently "
652 "supported return types.");
656 const CTypeInfo arg_info_storage_[
sizeof...(ArgBuilders)];
661 static_assert(
sizeof(T) !=
sizeof(T),
"This type is not supported");
664#define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR(T, Enum) \
666 struct TypeInfoHelper<T> { \
667 static constexpr CTypeInfo::Flags Flags() { \
668 return CTypeInfo::Flags::kNone; \
671 static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
672 static constexpr CTypeInfo::SequenceType SequenceType() { \
673 return CTypeInfo::SequenceType::kScalar; \
677template <CTypeInfo::Type type>
680#define DEFINE_TYPE_INFO_TRAITS(CType, Enum) \
682 struct CTypeInfoTraits<CTypeInfo::Type::Enum> { \
683 using ctype = CType; \
686#define PRIMITIVE_C_TYPES(V) \
690 V(uint32_t, kUint32) \
692 V(uint64_t, kUint64) \
694 V(double, kFloat64) \
698#define ALL_C_TYPES(V) \
699 PRIMITIVE_C_TYPES(V) \
701 V(v8::Local<v8::Value>, kV8Value) \
702 V(v8::Local<v8::Object>, kV8Value) \
712#undef PRIMITIVE_C_TYPES
715#define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA(T, Enum) \
717 struct TypeInfoHelper<const FastApiTypedArray<T>&> { \
718 static constexpr CTypeInfo::Flags Flags() { \
719 return CTypeInfo::Flags::kNone; \
722 static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
723 static constexpr CTypeInfo::SequenceType SequenceType() { \
724 return CTypeInfo::SequenceType::kIsTypedArray; \
728#define TYPED_ARRAY_C_TYPES(V) \
731 V(uint32_t, kUint32) \
733 V(uint64_t, kUint64) \
739#undef TYPED_ARRAY_C_TYPES
785#define STATIC_ASSERT_IMPLIES(COND, ASSERTION, MSG) \
786 static_assert(((COND) == 0) || (ASSERTION), MSG)
803 uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kAllowSharedBit),
804 (kSequenceType == CTypeInfo::SequenceType::kIsTypedArray ||
805 kSequenceType == CTypeInfo::SequenceType::kIsArrayBuffer),
806 "kAllowSharedBit is only allowed for TypedArrays and ArrayBuffers.");
808 uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kEnforceRangeBit),
809 CTypeInfo::IsIntegralType(kType),
810 "kEnforceRangeBit is only allowed for integral types.");
812 uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kClampBit),
813 CTypeInfo::IsIntegralType(kType),
814 "kClampBit is only allowed for integral types.");
816 uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kIsRestrictedBit),
817 CTypeInfo::IsFloatingPointType(kType),
818 "kIsRestrictedBit is only allowed for floating point types.");
820 kType == CTypeInfo::Type::kVoid,
821 "Sequences are only supported from void type.");
823 kSequenceType == CTypeInfo::SequenceType::kIsTypedArray,
824 CTypeInfo::IsPrimitive(kType) || kType == CTypeInfo::Type::kVoid,
825 "TypedArrays are only supported from primitive types or void.");
833 template <
typename... Rest>
838 static constexpr CTypeInfo::Flags MergeFlags() {
return CTypeInfo::Flags(0); }
842template <
typename RetBuilder,
typename... ArgBuilders>
851 ArgBuilders...>(fn_);
858 return ArgImpl<N, Flags...>(
859 std::make_index_sequence<
sizeof...(ArgBuilders)>());
863 template <
typename Ret,
typename... Args>
866 sizeof...(Args) ==
sizeof...(ArgBuilders),
867 "The patching function must have the same number of arguments.");
868 fn_ =
reinterpret_cast<void*
>(patching_func);
882 struct GetArgBuilder;
887 struct GetArgBuilder<false, N, Flags...> {
889 typename std::tuple_element<N, std::tuple<ArgBuilders...>>::type;
895 struct GetArgBuilder<true, N, Flags...> {
897 typename std::tuple_element<N,
898 std::tuple<ArgBuilders...>>::type::BaseType,
899 std::tuple_element<N, std::tuple<ArgBuilders...>>::type::Build()
908 constexpr auto ArgImpl(std::index_sequence<I...>) {
909 return CFunctionBuilderWithFunction<
910 RetBuilder,
typename GetArgBuilder<N == I, I, Flags...>::type...>(fn_);
920 template <
typename R,
typename... Args>
921 constexpr auto Fn(R (*fn)(Args...)) {
924 reinterpret_cast<const void*
>(fn));
931template <
typename R,
typename... Args>
932CFunction CFunction::ArgUnwrap<R (*)(Args...)>::Make(R (*func)(Args...)) {
933 return internal::CFunctionBuilder().Fn(func).
Build();
939static constexpr CTypeInfo kTypeInfoFloat64 =
954template <CTypeInfo::Identifier type_info_
id,
typename T>
960TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<int32_t>::Build().GetId(),
962 uint32_t max_length);
966TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<uint32_t>::Build().GetId(),
968 uint32_t max_length);
972TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<float>::Build().GetId(),
974 uint32_t max_length);
978TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<double>::Build().GetId(),
980 uint32_t max_length);
CFunction(const void *address, const CFunctionInfo *type_info)
static CFunction Make(R(*func)(Args...), R_Patch(*patching_func)(Args_Patch...))
const CTypeInfo & ArgumentInfo(unsigned int index) const
CFunctionInfo::Int64Representation GetInt64Representation() const
OverloadResolution GetOverloadResolution(const CFunction *other)
const void * GetAddress() const
const CFunctionInfo * GetTypeInfo() const
unsigned int ArgumentCount() const
const CTypeInfo & ReturnInfo() const
static CFunction Make(F *func)
Int64Representation GetInt64Representation() const
const CTypeInfo & ArgumentInfo(unsigned int index) const
unsigned int ArgumentCount() const
CFunctionInfo(const CTypeInfo &return_info, unsigned int arg_count, const CTypeInfo *arg_info, Int64Representation repr=Int64Representation::kNumber)
const CTypeInfo & ReturnInfo() const
static constexpr CTypeInfo Build()
constexpr Identifier GetId() const
constexpr SequenceType GetSequenceType() const
static constexpr Type kCallbackOptionsType
static constexpr bool IsIntegralType(Type type)
constexpr CTypeInfo(Identifier identifier)
constexpr CTypeInfo(Type type, SequenceType sequence_type=SequenceType::kScalar, Flags flags=Flags::kNone)
constexpr Flags GetFlags() const
static constexpr bool IsFloatingPointType(Type type)
constexpr Type GetType() const
static constexpr bool IsPrimitive(Type type)
constexpr CFunctionBuilder()
constexpr auto Fn(R(*fn)(Args...))
constexpr CFunctionBuilderWithFunction(const void *fn)
auto Patch(Ret(*patching_func)(Args...))
constexpr CFunctionInfoImpl()
bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(Local< Array > src, T *dst, uint32_t max_length)
FastApiTypedArray< uint8_t > *const wasm_memory
static FastApiCallbackOptions CreateForTesting(Isolate *isolate)
v8::Local< v8::Value > data
void V8_EXPORT ValidateIndex(size_t index) const
size_t V8_EXPORT length() const
V8_INLINE T get(size_t index) const
bool getStorageIfAligned(T **elements) const
static constexpr CTypeInfo::Flags Flags()
static constexpr CTypeInfo::Type Type()
static constexpr CTypeInfo::SequenceType SequenceType()
static constexpr CTypeInfo::Flags Flags()
static constexpr CTypeInfo::Type Type()
static constexpr CTypeInfo::SequenceType SequenceType()
static constexpr CTypeInfo::Flags Flags()
static constexpr CTypeInfo::Type Type()
static constexpr CTypeInfo::SequenceType SequenceType()
static constexpr CTypeInfo::Flags Flags()
static constexpr CTypeInfo::Type Type()
static constexpr CTypeInfo::SequenceType SequenceType()
const FastOneByteString * string_value
const FastApiTypedArray< int32_t > * int32_ta_value
const FastApiTypedArray< uint8_t > * uint8_ta_value
const FastApiTypedArray< uint32_t > * uint32_ta_value
FastApiCallbackOptions * options_value
const FastApiTypedArray< float > * float_ta_value
const FastApiTypedArray< double > * double_ta_value
Local< Object > object_value
Local< Array > sequence_value
const FastApiTypedArray< int64_t > * int64_ta_value
const FastApiTypedArray< uint64_t > * uint64_ta_value
#define DEFINE_TYPE_INFO_TRAITS(CType, Enum)
#define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA(T, Enum)
#define PRIMITIVE_C_TYPES(V)
#define TYPED_ARRAY_C_TYPES(V)
#define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR(T, Enum)
#define STATIC_ASSERT_IMPLIES(COND, ASSERTION, MSG)
#define V8_WARN_UNUSED_RESULT