libv8-node 15.12.0.0.beta1-aarch64-linux-musl → 17.9.1.0-aarch64-linux-musl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libv8-node/location.rb +1 -1
  3. data/ext/libv8-node/paths.rb +5 -1
  4. data/lib/libv8/node/version.rb +3 -3
  5. data/vendor/v8/{out.gn → aarch64-linux-musl}/libv8/obj/libv8_monolith.a +0 -0
  6. data/vendor/v8/include/cppgc/allocation.h +110 -44
  7. data/vendor/v8/include/cppgc/common.h +9 -6
  8. data/vendor/v8/include/cppgc/cross-thread-persistent.h +465 -0
  9. data/vendor/v8/include/cppgc/custom-space.h +37 -2
  10. data/vendor/v8/include/cppgc/default-platform.h +47 -48
  11. data/vendor/v8/include/cppgc/ephemeron-pair.h +30 -0
  12. data/vendor/v8/include/cppgc/explicit-management.h +82 -0
  13. data/vendor/v8/include/cppgc/garbage-collected.h +4 -3
  14. data/vendor/v8/include/cppgc/heap-consistency.h +253 -0
  15. data/vendor/v8/include/cppgc/heap-state.h +70 -0
  16. data/vendor/v8/include/cppgc/heap-statistics.h +120 -0
  17. data/vendor/v8/include/cppgc/heap.h +68 -6
  18. data/vendor/v8/include/cppgc/internal/api-constants.h +3 -3
  19. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +4 -3
  20. data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
  21. data/vendor/v8/include/cppgc/internal/finalizer-trait.h +2 -0
  22. data/vendor/v8/include/cppgc/internal/gc-info.h +124 -13
  23. data/vendor/v8/include/cppgc/internal/name-trait.h +122 -0
  24. data/vendor/v8/include/cppgc/internal/persistent-node.h +94 -6
  25. data/vendor/v8/include/cppgc/internal/pointer-policies.h +81 -29
  26. data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +1 -1
  27. data/vendor/v8/include/cppgc/internal/write-barrier.h +398 -35
  28. data/vendor/v8/include/cppgc/liveness-broker.h +11 -2
  29. data/vendor/v8/include/cppgc/macros.h +2 -0
  30. data/vendor/v8/include/cppgc/member.h +87 -25
  31. data/vendor/v8/include/cppgc/name-provider.h +65 -0
  32. data/vendor/v8/include/cppgc/object-size-trait.h +58 -0
  33. data/vendor/v8/include/cppgc/persistent.h +41 -11
  34. data/vendor/v8/include/cppgc/platform.h +49 -25
  35. data/vendor/v8/include/cppgc/prefinalizer.h +2 -2
  36. data/vendor/v8/include/cppgc/process-heap-statistics.h +36 -0
  37. data/vendor/v8/include/cppgc/sentinel-pointer.h +32 -0
  38. data/vendor/v8/include/cppgc/source-location.h +2 -1
  39. data/vendor/v8/include/cppgc/testing.h +99 -0
  40. data/vendor/v8/include/cppgc/trace-trait.h +8 -3
  41. data/vendor/v8/include/cppgc/type-traits.h +157 -19
  42. data/vendor/v8/include/cppgc/visitor.h +194 -28
  43. data/vendor/v8/include/libplatform/libplatform.h +11 -0
  44. data/vendor/v8/include/libplatform/v8-tracing.h +2 -0
  45. data/vendor/v8/include/v8-array-buffer.h +433 -0
  46. data/vendor/v8/include/v8-callbacks.h +377 -0
  47. data/vendor/v8/include/v8-container.h +129 -0
  48. data/vendor/v8/include/v8-context.h +418 -0
  49. data/vendor/v8/include/v8-cppgc.h +261 -159
  50. data/vendor/v8/include/v8-data.h +65 -0
  51. data/vendor/v8/include/v8-date.h +43 -0
  52. data/vendor/v8/include/v8-debug.h +151 -0
  53. data/vendor/v8/include/v8-embedder-heap.h +238 -0
  54. data/vendor/v8/include/v8-exception.h +224 -0
  55. data/vendor/v8/include/v8-extension.h +62 -0
  56. data/vendor/v8/include/v8-external.h +37 -0
  57. data/vendor/v8/include/v8-fast-api-calls.h +652 -152
  58. data/vendor/v8/include/v8-forward.h +81 -0
  59. data/vendor/v8/include/v8-function-callback.h +475 -0
  60. data/vendor/v8/include/v8-function.h +122 -0
  61. data/vendor/v8/include/v8-initialization.h +282 -0
  62. data/vendor/v8/include/v8-inspector.h +33 -25
  63. data/vendor/v8/include/v8-internal.h +178 -31
  64. data/vendor/v8/include/v8-isolate.h +1662 -0
  65. data/vendor/v8/include/v8-json.h +47 -0
  66. data/vendor/v8/include/v8-local-handle.h +459 -0
  67. data/vendor/v8/include/v8-locker.h +148 -0
  68. data/vendor/v8/include/v8-maybe.h +137 -0
  69. data/vendor/v8/include/v8-memory-span.h +43 -0
  70. data/vendor/v8/include/v8-message.h +241 -0
  71. data/vendor/v8/include/v8-metrics.h +114 -9
  72. data/vendor/v8/include/v8-microtask-queue.h +152 -0
  73. data/vendor/v8/include/v8-microtask.h +28 -0
  74. data/vendor/v8/include/v8-object.h +770 -0
  75. data/vendor/v8/include/v8-persistent-handle.h +590 -0
  76. data/vendor/v8/include/v8-platform.h +74 -25
  77. data/vendor/v8/include/v8-primitive-object.h +118 -0
  78. data/vendor/v8/include/v8-primitive.h +858 -0
  79. data/vendor/v8/include/v8-profiler.h +72 -9
  80. data/vendor/v8/include/v8-promise.h +174 -0
  81. data/vendor/v8/include/v8-proxy.h +50 -0
  82. data/vendor/v8/include/v8-regexp.h +105 -0
  83. data/vendor/v8/include/v8-script.h +771 -0
  84. data/vendor/v8/include/v8-snapshot.h +198 -0
  85. data/vendor/v8/include/v8-statistics.h +215 -0
  86. data/vendor/v8/include/v8-template.h +1052 -0
  87. data/vendor/v8/include/v8-traced-handle.h +605 -0
  88. data/vendor/v8/include/v8-typed-array.h +282 -0
  89. data/vendor/v8/include/v8-unwinder-state.h +31 -0
  90. data/vendor/v8/include/v8-unwinder.h +129 -0
  91. data/vendor/v8/include/v8-util.h +8 -2
  92. data/vendor/v8/include/v8-value-serializer.h +249 -0
  93. data/vendor/v8/include/v8-value.h +526 -0
  94. data/vendor/v8/include/v8-version.h +3 -3
  95. data/vendor/v8/include/v8-wasm.h +245 -0
  96. data/vendor/v8/include/v8-weak-callback-info.h +73 -0
  97. data/vendor/v8/include/v8.h +41 -12050
  98. data/vendor/v8/include/v8config.h +87 -11
  99. metadata +65 -11
  100. data/vendor/v8/include/cppgc/internal/process-heap.h +0 -34
@@ -18,6 +18,38 @@
18
18
  * &v8::CFunction::Make(FastMethod));
19
19
  * \endcode
20
20
  *
21
+ * By design, fast calls are limited by the following requirements, which
22
+ * the embedder should enforce themselves:
23
+ * - they should not allocate on the JS heap;
24
+ * - they should not trigger JS execution.
25
+ * To enforce them, the embedder could use the existing
26
+ * v8::Isolate::DisallowJavascriptExecutionScope and a utility similar to
27
+ * Blink's NoAllocationScope:
28
+ * https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/platform/heap/thread_state_scopes.h;l=16
29
+ *
30
+ * Due to these limitations, it's not directly possible to report errors by
31
+ * throwing a JS exception or to otherwise do an allocation. There is an
32
+ * alternative way of creating fast calls that supports falling back to the
33
+ * slow call and then performing the necessary allocation. When one creates
34
+ * the fast method by using CFunction::MakeWithFallbackSupport instead of
35
+ * CFunction::Make, the fast callback gets as last parameter an output variable,
36
+ * through which it can request falling back to the slow call. So one might
37
+ * declare their method like:
38
+ *
39
+ * \code
40
+ * void FastMethodWithFallback(int param, FastApiCallbackOptions& options);
41
+ * \endcode
42
+ *
43
+ * If the callback wants to signal an error condition or to perform an
44
+ * allocation, it must set options.fallback to true and do an early return from
45
+ * the fast method. Then V8 checks the value of options.fallback and if it's
46
+ * true, falls back to executing the SlowCallback, which is capable of reporting
47
+ * the error (either by throwing a JS exception or logging to the console) or
48
+ * doing the allocation. It's the embedder's responsibility to ensure that the
49
+ * fast callback is idempotent up to the point where error and fallback
50
+ * conditions are checked, because otherwise executing the slow callback might
51
+ * produce visible side-effects twice.
52
+ *
21
53
  * An example for custom embedder type support might employ a way to wrap/
22
54
  * unwrap various C++ types in JSObject instances, e.g:
23
55
  *
@@ -38,8 +70,7 @@
38
70
  * return GetInternalField<CustomEmbedderType,
39
71
  * kV8EmbedderWrapperObjectIndex>(wrapper);
40
72
  * }
41
- * static void FastMethod(v8::ApiObject receiver_obj, int param) {
42
- * v8::Object* v8_object = reinterpret_cast<v8::Object*>(&api_object);
73
+ * static void FastMethod(v8::Local<v8::Object> receiver_obj, int param) {
43
74
  * CustomEmbedderType* receiver = static_cast<CustomEmbedderType*>(
44
75
  * receiver_obj->GetAlignedPointerFromInternalField(
45
76
  * kV8EmbedderWrapperObjectIndex));
@@ -116,23 +147,73 @@
116
147
  * receiver := the {embedder_object} from above
117
148
  * param := 42
118
149
  *
119
- * Currently only void return types are supported.
150
+ * Currently supported return types:
151
+ * - void
152
+ * - bool
153
+ * - int32_t
154
+ * - uint32_t
155
+ * - float32_t
156
+ * - float64_t
120
157
  * Currently supported argument types:
121
158
  * - pointer to an embedder type
159
+ * - JavaScript array of primitive types
122
160
  * - bool
123
161
  * - int32_t
124
162
  * - uint32_t
125
163
  * - int64_t
126
164
  * - uint64_t
165
+ * - float32_t
166
+ * - float64_t
167
+ *
127
168
  * The 64-bit integer types currently have the IDL (unsigned) long long
128
169
  * semantics: https://heycam.github.io/webidl/#abstract-opdef-converttoint
129
170
  * In the future we'll extend the API to also provide conversions from/to
130
171
  * BigInt to preserve full precision.
172
+ * The floating point types currently have the IDL (unrestricted) semantics,
173
+ * which is the only one used by WebGL. We plan to add support also for
174
+ * restricted floats/doubles, similarly to the BigInt conversion policies.
175
+ * We also differ from the specific NaN bit pattern that WebIDL prescribes
176
+ * (https://heycam.github.io/webidl/#es-unrestricted-float) in that Blink
177
+ * passes NaN values as-is, i.e. doesn't normalize them.
178
+ *
131
179
  * To be supported types:
132
- * - float32_t
133
- * - float64_t
134
- * - arrays of C types
180
+ * - TypedArrays and ArrayBuffers
135
181
  * - arrays of embedder types
182
+ *
183
+ *
184
+ * The API offers a limited support for function overloads:
185
+ *
186
+ * \code
187
+ * void FastMethod_2Args(int param, bool another_param);
188
+ * void FastMethod_3Args(int param, bool another_param, int third_param);
189
+ *
190
+ * v8::CFunction fast_method_2args_c_func =
191
+ * MakeV8CFunction(FastMethod_2Args);
192
+ * v8::CFunction fast_method_3args_c_func =
193
+ * MakeV8CFunction(FastMethod_3Args);
194
+ * const v8::CFunction fast_method_overloads[] = {fast_method_2args_c_func,
195
+ * fast_method_3args_c_func};
196
+ * Local<v8::FunctionTemplate> method_template =
197
+ * v8::FunctionTemplate::NewWithCFunctionOverloads(
198
+ * isolate, SlowCallback, data, signature, length,
199
+ * constructor_behavior, side_effect_type,
200
+ * {fast_method_overloads, 2});
201
+ * \endcode
202
+ *
203
+ * In this example a single FunctionTemplate is associated to multiple C++
204
+ * functions. The overload resolution is currently only based on the number of
205
+ * arguments passed in a call. For example, if this method_template is
206
+ * registered with a wrapper JS object as described above, a call with two
207
+ * arguments:
208
+ * obj.method(42, true);
209
+ * will result in a fast call to FastMethod_2Args, while a call with three or
210
+ * more arguments:
211
+ * obj.method(42, true, 11);
212
+ * will result in a fast call to FastMethod_3Args. Instead a call with less than
213
+ * two arguments, like:
214
+ * obj.method(42);
215
+ * would not result in a fast call but would fall back to executing the
216
+ * associated SlowCallback.
136
217
  */
137
218
 
138
219
  #ifndef INCLUDE_V8_FAST_API_CALLS_H_
@@ -141,13 +222,22 @@
141
222
  #include <stddef.h>
142
223
  #include <stdint.h>
143
224
 
144
- #include "v8config.h" // NOLINT(build/include_directory)
225
+ #include <tuple>
226
+ #include <type_traits>
227
+
228
+ #include "v8-internal.h" // NOLINT(build/include_directory)
229
+ #include "v8-local-handle.h" // NOLINT(build/include_directory)
230
+ #include "v8-typed-array.h" // NOLINT(build/include_directory)
231
+ #include "v8-value.h" // NOLINT(build/include_directory)
232
+ #include "v8config.h" // NOLINT(build/include_directory)
145
233
 
146
234
  namespace v8 {
147
235
 
236
+ class Isolate;
237
+
148
238
  class CTypeInfo {
149
239
  public:
150
- enum class Type : char {
240
+ enum class Type : uint8_t {
151
241
  kVoid,
152
242
  kBool,
153
243
  kInt32,
@@ -157,170 +247,163 @@ class CTypeInfo {
157
247
  kFloat32,
158
248
  kFloat64,
159
249
  kV8Value,
250
+ kApiObject, // This will be deprecated once all users have
251
+ // migrated from v8::ApiObject to v8::Local<v8::Value>.
160
252
  };
161
253
 
162
- enum class ArgFlags : uint8_t {
163
- kNone = 0,
164
- kIsArrayBit = 1 << 0, // This argument is first in an array of values.
254
+ // kCallbackOptionsType is not part of the Type enum
255
+ // because it is only used internally. Use value 255 that is larger
256
+ // than any valid Type enum.
257
+ static constexpr Type kCallbackOptionsType = Type(255);
258
+
259
+ enum class SequenceType : uint8_t {
260
+ kScalar,
261
+ kIsSequence, // sequence<T>
262
+ kIsTypedArray, // TypedArray of T or any ArrayBufferView if T
263
+ // is void
264
+ kIsArrayBuffer // ArrayBuffer
165
265
  };
166
266
 
167
- static CTypeInfo FromWrapperType(ArgFlags flags = ArgFlags::kNone) {
168
- return CTypeInfo(static_cast<int>(flags) | kIsWrapperTypeBit);
169
- }
267
+ enum class Flags : uint8_t {
268
+ kNone = 0,
269
+ kAllowSharedBit = 1 << 0, // Must be an ArrayBuffer or TypedArray
270
+ kEnforceRangeBit = 1 << 1, // T must be integral
271
+ kClampBit = 1 << 2, // T must be integral
272
+ kIsRestrictedBit = 1 << 3, // T must be float or double
273
+ };
170
274
 
171
- static constexpr CTypeInfo FromCType(Type ctype,
172
- ArgFlags flags = ArgFlags::kNone) {
173
- // TODO(mslekova): Refactor the manual bit manipulations to use
174
- // PointerWithPayload instead.
175
- // ctype cannot be Type::kV8Value.
176
- return CTypeInfo(
177
- ((static_cast<uintptr_t>(ctype) << kTypeOffset) & kTypeMask) |
178
- static_cast<int>(flags));
275
+ explicit constexpr CTypeInfo(
276
+ Type type, SequenceType sequence_type = SequenceType::kScalar,
277
+ Flags flags = Flags::kNone)
278
+ : type_(type), sequence_type_(sequence_type), flags_(flags) {}
279
+
280
+ typedef uint32_t Identifier;
281
+ explicit constexpr CTypeInfo(Identifier identifier)
282
+ : CTypeInfo(static_cast<Type>(identifier >> 16),
283
+ static_cast<SequenceType>((identifier >> 8) & 255),
284
+ static_cast<Flags>(identifier & 255)) {}
285
+ constexpr Identifier GetId() const {
286
+ return static_cast<uint8_t>(type_) << 16 |
287
+ static_cast<uint8_t>(sequence_type_) << 8 |
288
+ static_cast<uint8_t>(flags_);
179
289
  }
180
290
 
181
- const void* GetWrapperInfo() const;
291
+ constexpr Type GetType() const { return type_; }
292
+ constexpr SequenceType GetSequenceType() const { return sequence_type_; }
293
+ constexpr Flags GetFlags() const { return flags_; }
182
294
 
183
- constexpr Type GetType() const {
184
- if (payload_ & kIsWrapperTypeBit) {
185
- return Type::kV8Value;
186
- }
187
- return static_cast<Type>((payload_ & kTypeMask) >> kTypeOffset);
295
+ static constexpr bool IsIntegralType(Type type) {
296
+ return type == Type::kInt32 || type == Type::kUint32 ||
297
+ type == Type::kInt64 || type == Type::kUint64;
188
298
  }
189
299
 
190
- constexpr bool IsArray() const {
191
- return payload_ & static_cast<int>(ArgFlags::kIsArrayBit);
300
+ static constexpr bool IsFloatingPointType(Type type) {
301
+ return type == Type::kFloat32 || type == Type::kFloat64;
192
302
  }
193
303
 
194
- static const CTypeInfo& Invalid() {
195
- static CTypeInfo invalid = CTypeInfo(0);
196
- return invalid;
304
+ static constexpr bool IsPrimitive(Type type) {
305
+ return IsIntegralType(type) || IsFloatingPointType(type) ||
306
+ type == Type::kBool;
197
307
  }
198
308
 
199
309
  private:
200
- explicit constexpr CTypeInfo(uintptr_t payload) : payload_(payload) {}
201
-
202
- // That must be the last bit after ArgFlags.
203
- static constexpr uintptr_t kIsWrapperTypeBit = 1 << 1;
204
- static constexpr uintptr_t kWrapperTypeInfoMask = static_cast<uintptr_t>(~0)
205
- << 2;
206
-
207
- static constexpr unsigned int kTypeOffset = kIsWrapperTypeBit;
208
- static constexpr unsigned int kTypeSize = 8 - kTypeOffset;
209
- static constexpr uintptr_t kTypeMask =
210
- (~(static_cast<uintptr_t>(~0) << kTypeSize)) << kTypeOffset;
211
-
212
- const uintptr_t payload_;
310
+ Type type_;
311
+ SequenceType sequence_type_;
312
+ Flags flags_;
213
313
  };
214
314
 
215
- class CFunctionInfo {
315
+ struct FastApiTypedArrayBase {
216
316
  public:
217
- virtual const CTypeInfo& ReturnInfo() const = 0;
218
- virtual unsigned int ArgumentCount() const = 0;
219
- virtual const CTypeInfo& ArgumentInfo(unsigned int index) const = 0;
220
- };
317
+ // Returns the length in number of elements.
318
+ size_t V8_EXPORT length() const { return length_; }
319
+ // Checks whether the given index is within the bounds of the collection.
320
+ void V8_EXPORT ValidateIndex(size_t index) const;
221
321
 
222
- struct ApiObject {
223
- uintptr_t address;
322
+ protected:
323
+ size_t length_ = 0;
224
324
  };
225
325
 
226
- namespace internal {
227
-
228
326
  template <typename T>
229
- struct GetCType {
230
- static constexpr CTypeInfo Get() {
231
- return CTypeInfo::FromCType(CTypeInfo::Type::kV8Value);
327
+ struct FastApiTypedArray : public FastApiTypedArrayBase {
328
+ public:
329
+ V8_INLINE T get(size_t index) const {
330
+ #ifdef DEBUG
331
+ ValidateIndex(index);
332
+ #endif // DEBUG
333
+ T tmp;
334
+ memcpy(&tmp, reinterpret_cast<T*>(data_) + index, sizeof(T));
335
+ return tmp;
232
336
  }
233
- };
234
-
235
- #define SPECIALIZE_GET_C_TYPE_FOR(ctype, ctypeinfo) \
236
- template <> \
237
- struct GetCType<ctype> { \
238
- static constexpr CTypeInfo Get() { \
239
- return CTypeInfo::FromCType(CTypeInfo::Type::ctypeinfo); \
240
- } \
241
- };
242
-
243
- #define SUPPORTED_C_TYPES(V) \
244
- V(void, kVoid) \
245
- V(bool, kBool) \
246
- V(int32_t, kInt32) \
247
- V(uint32_t, kUint32) \
248
- V(int64_t, kInt64) \
249
- V(uint64_t, kUint64) \
250
- V(float, kFloat32) \
251
- V(double, kFloat64) \
252
- V(ApiObject, kV8Value)
253
-
254
- SUPPORTED_C_TYPES(SPECIALIZE_GET_C_TYPE_FOR)
255
337
 
256
- // T* where T is a primitive (array of primitives).
257
- template <typename T, typename = void>
258
- struct GetCTypePointerImpl {
259
- static constexpr CTypeInfo Get() {
260
- return CTypeInfo::FromCType(GetCType<T>::Get().GetType(),
261
- CTypeInfo::ArgFlags::kIsArrayBit);
338
+ bool getStorageIfAligned(T** elements) const {
339
+ if (reinterpret_cast<uintptr_t>(data_) % alignof(T) != 0) {
340
+ return false;
341
+ }
342
+ *elements = reinterpret_cast<T*>(data_);
343
+ return true;
262
344
  }
263
- };
264
345
 
265
- // T* where T is an API object.
266
- template <typename T>
267
- struct GetCTypePointerImpl<T, void> {
268
- static constexpr CTypeInfo Get() { return CTypeInfo::FromWrapperType(); }
346
+ private:
347
+ // This pointer should include the typed array offset applied.
348
+ // It's not guaranteed that it's aligned to sizeof(T), it's only
349
+ // guaranteed that it's 4-byte aligned, so for 8-byte types we need to
350
+ // provide a special implementation for reading from it, which hides
351
+ // the possibly unaligned read in the `get` method.
352
+ void* data_;
269
353
  };
270
354
 
271
- // T** where T is a primitive. Not allowed.
272
- template <typename T, typename = void>
273
- struct GetCTypePointerPointerImpl {
274
- static_assert(sizeof(T**) != sizeof(T**), "Unsupported type");
355
+ // Any TypedArray. It uses kTypedArrayBit with base type void
356
+ // Overloaded args of ArrayBufferView and TypedArray are not supported
357
+ // (for now) because the generic “any” ArrayBufferView doesn’t have its
358
+ // own instance type. It could be supported if we specify that
359
+ // TypedArray<T> always has precedence over the generic ArrayBufferView,
360
+ // but this complicates overload resolution.
361
+ struct FastApiArrayBufferView {
362
+ void* data;
363
+ size_t byte_length;
275
364
  };
276
365
 
277
- // T** where T is an API object (array of API objects).
278
- template <typename T>
279
- struct GetCTypePointerPointerImpl<T, void> {
280
- static constexpr CTypeInfo Get() {
281
- return CTypeInfo::FromWrapperType(CTypeInfo::ArgFlags::kIsArrayBit);
282
- }
366
+ struct FastApiArrayBuffer {
367
+ void* data;
368
+ size_t byte_length;
283
369
  };
284
370
 
285
- template <typename T>
286
- struct GetCType<T**> : public GetCTypePointerPointerImpl<T> {};
287
-
288
- template <typename T>
289
- struct GetCType<T*> : public GetCTypePointerImpl<T> {};
290
-
291
- template <typename R, bool RaisesException, typename... Args>
292
- class CFunctionInfoImpl : public CFunctionInfo {
371
+ class V8_EXPORT CFunctionInfo {
293
372
  public:
294
- static constexpr int kHasErrorArgCount = (RaisesException ? 1 : 0);
295
- static constexpr int kReceiverCount = 1;
296
- CFunctionInfoImpl()
297
- : return_info_(internal::GetCType<R>::Get()),
298
- arg_count_(sizeof...(Args) - kHasErrorArgCount),
299
- arg_info_{internal::GetCType<Args>::Get()...} {
300
- static_assert(sizeof...(Args) >= kHasErrorArgCount + kReceiverCount,
301
- "The receiver or the has_error argument is missing.");
302
- static_assert(
303
- internal::GetCType<R>::Get().GetType() == CTypeInfo::Type::kVoid,
304
- "Only void return types are currently supported.");
373
+ // Construct a struct to hold a CFunction's type information.
374
+ // |return_info| describes the function's return type.
375
+ // |arg_info| is an array of |arg_count| CTypeInfos describing the
376
+ // arguments. Only the last argument may be of the special type
377
+ // CTypeInfo::kCallbackOptionsType.
378
+ CFunctionInfo(const CTypeInfo& return_info, unsigned int arg_count,
379
+ const CTypeInfo* arg_info);
380
+
381
+ const CTypeInfo& ReturnInfo() const { return return_info_; }
382
+
383
+ // The argument count, not including the v8::FastApiCallbackOptions
384
+ // if present.
385
+ unsigned int ArgumentCount() const {
386
+ return HasOptions() ? arg_count_ - 1 : arg_count_;
305
387
  }
306
388
 
307
- const CTypeInfo& ReturnInfo() const override { return return_info_; }
308
- unsigned int ArgumentCount() const override { return arg_count_; }
309
- const CTypeInfo& ArgumentInfo(unsigned int index) const override {
310
- if (index >= ArgumentCount()) {
311
- return CTypeInfo::Invalid();
312
- }
313
- return arg_info_[index];
389
+ // |index| must be less than ArgumentCount().
390
+ // Note: if the last argument passed on construction of CFunctionInfo
391
+ // has type CTypeInfo::kCallbackOptionsType, it is not included in
392
+ // ArgumentCount().
393
+ const CTypeInfo& ArgumentInfo(unsigned int index) const;
394
+
395
+ bool HasOptions() const {
396
+ // The options arg is always the last one.
397
+ return arg_count_ > 0 && arg_info_[arg_count_ - 1].GetType() ==
398
+ CTypeInfo::kCallbackOptionsType;
314
399
  }
315
400
 
316
401
  private:
317
402
  const CTypeInfo return_info_;
318
403
  const unsigned int arg_count_;
319
- const CTypeInfo arg_info_[sizeof...(Args)];
404
+ const CTypeInfo* arg_info_;
320
405
  };
321
406
 
322
- } // namespace internal
323
-
324
407
  class V8_EXPORT CFunction {
325
408
  public:
326
409
  constexpr CFunction() : address_(nullptr), type_info_(nullptr) {}
@@ -336,33 +419,59 @@ class V8_EXPORT CFunction {
336
419
  const void* GetAddress() const { return address_; }
337
420
  const CFunctionInfo* GetTypeInfo() const { return type_info_; }
338
421
 
422
+ enum class OverloadResolution { kImpossible, kAtRuntime, kAtCompileTime };
423
+
424
+ // Returns whether an overload between this and the given CFunction can
425
+ // be resolved at runtime by the RTTI available for the arguments or at
426
+ // compile time for functions with different number of arguments.
427
+ OverloadResolution GetOverloadResolution(const CFunction* other) {
428
+ // Runtime overload resolution can only deal with functions with the
429
+ // same number of arguments. Functions with different arity are handled
430
+ // by compile time overload resolution though.
431
+ if (ArgumentCount() != other->ArgumentCount()) {
432
+ return OverloadResolution::kAtCompileTime;
433
+ }
434
+
435
+ // The functions can only differ by a single argument position.
436
+ int diff_index = -1;
437
+ for (unsigned int i = 0; i < ArgumentCount(); ++i) {
438
+ if (ArgumentInfo(i).GetSequenceType() !=
439
+ other->ArgumentInfo(i).GetSequenceType()) {
440
+ if (diff_index >= 0) {
441
+ return OverloadResolution::kImpossible;
442
+ }
443
+ diff_index = i;
444
+
445
+ // We only support overload resolution between sequence types.
446
+ if (ArgumentInfo(i).GetSequenceType() ==
447
+ CTypeInfo::SequenceType::kScalar ||
448
+ other->ArgumentInfo(i).GetSequenceType() ==
449
+ CTypeInfo::SequenceType::kScalar) {
450
+ return OverloadResolution::kImpossible;
451
+ }
452
+ }
453
+ }
454
+
455
+ return OverloadResolution::kAtRuntime;
456
+ }
457
+
339
458
  template <typename F>
340
459
  static CFunction Make(F* func) {
341
460
  return ArgUnwrap<F*>::Make(func);
342
461
  }
343
462
 
344
463
  template <typename F>
345
- static CFunction MakeWithErrorSupport(F* func) {
346
- return ArgUnwrap<F*>::MakeWithErrorSupport(func);
464
+ V8_DEPRECATED("Use CFunctionBuilder instead.")
465
+ static CFunction MakeWithFallbackSupport(F* func) {
466
+ return ArgUnwrap<F*>::Make(func);
347
467
  }
348
468
 
349
- template <typename F>
350
- static CFunction Make(F* func, const CFunctionInfo* type_info) {
351
- return CFunction(reinterpret_cast<const void*>(func), type_info);
352
- }
469
+ CFunction(const void* address, const CFunctionInfo* type_info);
353
470
 
354
471
  private:
355
472
  const void* address_;
356
473
  const CFunctionInfo* type_info_;
357
474
 
358
- CFunction(const void* address, const CFunctionInfo* type_info);
359
-
360
- template <typename R, bool RaisesException, typename... Args>
361
- static CFunctionInfo* GetCFunctionInfo() {
362
- static internal::CFunctionInfoImpl<R, RaisesException, Args...> instance;
363
- return &instance;
364
- }
365
-
366
475
  template <typename F>
367
476
  class ArgUnwrap {
368
477
  static_assert(sizeof(F) != sizeof(F),
@@ -372,17 +481,408 @@ class V8_EXPORT CFunction {
372
481
  template <typename R, typename... Args>
373
482
  class ArgUnwrap<R (*)(Args...)> {
374
483
  public:
375
- static CFunction Make(R (*func)(Args...)) {
376
- return CFunction(reinterpret_cast<const void*>(func),
377
- GetCFunctionInfo<R, false, Args...>());
378
- }
379
- static CFunction MakeWithErrorSupport(R (*func)(Args...)) {
380
- return CFunction(reinterpret_cast<const void*>(func),
381
- GetCFunctionInfo<R, true, Args...>());
382
- }
484
+ static CFunction Make(R (*func)(Args...));
485
+ };
486
+ };
487
+
488
+ struct ApiObject {
489
+ uintptr_t address;
490
+ };
491
+
492
+ /**
493
+ * A struct which may be passed to a fast call callback, like so:
494
+ * \code
495
+ * void FastMethodWithOptions(int param, FastApiCallbackOptions& options);
496
+ * \endcode
497
+ */
498
+ struct FastApiCallbackOptions {
499
+ /**
500
+ * Creates a new instance of FastApiCallbackOptions for testing purpose. The
501
+ * returned instance may be filled with mock data.
502
+ */
503
+ static FastApiCallbackOptions CreateForTesting(Isolate* isolate) {
504
+ return {false, {0}};
505
+ }
506
+
507
+ /**
508
+ * If the callback wants to signal an error condition or to perform an
509
+ * allocation, it must set options.fallback to true and do an early return
510
+ * from the fast method. Then V8 checks the value of options.fallback and if
511
+ * it's true, falls back to executing the SlowCallback, which is capable of
512
+ * reporting the error (either by throwing a JS exception or logging to the
513
+ * console) or doing the allocation. It's the embedder's responsibility to
514
+ * ensure that the fast callback is idempotent up to the point where error and
515
+ * fallback conditions are checked, because otherwise executing the slow
516
+ * callback might produce visible side-effects twice.
517
+ */
518
+ bool fallback;
519
+
520
+ /**
521
+ * The `data` passed to the FunctionTemplate constructor, or `undefined`.
522
+ * `data_ptr` allows for default constructing FastApiCallbackOptions.
523
+ */
524
+ union {
525
+ uintptr_t data_ptr;
526
+ v8::Value data;
527
+ };
528
+ };
529
+
530
+ namespace internal {
531
+
532
+ // Helper to count the number of occurances of `T` in `List`
533
+ template <typename T, typename... List>
534
+ struct count : std::integral_constant<int, 0> {};
535
+ template <typename T, typename... Args>
536
+ struct count<T, T, Args...>
537
+ : std::integral_constant<std::size_t, 1 + count<T, Args...>::value> {};
538
+ template <typename T, typename U, typename... Args>
539
+ struct count<T, U, Args...> : count<T, Args...> {};
540
+
541
+ template <typename RetBuilder, typename... ArgBuilders>
542
+ class CFunctionInfoImpl : public CFunctionInfo {
543
+ static constexpr int kOptionsArgCount =
544
+ count<FastApiCallbackOptions&, ArgBuilders...>();
545
+ static constexpr int kReceiverCount = 1;
546
+
547
+ static_assert(kOptionsArgCount == 0 || kOptionsArgCount == 1,
548
+ "Only one options parameter is supported.");
549
+
550
+ static_assert(sizeof...(ArgBuilders) >= kOptionsArgCount + kReceiverCount,
551
+ "The receiver or the options argument is missing.");
552
+
553
+ public:
554
+ constexpr CFunctionInfoImpl()
555
+ : CFunctionInfo(RetBuilder::Build(), sizeof...(ArgBuilders),
556
+ arg_info_storage_),
557
+ arg_info_storage_{ArgBuilders::Build()...} {
558
+ constexpr CTypeInfo::Type kReturnType = RetBuilder::Build().GetType();
559
+ static_assert(kReturnType == CTypeInfo::Type::kVoid ||
560
+ kReturnType == CTypeInfo::Type::kBool ||
561
+ kReturnType == CTypeInfo::Type::kInt32 ||
562
+ kReturnType == CTypeInfo::Type::kUint32 ||
563
+ kReturnType == CTypeInfo::Type::kFloat32 ||
564
+ kReturnType == CTypeInfo::Type::kFloat64,
565
+ "64-bit int and api object values are not currently "
566
+ "supported return types.");
567
+ }
568
+
569
+ private:
570
+ const CTypeInfo arg_info_storage_[sizeof...(ArgBuilders)];
571
+ };
572
+
573
+ template <typename T>
574
+ struct TypeInfoHelper {
575
+ static_assert(sizeof(T) != sizeof(T), "This type is not supported");
576
+ };
577
+
578
+ #define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR(T, Enum) \
579
+ template <> \
580
+ struct TypeInfoHelper<T> { \
581
+ static constexpr CTypeInfo::Flags Flags() { \
582
+ return CTypeInfo::Flags::kNone; \
583
+ } \
584
+ \
585
+ static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
586
+ static constexpr CTypeInfo::SequenceType SequenceType() { \
587
+ return CTypeInfo::SequenceType::kScalar; \
588
+ } \
589
+ };
590
+
591
+ template <CTypeInfo::Type type>
592
+ struct CTypeInfoTraits {};
593
+
594
+ #define DEFINE_TYPE_INFO_TRAITS(CType, Enum) \
595
+ template <> \
596
+ struct CTypeInfoTraits<CTypeInfo::Type::Enum> { \
597
+ using ctype = CType; \
598
+ };
599
+
600
+ #define PRIMITIVE_C_TYPES(V) \
601
+ V(bool, kBool) \
602
+ V(int32_t, kInt32) \
603
+ V(uint32_t, kUint32) \
604
+ V(int64_t, kInt64) \
605
+ V(uint64_t, kUint64) \
606
+ V(float, kFloat32) \
607
+ V(double, kFloat64)
608
+
609
+ // Same as above, but includes deprecated types for compatibility.
610
+ #define ALL_C_TYPES(V) \
611
+ PRIMITIVE_C_TYPES(V) \
612
+ V(void, kVoid) \
613
+ V(v8::Local<v8::Value>, kV8Value) \
614
+ V(v8::Local<v8::Object>, kV8Value) \
615
+ V(ApiObject, kApiObject)
616
+
617
+ // ApiObject was a temporary solution to wrap the pointer to the v8::Value.
618
+ // Please use v8::Local<v8::Value> in new code for the arguments and
619
+ // v8::Local<v8::Object> for the receiver, as ApiObject will be deprecated.
620
+
621
+ ALL_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR)
622
+ PRIMITIVE_C_TYPES(DEFINE_TYPE_INFO_TRAITS)
623
+
624
+ #undef PRIMITIVE_C_TYPES
625
+ #undef ALL_C_TYPES
626
+
627
+ #define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA(T, Enum) \
628
+ template <> \
629
+ struct TypeInfoHelper<const FastApiTypedArray<T>&> { \
630
+ static constexpr CTypeInfo::Flags Flags() { \
631
+ return CTypeInfo::Flags::kNone; \
632
+ } \
633
+ \
634
+ static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
635
+ static constexpr CTypeInfo::SequenceType SequenceType() { \
636
+ return CTypeInfo::SequenceType::kIsTypedArray; \
637
+ } \
638
+ };
639
+
640
+ #define TYPED_ARRAY_C_TYPES(V) \
641
+ V(int32_t, kInt32) \
642
+ V(uint32_t, kUint32) \
643
+ V(int64_t, kInt64) \
644
+ V(uint64_t, kUint64) \
645
+ V(float, kFloat32) \
646
+ V(double, kFloat64)
647
+
648
+ TYPED_ARRAY_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA)
649
+
650
+ #undef TYPED_ARRAY_C_TYPES
651
+
652
+ template <>
653
+ struct TypeInfoHelper<v8::Local<v8::Array>> {
654
+ static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
655
+
656
+ static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::kVoid; }
657
+ static constexpr CTypeInfo::SequenceType SequenceType() {
658
+ return CTypeInfo::SequenceType::kIsSequence;
659
+ }
660
+ };
661
+
662
+ template <>
663
+ struct TypeInfoHelper<v8::Local<v8::Uint32Array>> {
664
+ static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
665
+
666
+ static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::kUint32; }
667
+ static constexpr CTypeInfo::SequenceType SequenceType() {
668
+ return CTypeInfo::SequenceType::kIsTypedArray;
669
+ }
670
+ };
671
+
672
+ template <>
673
+ struct TypeInfoHelper<FastApiCallbackOptions&> {
674
+ static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
675
+
676
+ static constexpr CTypeInfo::Type Type() {
677
+ return CTypeInfo::kCallbackOptionsType;
678
+ }
679
+ static constexpr CTypeInfo::SequenceType SequenceType() {
680
+ return CTypeInfo::SequenceType::kScalar;
681
+ }
682
+ };
683
+
684
+ #define STATIC_ASSERT_IMPLIES(COND, ASSERTION, MSG) \
685
+ static_assert(((COND) == 0) || (ASSERTION), MSG)
686
+
687
+ template <typename T, CTypeInfo::Flags... Flags>
688
+ class CTypeInfoBuilder {
689
+ public:
690
+ using BaseType = T;
691
+
692
+ static constexpr CTypeInfo Build() {
693
+ constexpr CTypeInfo::Flags kFlags =
694
+ MergeFlags(TypeInfoHelper<T>::Flags(), Flags...);
695
+ constexpr CTypeInfo::Type kType = TypeInfoHelper<T>::Type();
696
+ constexpr CTypeInfo::SequenceType kSequenceType =
697
+ TypeInfoHelper<T>::SequenceType();
698
+
699
+ STATIC_ASSERT_IMPLIES(
700
+ uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kAllowSharedBit),
701
+ (kSequenceType == CTypeInfo::SequenceType::kIsTypedArray ||
702
+ kSequenceType == CTypeInfo::SequenceType::kIsArrayBuffer),
703
+ "kAllowSharedBit is only allowed for TypedArrays and ArrayBuffers.");
704
+ STATIC_ASSERT_IMPLIES(
705
+ uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kEnforceRangeBit),
706
+ CTypeInfo::IsIntegralType(kType),
707
+ "kEnforceRangeBit is only allowed for integral types.");
708
+ STATIC_ASSERT_IMPLIES(
709
+ uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kClampBit),
710
+ CTypeInfo::IsIntegralType(kType),
711
+ "kClampBit is only allowed for integral types.");
712
+ STATIC_ASSERT_IMPLIES(
713
+ uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kIsRestrictedBit),
714
+ CTypeInfo::IsFloatingPointType(kType),
715
+ "kIsRestrictedBit is only allowed for floating point types.");
716
+ STATIC_ASSERT_IMPLIES(kSequenceType == CTypeInfo::SequenceType::kIsSequence,
717
+ kType == CTypeInfo::Type::kVoid,
718
+ "Sequences are only supported from void type.");
719
+ STATIC_ASSERT_IMPLIES(
720
+ kSequenceType == CTypeInfo::SequenceType::kIsTypedArray,
721
+ CTypeInfo::IsPrimitive(kType) || kType == CTypeInfo::Type::kVoid,
722
+ "TypedArrays are only supported from primitive types or void.");
723
+
724
+ // Return the same type with the merged flags.
725
+ return CTypeInfo(TypeInfoHelper<T>::Type(),
726
+ TypeInfoHelper<T>::SequenceType(), kFlags);
727
+ }
728
+
729
+ private:
730
+ template <typename... Rest>
731
+ static constexpr CTypeInfo::Flags MergeFlags(CTypeInfo::Flags flags,
732
+ Rest... rest) {
733
+ return CTypeInfo::Flags(uint8_t(flags) | uint8_t(MergeFlags(rest...)));
734
+ }
735
+ static constexpr CTypeInfo::Flags MergeFlags() { return CTypeInfo::Flags(0); }
736
+ };
737
+
738
+ template <typename RetBuilder, typename... ArgBuilders>
739
+ class CFunctionBuilderWithFunction {
740
+ public:
741
+ explicit constexpr CFunctionBuilderWithFunction(const void* fn) : fn_(fn) {}
742
+
743
+ template <CTypeInfo::Flags... Flags>
744
+ constexpr auto Ret() {
745
+ return CFunctionBuilderWithFunction<
746
+ CTypeInfoBuilder<typename RetBuilder::BaseType, Flags...>,
747
+ ArgBuilders...>(fn_);
748
+ }
749
+
750
+ template <unsigned int N, CTypeInfo::Flags... Flags>
751
+ constexpr auto Arg() {
752
+ // Return a copy of the builder with the Nth arg builder merged with
753
+ // template parameter pack Flags.
754
+ return ArgImpl<N, Flags...>(
755
+ std::make_index_sequence<sizeof...(ArgBuilders)>());
756
+ }
757
+
758
+ auto Build() {
759
+ static CFunctionInfoImpl<RetBuilder, ArgBuilders...> instance;
760
+ return CFunction(fn_, &instance);
761
+ }
762
+
763
+ private:
764
+ template <bool Merge, unsigned int N, CTypeInfo::Flags... Flags>
765
+ struct GetArgBuilder;
766
+
767
+ // Returns the same ArgBuilder as the one at index N, including its flags.
768
+ // Flags in the template parameter pack are ignored.
769
+ template <unsigned int N, CTypeInfo::Flags... Flags>
770
+ struct GetArgBuilder<false, N, Flags...> {
771
+ using type =
772
+ typename std::tuple_element<N, std::tuple<ArgBuilders...>>::type;
383
773
  };
774
+
775
+ // Returns an ArgBuilder with the same base type as the one at index N,
776
+ // but merges the flags with the flags in the template parameter pack.
777
+ template <unsigned int N, CTypeInfo::Flags... Flags>
778
+ struct GetArgBuilder<true, N, Flags...> {
779
+ using type = CTypeInfoBuilder<
780
+ typename std::tuple_element<N,
781
+ std::tuple<ArgBuilders...>>::type::BaseType,
782
+ std::tuple_element<N, std::tuple<ArgBuilders...>>::type::Build()
783
+ .GetFlags(),
784
+ Flags...>;
785
+ };
786
+
787
+ // Return a copy of the CFunctionBuilder, but merges the Flags on
788
+ // ArgBuilder index N with the new Flags passed in the template parameter
789
+ // pack.
790
+ template <unsigned int N, CTypeInfo::Flags... Flags, size_t... I>
791
+ constexpr auto ArgImpl(std::index_sequence<I...>) {
792
+ return CFunctionBuilderWithFunction<
793
+ RetBuilder, typename GetArgBuilder<N == I, I, Flags...>::type...>(fn_);
794
+ }
795
+
796
+ const void* fn_;
797
+ };
798
+
799
+ class CFunctionBuilder {
800
+ public:
801
+ constexpr CFunctionBuilder() {}
802
+
803
+ template <typename R, typename... Args>
804
+ constexpr auto Fn(R (*fn)(Args...)) {
805
+ return CFunctionBuilderWithFunction<CTypeInfoBuilder<R>,
806
+ CTypeInfoBuilder<Args>...>(
807
+ reinterpret_cast<const void*>(fn));
808
+ }
384
809
  };
385
810
 
811
+ } // namespace internal
812
+
813
+ // static
814
+ template <typename R, typename... Args>
815
+ CFunction CFunction::ArgUnwrap<R (*)(Args...)>::Make(R (*func)(Args...)) {
816
+ return internal::CFunctionBuilder().Fn(func).Build();
817
+ }
818
+
819
+ using CFunctionBuilder = internal::CFunctionBuilder;
820
+
821
+ static constexpr CTypeInfo kTypeInfoInt32 = CTypeInfo(CTypeInfo::Type::kInt32);
822
+ static constexpr CTypeInfo kTypeInfoFloat64 =
823
+ CTypeInfo(CTypeInfo::Type::kFloat64);
824
+
825
+ /**
826
+ * Copies the contents of this JavaScript array to a C++ buffer with
827
+ * a given max_length. A CTypeInfo is passed as an argument,
828
+ * instructing different rules for conversion (e.g. restricted float/double).
829
+ * The element type T of the destination array must match the C type
830
+ * corresponding to the CTypeInfo (specified by CTypeInfoTraits).
831
+ * If the array length is larger than max_length or the array is of
832
+ * unsupported type, the operation will fail, returning false. Generally, an
833
+ * array which contains objects, undefined, null or anything not convertible
834
+ * to the requested destination type, is considered unsupported. The operation
835
+ * returns true on success. `type_info` will be used for conversions.
836
+ */
837
+ template <const CTypeInfo* type_info, typename T>
838
+ V8_DEPRECATE_SOON(
839
+ "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
840
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT
841
+ TryCopyAndConvertArrayToCppBuffer(Local<Array> src, T* dst,
842
+ uint32_t max_length);
843
+
844
+ template <>
845
+ V8_DEPRECATE_SOON(
846
+ "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
847
+ inline bool V8_WARN_UNUSED_RESULT
848
+ TryCopyAndConvertArrayToCppBuffer<&kTypeInfoInt32, int32_t>(
849
+ Local<Array> src, int32_t* dst, uint32_t max_length) {
850
+ return false;
851
+ }
852
+
853
+ template <>
854
+ V8_DEPRECATE_SOON(
855
+ "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
856
+ inline bool V8_WARN_UNUSED_RESULT
857
+ TryCopyAndConvertArrayToCppBuffer<&kTypeInfoFloat64, double>(
858
+ Local<Array> src, double* dst, uint32_t max_length) {
859
+ return false;
860
+ }
861
+
862
+ template <CTypeInfo::Identifier type_info_id, typename T>
863
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(
864
+ Local<Array> src, T* dst, uint32_t max_length);
865
+
866
+ template <>
867
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer<
868
+ internal::CTypeInfoBuilder<int32_t>::Build().GetId(), int32_t>(
869
+ Local<Array> src, int32_t* dst, uint32_t max_length);
870
+
871
+ template <>
872
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer<
873
+ internal::CTypeInfoBuilder<uint32_t>::Build().GetId(), uint32_t>(
874
+ Local<Array> src, uint32_t* dst, uint32_t max_length);
875
+
876
+ template <>
877
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer<
878
+ internal::CTypeInfoBuilder<float>::Build().GetId(), float>(
879
+ Local<Array> src, float* dst, uint32_t max_length);
880
+
881
+ template <>
882
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer<
883
+ internal::CTypeInfoBuilder<double>::Build().GetId(), double>(
884
+ Local<Array> src, double* dst, uint32_t max_length);
885
+
386
886
  } // namespace v8
387
887
 
388
888
  #endif // INCLUDE_V8_FAST_API_CALLS_H_