v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
api.h
Go to the documentation of this file.
1// Copyright 2012 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 V8_API_API_H_
6#define V8_API_API_H_
7
8#include <memory>
9
11#include "include/v8-external.h"
13#include "include/v8-proxy.h"
15#include "include/v8-wasm.h"
16#include "src/base/contextual.h"
18#include "src/objects/bigint.h"
25#include "src/objects/objects.h"
30
31namespace v8 {
32
33class DictionaryTemplate;
34class Extension;
35class Signature;
36class Template;
37
38namespace internal {
39class JSArrayBufferView;
40class JSFinalizationRegistry;
41} // namespace internal
42
43namespace debug {
44class AccessorPair;
45class GeneratorObject;
46class ScriptSource;
47class Script;
48class EphemeronTable;
49} // namespace debug
50
51template <typename T, internal::ExternalPointerTag tag>
52inline T ToCData(i::Isolate* isolate,
54template <internal::ExternalPointerTag tag>
56 v8::internal::Isolate* isolate,
58
59template <internal::ExternalPointerTag tag, typename T>
62FromCData(v8::internal::Isolate* isolate, T obj);
63
64template <internal::ExternalPointerTag tag>
68
70 public:
71 explicit ApiFunction(v8::internal::Address addr) : addr_(addr) {}
73
74 private:
76};
77
79 public:
80 static void Register(std::unique_ptr<Extension>);
81 static void UnregisterAll();
82 Extension* extension() const { return extension_.get(); }
83 RegisteredExtension* next() const { return next_; }
85
86 private:
88 explicit RegisteredExtension(std::unique_ptr<Extension>);
89 std::unique_ptr<Extension> extension_;
92};
93
94#define TO_LOCAL_LIST(V) \
95 V(ToLocal, AccessorPair, debug::AccessorPair) \
96 V(ToLocal, NativeContext, Context) \
97 V(ToLocal, Object, Value) \
98 V(ToLocal, Module, Module) \
99 V(ToLocal, Name, Name) \
100 V(ToLocal, String, String) \
101 V(ToLocal, Symbol, Symbol) \
102 V(ToLocal, JSRegExp, RegExp) \
103 V(ToLocal, JSReceiver, Object) \
104 V(ToLocal, JSObject, Object) \
105 V(ToLocal, JSFunction, Function) \
106 V(ToLocal, JSArray, Array) \
107 V(ToLocal, JSMap, Map) \
108 V(ToLocal, JSSet, Set) \
109 V(ToLocal, JSProxy, Proxy) \
110 V(ToLocal, JSArrayBuffer, ArrayBuffer) \
111 V(ToLocal, JSArrayBufferView, ArrayBufferView) \
112 V(ToLocal, JSDataView, DataView) \
113 V(ToLocal, JSRabGsabDataView, DataView) \
114 V(ToLocal, JSTypedArray, TypedArray) \
115 V(ToLocalShared, JSArrayBuffer, SharedArrayBuffer) \
116 V(ToLocal, FunctionTemplateInfo, FunctionTemplate) \
117 V(ToLocal, ObjectTemplateInfo, ObjectTemplate) \
118 V(ToLocal, DictionaryTemplateInfo, DictionaryTemplate) \
119 V(SignatureToLocal, FunctionTemplateInfo, Signature) \
120 V(MessageToLocal, Object, Message) \
121 V(PromiseToLocal, JSObject, Promise) \
122 V(StackTraceToLocal, StackTraceInfo, StackTrace) \
123 V(StackFrameToLocal, StackFrameInfo, StackFrame) \
124 V(NumberToLocal, Object, Number) \
125 V(IntegerToLocal, Object, Integer) \
126 V(Uint32ToLocal, Object, Uint32) \
127 V(ToLocal, BigInt, BigInt) \
128 V(ExternalToLocal, JSObject, External) \
129 V(CallableToLocal, JSReceiver, Function) \
130 V(ToLocalPrimitive, Object, Primitive) \
131 V(FixedArrayToLocal, FixedArray, FixedArray) \
132 V(PrimitiveArrayToLocal, FixedArray, PrimitiveArray) \
133 V(ToLocal, ScriptOrModule, ScriptOrModule) \
134 IF_WASM(V, ToLocal, WasmMemoryMapDescriptor, WasmMemoryMapDescriptor) \
135 IF_WASM(V, ToLocal, WasmModuleObject, WasmModuleObject)
136
137#define TO_LOCAL_NAME_LIST(V) \
138 V(ToLocal) \
139 V(ToLocalShared) \
140 V(SignatureToLocal) \
141 V(MessageToLocal) \
142 V(PromiseToLocal) \
143 V(StackTraceToLocal) \
144 V(StackFrameToLocal) \
145 V(NumberToLocal) \
146 V(IntegerToLocal) \
147 V(Uint32ToLocal) \
148 V(ExternalToLocal) \
149 V(CallableToLocal) \
150 V(ToLocalPrimitive) \
151 V(FixedArrayToLocal) \
152 V(PrimitiveArrayToLocal)
153
154#define OPEN_HANDLE_LIST(V) \
155 V(Template, TemplateInfoWithProperties) \
156 V(FunctionTemplate, FunctionTemplateInfo) \
157 V(ObjectTemplate, ObjectTemplateInfo) \
158 V(DictionaryTemplate, DictionaryTemplateInfo) \
159 V(Signature, FunctionTemplateInfo) \
160 V(Data, Object) \
161 V(Number, Number) \
162 V(RegExp, JSRegExp) \
163 V(Object, JSReceiver) \
164 V(Array, JSArray) \
165 V(Map, JSMap) \
166 V(Set, JSSet) \
167 V(ArrayBuffer, JSArrayBuffer) \
168 V(ArrayBufferView, JSArrayBufferView) \
169 V(TypedArray, JSTypedArray) \
170 V(Uint8Array, JSTypedArray) \
171 V(Uint8ClampedArray, JSTypedArray) \
172 V(Int8Array, JSTypedArray) \
173 V(Uint16Array, JSTypedArray) \
174 V(Int16Array, JSTypedArray) \
175 V(Uint32Array, JSTypedArray) \
176 V(Int32Array, JSTypedArray) \
177 V(Float16Array, JSTypedArray) \
178 V(Float32Array, JSTypedArray) \
179 V(Float64Array, JSTypedArray) \
180 V(DataView, JSDataViewOrRabGsabDataView) \
181 V(SharedArrayBuffer, JSArrayBuffer) \
182 V(Name, Name) \
183 V(String, String) \
184 V(Symbol, Symbol) \
185 V(Script, JSFunction) \
186 V(UnboundModuleScript, SharedFunctionInfo) \
187 V(UnboundScript, SharedFunctionInfo) \
188 V(Module, Module) \
189 V(Function, JSReceiver) \
190 V(CompileHintsCollector, Script) \
191 V(Message, JSMessageObject) \
192 V(Context, NativeContext) \
193 V(External, Object) \
194 V(StackTrace, StackTraceInfo) \
195 V(StackFrame, StackFrameInfo) \
196 V(Proxy, JSProxy) \
197 V(debug::GeneratorObject, JSGeneratorObject) \
198 V(debug::ScriptSource, HeapObject) \
199 V(debug::Script, Script) \
200 V(debug::EphemeronTable, EphemeronHashTable) \
201 V(debug::AccessorPair, AccessorPair) \
202 V(Promise, JSPromise) \
203 V(Primitive, Object) \
204 V(PrimitiveArray, FixedArray) \
205 V(BigInt, BigInt) \
206 V(ScriptOrModule, ScriptOrModule) \
207 V(FixedArray, FixedArray) \
208 V(ModuleRequest, ModuleRequest) \
209 IF_WASM(V, WasmMemoryMapDescriptor, WasmMemoryMapDescriptor) \
210 IF_WASM(V, WasmMemoryObject, WasmMemoryObject)
211
212class Utils {
213 public:
214 static V8_INLINE bool ApiCheck(bool condition, const char* location,
215 const char* message) {
216 if (V8_UNLIKELY(!condition)) {
217 Utils::ReportApiFailure(location, message);
218 }
219 return condition;
220 }
221 static void ReportOOMFailure(v8::internal::Isolate* isolate,
222 const char* location, const OOMDetails& details);
223
224 // TODO(42203211): It would be nice if we could keep only a version with
225 // direct handles. But the implicit conversion from handles to direct handles
226 // combined with the heterogeneous copy constructor for direct handles make
227 // this ambiguous.
228 // TODO(42203211): Use C++20 concepts instead of the enable_if trait, when
229 // they are fully supported in V8.
230#define DECLARE_TO_LOCAL(Name) \
231 template <template <typename> typename HandleType, typename T, \
232 typename = std::enable_if_t<std::is_convertible_v< \
233 HandleType<T>, v8::internal::DirectHandle<T>>>> \
234 static inline auto Name(HandleType<T> obj);
235
237
238#define DECLARE_TO_LOCAL_TYPED_ARRAY(Type, typeName, TYPE, ctype) \
239 static inline Local<v8::Type##Array> ToLocal##Type##Array( \
240 v8::internal::DirectHandle<v8::internal::JSTypedArray> obj);
241
243
244#define DECLARE_OPEN_HANDLE(From, To) \
245 static inline v8::internal::Handle<v8::internal::To> OpenHandle( \
246 const From* that, bool allow_empty_handle = false); \
247 static inline v8::internal::DirectHandle<v8::internal::To> OpenDirectHandle( \
248 const From* that, bool allow_empty_handle = false); \
249 static inline v8::internal::IndirectHandle<v8::internal::To> \
250 OpenIndirectHandle(const From* that, bool allow_empty_handle = false);
251
253
254#undef DECLARE_OPEN_HANDLE
255#undef DECLARE_TO_LOCAL_TYPED_ARRAY
256#undef DECLARE_TO_LOCAL
257
258 template <class From, class To>
259 static inline Local<To> Convert(v8::internal::DirectHandle<From> obj);
260
261 template <class T>
266
267 template <class T>
269 v8::Persistent<T>* persistent) {
270 return OpenPersistent(*persistent);
271 }
272
273 template <class From, class To>
275 return OpenHandle(*handle);
276 }
277
278 template <class From, class To>
280 v8::Local<From> handle) {
281 return OpenDirectHandle(*handle);
282 }
283
284 private:
286 const char* location, const char* message);
287
288#define DECLARE_TO_LOCAL_PRIVATE(Name, From, To) \
289 static inline Local<v8::To> Name##_helper( \
290 v8::internal::DirectHandle<v8::internal::From> obj);
291
293#undef DECLARE_TO_LOCAL_PRIVATE
294};
295
296template <class T>
301
302template <class T>
304 Local<T>* local) {
306 if (maybe.ToHandle(&handle)) {
308 return true;
309 }
310 return false;
311}
312
313namespace internal {
314
315class PersistentHandles;
316
317// This class is here in order to be able to declare it a friend of
318// HandleScope. Moving these methods to be members of HandleScope would be
319// neat in some ways, but it would expose internal implementation details in
320// our public header file, which is undesirable.
321//
322// An isolate has a single instance of this class to hold the current thread's
323// data. In multithreaded V8 programs this data is copied in and out of storage
324// so that the currently executing thread always has its own copy of this
325// data.
327 public:
329 public:
331 : hsi_(hsi), saved_entered_context_count_(hsi->EnteredContextCount()) {}
332
334 DCHECK_LE(saved_entered_context_count_, hsi_->EnteredContextCount());
335 while (saved_entered_context_count_ < hsi_->EnteredContextCount())
336 hsi_->LeaveContext();
337 }
338
339 private:
342 };
343
345 : isolate_(isolate), spare_(nullptr) {}
346
348
351
352 // Threading support for handle data.
353 static int ArchiveSpacePerThread();
354 char* RestoreThread(char* from);
355 char* ArchiveThread(char* to);
356 void FreeThreadResources();
357
358 // Garbage collection support.
361 char* data);
362
364 inline void DeleteExtensions(internal::Address* prev_limit);
365
366 inline void EnterContext(Tagged<NativeContext> context);
367 inline void LeaveContext();
368 inline bool LastEnteredContextWas(Tagged<NativeContext> context);
369 inline size_t EnteredContextCount() const { return entered_contexts_.size(); }
370
371 // Returns the last entered context or an empty handle if no
372 // contexts have been entered.
374
375 inline void SaveContext(Tagged<Context> context);
377 inline bool HasSavedContexts();
378
380 Isolate* isolate() const { return isolate_; }
381
382 void ReturnBlock(Address* block) {
383 DCHECK_NOT_NULL(block);
384 if (spare_ != nullptr) DeleteArray(spare_);
385 spare_ = block;
386 }
387
388 static const size_t kEnteredContextsOffset;
389
390 private:
392 blocks_.detach();
393 entered_contexts_.detach();
394 saved_contexts_.detach();
395 spare_ = nullptr;
397 }
398
399 void Free() {
401 DCHECK(entered_contexts_.empty());
402 DCHECK(saved_contexts_.empty());
403
404 blocks_.free();
405 entered_contexts_.free();
406 saved_contexts_.free();
407 if (spare_ != nullptr) {
409 spare_ = nullptr;
410 }
412 }
413
418 bool HasPersistentScope() const {
419 return last_handle_before_persistent_block_.has_value();
420 }
421 std::unique_ptr<PersistentHandles> DetachPersistent(Address* first_block);
422
425
426 // Used as a stack to keep track of entered contexts.
428
429 // Used as a stack to keep track of saved contexts.
433 // This is only used for threading support.
435
436 void IterateThis(RootVisitor* v);
437 char* RestoreThreadHelper(char* from);
438 char* ArchiveThreadHelper(char* to);
439
442};
443
444const int kHandleBlockSize = v8::internal::KB - 2; // fit in one page
445
447 saved_contexts_.push_back(context);
448}
449
451 Tagged<Context> last_context = saved_contexts_.back();
452 saved_contexts_.pop_back();
453 return last_context;
454}
455
459
464
469
470// If there's a spare block, use it for growing the current scope.
478
480 while (!blocks_.empty()) {
481 internal::Address* block_start = blocks_.back();
482 internal::Address* block_limit = block_start + kHandleBlockSize;
483
484 // SealHandleScope may make the prev_limit to point inside the block.
485 // Cast possibly-unrelated pointers to plain Address before comparing them
486 // to avoid undefined behavior.
487 if (reinterpret_cast<Address>(block_start) <
488 reinterpret_cast<Address>(prev_limit) &&
489 reinterpret_cast<Address>(prev_limit) <=
490 reinterpret_cast<Address>(block_limit)) {
491#ifdef ENABLE_LOCAL_HANDLE_ZAPPING
492 internal::HandleScope::ZapRange(prev_limit, block_limit);
493#endif
494 break;
495 }
496
498#ifdef ENABLE_LOCAL_HANDLE_ZAPPING
499 internal::HandleScope::ZapRange(block_start, block_limit);
500#endif
501 if (spare_ != nullptr) {
503 }
504 spare_ = block_start;
505 }
506 DCHECK((blocks_.empty() && prev_limit == nullptr) ||
507 (!blocks_.empty() && prev_limit != nullptr));
508}
509
510// This is a wrapper function called from CallApiGetter builtin when profiling
511// or side-effect checking is enabled. It's supposed to set up the runtime
512// call stats scope and check if the getter has side-effects in case debugger
513// enabled the side-effects checking mode.
514// It gets additional argument, the AccessorInfo object, via
515// IsolateData::api_callback_thunk_argument slot.
517 v8::Local<v8::Name> property,
519
520// This is a wrapper function called from CallApiCallback builtin when profiling
521// or side-effect checking is enabled. It's supposed to set up the runtime
522// call stats scope and check if the callback has side-effects in case debugger
523// enabled the side-effects checking mode.
524// It gets additional argument, the v8::FunctionCallback address, via
525// IsolateData::api_callback_thunk_argument slot.
530
533 DirectHandle<JSFinalizationRegistry> finalization_registry);
534
535template <typename T>
537T ConvertDouble(double d);
538
539template <typename T>
542
543template <typename T>
546
547#ifdef ENABLE_SLOW_DCHECKS
548DECLARE_CONTEXTUAL_VARIABLE_WITH_DEFAULT(StackAllocatedCheck, const bool, true);
549#endif
550
551} // namespace internal
552} // namespace v8
553
554#endif // V8_API_API_H_
#define DECLARE_TO_LOCAL_TYPED_ARRAY(Type, typeName, TYPE, ctype)
Definition api.h:238
#define TO_LOCAL_NAME_LIST(V)
Definition api.h:137
#define DECLARE_TO_LOCAL(Name)
Definition api.h:230
#define OPEN_HANDLE_LIST(V)
Definition api.h:154
#define DECLARE_OPEN_HANDLE(From, To)
Definition api.h:244
#define DECLARE_TO_LOCAL_PRIVATE(Name, From, To)
Definition api.h:288
#define TO_LOCAL_LIST(V)
Definition api.h:94
ApiFunction(v8::internal::Address addr)
Definition api.h:71
v8::internal::Address address()
Definition api.h:72
v8::internal::Address addr_
Definition api.h:75
static RegisteredExtension * first_extension()
Definition api.h:84
std::unique_ptr< Extension > extension_
Definition api.h:89
Extension * extension() const
Definition api.h:82
static void Register(std::unique_ptr< Extension >)
Definition api.cc:452
static void UnregisterAll()
Definition api.cc:460
RegisteredExtension(Extension *)
RegisteredExtension * next() const
Definition api.h:83
RegisteredExtension * next_
Definition api.h:90
static RegisteredExtension * first_extension_
Definition api.h:91
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
Definition api.h:274
static Local< To > Convert(v8::internal::DirectHandle< From > obj)
Definition api-inl.h:59
static v8::internal::DirectHandle< To > OpenDirectHandle(v8::Local< From > handle)
Definition api.h:279
static v8::internal::Handle< v8::internal::Object > OpenPersistent(const v8::PersistentBase< T > &persistent)
Definition api.h:262
static void ReportOOMFailure(v8::internal::Isolate *isolate, const char *location, const OOMDetails &details)
Definition api.cc:272
static V8_INLINE bool ApiCheck(bool condition, const char *location, const char *message)
Definition api.h:214
static v8::internal::DirectHandle< v8::internal::Object > OpenPersistent(v8::Persistent< T > *persistent)
Definition api.h:268
V8_NOINLINE static V8_PRESERVE_MOST void ReportApiFailure(const char *location, const char *message)
Definition api.cc:256
V8_INLINE internal::Address *const & slot() const
DetachableVector< Address * > blocks_
Definition api.h:424
bool LastEnteredContextWas(Tagged< NativeContext > context)
Definition api.h:465
DetachableVector< Tagged< NativeContext > > entered_contexts_
Definition api.h:427
internal::Address * GetSpareOrNewBlock()
Definition api.h:471
V8_EXPORT_PRIVATE void Iterate(v8::internal::RootVisitor *v)
Definition api.cc:12050
static const size_t kEnteredContextsOffset
Definition api.h:388
HandleScopeData handle_scope_data_
Definition api.h:434
friend class HandleScopeImplementerOffsets
Definition api.h:440
HandleScopeImplementer(Isolate *isolate)
Definition api.h:344
void ReturnBlock(Address *block)
Definition api.h:382
void IterateThis(RootVisitor *v)
Definition api.cc:11996
void DeleteExtensions(internal::Address *prev_limit)
Definition api.h:479
HandleScopeImplementer & operator=(const HandleScopeImplementer &)=delete
Isolate * isolate() const
Definition api.h:380
size_t EnteredContextCount() const
Definition api.h:369
DirectHandle< NativeContext > LastEnteredContext()
Definition api-inl.h:349
DetachableVector< Address * > * blocks()
Definition api.h:379
DetachableVector< Tagged< Context > > saved_contexts_
Definition api.h:430
char * RestoreThread(char *from)
Definition api.cc:11990
HandleScopeImplementer(const HandleScopeImplementer &)=delete
void EnterContext(Tagged< NativeContext > context)
Definition api-inl.h:345
char * RestoreThreadHelper(char *from)
void SaveContext(Tagged< Context > context)
Definition api.h:446
std::unique_ptr< PersistentHandles > DetachPersistent(Address *first_block)
Definition api.cc:12063
Tagged< Context > RestoreContext()
Definition api.h:450
std::optional< Address * > last_handle_before_persistent_block_
Definition api.h:432
V8_INLINE HandleScopeData * handle_scope_data()
Definition isolate.h:1393
ThreadLocalTop * thread_local_top()
Definition isolate.h:1331
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
#define DECLARE_CONTEXTUAL_VARIABLE_WITH_DEFAULT(VarName,...)
Definition contextual.h:125
#define TYPED_ARRAYS(V)
#define EXPORT_TEMPLATE_DECLARE(export)
TNode< Context > context
RpoNumber block
void DeleteArray(T *array)
Definition allocation.h:63
void InvokeFinalizationRegistryCleanupFromTask(DirectHandle< NativeContext > native_context, DirectHandle< JSFinalizationRegistry > finalization_registry)
Definition api.cc:12192
void InvokeFunctionCallbackOptimized(const v8::FunctionCallbackInfo< v8::Value > &info)
Definition api.cc:12187
const int kHandleBlockSize
Definition api.h:444
bool V8_EXPORT ValidateCallbackInfo(const FunctionCallbackInfo< void > &info)
Definition api.cc:12301
int32_t ConvertDouble(double d)
Definition api.cc:12211
typename detail::FlattenUnionHelper< Union<>, Ts... >::type UnionOf
Definition union.h:123
void InvokeFunctionCallbackGeneric(const v8::FunctionCallbackInfo< v8::Value > &info)
Definition api.cc:12182
void InvokeAccessorGetterCallback(v8::Local< v8::Name > property, const v8::PropertyCallbackInfo< v8::Value > &info)
Definition api.cc:12097
T * NewArray(size_t size)
Definition allocation.h:43
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
bool ToLocal(v8::internal::MaybeDirectHandle< v8::internal::Object > maybe, Local< T > *local)
Definition api.h:303
v8::internal::DirectHandle< i::UnionOf< i::Smi, i::Foreign > > FromCData(v8::internal::Isolate *isolate, T obj)
Definition api-inl.h:41
v8::Local< T > ToApiHandle(v8::internal::DirectHandle< v8::internal::Object > obj)
Definition api.h:297
T ToCData(i::Isolate *isolate, v8::internal::Tagged< v8::internal::Object > obj)
Definition api-inl.h:23
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_INLINE
Definition v8config.h:500
#define V8_UNLIKELY(condition)
Definition v8config.h:660
#define V8_NOINLINE
Definition v8config.h:586
#define V8_PRESERVE_MOST
Definition v8config.h:598
#define V8_NODISCARD
Definition v8config.h:693