/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  | 5.05M  |   V8_INLINE void* GetAlignedPointerFromEmbedderData(int index) { | 
320  | 5.05M  |     return GetAlignedPointerFromEmbedderData(index,  | 
321  | 5.05M  |                                              kEmbedderDataTypeTagDefault);  | 
322  | 5.05M  |   }  | 
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  | 245  |   void SetAlignedPointerInEmbedderData(int index, void* value) { | 
336  | 245  |     SetAlignedPointerInEmbedderData(index, value, kEmbedderDataTypeTagDefault);  | 
337  | 245  |   }  | 
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  | 49.3k  |     explicit V8_INLINE Scope(Local<Context> context) : context_(context) { | 
409  | 49.3k  |       context_->Enter();  | 
410  | 49.3k  |     }  | 
411  | 49.3k  |     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  | 4  | Local<Value> Context::GetEmbedderData(int index) { | 
463  | 4  | #ifndef V8_ENABLE_CHECKS  | 
464  | 4  |   using A = internal::Address;  | 
465  | 4  |   using I = internal::Internals;  | 
466  | 4  |   A ctx = internal::ValueHelper::ValueAsAddress(this);  | 
467  | 4  |   A embedder_data =  | 
468  | 4  |       I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);  | 
469  | 4  |   int value_offset =  | 
470  | 4  |       I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);  | 
471  | 4  |   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  | 4  |   auto* isolate = I::GetCurrentIsolate();  | 
479  | 4  |   return Local<Value>::New(isolate, value);  | 
480  |  | #else  | 
481  |  |   return SlowGetEmbedderData(index);  | 
482  |  | #endif  | 
483  | 4  | }  | 
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  | 5.05M  |                                                  EmbedderDataTypeTag tag) { | 
505  | 5.05M  | #if !defined(V8_ENABLE_CHECKS)  | 
506  | 5.05M  |   using A = internal::Address;  | 
507  | 5.05M  |   using I = internal::Internals;  | 
508  | 5.05M  |   A ctx = internal::ValueHelper::ValueAsAddress(this);  | 
509  | 5.05M  |   A embedder_data =  | 
510  | 5.05M  |       I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);  | 
511  | 5.05M  |   int value_offset = I::kEmbedderDataArrayHeaderSize +  | 
512  | 5.05M  |                      (I::kEmbedderDataSlotSize * index) +  | 
513  | 5.05M  |                      I::kEmbedderDataSlotExternalPointerOffset;  | 
514  | 5.05M  |   Isolate* isolate = I::GetCurrentIsolateForSandbox();  | 
515  | 5.05M  |   return reinterpret_cast<void*>(I::ReadExternalPointerField(  | 
516  | 5.05M  |       isolate, embedder_data, value_offset, ToExternalPointerTag(tag)));  | 
517  |  | #else  | 
518  |  |   return SlowGetAlignedPointerFromEmbedderData(index, tag);  | 
519  |  | #endif  | 
520  | 5.05M  | }  | 
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_  |