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