libv8-node 15.14.0.1-aarch64-linux-musl → 18.8.0.0-aarch64-linux-musl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) 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 +184 -47
  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 +40 -49
  11. data/vendor/v8/include/cppgc/ephemeron-pair.h +30 -0
  12. data/vendor/v8/include/cppgc/explicit-management.h +100 -0
  13. data/vendor/v8/include/cppgc/garbage-collected.h +19 -29
  14. data/vendor/v8/include/cppgc/heap-consistency.h +266 -0
  15. data/vendor/v8/include/cppgc/heap-state.h +82 -0
  16. data/vendor/v8/include/cppgc/heap-statistics.h +120 -0
  17. data/vendor/v8/include/cppgc/heap.h +73 -6
  18. data/vendor/v8/include/cppgc/internal/api-constants.h +11 -3
  19. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +27 -15
  20. data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
  21. data/vendor/v8/include/cppgc/internal/finalizer-trait.h +4 -1
  22. data/vendor/v8/include/cppgc/internal/gc-info.h +124 -13
  23. data/vendor/v8/include/cppgc/internal/logging.h +3 -3
  24. data/vendor/v8/include/cppgc/internal/name-trait.h +122 -0
  25. data/vendor/v8/include/cppgc/internal/persistent-node.h +116 -16
  26. data/vendor/v8/include/cppgc/internal/pointer-policies.h +84 -32
  27. data/vendor/v8/include/cppgc/internal/write-barrier.h +392 -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 +91 -26
  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 +70 -41
  34. data/vendor/v8/include/cppgc/platform.h +52 -26
  35. data/vendor/v8/include/cppgc/prefinalizer.h +36 -13
  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 +106 -0
  40. data/vendor/v8/include/cppgc/trace-trait.h +8 -3
  41. data/vendor/v8/include/cppgc/type-traits.h +163 -32
  42. data/vendor/v8/include/cppgc/visitor.h +194 -28
  43. data/vendor/v8/include/libplatform/libplatform.h +11 -11
  44. data/vendor/v8/include/libplatform/v8-tracing.h +2 -1
  45. data/vendor/v8/include/v8-array-buffer.h +445 -0
  46. data/vendor/v8/include/v8-callbacks.h +397 -0
  47. data/vendor/v8/include/v8-container.h +129 -0
  48. data/vendor/v8/include/v8-context.h +407 -0
  49. data/vendor/v8/include/v8-cppgc.h +151 -159
  50. data/vendor/v8/include/v8-data.h +80 -0
  51. data/vendor/v8/include/v8-date.h +43 -0
  52. data/vendor/v8/include/v8-debug.h +168 -0
  53. data/vendor/v8/include/v8-embedder-heap.h +218 -0
  54. data/vendor/v8/include/v8-embedder-state-scope.h +51 -0
  55. data/vendor/v8/include/v8-exception.h +217 -0
  56. data/vendor/v8/include/v8-extension.h +62 -0
  57. data/vendor/v8/include/v8-external.h +37 -0
  58. data/vendor/v8/include/v8-fast-api-calls.h +703 -152
  59. data/vendor/v8/include/v8-forward.h +81 -0
  60. data/vendor/v8/include/v8-function-callback.h +475 -0
  61. data/vendor/v8/include/v8-function.h +125 -0
  62. data/vendor/v8/include/v8-initialization.h +315 -0
  63. data/vendor/v8/include/v8-inspector.h +76 -27
  64. data/vendor/v8/include/v8-internal.h +285 -51
  65. data/vendor/v8/include/v8-isolate.h +1709 -0
  66. data/vendor/v8/include/v8-json.h +47 -0
  67. data/vendor/v8/include/v8-local-handle.h +455 -0
  68. data/vendor/v8/include/v8-locker.h +149 -0
  69. data/vendor/v8/include/v8-maybe.h +137 -0
  70. data/vendor/v8/include/v8-memory-span.h +43 -0
  71. data/vendor/v8/include/v8-message.h +216 -0
  72. data/vendor/v8/include/v8-metrics.h +131 -9
  73. data/vendor/v8/include/v8-microtask-queue.h +152 -0
  74. data/vendor/v8/include/v8-microtask.h +28 -0
  75. data/vendor/v8/include/v8-object.h +775 -0
  76. data/vendor/v8/include/v8-persistent-handle.h +590 -0
  77. data/vendor/v8/include/v8-platform.h +433 -25
  78. data/vendor/v8/include/v8-primitive-object.h +118 -0
  79. data/vendor/v8/include/v8-primitive.h +866 -0
  80. data/vendor/v8/include/v8-profiler.h +149 -10
  81. data/vendor/v8/include/v8-promise.h +174 -0
  82. data/vendor/v8/include/v8-proxy.h +50 -0
  83. data/vendor/v8/include/v8-regexp.h +105 -0
  84. data/vendor/v8/include/v8-script.h +747 -0
  85. data/vendor/v8/include/v8-snapshot.h +196 -0
  86. data/vendor/v8/include/v8-statistics.h +217 -0
  87. data/vendor/v8/include/v8-template.h +1079 -0
  88. data/vendor/v8/include/v8-traced-handle.h +420 -0
  89. data/vendor/v8/include/v8-typed-array.h +282 -0
  90. data/vendor/v8/include/v8-unwinder-state.h +31 -0
  91. data/vendor/v8/include/v8-unwinder.h +132 -0
  92. data/vendor/v8/include/v8-util.h +8 -2
  93. data/vendor/v8/include/v8-value-serializer-version.h +1 -1
  94. data/vendor/v8/include/v8-value-serializer.h +279 -0
  95. data/vendor/v8/include/v8-value.h +526 -0
  96. data/vendor/v8/include/v8-version.h +4 -4
  97. data/vendor/v8/include/v8-wasm.h +257 -0
  98. data/vendor/v8/include/v8-weak-callback-info.h +87 -0
  99. data/vendor/v8/include/v8.h +41 -12051
  100. data/vendor/v8/include/v8config.h +142 -21
  101. metadata +64 -10
  102. data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +0 -30
  103. 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,169 +247,202 @@ 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>.
252
+ kAny, // This is added to enable untyped representation of fast
253
+ // call arguments for test purposes. It can represent any of
254
+ // the other types stored in the same memory as a union (see
255
+ // the AnyCType struct declared below). This allows for
256
+ // uniform passing of arguments w.r.t. their location
257
+ // (in a register or on the stack), independent of their
258
+ // actual type. It's currently used by the arm64 simulator
259
+ // and can be added to the other simulators as well when fast
260
+ // calls having both GP and FP params need to be supported.
160
261
  };
161
262
 
162
- enum class ArgFlags : uint8_t {
163
- kNone = 0,
164
- kIsArrayBit = 1 << 0, // This argument is first in an array of values.
263
+ // kCallbackOptionsType is not part of the Type enum
264
+ // because it is only used internally. Use value 255 that is larger
265
+ // than any valid Type enum.
266
+ static constexpr Type kCallbackOptionsType = Type(255);
267
+
268
+ enum class SequenceType : uint8_t {
269
+ kScalar,
270
+ kIsSequence, // sequence<T>
271
+ kIsTypedArray, // TypedArray of T or any ArrayBufferView if T
272
+ // is void
273
+ kIsArrayBuffer // ArrayBuffer
165
274
  };
166
275
 
167
- static CTypeInfo FromWrapperType(ArgFlags flags = ArgFlags::kNone) {
168
- return CTypeInfo(static_cast<int>(flags) | kIsWrapperTypeBit);
169
- }
276
+ enum class Flags : uint8_t {
277
+ kNone = 0,
278
+ kAllowSharedBit = 1 << 0, // Must be an ArrayBuffer or TypedArray
279
+ kEnforceRangeBit = 1 << 1, // T must be integral
280
+ kClampBit = 1 << 2, // T must be integral
281
+ kIsRestrictedBit = 1 << 3, // T must be float or double
282
+ };
170
283
 
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));
284
+ explicit constexpr CTypeInfo(
285
+ Type type, SequenceType sequence_type = SequenceType::kScalar,
286
+ Flags flags = Flags::kNone)
287
+ : type_(type), sequence_type_(sequence_type), flags_(flags) {}
288
+
289
+ typedef uint32_t Identifier;
290
+ explicit constexpr CTypeInfo(Identifier identifier)
291
+ : CTypeInfo(static_cast<Type>(identifier >> 16),
292
+ static_cast<SequenceType>((identifier >> 8) & 255),
293
+ static_cast<Flags>(identifier & 255)) {}
294
+ constexpr Identifier GetId() const {
295
+ return static_cast<uint8_t>(type_) << 16 |
296
+ static_cast<uint8_t>(sequence_type_) << 8 |
297
+ static_cast<uint8_t>(flags_);
179
298
  }
180
299
 
181
- const void* GetWrapperInfo() const;
300
+ constexpr Type GetType() const { return type_; }
301
+ constexpr SequenceType GetSequenceType() const { return sequence_type_; }
302
+ constexpr Flags GetFlags() const { return flags_; }
182
303
 
183
- constexpr Type GetType() const {
184
- if (payload_ & kIsWrapperTypeBit) {
185
- return Type::kV8Value;
186
- }
187
- return static_cast<Type>((payload_ & kTypeMask) >> kTypeOffset);
304
+ static constexpr bool IsIntegralType(Type type) {
305
+ return type == Type::kInt32 || type == Type::kUint32 ||
306
+ type == Type::kInt64 || type == Type::kUint64;
188
307
  }
189
308
 
190
- constexpr bool IsArray() const {
191
- return payload_ & static_cast<int>(ArgFlags::kIsArrayBit);
309
+ static constexpr bool IsFloatingPointType(Type type) {
310
+ return type == Type::kFloat32 || type == Type::kFloat64;
192
311
  }
193
312
 
194
- static const CTypeInfo& Invalid() {
195
- static CTypeInfo invalid = CTypeInfo(0);
196
- return invalid;
313
+ static constexpr bool IsPrimitive(Type type) {
314
+ return IsIntegralType(type) || IsFloatingPointType(type) ||
315
+ type == Type::kBool;
197
316
  }
198
317
 
199
318
  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_;
319
+ Type type_;
320
+ SequenceType sequence_type_;
321
+ Flags flags_;
213
322
  };
214
323
 
215
- class CFunctionInfo {
324
+ struct FastApiTypedArrayBase {
216
325
  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
- };
326
+ // Returns the length in number of elements.
327
+ size_t V8_EXPORT length() const { return length_; }
328
+ // Checks whether the given index is within the bounds of the collection.
329
+ void V8_EXPORT ValidateIndex(size_t index) const;
221
330
 
222
- struct ApiObject {
223
- uintptr_t address;
331
+ protected:
332
+ size_t length_ = 0;
224
333
  };
225
334
 
226
- namespace internal {
227
-
228
335
  template <typename T>
229
- struct GetCType {
230
- static constexpr CTypeInfo Get() {
231
- return CTypeInfo::FromCType(CTypeInfo::Type::kV8Value);
336
+ struct FastApiTypedArray : public FastApiTypedArrayBase {
337
+ public:
338
+ V8_INLINE T get(size_t index) const {
339
+ #ifdef DEBUG
340
+ ValidateIndex(index);
341
+ #endif // DEBUG
342
+ T tmp;
343
+ memcpy(&tmp, reinterpret_cast<T*>(data_) + index, sizeof(T));
344
+ return tmp;
232
345
  }
233
- };
234
346
 
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
-
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);
347
+ bool getStorageIfAligned(T** elements) const {
348
+ if (reinterpret_cast<uintptr_t>(data_) % alignof(T) != 0) {
349
+ return false;
350
+ }
351
+ *elements = reinterpret_cast<T*>(data_);
352
+ return true;
262
353
  }
263
- };
264
354
 
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(); }
355
+ private:
356
+ // This pointer should include the typed array offset applied.
357
+ // It's not guaranteed that it's aligned to sizeof(T), it's only
358
+ // guaranteed that it's 4-byte aligned, so for 8-byte types we need to
359
+ // provide a special implementation for reading from it, which hides
360
+ // the possibly unaligned read in the `get` method.
361
+ void* data_;
269
362
  };
270
363
 
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");
364
+ // Any TypedArray. It uses kTypedArrayBit with base type void
365
+ // Overloaded args of ArrayBufferView and TypedArray are not supported
366
+ // (for now) because the generic “any” ArrayBufferView doesn’t have its
367
+ // own instance type. It could be supported if we specify that
368
+ // TypedArray<T> always has precedence over the generic ArrayBufferView,
369
+ // but this complicates overload resolution.
370
+ struct FastApiArrayBufferView {
371
+ void* data;
372
+ size_t byte_length;
275
373
  };
276
374
 
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
- }
375
+ struct FastApiArrayBuffer {
376
+ void* data;
377
+ size_t byte_length;
283
378
  };
284
379
 
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 {
380
+ class V8_EXPORT CFunctionInfo {
293
381
  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.");
382
+ // Construct a struct to hold a CFunction's type information.
383
+ // |return_info| describes the function's return type.
384
+ // |arg_info| is an array of |arg_count| CTypeInfos describing the
385
+ // arguments. Only the last argument may be of the special type
386
+ // CTypeInfo::kCallbackOptionsType.
387
+ CFunctionInfo(const CTypeInfo& return_info, unsigned int arg_count,
388
+ const CTypeInfo* arg_info);
389
+
390
+ const CTypeInfo& ReturnInfo() const { return return_info_; }
391
+
392
+ // The argument count, not including the v8::FastApiCallbackOptions
393
+ // if present.
394
+ unsigned int ArgumentCount() const {
395
+ return HasOptions() ? arg_count_ - 1 : arg_count_;
305
396
  }
306
397
 
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];
398
+ // |index| must be less than ArgumentCount().
399
+ // Note: if the last argument passed on construction of CFunctionInfo
400
+ // has type CTypeInfo::kCallbackOptionsType, it is not included in
401
+ // ArgumentCount().
402
+ const CTypeInfo& ArgumentInfo(unsigned int index) const;
403
+
404
+ bool HasOptions() const {
405
+ // The options arg is always the last one.
406
+ return arg_count_ > 0 && arg_info_[arg_count_ - 1].GetType() ==
407
+ CTypeInfo::kCallbackOptionsType;
314
408
  }
315
409
 
316
410
  private:
317
411
  const CTypeInfo return_info_;
318
412
  const unsigned int arg_count_;
319
- const CTypeInfo arg_info_[sizeof...(Args)];
413
+ const CTypeInfo* arg_info_;
320
414
  };
321
415
 
322
- } // namespace internal
416
+ struct FastApiCallbackOptions;
417
+
418
+ // Provided for testing.
419
+ struct AnyCType {
420
+ AnyCType() : int64_value(0) {}
421
+
422
+ union {
423
+ bool bool_value;
424
+ int32_t int32_value;
425
+ uint32_t uint32_value;
426
+ int64_t int64_value;
427
+ uint64_t uint64_value;
428
+ float float_value;
429
+ double double_value;
430
+ Local<Object> object_value;
431
+ Local<Array> sequence_value;
432
+ const FastApiTypedArray<int32_t>* int32_ta_value;
433
+ const FastApiTypedArray<uint32_t>* uint32_ta_value;
434
+ const FastApiTypedArray<int64_t>* int64_ta_value;
435
+ const FastApiTypedArray<uint64_t>* uint64_ta_value;
436
+ const FastApiTypedArray<float>* float_ta_value;
437
+ const FastApiTypedArray<double>* double_ta_value;
438
+ FastApiCallbackOptions* options_value;
439
+ };
440
+ };
441
+
442
+ static_assert(
443
+ sizeof(AnyCType) == 8,
444
+ "The AnyCType struct should have size == 64 bits, as this is assumed "
445
+ "by EffectControlLinearizer.");
323
446
 
324
447
  class V8_EXPORT CFunction {
325
448
  public:
@@ -336,33 +459,66 @@ class V8_EXPORT CFunction {
336
459
  const void* GetAddress() const { return address_; }
337
460
  const CFunctionInfo* GetTypeInfo() const { return type_info_; }
338
461
 
462
+ enum class OverloadResolution { kImpossible, kAtRuntime, kAtCompileTime };
463
+
464
+ // Returns whether an overload between this and the given CFunction can
465
+ // be resolved at runtime by the RTTI available for the arguments or at
466
+ // compile time for functions with different number of arguments.
467
+ OverloadResolution GetOverloadResolution(const CFunction* other) {
468
+ // Runtime overload resolution can only deal with functions with the
469
+ // same number of arguments. Functions with different arity are handled
470
+ // by compile time overload resolution though.
471
+ if (ArgumentCount() != other->ArgumentCount()) {
472
+ return OverloadResolution::kAtCompileTime;
473
+ }
474
+
475
+ // The functions can only differ by a single argument position.
476
+ int diff_index = -1;
477
+ for (unsigned int i = 0; i < ArgumentCount(); ++i) {
478
+ if (ArgumentInfo(i).GetSequenceType() !=
479
+ other->ArgumentInfo(i).GetSequenceType()) {
480
+ if (diff_index >= 0) {
481
+ return OverloadResolution::kImpossible;
482
+ }
483
+ diff_index = i;
484
+
485
+ // We only support overload resolution between sequence types.
486
+ if (ArgumentInfo(i).GetSequenceType() ==
487
+ CTypeInfo::SequenceType::kScalar ||
488
+ other->ArgumentInfo(i).GetSequenceType() ==
489
+ CTypeInfo::SequenceType::kScalar) {
490
+ return OverloadResolution::kImpossible;
491
+ }
492
+ }
493
+ }
494
+
495
+ return OverloadResolution::kAtRuntime;
496
+ }
497
+
339
498
  template <typename F>
340
499
  static CFunction Make(F* func) {
341
500
  return ArgUnwrap<F*>::Make(func);
342
501
  }
343
502
 
344
- template <typename F>
345
- static CFunction MakeWithErrorSupport(F* func) {
346
- return ArgUnwrap<F*>::MakeWithErrorSupport(func);
503
+ // Provided for testing purposes.
504
+ template <typename R, typename... Args, typename R_Patch,
505
+ typename... Args_Patch>
506
+ static CFunction Make(R (*func)(Args...),
507
+ R_Patch (*patching_func)(Args_Patch...)) {
508
+ CFunction c_func = ArgUnwrap<R (*)(Args...)>::Make(func);
509
+ static_assert(
510
+ sizeof...(Args_Patch) == sizeof...(Args),
511
+ "The patching function must have the same number of arguments.");
512
+ c_func.address_ = reinterpret_cast<void*>(patching_func);
513
+ return c_func;
347
514
  }
348
515
 
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
- }
516
+ CFunction(const void* address, const CFunctionInfo* type_info);
353
517
 
354
518
  private:
355
519
  const void* address_;
356
520
  const CFunctionInfo* type_info_;
357
521
 
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
522
  template <typename F>
367
523
  class ArgUnwrap {
368
524
  static_assert(sizeof(F) != sizeof(F),
@@ -372,17 +528,412 @@ class V8_EXPORT CFunction {
372
528
  template <typename R, typename... Args>
373
529
  class ArgUnwrap<R (*)(Args...)> {
374
530
  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
- }
531
+ static CFunction Make(R (*func)(Args...));
532
+ };
533
+ };
534
+
535
+ /**
536
+ * A struct which may be passed to a fast call callback, like so:
537
+ * \code
538
+ * void FastMethodWithOptions(int param, FastApiCallbackOptions& options);
539
+ * \endcode
540
+ */
541
+ struct FastApiCallbackOptions {
542
+ /**
543
+ * Creates a new instance of FastApiCallbackOptions for testing purpose. The
544
+ * returned instance may be filled with mock data.
545
+ */
546
+ static FastApiCallbackOptions CreateForTesting(Isolate* isolate) {
547
+ return {false, {0}};
548
+ }
549
+
550
+ /**
551
+ * If the callback wants to signal an error condition or to perform an
552
+ * allocation, it must set options.fallback to true and do an early return
553
+ * from the fast method. Then V8 checks the value of options.fallback and if
554
+ * it's true, falls back to executing the SlowCallback, which is capable of
555
+ * reporting the error (either by throwing a JS exception or logging to the
556
+ * console) or doing the allocation. It's the embedder's responsibility to
557
+ * ensure that the fast callback is idempotent up to the point where error and
558
+ * fallback conditions are checked, because otherwise executing the slow
559
+ * callback might produce visible side-effects twice.
560
+ */
561
+ bool fallback;
562
+
563
+ /**
564
+ * The `data` passed to the FunctionTemplate constructor, or `undefined`.
565
+ * `data_ptr` allows for default constructing FastApiCallbackOptions.
566
+ */
567
+ union {
568
+ uintptr_t data_ptr;
569
+ v8::Value data;
383
570
  };
384
571
  };
385
572
 
573
+ namespace internal {
574
+
575
+ // Helper to count the number of occurances of `T` in `List`
576
+ template <typename T, typename... List>
577
+ struct count : std::integral_constant<int, 0> {};
578
+ template <typename T, typename... Args>
579
+ struct count<T, T, Args...>
580
+ : std::integral_constant<std::size_t, 1 + count<T, Args...>::value> {};
581
+ template <typename T, typename U, typename... Args>
582
+ struct count<T, U, Args...> : count<T, Args...> {};
583
+
584
+ template <typename RetBuilder, typename... ArgBuilders>
585
+ class CFunctionInfoImpl : public CFunctionInfo {
586
+ static constexpr int kOptionsArgCount =
587
+ count<FastApiCallbackOptions&, ArgBuilders...>();
588
+ static constexpr int kReceiverCount = 1;
589
+
590
+ static_assert(kOptionsArgCount == 0 || kOptionsArgCount == 1,
591
+ "Only one options parameter is supported.");
592
+
593
+ static_assert(sizeof...(ArgBuilders) >= kOptionsArgCount + kReceiverCount,
594
+ "The receiver or the options argument is missing.");
595
+
596
+ public:
597
+ constexpr CFunctionInfoImpl()
598
+ : CFunctionInfo(RetBuilder::Build(), sizeof...(ArgBuilders),
599
+ arg_info_storage_),
600
+ arg_info_storage_{ArgBuilders::Build()...} {
601
+ constexpr CTypeInfo::Type kReturnType = RetBuilder::Build().GetType();
602
+ static_assert(kReturnType == CTypeInfo::Type::kVoid ||
603
+ kReturnType == CTypeInfo::Type::kBool ||
604
+ kReturnType == CTypeInfo::Type::kInt32 ||
605
+ kReturnType == CTypeInfo::Type::kUint32 ||
606
+ kReturnType == CTypeInfo::Type::kFloat32 ||
607
+ kReturnType == CTypeInfo::Type::kFloat64 ||
608
+ kReturnType == CTypeInfo::Type::kAny,
609
+ "64-bit int and api object values are not currently "
610
+ "supported return types.");
611
+ }
612
+
613
+ private:
614
+ const CTypeInfo arg_info_storage_[sizeof...(ArgBuilders)];
615
+ };
616
+
617
+ template <typename T>
618
+ struct TypeInfoHelper {
619
+ static_assert(sizeof(T) != sizeof(T), "This type is not supported");
620
+ };
621
+
622
+ #define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR(T, Enum) \
623
+ template <> \
624
+ struct TypeInfoHelper<T> { \
625
+ static constexpr CTypeInfo::Flags Flags() { \
626
+ return CTypeInfo::Flags::kNone; \
627
+ } \
628
+ \
629
+ static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
630
+ static constexpr CTypeInfo::SequenceType SequenceType() { \
631
+ return CTypeInfo::SequenceType::kScalar; \
632
+ } \
633
+ };
634
+
635
+ template <CTypeInfo::Type type>
636
+ struct CTypeInfoTraits {};
637
+
638
+ #define DEFINE_TYPE_INFO_TRAITS(CType, Enum) \
639
+ template <> \
640
+ struct CTypeInfoTraits<CTypeInfo::Type::Enum> { \
641
+ using ctype = CType; \
642
+ };
643
+
644
+ #define PRIMITIVE_C_TYPES(V) \
645
+ V(bool, kBool) \
646
+ V(int32_t, kInt32) \
647
+ V(uint32_t, kUint32) \
648
+ V(int64_t, kInt64) \
649
+ V(uint64_t, kUint64) \
650
+ V(float, kFloat32) \
651
+ V(double, kFloat64)
652
+
653
+ // Same as above, but includes deprecated types for compatibility.
654
+ #define ALL_C_TYPES(V) \
655
+ PRIMITIVE_C_TYPES(V) \
656
+ V(void, kVoid) \
657
+ V(v8::Local<v8::Value>, kV8Value) \
658
+ V(v8::Local<v8::Object>, kV8Value) \
659
+ V(AnyCType, kAny)
660
+
661
+ // ApiObject was a temporary solution to wrap the pointer to the v8::Value.
662
+ // Please use v8::Local<v8::Value> in new code for the arguments and
663
+ // v8::Local<v8::Object> for the receiver, as ApiObject will be deprecated.
664
+
665
+ ALL_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR)
666
+ PRIMITIVE_C_TYPES(DEFINE_TYPE_INFO_TRAITS)
667
+
668
+ #undef PRIMITIVE_C_TYPES
669
+ #undef ALL_C_TYPES
670
+
671
+ #define SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA(T, Enum) \
672
+ template <> \
673
+ struct TypeInfoHelper<const FastApiTypedArray<T>&> { \
674
+ static constexpr CTypeInfo::Flags Flags() { \
675
+ return CTypeInfo::Flags::kNone; \
676
+ } \
677
+ \
678
+ static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
679
+ static constexpr CTypeInfo::SequenceType SequenceType() { \
680
+ return CTypeInfo::SequenceType::kIsTypedArray; \
681
+ } \
682
+ };
683
+
684
+ #define TYPED_ARRAY_C_TYPES(V) \
685
+ V(int32_t, kInt32) \
686
+ V(uint32_t, kUint32) \
687
+ V(int64_t, kInt64) \
688
+ V(uint64_t, kUint64) \
689
+ V(float, kFloat32) \
690
+ V(double, kFloat64)
691
+
692
+ TYPED_ARRAY_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA)
693
+
694
+ #undef TYPED_ARRAY_C_TYPES
695
+
696
+ template <>
697
+ struct TypeInfoHelper<v8::Local<v8::Array>> {
698
+ static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
699
+
700
+ static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::kVoid; }
701
+ static constexpr CTypeInfo::SequenceType SequenceType() {
702
+ return CTypeInfo::SequenceType::kIsSequence;
703
+ }
704
+ };
705
+
706
+ template <>
707
+ struct TypeInfoHelper<v8::Local<v8::Uint32Array>> {
708
+ static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
709
+
710
+ static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::kUint32; }
711
+ static constexpr CTypeInfo::SequenceType SequenceType() {
712
+ return CTypeInfo::SequenceType::kIsTypedArray;
713
+ }
714
+ };
715
+
716
+ template <>
717
+ struct TypeInfoHelper<FastApiCallbackOptions&> {
718
+ static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }
719
+
720
+ static constexpr CTypeInfo::Type Type() {
721
+ return CTypeInfo::kCallbackOptionsType;
722
+ }
723
+ static constexpr CTypeInfo::SequenceType SequenceType() {
724
+ return CTypeInfo::SequenceType::kScalar;
725
+ }
726
+ };
727
+
728
+ #define STATIC_ASSERT_IMPLIES(COND, ASSERTION, MSG) \
729
+ static_assert(((COND) == 0) || (ASSERTION), MSG)
730
+
731
+ } // namespace internal
732
+
733
+ template <typename T, CTypeInfo::Flags... Flags>
734
+ class V8_EXPORT CTypeInfoBuilder {
735
+ public:
736
+ using BaseType = T;
737
+
738
+ static constexpr CTypeInfo Build() {
739
+ constexpr CTypeInfo::Flags kFlags =
740
+ MergeFlags(internal::TypeInfoHelper<T>::Flags(), Flags...);
741
+ constexpr CTypeInfo::Type kType = internal::TypeInfoHelper<T>::Type();
742
+ constexpr CTypeInfo::SequenceType kSequenceType =
743
+ internal::TypeInfoHelper<T>::SequenceType();
744
+
745
+ STATIC_ASSERT_IMPLIES(
746
+ uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kAllowSharedBit),
747
+ (kSequenceType == CTypeInfo::SequenceType::kIsTypedArray ||
748
+ kSequenceType == CTypeInfo::SequenceType::kIsArrayBuffer),
749
+ "kAllowSharedBit is only allowed for TypedArrays and ArrayBuffers.");
750
+ STATIC_ASSERT_IMPLIES(
751
+ uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kEnforceRangeBit),
752
+ CTypeInfo::IsIntegralType(kType),
753
+ "kEnforceRangeBit is only allowed for integral types.");
754
+ STATIC_ASSERT_IMPLIES(
755
+ uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kClampBit),
756
+ CTypeInfo::IsIntegralType(kType),
757
+ "kClampBit is only allowed for integral types.");
758
+ STATIC_ASSERT_IMPLIES(
759
+ uint8_t(kFlags) & uint8_t(CTypeInfo::Flags::kIsRestrictedBit),
760
+ CTypeInfo::IsFloatingPointType(kType),
761
+ "kIsRestrictedBit is only allowed for floating point types.");
762
+ STATIC_ASSERT_IMPLIES(kSequenceType == CTypeInfo::SequenceType::kIsSequence,
763
+ kType == CTypeInfo::Type::kVoid,
764
+ "Sequences are only supported from void type.");
765
+ STATIC_ASSERT_IMPLIES(
766
+ kSequenceType == CTypeInfo::SequenceType::kIsTypedArray,
767
+ CTypeInfo::IsPrimitive(kType) || kType == CTypeInfo::Type::kVoid,
768
+ "TypedArrays are only supported from primitive types or void.");
769
+
770
+ // Return the same type with the merged flags.
771
+ return CTypeInfo(internal::TypeInfoHelper<T>::Type(),
772
+ internal::TypeInfoHelper<T>::SequenceType(), kFlags);
773
+ }
774
+
775
+ private:
776
+ template <typename... Rest>
777
+ static constexpr CTypeInfo::Flags MergeFlags(CTypeInfo::Flags flags,
778
+ Rest... rest) {
779
+ return CTypeInfo::Flags(uint8_t(flags) | uint8_t(MergeFlags(rest...)));
780
+ }
781
+ static constexpr CTypeInfo::Flags MergeFlags() { return CTypeInfo::Flags(0); }
782
+ };
783
+
784
+ namespace internal {
785
+ template <typename RetBuilder, typename... ArgBuilders>
786
+ class CFunctionBuilderWithFunction {
787
+ public:
788
+ explicit constexpr CFunctionBuilderWithFunction(const void* fn) : fn_(fn) {}
789
+
790
+ template <CTypeInfo::Flags... Flags>
791
+ constexpr auto Ret() {
792
+ return CFunctionBuilderWithFunction<
793
+ CTypeInfoBuilder<typename RetBuilder::BaseType, Flags...>,
794
+ ArgBuilders...>(fn_);
795
+ }
796
+
797
+ template <unsigned int N, CTypeInfo::Flags... Flags>
798
+ constexpr auto Arg() {
799
+ // Return a copy of the builder with the Nth arg builder merged with
800
+ // template parameter pack Flags.
801
+ return ArgImpl<N, Flags...>(
802
+ std::make_index_sequence<sizeof...(ArgBuilders)>());
803
+ }
804
+
805
+ auto Build() {
806
+ static CFunctionInfoImpl<RetBuilder, ArgBuilders...> instance;
807
+ return CFunction(fn_, &instance);
808
+ }
809
+
810
+ private:
811
+ template <bool Merge, unsigned int N, CTypeInfo::Flags... Flags>
812
+ struct GetArgBuilder;
813
+
814
+ // Returns the same ArgBuilder as the one at index N, including its flags.
815
+ // Flags in the template parameter pack are ignored.
816
+ template <unsigned int N, CTypeInfo::Flags... Flags>
817
+ struct GetArgBuilder<false, N, Flags...> {
818
+ using type =
819
+ typename std::tuple_element<N, std::tuple<ArgBuilders...>>::type;
820
+ };
821
+
822
+ // Returns an ArgBuilder with the same base type as the one at index N,
823
+ // but merges the flags with the flags in the template parameter pack.
824
+ template <unsigned int N, CTypeInfo::Flags... Flags>
825
+ struct GetArgBuilder<true, N, Flags...> {
826
+ using type = CTypeInfoBuilder<
827
+ typename std::tuple_element<N,
828
+ std::tuple<ArgBuilders...>>::type::BaseType,
829
+ std::tuple_element<N, std::tuple<ArgBuilders...>>::type::Build()
830
+ .GetFlags(),
831
+ Flags...>;
832
+ };
833
+
834
+ // Return a copy of the CFunctionBuilder, but merges the Flags on
835
+ // ArgBuilder index N with the new Flags passed in the template parameter
836
+ // pack.
837
+ template <unsigned int N, CTypeInfo::Flags... Flags, size_t... I>
838
+ constexpr auto ArgImpl(std::index_sequence<I...>) {
839
+ return CFunctionBuilderWithFunction<
840
+ RetBuilder, typename GetArgBuilder<N == I, I, Flags...>::type...>(fn_);
841
+ }
842
+
843
+ const void* fn_;
844
+ };
845
+
846
+ class CFunctionBuilder {
847
+ public:
848
+ constexpr CFunctionBuilder() {}
849
+
850
+ template <typename R, typename... Args>
851
+ constexpr auto Fn(R (*fn)(Args...)) {
852
+ return CFunctionBuilderWithFunction<CTypeInfoBuilder<R>,
853
+ CTypeInfoBuilder<Args>...>(
854
+ reinterpret_cast<const void*>(fn));
855
+ }
856
+ };
857
+
858
+ } // namespace internal
859
+
860
+ // static
861
+ template <typename R, typename... Args>
862
+ CFunction CFunction::ArgUnwrap<R (*)(Args...)>::Make(R (*func)(Args...)) {
863
+ return internal::CFunctionBuilder().Fn(func).Build();
864
+ }
865
+
866
+ using CFunctionBuilder = internal::CFunctionBuilder;
867
+
868
+ static constexpr CTypeInfo kTypeInfoInt32 = CTypeInfo(CTypeInfo::Type::kInt32);
869
+ static constexpr CTypeInfo kTypeInfoFloat64 =
870
+ CTypeInfo(CTypeInfo::Type::kFloat64);
871
+
872
+ /**
873
+ * Copies the contents of this JavaScript array to a C++ buffer with
874
+ * a given max_length. A CTypeInfo is passed as an argument,
875
+ * instructing different rules for conversion (e.g. restricted float/double).
876
+ * The element type T of the destination array must match the C type
877
+ * corresponding to the CTypeInfo (specified by CTypeInfoTraits).
878
+ * If the array length is larger than max_length or the array is of
879
+ * unsupported type, the operation will fail, returning false. Generally, an
880
+ * array which contains objects, undefined, null or anything not convertible
881
+ * to the requested destination type, is considered unsupported. The operation
882
+ * returns true on success. `type_info` will be used for conversions.
883
+ */
884
+ template <const CTypeInfo* type_info, typename T>
885
+ V8_DEPRECATED(
886
+ "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
887
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT
888
+ TryCopyAndConvertArrayToCppBuffer(Local<Array> src, T* dst,
889
+ uint32_t max_length);
890
+
891
+ template <>
892
+ V8_DEPRECATED(
893
+ "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
894
+ inline bool V8_WARN_UNUSED_RESULT
895
+ TryCopyAndConvertArrayToCppBuffer<&kTypeInfoInt32, int32_t>(
896
+ Local<Array> src, int32_t* dst, uint32_t max_length) {
897
+ return false;
898
+ }
899
+
900
+ template <>
901
+ V8_DEPRECATED(
902
+ "Use TryToCopyAndConvertArrayToCppBuffer<CTypeInfo::Identifier, T>()")
903
+ inline bool V8_WARN_UNUSED_RESULT
904
+ TryCopyAndConvertArrayToCppBuffer<&kTypeInfoFloat64, double>(
905
+ Local<Array> src, double* dst, uint32_t max_length) {
906
+ return false;
907
+ }
908
+
909
+ template <CTypeInfo::Identifier type_info_id, typename T>
910
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(
911
+ Local<Array> src, T* dst, uint32_t max_length);
912
+
913
+ template <>
914
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT
915
+ TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<int32_t>::Build().GetId(),
916
+ int32_t>(Local<Array> src, int32_t* dst,
917
+ uint32_t max_length);
918
+
919
+ template <>
920
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT
921
+ TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<uint32_t>::Build().GetId(),
922
+ uint32_t>(Local<Array> src, uint32_t* dst,
923
+ uint32_t max_length);
924
+
925
+ template <>
926
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT
927
+ TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<float>::Build().GetId(),
928
+ float>(Local<Array> src, float* dst,
929
+ uint32_t max_length);
930
+
931
+ template <>
932
+ bool V8_EXPORT V8_WARN_UNUSED_RESULT
933
+ TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<double>::Build().GetId(),
934
+ double>(Local<Array> src, double* dst,
935
+ uint32_t max_length);
936
+
386
937
  } // namespace v8
387
938
 
388
939
  #endif // INCLUDE_V8_FAST_API_CALLS_H_