v8 10.2.154 (node 18.16.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
v8-function-callback.h
Go to the documentation of this file.
1// Copyright 2021 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef INCLUDE_V8_FUNCTION_CALLBACK_H_
6#define INCLUDE_V8_FUNCTION_CALLBACK_H_
7
8#include "v8-local-handle.h" // NOLINT(build/include_directory)
9#include "v8-primitive.h" // NOLINT(build/include_directory)
10#include "v8config.h" // NOLINT(build/include_directory)
11
12namespace v8 {
13
14template <typename T>
15class BasicTracedReference;
16template <typename T>
17class Global;
18class Object;
19class Value;
20
21namespace internal {
22class FunctionCallbackArguments;
23class PropertyCallbackArguments;
24} // namespace internal
25
26namespace debug {
27class ConsoleCallArguments;
28} // namespace debug
29
30template <typename T>
32 public:
33 template <class S>
34 V8_INLINE ReturnValue(const ReturnValue<S>& that) : value_(that.value_) {
35 static_assert(std::is_base_of<T, S>::value, "type check");
36 }
37 // Local setters
38 template <typename S>
39 V8_INLINE void Set(const Global<S>& handle);
40 template <typename S>
42 template <typename S>
43 V8_INLINE void Set(const Local<S> handle);
44 // Fast primitive setters
45 V8_INLINE void Set(bool value);
46 V8_INLINE void Set(double i);
47 V8_INLINE void Set(int32_t i);
48 V8_INLINE void Set(uint32_t i);
49 // Fast JS primitive setters
50 V8_INLINE void SetNull();
53 // Convenience getter for Isolate
55
56 // Pointer setter: Uncompilable to prevent inadvertent misuse.
57 template <typename S>
58 V8_INLINE void Set(S* whatever);
59
60 // Getter. Creates a new Local<> so it comes with a certain performance
61 // hit. If the ReturnValue was not yet set, this will return the undefined
62 // value.
64
65 private:
66 template <class F>
67 friend class ReturnValue;
68 template <class F>
70 template <class F>
72 template <class F, class G, class H>
74 V8_INLINE void SetInternal(internal::Address value) { *value_ = value; }
75 V8_INLINE internal::Address GetDefaultValue();
77 internal::Address* value_;
78};
79
86template <typename T>
88 public:
90 V8_INLINE int Length() const;
112 V8_INLINE bool IsConstructCall() const;
119 // This shouldn't be public, but the arm compiler needs it.
120 static const int kArgsLength = 6;
121
122 protected:
126 static const int kHolderIndex = 0;
127 static const int kIsolateIndex = 1;
128 static const int kReturnValueDefaultValueIndex = 2;
129 static const int kReturnValueIndex = 3;
130 static const int kDataIndex = 4;
131 static const int kNewTargetIndex = 5;
132
134 internal::Address* values, int length);
138};
139
144template <typename T>
146 public:
151
158
201
212
222
231
232 // This shouldn't be public, but the arm compiler needs it.
233 static const int kArgsLength = 7;
234
235 protected:
236 friend class MacroAssembler;
239 static const int kShouldThrowOnErrorIndex = 0;
240 static const int kHolderIndex = 1;
241 static const int kIsolateIndex = 2;
242 static const int kReturnValueDefaultValueIndex = 3;
243 static const int kReturnValueIndex = 4;
244 static const int kDataIndex = 5;
245 static const int kThisIndex = 6;
246
249};
250
251using FunctionCallback = void (*)(const FunctionCallbackInfo<Value>& info);
252
253// --- Implementation ---
254
255template <typename T>
256ReturnValue<T>::ReturnValue(internal::Address* slot) : value_(slot) {}
257
258template <typename T>
259template <typename S>
260void ReturnValue<T>::Set(const Global<S>& handle) {
261 static_assert(std::is_base_of<T, S>::value, "type check");
262 if (V8_UNLIKELY(handle.IsEmpty())) {
263 *value_ = GetDefaultValue();
264 } else {
265 *value_ = *reinterpret_cast<internal::Address*>(*handle);
266 }
267}
268
269template <typename T>
270template <typename S>
272 static_assert(std::is_base_of<T, S>::value, "type check");
273 if (V8_UNLIKELY(handle.IsEmpty())) {
274 *value_ = GetDefaultValue();
275 } else {
276 *value_ = *reinterpret_cast<internal::Address*>(handle.val_);
277 }
278}
279
280template <typename T>
281template <typename S>
282void ReturnValue<T>::Set(const Local<S> handle) {
283 static_assert(std::is_void<T>::value || std::is_base_of<T, S>::value,
284 "type check");
285 if (V8_UNLIKELY(handle.IsEmpty())) {
286 *value_ = GetDefaultValue();
287 } else {
288 *value_ = *reinterpret_cast<internal::Address*>(*handle);
289 }
290}
291
292template <typename T>
293void ReturnValue<T>::Set(double i) {
294 static_assert(std::is_base_of<T, Number>::value, "type check");
295 Set(Number::New(GetIsolate(), i));
296}
297
298template <typename T>
299void ReturnValue<T>::Set(int32_t i) {
300 static_assert(std::is_base_of<T, Integer>::value, "type check");
301 using I = internal::Internals;
302 if (V8_LIKELY(I::IsValidSmi(i))) {
303 *value_ = I::IntToSmi(i);
304 return;
305 }
306 Set(Integer::New(GetIsolate(), i));
307}
308
309template <typename T>
310void ReturnValue<T>::Set(uint32_t i) {
311 static_assert(std::is_base_of<T, Integer>::value, "type check");
312 // Can't simply use INT32_MAX here for whatever reason.
313 bool fits_into_int32_t = (i & (1U << 31)) == 0;
314 if (V8_LIKELY(fits_into_int32_t)) {
315 Set(static_cast<int32_t>(i));
316 return;
317 }
318 Set(Integer::NewFromUnsigned(GetIsolate(), i));
319}
320
321template <typename T>
322void ReturnValue<T>::Set(bool value) {
323 static_assert(std::is_base_of<T, Boolean>::value, "type check");
324 using I = internal::Internals;
325 int root_index;
326 if (value) {
327 root_index = I::kTrueValueRootIndex;
328 } else {
329 root_index = I::kFalseValueRootIndex;
330 }
331 *value_ = *I::GetRoot(GetIsolate(), root_index);
332}
333
334template <typename T>
336 static_assert(std::is_base_of<T, Primitive>::value, "type check");
337 using I = internal::Internals;
338 *value_ = *I::GetRoot(GetIsolate(), I::kNullValueRootIndex);
339}
340
341template <typename T>
343 static_assert(std::is_base_of<T, Primitive>::value, "type check");
344 using I = internal::Internals;
345 *value_ = *I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex);
346}
347
348template <typename T>
350 static_assert(std::is_base_of<T, String>::value, "type check");
351 using I = internal::Internals;
352 *value_ = *I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex);
353}
354
355template <typename T>
357 // Isolate is always the pointer below the default value on the stack.
358 return *reinterpret_cast<Isolate**>(&value_[-2]);
359}
360
361template <typename T>
363 using I = internal::Internals;
364 if (*value_ == *I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex))
365 return Local<Value>(*Undefined(GetIsolate()));
366 return Local<Value>::New(GetIsolate(), reinterpret_cast<Value*>(value_));
367}
368
369template <typename T>
370template <typename S>
371void ReturnValue<T>::Set(S* whatever) {
372 static_assert(sizeof(S) < 0, "incompilable to prevent inadvertent misuse");
373}
374
375template <typename T>
377 // Default value is always the pointer below value_ on the stack.
378 return value_[-1];
379}
380
381template <typename T>
383 internal::Address* values,
384 int length)
385 : implicit_args_(implicit_args), values_(values), length_(length) {}
386
387template <typename T>
389 // values_ points to the first argument (not the receiver).
390 if (i < 0 || length_ <= i) return Local<Value>(*Undefined(GetIsolate()));
391 return Local<Value>(reinterpret_cast<Value*>(values_ + i));
392}
393
394template <typename T>
396 // values_ points to the first argument (not the receiver).
397 return Local<Object>(reinterpret_cast<Object*>(values_ - 1));
398}
399
400template <typename T>
402 return Local<Object>(
403 reinterpret_cast<Object*>(&implicit_args_[kHolderIndex]));
404}
405
406template <typename T>
408 return Local<Value>(
409 reinterpret_cast<Value*>(&implicit_args_[kNewTargetIndex]));
410}
411
412template <typename T>
414 return Local<Value>(reinterpret_cast<Value*>(&implicit_args_[kDataIndex]));
415}
416
417template <typename T>
419 return *reinterpret_cast<Isolate**>(&implicit_args_[kIsolateIndex]);
420}
421
422template <typename T>
424 return ReturnValue<T>(&implicit_args_[kReturnValueIndex]);
425}
426
427template <typename T>
429 return !NewTarget()->IsUndefined();
430}
431
432template <typename T>
434 return length_;
435}
436
437template <typename T>
439 return *reinterpret_cast<Isolate**>(&args_[kIsolateIndex]);
440}
441
442template <typename T>
444 return Local<Value>(reinterpret_cast<Value*>(&args_[kDataIndex]));
445}
446
447template <typename T>
449 return Local<Object>(reinterpret_cast<Object*>(&args_[kThisIndex]));
450}
451
452template <typename T>
454 return Local<Object>(reinterpret_cast<Object*>(&args_[kHolderIndex]));
455}
456
457template <typename T>
459 return ReturnValue<T>(&args_[kReturnValueIndex]);
460}
461
462template <typename T>
464 using I = internal::Internals;
465 if (args_[kShouldThrowOnErrorIndex] !=
466 I::IntToSmi(I::kInferShouldThrowMode)) {
467 return args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kDontThrow);
468 }
470 reinterpret_cast<v8::internal::Isolate*>(GetIsolate()));
471}
472
473} // namespace v8
474
475#endif // INCLUDE_V8_FUNCTION_CALLBACK_H_
static const int kReturnValueDefaultValueIndex
V8_INLINE ReturnValue< T > GetReturnValue() const
V8_INLINE bool IsConstructCall() const
V8_INLINE Local< Object > This() const
V8_INLINE Local< Object > Holder() const
V8_INLINE Isolate * GetIsolate() const
V8_INLINE Local< Value > Data() const
internal::Address * implicit_args_
V8_INLINE int Length() const
friend class debug::ConsoleCallArguments
V8_INLINE Local< Value > NewTarget() const
friend class internal::FunctionCallbackArguments
V8_INLINE Local< Value > operator[](int i) const
V8_INLINE bool IsEmpty() const
V8_INLINE bool IsEmpty() const
static const int kShouldThrowOnErrorIndex
static const int kReturnValueDefaultValueIndex
V8_INLINE ReturnValue< T > GetReturnValue() const
friend class internal::PropertyCallbackArguments
V8_INLINE Local< Object > This() const
V8_INLINE Local< Object > Holder() const
V8_INLINE Isolate * GetIsolate() const
V8_INLINE Local< Value > Data() const
V8_INLINE bool ShouldThrowOnError() const
V8_INLINE PropertyCallbackInfo(internal::Address *args)
V8_INLINE ReturnValue(const ReturnValue< S > &that)
V8_INLINE Isolate * GetIsolate() const
V8_INLINE void Set(const BasicTracedReference< S > &handle)
V8_INLINE void SetNull()
V8_INLINE void SetUndefined()
V8_INLINE void Set(const Global< S > &handle)
V8_INLINE void SetEmptyString()
V8_INLINE void Set(const Local< S > handle)
V8_INLINE void Set(S *whatever)
V8_INLINE Local< Value > Get() const
internal::Address * val_
uintptr_t Address
Definition v8-internal.h:29
V8_EXPORT bool ShouldThrowOnError(v8::internal::Isolate *isolate)
void(*)(const FunctionCallbackInfo< Value > &info) FunctionCallback
int32_t(Local< Array > src, int32_t *dst, uint32_t max_length)
V8_INLINE Local< Primitive > Undefined(Isolate *isolate)
#define V8_INLINE
Definition v8config.h:425
#define V8_LIKELY(condition)
Definition v8config.h:489
#define V8_UNLIKELY(condition)
Definition v8config.h:488