Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/node/v8-function-callback.h
$ cat -n /usr/include/node/v8-function-callback.h 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
9 #include
10 11 #include "v8-local-handle.h" // NOLINT(build/include_directory) 12 #include "v8-primitive.h" // NOLINT(build/include_directory) 13 #include "v8config.h" // NOLINT(build/include_directory) 14 15 namespace v8 { 16 17 template
18 class BasicTracedReference; 19 template
20 class Global; 21 class Object; 22 class Value; 23 24 namespace internal { 25 class FunctionCallbackArguments; 26 class PropertyCallbackArguments; 27 class Builtins; 28 } // namespace internal 29 30 namespace debug { 31 class ConsoleCallArguments; 32 } // namespace debug 33 34 template
35 class ReturnValue { 36 public: 37 template
38 V8_INLINE ReturnValue(const ReturnValue
& that) : value_(that.value_) { 39 static_assert(std::is_base_of
::value, "type check"); 40 } 41 // Local setters 42 template
43 V8_INLINE void Set(const Global
& handle); 44 template
45 V8_INLINE void SetNonEmpty(const Global
& handle); 46 template
47 V8_INLINE void Set(const BasicTracedReference
& handle); 48 template
49 V8_INLINE void SetNonEmpty(const BasicTracedReference
& handle); 50 template
51 V8_INLINE void Set(const Local
handle); 52 template
53 V8_INLINE void SetNonEmpty(const Local
handle); 54 // Fast primitive setters 55 V8_INLINE void Set(bool value); 56 V8_INLINE void Set(double i); 57 V8_INLINE void Set(int32_t i); 58 V8_INLINE void Set(uint32_t i); 59 V8_INLINE void Set(uint16_t); 60 // Fast JS primitive setters 61 V8_INLINE void SetNull(); 62 V8_INLINE void SetUndefined(); 63 V8_INLINE void SetEmptyString(); 64 // Convenience getter for Isolate 65 V8_INLINE Isolate* GetIsolate() const; 66 67 // Pointer setter: Uncompilable to prevent inadvertent misuse. 68 template
69 V8_INLINE void Set(S* whatever); 70 71 // Getter. Creates a new Local<> so it comes with a certain performance 72 // hit. If the ReturnValue was not yet set, this will return the undefined 73 // value. 74 V8_INLINE Local
Get() const; 75 76 private: 77 template
78 friend class ReturnValue; 79 template
80 friend class FunctionCallbackInfo; 81 template
82 friend class PropertyCallbackInfo; 83 template
84 friend class PersistentValueMapBase; 85 V8_INLINE void SetInternal(internal::Address value); 86 // Setting the hole value has different meanings depending on the usage: 87 // - for function template callbacks it means that the callback returns 88 // the undefined value, 89 // - for property getter callbacks is means that the callback returns 90 // the undefined value (for property setter callbacks the value returned 91 // is ignored), 92 // - for interceptor callbacks it means that the request was not handled. 93 V8_INLINE void SetTheHole(); 94 V8_INLINE explicit ReturnValue(internal::Address* slot); 95 96 // See FunctionCallbackInfo. 97 static constexpr int kIsolateValueIndex = -2; 98 99 internal::Address* value_; 100 }; 101 102 /** 103 * The argument information given to function call callbacks. This 104 * class provides access to information about the context of the call, 105 * including the receiver, the number and values of arguments, and 106 * the holder of the function. 107 */ 108 template
109 class FunctionCallbackInfo { 110 public: 111 /** The number of available arguments. */ 112 V8_INLINE int Length() const; 113 /** 114 * Accessor for the available arguments. Returns `undefined` if the index 115 * is out of bounds. 116 */ 117 V8_INLINE Local
operator[](int i) const; 118 /** Returns the receiver. This corresponds to the "this" value. */ 119 V8_INLINE Local
This() const; 120 /** 121 * If the callback was created without a Signature, this is the same 122 * value as This(). If there is a signature, and the signature didn't match 123 * This() but one of its hidden prototypes, this will be the respective 124 * hidden prototype. 125 * 126 * Note that this is not the prototype of This() on which the accessor 127 * referencing this callback was found (which in V8 internally is often 128 * referred to as holder [sic]). 129 */ 130 V8_INLINE Local
Holder() const; 131 /** For construct calls, this returns the "new.target" value. */ 132 V8_INLINE Local
NewTarget() const; 133 /** Indicates whether this is a regular call or a construct call. */ 134 V8_INLINE bool IsConstructCall() const; 135 /** The data argument specified when creating the callback. */ 136 V8_INLINE Local
Data() const; 137 /** The current Isolate. */ 138 V8_INLINE Isolate* GetIsolate() const; 139 /** The ReturnValue for the call. */ 140 V8_INLINE ReturnValue
GetReturnValue() const; 141 142 private: 143 friend class internal::FunctionCallbackArguments; 144 friend class internal::CustomArguments
; 145 friend class debug::ConsoleCallArguments; 146 147 static constexpr int kHolderIndex = 0; 148 static constexpr int kIsolateIndex = 1; 149 static constexpr int kUnusedIndex = 2; 150 static constexpr int kReturnValueIndex = 3; 151 static constexpr int kDataIndex = 4; 152 static constexpr int kNewTargetIndex = 5; 153 static constexpr int kArgsLength = 6; 154 155 static constexpr int kArgsLengthWithReceiver = kArgsLength + 1; 156 157 // Codegen constants: 158 static constexpr int kSize = 3 * internal::kApiSystemPointerSize; 159 static constexpr int kImplicitArgsOffset = 0; 160 static constexpr int kValuesOffset = 161 kImplicitArgsOffset + internal::kApiSystemPointerSize; 162 static constexpr int kLengthOffset = 163 kValuesOffset + internal::kApiSystemPointerSize; 164 165 static constexpr int kThisValuesIndex = -1; 166 static_assert(ReturnValue
::kIsolateValueIndex == 167 kIsolateIndex - kReturnValueIndex); 168 169 V8_INLINE FunctionCallbackInfo(internal::Address* implicit_args, 170 internal::Address* values, int length); 171 internal::Address* implicit_args_; 172 internal::Address* values_; 173 int length_; 174 }; 175 176 /** 177 * The information passed to a property callback about the context 178 * of the property access. 179 */ 180 template
181 class PropertyCallbackInfo { 182 public: 183 /** 184 * \return The isolate of the property access. 185 */ 186 V8_INLINE Isolate* GetIsolate() const; 187 188 /** 189 * \return The data set in the configuration, i.e., in 190 * `NamedPropertyHandlerConfiguration` or 191 * `IndexedPropertyHandlerConfiguration.` 192 */ 193 V8_INLINE Local
Data() const; 194 195 /** 196 * \return The receiver. In many cases, this is the object on which the 197 * property access was intercepted. When using 198 * `Reflect.get`, `Function.prototype.call`, or similar functions, it is the 199 * object passed in as receiver or thisArg. 200 * 201 * \code 202 * void GetterCallback(Local
name, 203 * const v8::PropertyCallbackInfo
& info) { 204 * auto context = info.GetIsolate()->GetCurrentContext(); 205 * 206 * v8::Local
a_this = 207 * info.This() 208 * ->GetRealNamedProperty(context, v8_str("a")) 209 * .ToLocalChecked(); 210 * v8::Local
a_holder = 211 * info.Holder() 212 * ->GetRealNamedProperty(context, v8_str("a")) 213 * .ToLocalChecked(); 214 * 215 * CHECK(v8_str("r")->Equals(context, a_this).FromJust()); 216 * CHECK(v8_str("obj")->Equals(context, a_holder).FromJust()); 217 * 218 * info.GetReturnValue().Set(name); 219 * } 220 * 221 * v8::Local
templ = 222 * v8::FunctionTemplate::New(isolate); 223 * templ->InstanceTemplate()->SetHandler( 224 * v8::NamedPropertyHandlerConfiguration(GetterCallback)); 225 * LocalContext env; 226 * env->Global() 227 * ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) 228 * .ToLocalChecked() 229 * ->NewInstance(env.local()) 230 * .ToLocalChecked()) 231 * .FromJust(); 232 * 233 * CompileRun("obj.a = 'obj'; var r = {a: 'r'}; Reflect.get(obj, 'x', r)"); 234 * \endcode 235 */ 236 V8_INLINE Local
This() const; 237 238 /** 239 * \return The object in the prototype chain of the receiver that has the 240 * interceptor. Suppose you have `x` and its prototype is `y`, and `y` 241 * has an interceptor. Then `info.This()` is `x` and `info.Holder()` is `y`. 242 * The Holder() could be a hidden object (the global object, rather 243 * than the global proxy). 244 * 245 * \note For security reasons, do not pass the object back into the runtime. 246 */ 247 V8_INLINE Local
Holder() const; 248 249 /** 250 * \return The return value of the callback. 251 * Can be changed by calling Set(). 252 * \code 253 * info.GetReturnValue().Set(...) 254 * \endcode 255 * 256 */ 257 V8_INLINE ReturnValue
GetReturnValue() const; 258 259 /** 260 * \return True if the intercepted function should throw if an error occurs. 261 * Usually, `true` corresponds to `'use strict'`. 262 * 263 * \note Always `false` when intercepting `Reflect.set()` 264 * independent of the language mode. 265 */ 266 V8_INLINE bool ShouldThrowOnError() const; 267 268 private: 269 friend class MacroAssembler; 270 friend class internal::PropertyCallbackArguments; 271 friend class internal::CustomArguments
; 272 static constexpr int kShouldThrowOnErrorIndex = 0; 273 static constexpr int kHolderIndex = 1; 274 static constexpr int kIsolateIndex = 2; 275 static constexpr int kUnusedIndex = 3; 276 static constexpr int kReturnValueIndex = 4; 277 static constexpr int kDataIndex = 5; 278 static constexpr int kThisIndex = 6; 279 static constexpr int kArgsLength = 7; 280 281 static constexpr int kSize = 1 * internal::kApiSystemPointerSize; 282 283 V8_INLINE explicit PropertyCallbackInfo(internal::Address* args) 284 : args_(args) {} 285 286 internal::Address* args_; 287 }; 288 289 using FunctionCallback = void (*)(const FunctionCallbackInfo
& info); 290 291 // --- Implementation --- 292 293 template
294 ReturnValue
::ReturnValue(internal::Address* slot) : value_(slot) {} 295 296 template
297 void ReturnValue
::SetInternal(internal::Address value) { 298 #if V8_STATIC_ROOTS_BOOL 299 using I = internal::Internals; 300 // Ensure that the upper 32-bits are not modified. Compiler should be 301 // able to optimize this to a store of a lower 32-bits of the value. 302 // This is fine since the callback can return only JavaScript values which 303 // are either Smis or heap objects allocated in the main cage. 304 *value_ = I::DecompressTaggedField(*value_, I::CompressTagged(value)); 305 #else 306 *value_ = value; 307 #endif // V8_STATIC_ROOTS_BOOL 308 } 309 310 template
311 template
312 void ReturnValue
::Set(const Global
& handle) { 313 static_assert(std::is_base_of
::value, "type check"); 314 if (V8_UNLIKELY(handle.IsEmpty())) { 315 SetTheHole(); 316 } else { 317 SetInternal(handle.ptr()); 318 } 319 } 320 321 template
322 template
323 void ReturnValue
::SetNonEmpty(const Global
& handle) { 324 static_assert(std::is_base_of
::value, "type check"); 325 #ifdef V8_ENABLE_CHECKS 326 internal::VerifyHandleIsNonEmpty(handle.IsEmpty()); 327 #endif // V8_ENABLE_CHECKS 328 SetInternal(handle.ptr()); 329 } 330 331 template
332 template
333 void ReturnValue
::Set(const BasicTracedReference
& handle) { 334 static_assert(std::is_base_of
::value, "type check"); 335 if (V8_UNLIKELY(handle.IsEmpty())) { 336 SetTheHole(); 337 } else { 338 SetInternal(handle.ptr()); 339 } 340 } 341 342 template
343 template
344 void ReturnValue
::SetNonEmpty(const BasicTracedReference
& handle) { 345 static_assert(std::is_base_of
::value, "type check"); 346 #ifdef V8_ENABLE_CHECKS 347 internal::VerifyHandleIsNonEmpty(handle.IsEmpty()); 348 #endif // V8_ENABLE_CHECKS 349 SetInternal(handle.ptr()); 350 } 351 352 template
353 template
354 void ReturnValue
::Set(const Local
handle) { 355 static_assert(std::is_void
::value || std::is_base_of
::value, 356 "type check"); 357 if (V8_UNLIKELY(handle.IsEmpty())) { 358 SetTheHole(); 359 } else { 360 SetInternal(handle.ptr()); 361 } 362 } 363 364 template
365 template
366 void ReturnValue
::SetNonEmpty(const Local
handle) { 367 static_assert(std::is_void
::value || std::is_base_of
::value, 368 "type check"); 369 #ifdef V8_ENABLE_CHECKS 370 internal::VerifyHandleIsNonEmpty(handle.IsEmpty()); 371 #endif // V8_ENABLE_CHECKS 372 SetInternal(handle.ptr()); 373 } 374 375 template
376 void ReturnValue
::Set(double i) { 377 static_assert(std::is_base_of
::value, "type check"); 378 SetNonEmpty(Number::New(GetIsolate(), i)); 379 } 380 381 template
382 void ReturnValue
::Set(int32_t i) { 383 static_assert(std::is_base_of
::value, "type check"); 384 using I = internal::Internals; 385 if (V8_LIKELY(I::IsValidSmi(i))) { 386 SetInternal(I::IntToSmi(i)); 387 return; 388 } 389 SetNonEmpty(Integer::New(GetIsolate(), i)); 390 } 391 392 template
393 void ReturnValue
::Set(uint32_t i) { 394 static_assert(std::is_base_of
::value, "type check"); 395 // Can't simply use INT32_MAX here for whatever reason. 396 bool fits_into_int32_t = (i & (1U << 31)) == 0; 397 if (V8_LIKELY(fits_into_int32_t)) { 398 Set(static_cast
(i)); 399 return; 400 } 401 SetNonEmpty(Integer::NewFromUnsigned(GetIsolate(), i)); 402 } 403 404 template
405 void ReturnValue
::Set(uint16_t i) { 406 static_assert(std::is_base_of
::value, "type check"); 407 using I = internal::Internals; 408 static_assert(I::IsValidSmi(std::numeric_limits
::min())); 409 static_assert(I::IsValidSmi(std::numeric_limits
::max())); 410 SetInternal(I::IntToSmi(i)); 411 } 412 413 template
414 void ReturnValue
::Set(bool value) { 415 static_assert(std::is_base_of
::value, "type check"); 416 using I = internal::Internals; 417 #if V8_STATIC_ROOTS_BOOL 418 #ifdef V8_ENABLE_CHECKS 419 internal::PerformCastCheck( 420 internal::ValueHelper::SlotAsValue
(value_)); 421 #endif // V8_ENABLE_CHECKS 422 SetInternal(value ? I::StaticReadOnlyRoot::kTrueValue 423 : I::StaticReadOnlyRoot::kFalseValue); 424 #else 425 int root_index; 426 if (value) { 427 root_index = I::kTrueValueRootIndex; 428 } else { 429 root_index = I::kFalseValueRootIndex; 430 } 431 *value_ = I::GetRoot(GetIsolate(), root_index); 432 #endif // V8_STATIC_ROOTS_BOOL 433 } 434 435 template
436 void ReturnValue
::SetTheHole() { 437 using I = internal::Internals; 438 #if V8_STATIC_ROOTS_BOOL 439 SetInternal(I::StaticReadOnlyRoot::kTheHoleValue); 440 #else 441 *value_ = I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex); 442 #endif // V8_STATIC_ROOTS_BOOL 443 } 444 445 template
446 void ReturnValue
::SetNull() { 447 static_assert(std::is_base_of
::value, "type check"); 448 using I = internal::Internals; 449 #if V8_STATIC_ROOTS_BOOL 450 #ifdef V8_ENABLE_CHECKS 451 internal::PerformCastCheck( 452 internal::ValueHelper::SlotAsValue
(value_)); 453 #endif // V8_ENABLE_CHECKS 454 SetInternal(I::StaticReadOnlyRoot::kNullValue); 455 #else 456 *value_ = I::GetRoot(GetIsolate(), I::kNullValueRootIndex); 457 #endif // V8_STATIC_ROOTS_BOOL 458 } 459 460 template
461 void ReturnValue
::SetUndefined() { 462 static_assert(std::is_base_of
::value, "type check"); 463 using I = internal::Internals; 464 #if V8_STATIC_ROOTS_BOOL 465 #ifdef V8_ENABLE_CHECKS 466 internal::PerformCastCheck( 467 internal::ValueHelper::SlotAsValue
(value_)); 468 #endif // V8_ENABLE_CHECKS 469 SetInternal(I::StaticReadOnlyRoot::kUndefinedValue); 470 #else 471 *value_ = I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex); 472 #endif // V8_STATIC_ROOTS_BOOL 473 } 474 475 template
476 void ReturnValue
::SetEmptyString() { 477 static_assert(std::is_base_of
::value, "type check"); 478 using I = internal::Internals; 479 #if V8_STATIC_ROOTS_BOOL 480 #ifdef V8_ENABLE_CHECKS 481 internal::PerformCastCheck( 482 internal::ValueHelper::SlotAsValue
(value_)); 483 #endif // V8_ENABLE_CHECKS 484 SetInternal(I::StaticReadOnlyRoot::kEmptyString); 485 #else 486 *value_ = I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex); 487 #endif // V8_STATIC_ROOTS_BOOL 488 } 489 490 template
491 Isolate* ReturnValue
::GetIsolate() const { 492 return *reinterpret_cast
(&value_[kIsolateValueIndex]); 493 } 494 495 template
496 Local
ReturnValue
::Get() const { 497 using I = internal::Internals; 498 #if V8_STATIC_ROOTS_BOOL 499 if (I::is_identical(*value_, I::StaticReadOnlyRoot::kTheHoleValue)) { 500 #else 501 if (*value_ == I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex)) { 502 #endif // V8_STATIC_ROOTS_BOOL 503 return Undefined(GetIsolate()); 504 } 505 return Local
::New(GetIsolate(), 506 internal::ValueHelper::SlotAsValue
(value_)); 507 } 508 509 template
510 template
511 void ReturnValue
::Set(S* whatever) { 512 static_assert(sizeof(S) < 0, "incompilable to prevent inadvertent misuse"); 513 } 514 515 template
516 FunctionCallbackInfo
::FunctionCallbackInfo(internal::Address* implicit_args, 517 internal::Address* values, 518 int length) 519 : implicit_args_(implicit_args), values_(values), length_(length) {} 520 521 template
522 Local
FunctionCallbackInfo
::operator[](int i) const { 523 // values_ points to the first argument (not the receiver). 524 if (i < 0 || length_ <= i) return Undefined(GetIsolate()); 525 return Local
::FromSlot(values_ + i); 526 } 527 528 template
529 Local
FunctionCallbackInfo
::This() const { 530 // values_ points to the first argument (not the receiver). 531 return Local
::FromSlot(values_ + kThisValuesIndex); 532 } 533 534 template
535 Local
FunctionCallbackInfo
::Holder() const { 536 return Local
::FromSlot(&implicit_args_[kHolderIndex]); 537 } 538 539 template
540 Local
FunctionCallbackInfo
::NewTarget() const { 541 return Local
::FromSlot(&implicit_args_[kNewTargetIndex]); 542 } 543 544 template
545 Local
FunctionCallbackInfo
::Data() const { 546 return Local
::FromSlot(&implicit_args_[kDataIndex]); 547 } 548 549 template
550 Isolate* FunctionCallbackInfo
::GetIsolate() const { 551 return *reinterpret_cast
(&implicit_args_[kIsolateIndex]); 552 } 553 554 template
555 ReturnValue
FunctionCallbackInfo
::GetReturnValue() const { 556 return ReturnValue
(&implicit_args_[kReturnValueIndex]); 557 } 558 559 template
560 bool FunctionCallbackInfo
::IsConstructCall() const { 561 return !NewTarget()->IsUndefined(); 562 } 563 564 template
565 int FunctionCallbackInfo
::Length() const { 566 return length_; 567 } 568 569 template
570 Isolate* PropertyCallbackInfo
::GetIsolate() const { 571 return *reinterpret_cast
(&args_[kIsolateIndex]); 572 } 573 574 template
575 Local
PropertyCallbackInfo
::Data() const { 576 return Local
::FromSlot(&args_[kDataIndex]); 577 } 578 579 template
580 Local
PropertyCallbackInfo
::This() const { 581 return Local
::FromSlot(&args_[kThisIndex]); 582 } 583 584 template
585 Local
PropertyCallbackInfo
::Holder() const { 586 return Local
::FromSlot(&args_[kHolderIndex]); 587 } 588 589 template
590 ReturnValue
PropertyCallbackInfo
::GetReturnValue() const { 591 return ReturnValue
(&args_[kReturnValueIndex]); 592 } 593 594 template
595 bool PropertyCallbackInfo
::ShouldThrowOnError() const { 596 using I = internal::Internals; 597 if (args_[kShouldThrowOnErrorIndex] != 598 I::IntToSmi(I::kInferShouldThrowMode)) { 599 return args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kDontThrow); 600 } 601 return v8::internal::ShouldThrowOnError( 602 reinterpret_cast
(GetIsolate())); 603 } 604 605 } // namespace v8 606 607 #endif // INCLUDE_V8_FUNCTION_CALLBACK_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™