v8 11.3.244 (node 20.3.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;
24class Builtins;
25} // namespace internal
26
27namespace debug {
28class ConsoleCallArguments;
29} // namespace debug
30
31template <typename T>
33 public:
34 template <class S>
35 V8_INLINE ReturnValue(const ReturnValue<S>& that) : value_(that.value_) {
36 static_assert(std::is_base_of<T, S>::value, "type check");
37 }
38 // Local setters
39 template <typename S>
40 V8_INLINE void Set(const Global<S>& handle);
41 template <typename S>
43 template <typename S>
44 V8_INLINE void Set(const Local<S> handle);
45 // Fast primitive setters
46 V8_INLINE void Set(bool value);
47 V8_INLINE void Set(double i);
48 V8_INLINE void Set(int32_t i);
49 V8_INLINE void Set(uint32_t i);
50 // Fast JS primitive setters
51 V8_INLINE void SetNull();
54 // Convenience getter for Isolate
56
57 // Pointer setter: Uncompilable to prevent inadvertent misuse.
58 template <typename S>
59 V8_INLINE void Set(S* whatever);
60
61 // Getter. Creates a new Local<> so it comes with a certain performance
62 // hit. If the ReturnValue was not yet set, this will return the undefined
63 // value.
65
66 private:
67 template <class F>
68 friend class ReturnValue;
69 template <class F>
71 template <class F>
73 template <class F, class G, class H>
75 V8_INLINE void SetInternal(internal::Address value) { *value_ = value; }
76 V8_INLINE internal::Address GetDefaultValue();
78
79 // See FunctionCallbackInfo.
80 static constexpr int kIsolateValueIndex = -2;
81 static constexpr int kDefaultValueValueIndex = -1;
82
83 internal::Address* value_;
84};
85
92template <typename T>
94 public:
96 V8_INLINE int Length() const;
101 V8_INLINE Local<Value> operator[](int i) const;
118 V8_INLINE bool IsConstructCall() const;
125
126 private:
130 friend class internal::Builtins;
131 static constexpr int kHolderIndex = 0;
132 static constexpr int kIsolateIndex = 1;
133 static constexpr int kReturnValueDefaultValueIndex = 2;
134 static constexpr int kReturnValueIndex = 3;
135 static constexpr int kDataIndex = 4;
136 static constexpr int kNewTargetIndex = 5;
137
138 static constexpr int kArgsLength = 6;
139 static constexpr int kArgsLengthWithReceiver = 7;
140
141 // Codegen constants:
142 static constexpr int kSize = 3 * internal::kApiSystemPointerSize;
143 static constexpr int kImplicitArgsOffset = 0;
144 static constexpr int kValuesOffset =
145 kImplicitArgsOffset + internal::kApiSystemPointerSize;
146 static constexpr int kLengthOffset =
147 kValuesOffset + internal::kApiSystemPointerSize;
148
149 static constexpr int kThisValuesIndex = -1;
151 kReturnValueDefaultValueIndex - kReturnValueIndex);
153 kIsolateIndex - kReturnValueIndex);
154
156 internal::Address* values, int length);
157 internal::Address* implicit_args_;
158 internal::Address* values_;
159 int length_;
160};
161
166template <typename T>
168 public:
173
180
223
234
244
253
254 private:
255 friend class MacroAssembler;
258 static constexpr int kShouldThrowOnErrorIndex = 0;
259 static constexpr int kHolderIndex = 1;
260 static constexpr int kIsolateIndex = 2;
261 static constexpr int kReturnValueDefaultValueIndex = 3;
262 static constexpr int kReturnValueIndex = 4;
263 static constexpr int kDataIndex = 5;
264 static constexpr int kThisIndex = 6;
265
266 static constexpr int kArgsLength = 7;
267
268 static constexpr int kSize = 1 * internal::kApiSystemPointerSize;
269
271 : args_(args) {}
272 internal::Address* args_;
273};
274
275using FunctionCallback = void (*)(const FunctionCallbackInfo<Value>& info);
276
277// --- Implementation ---
278
279template <typename T>
280ReturnValue<T>::ReturnValue(internal::Address* slot) : value_(slot) {}
281
282template <typename T>
283template <typename S>
284void ReturnValue<T>::Set(const Global<S>& handle) {
285 static_assert(std::is_base_of<T, S>::value, "type check");
286 if (V8_UNLIKELY(handle.IsEmpty())) {
287 *value_ = GetDefaultValue();
288 } else {
289 *value_ = *reinterpret_cast<internal::Address*>(*handle);
290 }
291}
292
293template <typename T>
294template <typename S>
296 static_assert(std::is_base_of<T, S>::value, "type check");
297 if (V8_UNLIKELY(handle.IsEmpty())) {
298 *value_ = GetDefaultValue();
299 } else {
300 *value_ = *reinterpret_cast<internal::Address*>(handle.val_);
301 }
302}
303
304template <typename T>
305template <typename S>
306void ReturnValue<T>::Set(const Local<S> handle) {
307 static_assert(std::is_void<T>::value || std::is_base_of<T, S>::value,
308 "type check");
309 if (V8_UNLIKELY(handle.IsEmpty())) {
310 *value_ = GetDefaultValue();
311 } else {
312 *value_ = internal::ValueHelper::ValueAsAddress(*handle);
313 }
314}
315
316template <typename T>
317void ReturnValue<T>::Set(double i) {
318 static_assert(std::is_base_of<T, Number>::value, "type check");
319 Set(Number::New(GetIsolate(), i));
320}
321
322template <typename T>
323void ReturnValue<T>::Set(int32_t i) {
324 static_assert(std::is_base_of<T, Integer>::value, "type check");
325 using I = internal::Internals;
326 if (V8_LIKELY(I::IsValidSmi(i))) {
327 *value_ = I::IntToSmi(i);
328 return;
329 }
330 Set(Integer::New(GetIsolate(), i));
331}
332
333template <typename T>
334void ReturnValue<T>::Set(uint32_t i) {
335 static_assert(std::is_base_of<T, Integer>::value, "type check");
336 // Can't simply use INT32_MAX here for whatever reason.
337 bool fits_into_int32_t = (i & (1U << 31)) == 0;
338 if (V8_LIKELY(fits_into_int32_t)) {
339 Set(static_cast<int32_t>(i));
340 return;
341 }
342 Set(Integer::NewFromUnsigned(GetIsolate(), i));
343}
344
345template <typename T>
346void ReturnValue<T>::Set(bool value) {
347 static_assert(std::is_base_of<T, Boolean>::value, "type check");
348 using I = internal::Internals;
349 int root_index;
350 if (value) {
351 root_index = I::kTrueValueRootIndex;
352 } else {
353 root_index = I::kFalseValueRootIndex;
354 }
355 *value_ = I::GetRoot(GetIsolate(), root_index);
356}
357
358template <typename T>
360 static_assert(std::is_base_of<T, Primitive>::value, "type check");
361 using I = internal::Internals;
362 *value_ = I::GetRoot(GetIsolate(), I::kNullValueRootIndex);
363}
364
365template <typename T>
367 static_assert(std::is_base_of<T, Primitive>::value, "type check");
368 using I = internal::Internals;
369 *value_ = I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex);
370}
371
372template <typename T>
374 static_assert(std::is_base_of<T, String>::value, "type check");
375 using I = internal::Internals;
376 *value_ = I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex);
377}
378
379template <typename T>
381 // Isolate is always the pointer below the default value on the stack.
382 return *reinterpret_cast<Isolate**>(&value_[kIsolateValueIndex]);
383}
384
385template <typename T>
387 using I = internal::Internals;
388#if V8_STATIC_ROOTS_BOOL
389 if (I::is_identical(*value_, I::StaticReadOnlyRoot::kTheHoleValue)) {
390#else
391 if (*value_ == I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex)) {
392#endif
393 return Undefined(GetIsolate());
394 }
395 return Local<Value>::New(GetIsolate(), reinterpret_cast<Value*>(value_));
396}
397
398template <typename T>
399template <typename S>
400void ReturnValue<T>::Set(S* whatever) {
401 static_assert(sizeof(S) < 0, "incompilable to prevent inadvertent misuse");
402}
403
404template <typename T>
406 // Default value is always the pointer below value_ on the stack.
407 return value_[kDefaultValueValueIndex];
408}
409
410template <typename T>
411FunctionCallbackInfo<T>::FunctionCallbackInfo(internal::Address* implicit_args,
412 internal::Address* values,
413 int length)
414 : implicit_args_(implicit_args), values_(values), length_(length) {}
415
416template <typename T>
418 // values_ points to the first argument (not the receiver).
419 if (i < 0 || length_ <= i) return Undefined(GetIsolate());
420 return Local<Value>::FromSlot(values_ + i);
421}
422
423template <typename T>
425 // values_ points to the first argument (not the receiver).
426 return Local<Object>::FromSlot(values_ + kThisValuesIndex);
427}
428
429template <typename T>
431 return Local<Object>::FromSlot(&implicit_args_[kHolderIndex]);
432}
433
434template <typename T>
436 return Local<Value>::FromSlot(&implicit_args_[kNewTargetIndex]);
437}
438
439template <typename T>
441 return Local<Value>::FromSlot(&implicit_args_[kDataIndex]);
442}
443
444template <typename T>
446 return *reinterpret_cast<Isolate**>(&implicit_args_[kIsolateIndex]);
447}
448
449template <typename T>
451 return ReturnValue<T>(&implicit_args_[kReturnValueIndex]);
452}
453
454template <typename T>
456 return !NewTarget()->IsUndefined();
457}
458
459template <typename T>
461 return length_;
462}
463
464template <typename T>
466 return *reinterpret_cast<Isolate**>(&args_[kIsolateIndex]);
467}
468
469template <typename T>
471 return Local<Value>::FromSlot(&args_[kDataIndex]);
472}
473
474template <typename T>
476 return Local<Object>::FromSlot(&args_[kThisIndex]);
477}
478
479template <typename T>
481 return Local<Object>::FromSlot(&args_[kHolderIndex]);
482}
483
484template <typename T>
486 return ReturnValue<T>(&args_[kReturnValueIndex]);
487}
488
489template <typename T>
491 using I = internal::Internals;
492 if (args_[kShouldThrowOnErrorIndex] !=
493 I::IntToSmi(I::kInferShouldThrowMode)) {
494 return args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kDontThrow);
495 }
497 reinterpret_cast<v8::internal::Isolate*>(GetIsolate()));
498}
499
500} // namespace v8
501
502#endif // INCLUDE_V8_FUNCTION_CALLBACK_H_
friend class internal::Builtins
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
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
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 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_
const int kApiSystemPointerSize
Definition v8-internal.h:42
uintptr_t Address
Definition v8-internal.h:29
V8_EXPORT bool ShouldThrowOnError(internal::Isolate *isolate)
void(*)(const FunctionCallbackInfo< Value > &info) FunctionCallback
V8_INLINE Local< Primitive > Undefined(Isolate *isolate)
#define V8_INLINE
Definition v8config.h:460
#define V8_LIKELY(condition)
Definition v8config.h:599
#define V8_UNLIKELY(condition)
Definition v8config.h:598