/src/node/deps/v8/include/v8-context.h
Line | Count | Source |
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_CONTEXT_H_ |
6 | | #define INCLUDE_V8_CONTEXT_H_ |
7 | | |
8 | | #include <stdint.h> |
9 | | |
10 | | #include <vector> |
11 | | |
12 | | #include "v8-data.h" // NOLINT(build/include_directory) |
13 | | #include "v8-local-handle.h" // NOLINT(build/include_directory) |
14 | | #include "v8-maybe.h" // NOLINT(build/include_directory) |
15 | | #include "v8-snapshot.h" // NOLINT(build/include_directory) |
16 | | #include "v8config.h" // NOLINT(build/include_directory) |
17 | | |
18 | | namespace v8 { |
19 | | |
20 | | class Function; |
21 | | class MicrotaskQueue; |
22 | | class Object; |
23 | | class ObjectTemplate; |
24 | | class Value; |
25 | | class String; |
26 | | |
27 | | /** |
28 | | * A container for extension names. |
29 | | */ |
30 | | class V8_EXPORT ExtensionConfiguration { |
31 | | public: |
32 | 0 | ExtensionConfiguration() : name_count_(0), names_(nullptr) {} |
33 | | ExtensionConfiguration(int name_count, const char* names[]) |
34 | 0 | : name_count_(name_count), names_(names) {} |
35 | | |
36 | 0 | const char** begin() const { return &names_[0]; } |
37 | 0 | const char** end() const { return &names_[name_count_]; } |
38 | | |
39 | | private: |
40 | | const int name_count_; |
41 | | const char** names_; |
42 | | }; |
43 | | |
44 | | /** |
45 | | * A sandboxed execution context with its own set of built-in objects |
46 | | * and functions. |
47 | | */ |
48 | | class V8_EXPORT Context : public Data { |
49 | | public: |
50 | | /** |
51 | | * Returns the global proxy object. |
52 | | * |
53 | | * Global proxy object is a thin wrapper whose prototype points to actual |
54 | | * context's global object with the properties like Object, etc. This is done |
55 | | * that way for security reasons (for more details see |
56 | | * https://wiki.mozilla.org/Gecko:SplitWindow). |
57 | | * |
58 | | * Please note that changes to global proxy object prototype most probably |
59 | | * would break VM---v8 expects only global object as a prototype of global |
60 | | * proxy object. |
61 | | */ |
62 | | Local<Object> Global(); |
63 | | |
64 | | /** |
65 | | * Detaches the global object from its context before |
66 | | * the global object can be reused to create a new context. |
67 | | */ |
68 | | void DetachGlobal(); |
69 | | |
70 | | /** |
71 | | * Creates a new context and returns a handle to the newly allocated |
72 | | * context. |
73 | | * |
74 | | * \param isolate The isolate in which to create the context. |
75 | | * |
76 | | * \param extensions An optional extension configuration containing |
77 | | * the extensions to be installed in the newly created context. |
78 | | * |
79 | | * \param global_template An optional object template from which the |
80 | | * global object for the newly created context will be created. |
81 | | * |
82 | | * \param global_object An optional global object to be reused for |
83 | | * the newly created context. This global object must have been |
84 | | * created by a previous call to Context::New with the same global |
85 | | * template. The state of the global object will be completely reset |
86 | | * and only object identify will remain. |
87 | | * |
88 | | * \param internal_fields_deserializer An optional callback used |
89 | | * to deserialize fields set by |
90 | | * v8::Object::SetAlignedPointerInInternalField() in wrapper objects |
91 | | * from the default context snapshot. It should match the |
92 | | * SerializeInternalFieldsCallback() used by |
93 | | * v8::SnapshotCreator::SetDefaultContext() when the default context |
94 | | * snapshot is created. It does not need to be configured if the default |
95 | | * context snapshot contains no wrapper objects with pointer internal |
96 | | * fields, or if no custom startup snapshot is configured |
97 | | * in the v8::CreateParams used to create the isolate. |
98 | | * |
99 | | * \param microtask_queue An optional microtask queue used to manage |
100 | | * the microtasks created in this context. If not set the per-isolate |
101 | | * default microtask queue would be used. |
102 | | * |
103 | | * \param context_data_deserializer An optional callback used |
104 | | * to deserialize embedder data set by |
105 | | * v8::Context::SetAlignedPointerInEmbedderData() in the default |
106 | | * context from the default context snapshot. It does not need to be |
107 | | * configured if the default context snapshot contains no pointer embedder |
108 | | * data, or if no custom startup snapshot is configured in the |
109 | | * v8::CreateParams used to create the isolate. |
110 | | * |
111 | | * \param api_wrapper_deserializer An optional callback used to deserialize |
112 | | * API wrapper objects that was initially set with v8::Object::Wrap() and then |
113 | | * serialized using SerializeAPIWrapperCallback. |
114 | | */ |
115 | | static Local<Context> New( |
116 | | Isolate* isolate, ExtensionConfiguration* extensions = nullptr, |
117 | | MaybeLocal<ObjectTemplate> global_template = MaybeLocal<ObjectTemplate>(), |
118 | | MaybeLocal<Value> global_object = MaybeLocal<Value>(), |
119 | | DeserializeInternalFieldsCallback internal_fields_deserializer = |
120 | | DeserializeInternalFieldsCallback(), |
121 | | MicrotaskQueue* microtask_queue = nullptr, |
122 | | DeserializeContextDataCallback context_data_deserializer = |
123 | | DeserializeContextDataCallback(), |
124 | | DeserializeAPIWrapperCallback api_wrapper_deserializer = |
125 | | DeserializeAPIWrapperCallback()); |
126 | | |
127 | | /** |
128 | | * Create a new context from a (non-default) context snapshot. There |
129 | | * is no way to provide a global object template since we do not create |
130 | | * a new global object from template, but we can reuse a global object. |
131 | | * |
132 | | * \param isolate See v8::Context::New(). |
133 | | * |
134 | | * \param context_snapshot_index The index of the context snapshot to |
135 | | * deserialize from. Use v8::Context::New() for the default snapshot. |
136 | | * |
137 | | * \param internal_fields_deserializer An optional callback used |
138 | | * to deserialize fields set by |
139 | | * v8::Object::SetAlignedPointerInInternalField() in wrapper objects |
140 | | * from the default context snapshot. It does not need to be |
141 | | * configured if there are no wrapper objects with no internal |
142 | | * pointer fields in the default context snapshot or if no startup |
143 | | * snapshot is configured when the isolate is created. |
144 | | * |
145 | | * \param extensions See v8::Context::New(). |
146 | | * |
147 | | * \param global_object See v8::Context::New(). |
148 | | * |
149 | | * \param internal_fields_deserializer Similar to |
150 | | * internal_fields_deserializer in v8::Context::New() but applies to |
151 | | * the context specified by the context_snapshot_index. |
152 | | * |
153 | | * \param microtask_queue See v8::Context::New(). |
154 | | * |
155 | | * \param context_data_deserializer Similar to |
156 | | * context_data_deserializer in v8::Context::New() but applies to |
157 | | * the context specified by the context_snapshot_index. |
158 | | * |
159 | | *\param api_wrapper_deserializer Similar to api_wrapper_deserializer in |
160 | | * v8::Context::New() but applies to the context specified by the |
161 | | * context_snapshot_index. |
162 | | */ |
163 | | static MaybeLocal<Context> FromSnapshot( |
164 | | Isolate* isolate, size_t context_snapshot_index, |
165 | | DeserializeInternalFieldsCallback internal_fields_deserializer = |
166 | | DeserializeInternalFieldsCallback(), |
167 | | ExtensionConfiguration* extensions = nullptr, |
168 | | MaybeLocal<Value> global_object = MaybeLocal<Value>(), |
169 | | MicrotaskQueue* microtask_queue = nullptr, |
170 | | DeserializeContextDataCallback context_data_deserializer = |
171 | | DeserializeContextDataCallback(), |
172 | | DeserializeAPIWrapperCallback api_wrapper_deserializer = |
173 | | DeserializeAPIWrapperCallback()); |
174 | | |
175 | | /** |
176 | | * Returns an global object that isn't backed by an actual context. |
177 | | * |
178 | | * The global template needs to have access checks with handlers installed. |
179 | | * If an existing global object is passed in, the global object is detached |
180 | | * from its context. |
181 | | * |
182 | | * Note that this is different from a detached context where all accesses to |
183 | | * the global proxy will fail. Instead, the access check handlers are invoked. |
184 | | * |
185 | | * It is also not possible to detach an object returned by this method. |
186 | | * Instead, the access check handlers need to return nothing to achieve the |
187 | | * same effect. |
188 | | * |
189 | | * It is possible, however, to create a new context from the global object |
190 | | * returned by this method. |
191 | | */ |
192 | | static MaybeLocal<Object> NewRemoteContext( |
193 | | Isolate* isolate, Local<ObjectTemplate> global_template, |
194 | | MaybeLocal<Value> global_object = MaybeLocal<Value>()); |
195 | | |
196 | | /** |
197 | | * Sets the security token for the context. To access an object in |
198 | | * another context, the security tokens must match. |
199 | | */ |
200 | | void SetSecurityToken(Local<Value> token); |
201 | | |
202 | | /** Restores the security token to the default value. */ |
203 | | void UseDefaultSecurityToken(); |
204 | | |
205 | | /** Returns the security token of this context.*/ |
206 | | Local<Value> GetSecurityToken(); |
207 | | |
208 | | /** |
209 | | * Enter this context. After entering a context, all code compiled |
210 | | * and run is compiled and run in this context. If another context |
211 | | * is already entered, this old context is saved so it can be |
212 | | * restored when the new context is exited. |
213 | | */ |
214 | | void Enter(); |
215 | | |
216 | | /** |
217 | | * Exit this context. Exiting the current context restores the |
218 | | * context that was in place when entering the current context. |
219 | | */ |
220 | | void Exit(); |
221 | | |
222 | | /** |
223 | | * Delegate to help with Deep freezing embedder-specific objects (such as |
224 | | * JSApiObjects) that can not be frozen natively. |
225 | | */ |
226 | | class DeepFreezeDelegate { |
227 | | public: |
228 | | /** |
229 | | * Performs embedder-specific operations to freeze the provided embedder |
230 | | * object. The provided object *will* be frozen by DeepFreeze after this |
231 | | * function returns, so only embedder-specific objects need to be frozen. |
232 | | * This function *may not* create new JS objects or perform JS allocations. |
233 | | * Any v8 objects reachable from the provided embedder object that should |
234 | | * also be considered for freezing should be added to the children_out |
235 | | * parameter. Returns true if the operation completed successfully. |
236 | | */ |
237 | | virtual bool FreezeEmbedderObjectAndGetChildren( |
238 | | Local<Object> obj, LocalVector<Object>& children_out) = 0; |
239 | | }; |
240 | | |
241 | | /** |
242 | | * Attempts to recursively freeze all objects reachable from this context. |
243 | | * Some objects (generators, iterators, non-const closures) can not be frozen |
244 | | * and will cause this method to throw an error. An optional delegate can be |
245 | | * provided to help freeze embedder-specific objects. |
246 | | * |
247 | | * Freezing occurs in two steps: |
248 | | * 1. "Marking" where we iterate through all objects reachable by this |
249 | | * context, accumulating a list of objects that need to be frozen and |
250 | | * looking for objects that can't be frozen. This step is separated because |
251 | | * it is more efficient when we can assume there is no garbage collection. |
252 | | * 2. "Freezing" where we go through the list of objects and freezing them. |
253 | | * This effectively requires copying them so it may trigger garbage |
254 | | * collection. |
255 | | */ |
256 | | Maybe<void> DeepFreeze(DeepFreezeDelegate* delegate = nullptr); |
257 | | |
258 | | /** Returns the microtask queue associated with a current context. */ |
259 | | MicrotaskQueue* GetMicrotaskQueue(); |
260 | | |
261 | | /** Sets the microtask queue associated with the current context. */ |
262 | | void SetMicrotaskQueue(MicrotaskQueue* queue); |
263 | | |
264 | | /** |
265 | | * The field at kDebugIdIndex used to be reserved for the inspector. |
266 | | * It now serves no purpose. |
267 | | */ |
268 | | enum EmbedderDataFields { kDebugIdIndex = 0 }; |
269 | | |
270 | | /** |
271 | | * Return the number of fields allocated for embedder data. |
272 | | */ |
273 | | uint32_t GetNumberOfEmbedderDataFields(); |
274 | | |
275 | | /** |
276 | | * Gets the embedder data with the given index, which must have been set by a |
277 | | * previous call to SetEmbedderData with the same index. |
278 | | */ |
279 | | V8_INLINE Local<Value> GetEmbedderData(int index); |
280 | | |
281 | | /** |
282 | | * Gets the binding object used by V8 extras. Extra natives get a reference |
283 | | * to this object and can use it to "export" functionality by adding |
284 | | * properties. Extra natives can also "import" functionality by accessing |
285 | | * properties added by the embedder using the V8 API. |
286 | | */ |
287 | | Local<Object> GetExtrasBindingObject(); |
288 | | |
289 | | /** |
290 | | * Sets the embedder data with the given index, growing the data as |
291 | | * needed. Note that index 0 currently has a special meaning for Chrome's |
292 | | * debugger. |
293 | | */ |
294 | | void SetEmbedderData(int index, Local<Value> value); |
295 | | |
296 | | /** |
297 | | * Gets a 2-byte-aligned native pointer from the embedder data with the given |
298 | | * index, which must have been set by a previous call to |
299 | | * SetAlignedPointerInEmbedderData with the same index. Note that index 0 |
300 | | * currently has a special meaning for Chrome's debugger. |
301 | | */ |
302 | | V8_INLINE void* GetAlignedPointerFromEmbedderData(Isolate* isolate, int index, |
303 | | EmbedderDataTypeTag tag); |
304 | | V8_INLINE void* GetAlignedPointerFromEmbedderData(int index, |
305 | | EmbedderDataTypeTag tag); |
306 | | |
307 | | V8_DEPRECATE_SOON( |
308 | | "Use GetAlignedPointerFromEmbedderData with EmbedderDataTypeTag " |
309 | | "parameter instead.") |
310 | | V8_INLINE void* GetAlignedPointerFromEmbedderData(Isolate* isolate, |
311 | 0 | int index) { |
312 | 0 | return GetAlignedPointerFromEmbedderData(isolate, index, |
313 | 0 | kEmbedderDataTypeTagDefault); |
314 | 0 | } |
315 | | |
316 | | V8_DEPRECATE_SOON( |
317 | | "Use GetAlignedPointerFromEmbedderData with EmbedderDataTypeTag " |
318 | | "parameter instead.") |
319 | 0 | V8_INLINE void* GetAlignedPointerFromEmbedderData(int index) { |
320 | 0 | return GetAlignedPointerFromEmbedderData(index, |
321 | 0 | kEmbedderDataTypeTagDefault); |
322 | 0 | } |
323 | | |
324 | | void SetAlignedPointerInEmbedderData(int index, void* value, |
325 | | EmbedderDataTypeTag tag); |
326 | | |
327 | | /** |
328 | | * Sets a 2-byte-aligned native pointer in the embedder data with the given |
329 | | * index, growing the data as needed. Note that index 0 currently has a |
330 | | * special meaning for Chrome's debugger. |
331 | | */ |
332 | | V8_DEPRECATE_SOON( |
333 | | "Use SetAlignedPointerInEmbedderData with EmbedderDataTypeTag parameter " |
334 | | "instead.") |
335 | 0 | void SetAlignedPointerInEmbedderData(int index, void* value) { |
336 | 0 | SetAlignedPointerInEmbedderData(index, value, kEmbedderDataTypeTagDefault); |
337 | 0 | } |
338 | | |
339 | | /** |
340 | | * Control whether code generation from strings is allowed. Calling |
341 | | * this method with false will disable 'eval' and the 'Function' |
342 | | * constructor for code running in this context. If 'eval' or the |
343 | | * 'Function' constructor are used an exception will be thrown. |
344 | | * |
345 | | * If code generation from strings is not allowed the |
346 | | * V8::ModifyCodeGenerationFromStringsCallback callback will be invoked if |
347 | | * set before blocking the call to 'eval' or the 'Function' |
348 | | * constructor. If that callback returns true, the call will be |
349 | | * allowed, otherwise an exception will be thrown. If no callback is |
350 | | * set an exception will be thrown. |
351 | | */ |
352 | | void AllowCodeGenerationFromStrings(bool allow); |
353 | | |
354 | | /** |
355 | | * Returns true if code generation from strings is allowed for the context. |
356 | | * For more details see AllowCodeGenerationFromStrings(bool) documentation. |
357 | | */ |
358 | | bool IsCodeGenerationFromStringsAllowed() const; |
359 | | |
360 | | /** |
361 | | * Sets the error description for the exception that is thrown when |
362 | | * code generation from strings is not allowed and 'eval' or the 'Function' |
363 | | * constructor are called. |
364 | | */ |
365 | | void SetErrorMessageForCodeGenerationFromStrings(Local<String> message); |
366 | | |
367 | | /** |
368 | | * Sets the error description for the exception that is thrown when |
369 | | * wasm code generation is not allowed. |
370 | | */ |
371 | | void SetErrorMessageForWasmCodeGeneration(Local<String> message); |
372 | | |
373 | | /** |
374 | | * Return data that was previously attached to the context snapshot via |
375 | | * SnapshotCreator, and removes the reference to it. |
376 | | * Repeated call with the same index returns an empty MaybeLocal. |
377 | | */ |
378 | | template <class T> |
379 | | V8_INLINE MaybeLocal<T> GetDataFromSnapshotOnce(size_t index); |
380 | | |
381 | | /** |
382 | | * If callback is set, abort any attempt to execute JavaScript in this |
383 | | * context, call the specified callback, and throw an exception. |
384 | | * To unset abort, pass nullptr as callback. |
385 | | */ |
386 | | using AbortScriptExecutionCallback = void (*)(Isolate* isolate, |
387 | | Local<Context> context); |
388 | | void SetAbortScriptExecution(AbortScriptExecutionCallback callback); |
389 | | |
390 | | /** |
391 | | * Set or clear hooks to be invoked for promise lifecycle operations. |
392 | | * To clear a hook, set it to an empty v8::Function. Each function will |
393 | | * receive the observed promise as the first argument. If a chaining |
394 | | * operation is used on a promise, the init will additionally receive |
395 | | * the parent promise as the second argument. |
396 | | */ |
397 | | void SetPromiseHooks(Local<Function> init_hook, Local<Function> before_hook, |
398 | | Local<Function> after_hook, |
399 | | Local<Function> resolve_hook); |
400 | | |
401 | | bool HasTemplateLiteralObject(Local<Value> object); |
402 | | /** |
403 | | * Stack-allocated class which sets the execution context for all |
404 | | * operations executed within a local scope. |
405 | | */ |
406 | | class V8_NODISCARD Scope { |
407 | | public: |
408 | 10.8k | explicit V8_INLINE Scope(Local<Context> context) : context_(context) { |
409 | 10.8k | context_->Enter(); |
410 | 10.8k | } |
411 | 10.8k | V8_INLINE ~Scope() { context_->Exit(); } |
412 | | |
413 | | private: |
414 | | Local<Context> context_; |
415 | | }; |
416 | | |
417 | | /** |
418 | | * Stack-allocated class to support the backup incumbent settings object |
419 | | * stack. |
420 | | * https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack |
421 | | */ |
422 | | class V8_EXPORT V8_NODISCARD BackupIncumbentScope final { |
423 | | public: |
424 | | /** |
425 | | * |backup_incumbent_context| is pushed onto the backup incumbent settings |
426 | | * object stack. |
427 | | */ |
428 | | explicit BackupIncumbentScope(Local<Context> backup_incumbent_context); |
429 | | ~BackupIncumbentScope(); |
430 | | |
431 | | private: |
432 | | friend class internal::Isolate; |
433 | | |
434 | 0 | uintptr_t JSStackComparableAddressPrivate() const { |
435 | 0 | return js_stack_comparable_address_; |
436 | 0 | } |
437 | | |
438 | | Local<Context> backup_incumbent_context_; |
439 | | uintptr_t js_stack_comparable_address_ = 0; |
440 | | const BackupIncumbentScope* prev_ = nullptr; |
441 | | }; |
442 | | |
443 | | V8_INLINE static Context* Cast(Data* data); |
444 | | |
445 | | private: |
446 | | friend class Value; |
447 | | friend class Script; |
448 | | friend class Object; |
449 | | friend class Function; |
450 | | |
451 | | static void CheckCast(Data* obj); |
452 | | |
453 | | internal::ValueHelper::InternalRepresentationType GetDataFromSnapshotOnce( |
454 | | size_t index); |
455 | | Local<Value> SlowGetEmbedderData(int index); |
456 | | void* SlowGetAlignedPointerFromEmbedderData(int index, |
457 | | EmbedderDataTypeTag tag); |
458 | | }; |
459 | | |
460 | | // --- Implementation --- |
461 | | |
462 | 0 | Local<Value> Context::GetEmbedderData(int index) { |
463 | 0 | #ifndef V8_ENABLE_CHECKS |
464 | 0 | using A = internal::Address; |
465 | 0 | using I = internal::Internals; |
466 | 0 | A ctx = internal::ValueHelper::ValueAsAddress(this); |
467 | 0 | A embedder_data = |
468 | 0 | I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset); |
469 | 0 | int value_offset = |
470 | 0 | I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index); |
471 | 0 | A value = I::ReadRawField<A>(embedder_data, value_offset); |
472 | | #ifdef V8_COMPRESS_POINTERS |
473 | | // We read the full pointer value and then decompress it in order to avoid |
474 | | // dealing with potential endiannes issues. |
475 | | value = I::DecompressTaggedField(embedder_data, static_cast<uint32_t>(value)); |
476 | | #endif |
477 | |
|
478 | 0 | auto* isolate = I::GetCurrentIsolate(); |
479 | 0 | return Local<Value>::New(isolate, value); |
480 | | #else |
481 | | return SlowGetEmbedderData(index); |
482 | | #endif |
483 | 0 | } |
484 | | |
485 | | void* Context::GetAlignedPointerFromEmbedderData(Isolate* isolate, int index, |
486 | 0 | EmbedderDataTypeTag tag) { |
487 | 0 | #if !defined(V8_ENABLE_CHECKS) |
488 | 0 | using A = internal::Address; |
489 | 0 | using I = internal::Internals; |
490 | 0 | A ctx = internal::ValueHelper::ValueAsAddress(this); |
491 | 0 | A embedder_data = |
492 | 0 | I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset); |
493 | 0 | int value_offset = I::kEmbedderDataArrayHeaderSize + |
494 | 0 | (I::kEmbedderDataSlotSize * index) + |
495 | 0 | I::kEmbedderDataSlotExternalPointerOffset; |
496 | 0 | return reinterpret_cast<void*>(I::ReadExternalPointerField( |
497 | 0 | isolate, embedder_data, value_offset, ToExternalPointerTag(tag))); |
498 | 0 | #else |
499 | 0 | return SlowGetAlignedPointerFromEmbedderData(index, tag); |
500 | 0 | #endif |
501 | 0 | } |
502 | | |
503 | | void* Context::GetAlignedPointerFromEmbedderData(int index, |
504 | 1.72M | EmbedderDataTypeTag tag) { |
505 | 1.72M | #if !defined(V8_ENABLE_CHECKS) |
506 | 1.72M | using A = internal::Address; |
507 | 1.72M | using I = internal::Internals; |
508 | 1.72M | A ctx = internal::ValueHelper::ValueAsAddress(this); |
509 | 1.72M | A embedder_data = |
510 | 1.72M | I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset); |
511 | 1.72M | int value_offset = I::kEmbedderDataArrayHeaderSize + |
512 | 1.72M | (I::kEmbedderDataSlotSize * index) + |
513 | 1.72M | I::kEmbedderDataSlotExternalPointerOffset; |
514 | 1.72M | Isolate* isolate = I::GetCurrentIsolateForSandbox(); |
515 | 1.72M | return reinterpret_cast<void*>(I::ReadExternalPointerField( |
516 | 1.72M | isolate, embedder_data, value_offset, ToExternalPointerTag(tag))); |
517 | | #else |
518 | | return SlowGetAlignedPointerFromEmbedderData(index, tag); |
519 | | #endif |
520 | 1.72M | } |
521 | | |
522 | | template <class T> |
523 | 0 | MaybeLocal<T> Context::GetDataFromSnapshotOnce(size_t index) { |
524 | 0 | if (auto repr = GetDataFromSnapshotOnce(index); |
525 | 0 | repr != internal::ValueHelper::kEmpty) { |
526 | 0 | internal::PerformCastCheck(internal::ValueHelper::ReprAsValue<T>(repr)); |
527 | 0 | return Local<T>::FromRepr(repr); |
528 | 0 | } |
529 | 0 | return {}; |
530 | 0 | } Unexecuted instantiation: v8::MaybeLocal<v8::Uint32Array> v8::Context::GetDataFromSnapshotOnce<v8::Uint32Array>(unsigned long) Unexecuted instantiation: v8::MaybeLocal<v8::Uint8Array> v8::Context::GetDataFromSnapshotOnce<v8::Uint8Array>(unsigned long) Unexecuted instantiation: v8::MaybeLocal<v8::Float64Array> v8::Context::GetDataFromSnapshotOnce<v8::Float64Array>(unsigned long) Unexecuted instantiation: v8::MaybeLocal<v8::Array> v8::Context::GetDataFromSnapshotOnce<v8::Array>(unsigned long) Unexecuted instantiation: v8::MaybeLocal<v8::Object> v8::Context::GetDataFromSnapshotOnce<v8::Object>(unsigned long) Unexecuted instantiation: v8::MaybeLocal<v8::Int32Array> v8::Context::GetDataFromSnapshotOnce<v8::Int32Array>(unsigned long) Unexecuted instantiation: v8::MaybeLocal<v8::BigInt64Array> v8::Context::GetDataFromSnapshotOnce<v8::BigInt64Array>(unsigned long) Unexecuted instantiation: v8::MaybeLocal<v8::Function> v8::Context::GetDataFromSnapshotOnce<v8::Function>(unsigned long) Unexecuted instantiation: v8::MaybeLocal<v8::Context> v8::Context::GetDataFromSnapshotOnce<v8::Context>(unsigned long) |
531 | | |
532 | 0 | Context* Context::Cast(v8::Data* data) { |
533 | | #ifdef V8_ENABLE_CHECKS |
534 | | CheckCast(data); |
535 | | #endif |
536 | 0 | return static_cast<Context*>(data); |
537 | 0 | } |
538 | | |
539 | | } // namespace v8 |
540 | | |
541 | | #endif // INCLUDE_V8_CONTEXT_H_ |