5#ifndef INCLUDE_V8_FAST_API_CALLS_H_
6#define INCLUDE_V8_FAST_API_CALLS_H_
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
210#include <type_traits>
264 : type_(type), flags_(flags) {}
268 : type_(
static_cast<
Type>((identifier >> 8) & 255)),
269 flags_(
static_cast<
Flags>(identifier & 255)) {}
271 return static_cast<uint8_t>(type_) << 8 |
272 static_cast<uint8_t>(flags_);
337 return arg_count_ > 0 && arg_info_[arg_count_ - 1]
.GetType() ==
344 const unsigned int arg_count_;
380 "The union AnyCType should have size == 64 bits, as this is assumed "
381 "by EffectControlLinearizer.");
385 constexpr CFunction() : address_(
nullptr), type_info_(
nullptr) {}
403 template <
typename F>
407 CFunction result = ArgUnwrap<F*>::Make(func, int64_rep);
413 template <
typename R,
typename... Args,
typename R_Patch,
414 typename... Args_Patch>
416 R_Patch (*patching_func)(Args_Patch...),
419 CFunction c_func = ArgUnwrap<R (*)(Args...)>::Make(func, int64_rep);
421 sizeof...(Args_Patch) ==
sizeof...(Args),
422 "The patching function must have the same number of arguments.");
423 c_func.address_ =
reinterpret_cast<
void*>(patching_func);
430 const void* address_;
433 template <
typename F>
435 static_assert(
sizeof(F) !=
sizeof(F),
436 "CFunction must be created from a function pointer.");
439 template <
typename R,
typename... Args>
440 class ArgUnwrap<R (*)(Args...)> {
442 static CFunction Make(R (*func)(Args...),
449
450
451
452
453
456
457
458
466
467
474template <
typename T,
typename... List>
476template <
typename T,
typename... Args>
479template <
typename T,
typename U,
typename... Args>
483 typename RetBuilder,
typename... ArgBuilders>
485 static constexpr int kOptionsArgCount =
487 static constexpr int kReceiverCount = 1;
489 static_assert(kOptionsArgCount == 0 || kOptionsArgCount == 1,
490 "Only one options parameter is supported.");
492 static_assert(
sizeof...(ArgBuilders) >= kOptionsArgCount + kReceiverCount,
493 "The receiver or the options argument is missing.");
498 arg_info_storage_, Representation),
499 arg_info_storage_{ArgBuilders::Build()...} {
500 constexpr CTypeInfo::
Type kReturnType = RetBuilder::Build().GetType();
511 "String and api object values are not currently "
512 "supported return types.");
516 const CTypeInfo arg_info_storage_[
sizeof...(ArgBuilders)];
521 static_assert(
sizeof(T) !=
sizeof(T),
"This type is not supported");
524#define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR(T, Enum)
526 struct TypeInfoHelper<T> {
527 static constexpr CTypeInfo::Flags Flags() {
528 return CTypeInfo::Flags::kNone;
531 static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; }
537#define DEFINE_TYPE_INFO_TRAITS(CType, Enum)
539 struct CTypeInfoTraits<CTypeInfo::Type::Enum> {
543#define PRIMITIVE_C_TYPES(V)
555#define ALL_C_TYPES(V)
558 V(v8::Local<v8::Value>, kV8Value)
559 V(v8::Local<v8::Object>, kV8Value)
560 V(v8::Local<v8::Array>, kV8Value)
570#undef PRIMITIVE_C_TYPES
573#undef TYPED_ARRAY_C_TYPES
593#define STATIC_ASSERT_IMPLIES(COND, ASSERTION, MSG)
594 static_assert(((COND) == 0
) || (ASSERTION), MSG)
611 "kEnforceRangeBit is only allowed for integral types.");
615 "kClampBit is only allowed for integral types.");
619 "kIsRestrictedBit is only allowed for floating point types.");
626 template <
typename... Rest>
629 return CTypeInfo::
Flags(uint8_t(flags) | uint8_t(MergeFlags(rest...)));
635template <
typename RetBuilder,
typename... ArgBuilders>
636class CFunctionBuilderWithFunction {
638 explicit constexpr CFunctionBuilderWithFunction(
const void* fn) : fn_(fn) {}
641 constexpr auto Ret() {
642 return CFunctionBuilderWithFunction<
644 ArgBuilders...>(fn_);
648 constexpr auto Arg() {
651 return ArgImpl<N, Flags...>(
652 std::make_index_sequence<
sizeof...(ArgBuilders)>());
656 template <
typename Ret,
typename... Args>
657 auto Patch(Ret (*patching_func)(Args...)) {
659 sizeof...(Args) ==
sizeof...(ArgBuilders),
660 "The patching function must have the same number of arguments.");
661 fn_ =
reinterpret_cast<
void*>(patching_func);
675 struct GetArgBuilder;
680 struct GetArgBuilder<
false, N, Flags...> {
681 using type = std::tuple_element_t<N, std::tuple<ArgBuilders...>>;
687 struct GetArgBuilder<
true, N, Flags...> {
688 using type = CTypeInfoBuilder<
689 typename std::tuple_element_t<N, std::tuple<ArgBuilders...>>::BaseType,
690 std::tuple_element_t<N, std::tuple<ArgBuilders...>>::Build().GetFlags(),
698 constexpr auto ArgImpl(std::index_sequence<I...>) {
699 return CFunctionBuilderWithFunction<
700 RetBuilder,
typename GetArgBuilder<N == I, I, Flags...>::type...>(fn_);
706class CFunctionBuilder {
708 constexpr CFunctionBuilder() {}
710 template <
typename R,
typename... Args>
711 constexpr auto Fn(R (*fn)(Args...)) {
714 reinterpret_cast<
const void*>(fn));
721template <
typename R,
typename... Args>
725 return internal::CFunctionBuilder().Fn(func).Build();
732using CFunctionBuilder =
internal::CFunctionBuilder;
735static constexpr CTypeInfo kTypeInfoFloat64 =
739
740
741
742
743
744
745
746
747
748
749
752 Local<
Array> src, T* dst, uint32_t max_length);
CFunction(const void *address, const CFunctionInfo *type_info)
const CTypeInfo & ArgumentInfo(unsigned int index) const
CFunctionInfo::Int64Representation GetInt64Representation() const
const void * GetAddress() const
const CFunctionInfo * GetTypeInfo() const
unsigned int ArgumentCount() const
static CFunction Make(F *func, CFunctionInfo::Int64Representation int64_rep=CFunctionInfo::Int64Representation::kNumber)
const CTypeInfo & ReturnInfo() const
static CFunction Make(R(*func)(Args...), R_Patch(*patching_func)(Args_Patch...), CFunctionInfo::Int64Representation int64_rep=CFunctionInfo::Int64Representation::kNumber)
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 CTypeInfo(Type type, Flags flags=Flags::kNone)
constexpr Identifier GetId() const
static constexpr Type kCallbackOptionsType
static constexpr bool IsIntegralType(Type type)
constexpr CTypeInfo(Identifier identifier)
constexpr Flags GetFlags() const
static constexpr bool IsFloatingPointType(Type type)
constexpr Type GetType() const
static constexpr bool IsPrimitive(Type type)
constexpr CFunctionInfoImpl()
bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(Local< Array > src, T *dst, uint32_t max_length)
static FastApiCallbackOptions CreateForTesting(Isolate *isolate)
v8::Local< v8::Value > data
const FastOneByteString * string_value
FastApiCallbackOptions * options_value
Local< Object > object_value
Local< Array > sequence_value
#define PRIMITIVE_C_TYPES(V)
#define STATIC_ASSERT_IMPLIES(COND, ASSERTION, MSG)
#define V8_HAS_ATTRIBUTE_TRIVIAL_ABI
#define V8_WARN_UNUSED_RESULT