v8-context.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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. #ifndef INCLUDE_V8_CONTEXT_H_
  5. #define INCLUDE_V8_CONTEXT_H_
  6. #include <stdint.h>
  7. #include "v8-data.h" // NOLINT(build/include_directory)
  8. #include "v8-local-handle.h" // NOLINT(build/include_directory)
  9. #include "v8-snapshot.h" // NOLINT(build/include_directory)
  10. #include "v8config.h" // NOLINT(build/include_directory)
  11. namespace v8 {
  12. class Function;
  13. class MicrotaskQueue;
  14. class Object;
  15. class ObjectTemplate;
  16. class Value;
  17. class String;
  18. /**
  19. * A container for extension names.
  20. */
  21. class V8_EXPORT ExtensionConfiguration {
  22. public:
  23. ExtensionConfiguration() : name_count_(0), names_(nullptr) {}
  24. ExtensionConfiguration(int name_count, const char* names[])
  25. : name_count_(name_count), names_(names) {}
  26. const char** begin() const { return &names_[0]; }
  27. const char** end() const { return &names_[name_count_]; }
  28. private:
  29. const int name_count_;
  30. const char** names_;
  31. };
  32. /**
  33. * A sandboxed execution context with its own set of built-in objects
  34. * and functions.
  35. */
  36. class V8_EXPORT Context : public Data {
  37. public:
  38. /**
  39. * Returns the global proxy object.
  40. *
  41. * Global proxy object is a thin wrapper whose prototype points to actual
  42. * context's global object with the properties like Object, etc. This is done
  43. * that way for security reasons (for more details see
  44. * https://wiki.mozilla.org/Gecko:SplitWindow).
  45. *
  46. * Please note that changes to global proxy object prototype most probably
  47. * would break VM---v8 expects only global object as a prototype of global
  48. * proxy object.
  49. */
  50. Local<Object> Global();
  51. /**
  52. * Detaches the global object from its context before
  53. * the global object can be reused to create a new context.
  54. */
  55. void DetachGlobal();
  56. /**
  57. * Creates a new context and returns a handle to the newly allocated
  58. * context.
  59. *
  60. * \param isolate The isolate in which to create the context.
  61. *
  62. * \param extensions An optional extension configuration containing
  63. * the extensions to be installed in the newly created context.
  64. *
  65. * \param global_template An optional object template from which the
  66. * global object for the newly created context will be created.
  67. *
  68. * \param global_object An optional global object to be reused for
  69. * the newly created context. This global object must have been
  70. * created by a previous call to Context::New with the same global
  71. * template. The state of the global object will be completely reset
  72. * and only object identify will remain.
  73. */
  74. static Local<Context> New(
  75. Isolate* isolate, ExtensionConfiguration* extensions = nullptr,
  76. MaybeLocal<ObjectTemplate> global_template = MaybeLocal<ObjectTemplate>(),
  77. MaybeLocal<Value> global_object = MaybeLocal<Value>(),
  78. DeserializeInternalFieldsCallback internal_fields_deserializer =
  79. DeserializeInternalFieldsCallback(),
  80. MicrotaskQueue* microtask_queue = nullptr);
  81. /**
  82. * Create a new context from a (non-default) context snapshot. There
  83. * is no way to provide a global object template since we do not create
  84. * a new global object from template, but we can reuse a global object.
  85. *
  86. * \param isolate See v8::Context::New.
  87. *
  88. * \param context_snapshot_index The index of the context snapshot to
  89. * deserialize from. Use v8::Context::New for the default snapshot.
  90. *
  91. * \param embedder_fields_deserializer Optional callback to deserialize
  92. * internal fields. It should match the SerializeInternalFieldCallback used
  93. * to serialize.
  94. *
  95. * \param extensions See v8::Context::New.
  96. *
  97. * \param global_object See v8::Context::New.
  98. */
  99. static MaybeLocal<Context> FromSnapshot(
  100. Isolate* isolate, size_t context_snapshot_index,
  101. DeserializeInternalFieldsCallback embedder_fields_deserializer =
  102. DeserializeInternalFieldsCallback(),
  103. ExtensionConfiguration* extensions = nullptr,
  104. MaybeLocal<Value> global_object = MaybeLocal<Value>(),
  105. MicrotaskQueue* microtask_queue = nullptr);
  106. /**
  107. * Returns an global object that isn't backed by an actual context.
  108. *
  109. * The global template needs to have access checks with handlers installed.
  110. * If an existing global object is passed in, the global object is detached
  111. * from its context.
  112. *
  113. * Note that this is different from a detached context where all accesses to
  114. * the global proxy will fail. Instead, the access check handlers are invoked.
  115. *
  116. * It is also not possible to detach an object returned by this method.
  117. * Instead, the access check handlers need to return nothing to achieve the
  118. * same effect.
  119. *
  120. * It is possible, however, to create a new context from the global object
  121. * returned by this method.
  122. */
  123. static MaybeLocal<Object> NewRemoteContext(
  124. Isolate* isolate, Local<ObjectTemplate> global_template,
  125. MaybeLocal<Value> global_object = MaybeLocal<Value>());
  126. /**
  127. * Sets the security token for the context. To access an object in
  128. * another context, the security tokens must match.
  129. */
  130. void SetSecurityToken(Local<Value> token);
  131. /** Restores the security token to the default value. */
  132. void UseDefaultSecurityToken();
  133. /** Returns the security token of this context.*/
  134. Local<Value> GetSecurityToken();
  135. /**
  136. * Enter this context. After entering a context, all code compiled
  137. * and run is compiled and run in this context. If another context
  138. * is already entered, this old context is saved so it can be
  139. * restored when the new context is exited.
  140. */
  141. void Enter();
  142. /**
  143. * Exit this context. Exiting the current context restores the
  144. * context that was in place when entering the current context.
  145. */
  146. void Exit();
  147. /** Returns the isolate associated with a current context. */
  148. Isolate* GetIsolate();
  149. /** Returns the microtask queue associated with a current context. */
  150. MicrotaskQueue* GetMicrotaskQueue();
  151. /**
  152. * The field at kDebugIdIndex used to be reserved for the inspector.
  153. * It now serves no purpose.
  154. */
  155. enum EmbedderDataFields { kDebugIdIndex = 0 };
  156. /**
  157. * Return the number of fields allocated for embedder data.
  158. */
  159. uint32_t GetNumberOfEmbedderDataFields();
  160. /**
  161. * Gets the embedder data with the given index, which must have been set by a
  162. * previous call to SetEmbedderData with the same index.
  163. */
  164. V8_INLINE Local<Value> GetEmbedderData(int index);
  165. /**
  166. * Gets the binding object used by V8 extras. Extra natives get a reference
  167. * to this object and can use it to "export" functionality by adding
  168. * properties. Extra natives can also "import" functionality by accessing
  169. * properties added by the embedder using the V8 API.
  170. */
  171. Local<Object> GetExtrasBindingObject();
  172. /**
  173. * Sets the embedder data with the given index, growing the data as
  174. * needed. Note that index 0 currently has a special meaning for Chrome's
  175. * debugger.
  176. */
  177. void SetEmbedderData(int index, Local<Value> value);
  178. /**
  179. * Gets a 2-byte-aligned native pointer from the embedder data with the given
  180. * index, which must have been set by a previous call to
  181. * SetAlignedPointerInEmbedderData with the same index. Note that index 0
  182. * currently has a special meaning for Chrome's debugger.
  183. */
  184. V8_INLINE void* GetAlignedPointerFromEmbedderData(int index);
  185. /**
  186. * Sets a 2-byte-aligned native pointer in the embedder data with the given
  187. * index, growing the data as needed. Note that index 0 currently has a
  188. * special meaning for Chrome's debugger.
  189. */
  190. void SetAlignedPointerInEmbedderData(int index, void* value);
  191. /**
  192. * Control whether code generation from strings is allowed. Calling
  193. * this method with false will disable 'eval' and the 'Function'
  194. * constructor for code running in this context. If 'eval' or the
  195. * 'Function' constructor are used an exception will be thrown.
  196. *
  197. * If code generation from strings is not allowed the
  198. * V8::AllowCodeGenerationFromStrings callback will be invoked if
  199. * set before blocking the call to 'eval' or the 'Function'
  200. * constructor. If that callback returns true, the call will be
  201. * allowed, otherwise an exception will be thrown. If no callback is
  202. * set an exception will be thrown.
  203. */
  204. void AllowCodeGenerationFromStrings(bool allow);
  205. /**
  206. * Returns true if code generation from strings is allowed for the context.
  207. * For more details see AllowCodeGenerationFromStrings(bool) documentation.
  208. */
  209. bool IsCodeGenerationFromStringsAllowed() const;
  210. /**
  211. * Sets the error description for the exception that is thrown when
  212. * code generation from strings is not allowed and 'eval' or the 'Function'
  213. * constructor are called.
  214. */
  215. void SetErrorMessageForCodeGenerationFromStrings(Local<String> message);
  216. /**
  217. * Return data that was previously attached to the context snapshot via
  218. * SnapshotCreator, and removes the reference to it.
  219. * Repeated call with the same index returns an empty MaybeLocal.
  220. */
  221. template <class T>
  222. V8_INLINE MaybeLocal<T> GetDataFromSnapshotOnce(size_t index);
  223. /**
  224. * If callback is set, abort any attempt to execute JavaScript in this
  225. * context, call the specified callback, and throw an exception.
  226. * To unset abort, pass nullptr as callback.
  227. */
  228. using AbortScriptExecutionCallback = void (*)(Isolate* isolate,
  229. Local<Context> context);
  230. void SetAbortScriptExecution(AbortScriptExecutionCallback callback);
  231. /**
  232. * Returns the value that was set or restored by
  233. * SetContinuationPreservedEmbedderData(), if any.
  234. */
  235. Local<Value> GetContinuationPreservedEmbedderData() const;
  236. /**
  237. * Sets a value that will be stored on continuations and reset while the
  238. * continuation runs.
  239. */
  240. void SetContinuationPreservedEmbedderData(Local<Value> context);
  241. /**
  242. * Set or clear hooks to be invoked for promise lifecycle operations.
  243. * To clear a hook, set it to an empty v8::Function. Each function will
  244. * receive the observed promise as the first argument. If a chaining
  245. * operation is used on a promise, the init will additionally receive
  246. * the parent promise as the second argument.
  247. */
  248. void SetPromiseHooks(Local<Function> init_hook, Local<Function> before_hook,
  249. Local<Function> after_hook,
  250. Local<Function> resolve_hook);
  251. /**
  252. * Stack-allocated class which sets the execution context for all
  253. * operations executed within a local scope.
  254. */
  255. class V8_NODISCARD Scope {
  256. public:
  257. explicit V8_INLINE Scope(Local<Context> context) : context_(context) {
  258. context_->Enter();
  259. }
  260. V8_INLINE ~Scope() { context_->Exit(); }
  261. private:
  262. Local<Context> context_;
  263. };
  264. /**
  265. * Stack-allocated class to support the backup incumbent settings object
  266. * stack.
  267. * https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack
  268. */
  269. class V8_EXPORT V8_NODISCARD BackupIncumbentScope final {
  270. public:
  271. /**
  272. * |backup_incumbent_context| is pushed onto the backup incumbent settings
  273. * object stack.
  274. */
  275. explicit BackupIncumbentScope(Local<Context> backup_incumbent_context);
  276. ~BackupIncumbentScope();
  277. private:
  278. friend class internal::Isolate;
  279. uintptr_t JSStackComparableAddressPrivate() const {
  280. return js_stack_comparable_address_;
  281. }
  282. Local<Context> backup_incumbent_context_;
  283. uintptr_t js_stack_comparable_address_ = 0;
  284. const BackupIncumbentScope* prev_ = nullptr;
  285. };
  286. V8_INLINE static Context* Cast(Data* data);
  287. private:
  288. friend class Value;
  289. friend class Script;
  290. friend class Object;
  291. friend class Function;
  292. static void CheckCast(Data* obj);
  293. internal::Address* GetDataFromSnapshotOnce(size_t index);
  294. Local<Value> SlowGetEmbedderData(int index);
  295. void* SlowGetAlignedPointerFromEmbedderData(int index);
  296. };
  297. // --- Implementation ---
  298. Local<Value> Context::GetEmbedderData(int index) {
  299. #ifndef V8_ENABLE_CHECKS
  300. using A = internal::Address;
  301. using I = internal::Internals;
  302. A ctx = *reinterpret_cast<const A*>(this);
  303. A embedder_data =
  304. I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
  305. int value_offset =
  306. I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);
  307. A value = I::ReadRawField<A>(embedder_data, value_offset);
  308. #ifdef V8_COMPRESS_POINTERS
  309. // We read the full pointer value and then decompress it in order to avoid
  310. // dealing with potential endiannes issues.
  311. value =
  312. I::DecompressTaggedAnyField(embedder_data, static_cast<uint32_t>(value));
  313. #endif
  314. internal::Isolate* isolate = internal::IsolateFromNeverReadOnlySpaceObject(
  315. *reinterpret_cast<A*>(this));
  316. A* result = HandleScope::CreateHandle(isolate, value);
  317. return Local<Value>(reinterpret_cast<Value*>(result));
  318. #else
  319. return SlowGetEmbedderData(index);
  320. #endif
  321. }
  322. void* Context::GetAlignedPointerFromEmbedderData(int index) {
  323. #if !defined(V8_ENABLE_CHECKS)
  324. using A = internal::Address;
  325. using I = internal::Internals;
  326. A ctx = *reinterpret_cast<const A*>(this);
  327. A embedder_data =
  328. I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
  329. int value_offset =
  330. I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);
  331. #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
  332. value_offset += I::kEmbedderDataSlotRawPayloadOffset;
  333. #endif
  334. internal::Isolate* isolate = I::GetIsolateForSandbox(ctx);
  335. return reinterpret_cast<void*>(
  336. I::ReadExternalPointerField(isolate, embedder_data, value_offset,
  337. internal::kEmbedderDataSlotPayloadTag));
  338. #else
  339. return SlowGetAlignedPointerFromEmbedderData(index);
  340. #endif
  341. }
  342. template <class T>
  343. MaybeLocal<T> Context::GetDataFromSnapshotOnce(size_t index) {
  344. T* data = reinterpret_cast<T*>(GetDataFromSnapshotOnce(index));
  345. if (data) internal::PerformCastCheck(data);
  346. return Local<T>(data);
  347. }
  348. Context* Context::Cast(v8::Data* data) {
  349. #ifdef V8_ENABLE_CHECKS
  350. CheckCast(data);
  351. #endif
  352. return static_cast<Context*>(data);
  353. }
  354. } // namespace v8
  355. #endif // INCLUDE_V8_CONTEXT_H_