• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_H_
6 #define V8_API_H_
7 
8 #include "include/v8-testing.h"
9 #include "src/contexts.h"
10 #include "src/debug/debug-interface.h"
11 #include "src/detachable-vector.h"
12 #include "src/heap/factory.h"
13 #include "src/isolate.h"
14 #include "src/objects.h"
15 #include "src/objects/bigint.h"
16 #include "src/objects/js-collection.h"
17 #include "src/objects/js-generator.h"
18 #include "src/objects/js-promise.h"
19 #include "src/objects/js-proxy.h"
20 #include "src/objects/module.h"
21 #include "src/objects/shared-function-info.h"
22 
23 #include "src/objects/templates.h"
24 
25 namespace v8 {
26 
27 // Constants used in the implementation of the API.  The most natural thing
28 // would usually be to place these with the classes that use them, but
29 // we want to keep them out of v8.h because it is an externally
30 // visible file.
31 class Consts {
32  public:
33   enum TemplateType {
34     FUNCTION_TEMPLATE = 0,
35     OBJECT_TEMPLATE = 1
36   };
37 };
38 
39 template <typename T>
40 inline T ToCData(v8::internal::Object* obj);
41 
42 template <>
43 inline v8::internal::Address ToCData(v8::internal::Object* obj);
44 
45 template <typename T>
46 inline v8::internal::Handle<v8::internal::Object> FromCData(
47     v8::internal::Isolate* isolate, T obj);
48 
49 template <>
50 inline v8::internal::Handle<v8::internal::Object> FromCData(
51     v8::internal::Isolate* isolate, v8::internal::Address obj);
52 
53 class ApiFunction {
54  public:
ApiFunction(v8::internal::Address addr)55   explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { }
address()56   v8::internal::Address address() { return addr_; }
57  private:
58   v8::internal::Address addr_;
59 };
60 
61 
62 
63 class RegisteredExtension {
64  public:
65   explicit RegisteredExtension(Extension* extension);
66   static void Register(RegisteredExtension* that);
67   static void UnregisterAll();
extension()68   Extension* extension() { return extension_; }
next()69   RegisteredExtension* next() { return next_; }
first_extension()70   static RegisteredExtension* first_extension() { return first_extension_; }
71  private:
72   Extension* extension_;
73   RegisteredExtension* next_;
74   static RegisteredExtension* first_extension_;
75 };
76 
77 #define OPEN_HANDLE_LIST(V)                    \
78   V(Template, TemplateInfo)                    \
79   V(FunctionTemplate, FunctionTemplateInfo)    \
80   V(ObjectTemplate, ObjectTemplateInfo)        \
81   V(Signature, FunctionTemplateInfo)           \
82   V(AccessorSignature, FunctionTemplateInfo)   \
83   V(Data, Object)                              \
84   V(RegExp, JSRegExp)                          \
85   V(Object, JSReceiver)                        \
86   V(Array, JSArray)                            \
87   V(Map, JSMap)                                \
88   V(Set, JSSet)                                \
89   V(ArrayBuffer, JSArrayBuffer)                \
90   V(ArrayBufferView, JSArrayBufferView)        \
91   V(TypedArray, JSTypedArray)                  \
92   V(Uint8Array, JSTypedArray)                  \
93   V(Uint8ClampedArray, JSTypedArray)           \
94   V(Int8Array, JSTypedArray)                   \
95   V(Uint16Array, JSTypedArray)                 \
96   V(Int16Array, JSTypedArray)                  \
97   V(Uint32Array, JSTypedArray)                 \
98   V(Int32Array, JSTypedArray)                  \
99   V(Float32Array, JSTypedArray)                \
100   V(Float64Array, JSTypedArray)                \
101   V(DataView, JSDataView)                      \
102   V(SharedArrayBuffer, JSArrayBuffer)          \
103   V(Name, Name)                                \
104   V(String, String)                            \
105   V(Symbol, Symbol)                            \
106   V(Script, JSFunction)                        \
107   V(UnboundModuleScript, SharedFunctionInfo)   \
108   V(UnboundScript, SharedFunctionInfo)         \
109   V(Module, Module)                            \
110   V(Function, JSReceiver)                      \
111   V(Message, JSMessageObject)                  \
112   V(Context, Context)                          \
113   V(External, Object)                          \
114   V(StackTrace, FixedArray)                    \
115   V(StackFrame, StackFrameInfo)                \
116   V(Proxy, JSProxy)                            \
117   V(debug::GeneratorObject, JSGeneratorObject) \
118   V(debug::Script, Script)                     \
119   V(Promise, JSPromise)                        \
120   V(Primitive, Object)                         \
121   V(PrimitiveArray, FixedArray)                \
122   V(BigInt, BigInt)                            \
123   V(ScriptOrModule, Script)
124 
125 class Utils {
126  public:
ApiCheck(bool condition,const char * location,const char * message)127   static inline bool ApiCheck(bool condition,
128                               const char* location,
129                               const char* message) {
130     if (!condition) Utils::ReportApiFailure(location, message);
131     return condition;
132   }
133   static void ReportOOMFailure(v8::internal::Isolate* isolate,
134                                const char* location, bool is_heap_oom);
135 
136   static inline Local<Context> ToLocal(
137       v8::internal::Handle<v8::internal::Context> obj);
138   static inline Local<Value> ToLocal(
139       v8::internal::Handle<v8::internal::Object> obj);
140   static inline Local<Module> ToLocal(
141       v8::internal::Handle<v8::internal::Module> obj);
142   static inline Local<Name> ToLocal(
143       v8::internal::Handle<v8::internal::Name> obj);
144   static inline Local<String> ToLocal(
145       v8::internal::Handle<v8::internal::String> obj);
146   static inline Local<Symbol> ToLocal(
147       v8::internal::Handle<v8::internal::Symbol> obj);
148   static inline Local<RegExp> ToLocal(
149       v8::internal::Handle<v8::internal::JSRegExp> obj);
150   static inline Local<Object> ToLocal(
151       v8::internal::Handle<v8::internal::JSReceiver> obj);
152   static inline Local<Object> ToLocal(
153       v8::internal::Handle<v8::internal::JSObject> obj);
154   static inline Local<Function> ToLocal(
155       v8::internal::Handle<v8::internal::JSFunction> obj);
156   static inline Local<Array> ToLocal(
157       v8::internal::Handle<v8::internal::JSArray> obj);
158   static inline Local<Map> ToLocal(
159       v8::internal::Handle<v8::internal::JSMap> obj);
160   static inline Local<Set> ToLocal(
161       v8::internal::Handle<v8::internal::JSSet> obj);
162   static inline Local<Proxy> ToLocal(
163       v8::internal::Handle<v8::internal::JSProxy> obj);
164   static inline Local<ArrayBuffer> ToLocal(
165       v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
166   static inline Local<ArrayBufferView> ToLocal(
167       v8::internal::Handle<v8::internal::JSArrayBufferView> obj);
168   static inline Local<DataView> ToLocal(
169       v8::internal::Handle<v8::internal::JSDataView> obj);
170   static inline Local<TypedArray> ToLocal(
171       v8::internal::Handle<v8::internal::JSTypedArray> obj);
172   static inline Local<Uint8Array> ToLocalUint8Array(
173       v8::internal::Handle<v8::internal::JSTypedArray> obj);
174   static inline Local<Uint8ClampedArray> ToLocalUint8ClampedArray(
175       v8::internal::Handle<v8::internal::JSTypedArray> obj);
176   static inline Local<Int8Array> ToLocalInt8Array(
177       v8::internal::Handle<v8::internal::JSTypedArray> obj);
178   static inline Local<Uint16Array> ToLocalUint16Array(
179       v8::internal::Handle<v8::internal::JSTypedArray> obj);
180   static inline Local<Int16Array> ToLocalInt16Array(
181       v8::internal::Handle<v8::internal::JSTypedArray> obj);
182   static inline Local<Uint32Array> ToLocalUint32Array(
183       v8::internal::Handle<v8::internal::JSTypedArray> obj);
184   static inline Local<Int32Array> ToLocalInt32Array(
185       v8::internal::Handle<v8::internal::JSTypedArray> obj);
186   static inline Local<Float32Array> ToLocalFloat32Array(
187       v8::internal::Handle<v8::internal::JSTypedArray> obj);
188   static inline Local<Float64Array> ToLocalFloat64Array(
189       v8::internal::Handle<v8::internal::JSTypedArray> obj);
190   static inline Local<BigInt64Array> ToLocalBigInt64Array(
191       v8::internal::Handle<v8::internal::JSTypedArray> obj);
192   static inline Local<BigUint64Array> ToLocalBigUint64Array(
193       v8::internal::Handle<v8::internal::JSTypedArray> obj);
194 
195   static inline Local<SharedArrayBuffer> ToLocalShared(
196       v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
197 
198   static inline Local<Message> MessageToLocal(
199       v8::internal::Handle<v8::internal::Object> obj);
200   static inline Local<Promise> PromiseToLocal(
201       v8::internal::Handle<v8::internal::JSObject> obj);
202   static inline Local<StackTrace> StackTraceToLocal(
203       v8::internal::Handle<v8::internal::FixedArray> obj);
204   static inline Local<StackFrame> StackFrameToLocal(
205       v8::internal::Handle<v8::internal::StackFrameInfo> obj);
206   static inline Local<Number> NumberToLocal(
207       v8::internal::Handle<v8::internal::Object> obj);
208   static inline Local<Integer> IntegerToLocal(
209       v8::internal::Handle<v8::internal::Object> obj);
210   static inline Local<Uint32> Uint32ToLocal(
211       v8::internal::Handle<v8::internal::Object> obj);
212   static inline Local<BigInt> ToLocal(
213       v8::internal::Handle<v8::internal::BigInt> obj);
214   static inline Local<FunctionTemplate> ToLocal(
215       v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
216   static inline Local<ObjectTemplate> ToLocal(
217       v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj);
218   static inline Local<Signature> SignatureToLocal(
219       v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
220   static inline Local<AccessorSignature> AccessorSignatureToLocal(
221       v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
222   static inline Local<External> ExternalToLocal(
223       v8::internal::Handle<v8::internal::JSObject> obj);
224   static inline Local<Function> CallableToLocal(
225       v8::internal::Handle<v8::internal::JSReceiver> obj);
226   static inline Local<Primitive> ToLocalPrimitive(
227       v8::internal::Handle<v8::internal::Object> obj);
228   static inline Local<PrimitiveArray> ToLocal(
229       v8::internal::Handle<v8::internal::FixedArray> obj);
230   static inline Local<ScriptOrModule> ScriptOrModuleToLocal(
231       v8::internal::Handle<v8::internal::Script> obj);
232 
233 #define DECLARE_OPEN_HANDLE(From, To) \
234   static inline v8::internal::Handle<v8::internal::To> \
235       OpenHandle(const From* that, bool allow_empty_handle = false);
236 
237 OPEN_HANDLE_LIST(DECLARE_OPEN_HANDLE)
238 
239 #undef DECLARE_OPEN_HANDLE
240 
241 template <class From, class To>
242 static inline Local<To> Convert(v8::internal::Handle<From> obj);
243 
244 template <class T>
OpenPersistent(const v8::Persistent<T> & persistent)245 static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
246     const v8::Persistent<T>& persistent) {
247   return v8::internal::Handle<v8::internal::Object>(
248       reinterpret_cast<v8::internal::Object**>(persistent.val_));
249   }
250 
251   template <class T>
OpenPersistent(v8::Persistent<T> * persistent)252   static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
253       v8::Persistent<T>* persistent) {
254     return OpenPersistent(*persistent);
255   }
256 
257   template <class From, class To>
OpenHandle(v8::Local<From> handle)258   static inline v8::internal::Handle<To> OpenHandle(v8::Local<From> handle) {
259     return OpenHandle(*handle);
260   }
261 
262  private:
263   static void ReportApiFailure(const char* location, const char* message);
264 };
265 
266 
267 template <class T>
ToApi(v8::internal::Handle<v8::internal::Object> obj)268 inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
269   return reinterpret_cast<T*>(obj.location());
270 }
271 
272 template <class T>
ToApiHandle(v8::internal::Handle<v8::internal::Object> obj)273 inline v8::Local<T> ToApiHandle(
274     v8::internal::Handle<v8::internal::Object> obj) {
275   return Utils::Convert<v8::internal::Object, T>(obj);
276 }
277 
278 
279 template <class T>
ToLocal(v8::internal::MaybeHandle<v8::internal::Object> maybe,Local<T> * local)280 inline bool ToLocal(v8::internal::MaybeHandle<v8::internal::Object> maybe,
281                     Local<T>* local) {
282   v8::internal::Handle<v8::internal::Object> handle;
283   if (maybe.ToHandle(&handle)) {
284     *local = Utils::Convert<v8::internal::Object, T>(handle);
285     return true;
286   }
287   return false;
288 }
289 
290 namespace internal {
291 
292 class V8_EXPORT_PRIVATE DeferredHandles {
293  public:
294   ~DeferredHandles();
295 
296  private:
DeferredHandles(Object ** first_block_limit,Isolate * isolate)297   DeferredHandles(Object** first_block_limit, Isolate* isolate)
298       : next_(nullptr),
299         previous_(nullptr),
300         first_block_limit_(first_block_limit),
301         isolate_(isolate) {
302     isolate->LinkDeferredHandles(this);
303   }
304 
305   void Iterate(RootVisitor* v);
306 
307   std::vector<Object**> blocks_;
308   DeferredHandles* next_;
309   DeferredHandles* previous_;
310   Object** first_block_limit_;
311   Isolate* isolate_;
312 
313   friend class HandleScopeImplementer;
314   friend class Isolate;
315 };
316 
317 
318 // This class is here in order to be able to declare it a friend of
319 // HandleScope.  Moving these methods to be members of HandleScope would be
320 // neat in some ways, but it would expose internal implementation details in
321 // our public header file, which is undesirable.
322 //
323 // An isolate has a single instance of this class to hold the current thread's
324 // data. In multithreaded V8 programs this data is copied in and out of storage
325 // so that the currently executing thread always has its own copy of this
326 // data.
327 class HandleScopeImplementer {
328  public:
HandleScopeImplementer(Isolate * isolate)329   explicit HandleScopeImplementer(Isolate* isolate)
330       : isolate_(isolate),
331         microtask_context_(nullptr),
332         spare_(nullptr),
333         call_depth_(0),
334         microtasks_depth_(0),
335         microtasks_suppressions_(0),
336         entered_contexts_count_(0),
337         entered_context_count_during_microtasks_(0),
338 #ifdef DEBUG
339         debug_microtasks_depth_(0),
340 #endif
341         microtasks_policy_(v8::MicrotasksPolicy::kAuto),
342         last_handle_before_deferred_block_(nullptr) {
343   }
344 
~HandleScopeImplementer()345   ~HandleScopeImplementer() {
346     DeleteArray(spare_);
347   }
348 
349   // Threading support for handle data.
350   static int ArchiveSpacePerThread();
351   char* RestoreThread(char* from);
352   char* ArchiveThread(char* to);
353   void FreeThreadResources();
354 
355   // Garbage collection support.
356   void Iterate(v8::internal::RootVisitor* v);
357   static char* Iterate(v8::internal::RootVisitor* v, char* data);
358 
359   inline internal::Object** GetSpareOrNewBlock();
360   inline void DeleteExtensions(internal::Object** prev_limit);
361 
362   // Call depth represents nested v8 api calls.
IncrementCallDepth()363   inline void IncrementCallDepth() {call_depth_++;}
DecrementCallDepth()364   inline void DecrementCallDepth() {call_depth_--;}
CallDepthIsZero()365   inline bool CallDepthIsZero() { return call_depth_ == 0; }
366 
367   // Microtasks scope depth represents nested scopes controlling microtasks
368   // invocation, which happens when depth reaches zero.
IncrementMicrotasksScopeDepth()369   inline void IncrementMicrotasksScopeDepth() {microtasks_depth_++;}
DecrementMicrotasksScopeDepth()370   inline void DecrementMicrotasksScopeDepth() {microtasks_depth_--;}
GetMicrotasksScopeDepth()371   inline int GetMicrotasksScopeDepth() { return microtasks_depth_; }
372 
373   // Possibly nested microtasks suppression scopes prevent microtasks
374   // from running.
IncrementMicrotasksSuppressions()375   inline void IncrementMicrotasksSuppressions() {microtasks_suppressions_++;}
DecrementMicrotasksSuppressions()376   inline void DecrementMicrotasksSuppressions() {microtasks_suppressions_--;}
HasMicrotasksSuppressions()377   inline bool HasMicrotasksSuppressions() { return !!microtasks_suppressions_; }
378 
379 #ifdef DEBUG
380   // In debug we check that calls not intended to invoke microtasks are
381   // still correctly wrapped with microtask scopes.
IncrementDebugMicrotasksScopeDepth()382   inline void IncrementDebugMicrotasksScopeDepth() {debug_microtasks_depth_++;}
DecrementDebugMicrotasksScopeDepth()383   inline void DecrementDebugMicrotasksScopeDepth() {debug_microtasks_depth_--;}
DebugMicrotasksScopeDepthIsZero()384   inline bool DebugMicrotasksScopeDepthIsZero() {
385     return debug_microtasks_depth_ == 0;
386   }
387 #endif
388 
389   inline void set_microtasks_policy(v8::MicrotasksPolicy policy);
390   inline v8::MicrotasksPolicy microtasks_policy() const;
391 
392   inline void EnterContext(Handle<Context> context);
393   inline void LeaveContext();
394   inline bool LastEnteredContextWas(Handle<Context> context);
395 
396   // Returns the last entered context or an empty handle if no
397   // contexts have been entered.
398   inline Handle<Context> LastEnteredContext();
399 
400   inline void EnterMicrotaskContext(Handle<Context> context);
401   inline void LeaveMicrotaskContext();
402   inline Handle<Context> MicrotaskContext();
MicrotaskContextIsLastEnteredContext()403   inline bool MicrotaskContextIsLastEnteredContext() const {
404     return microtask_context_ &&
405            entered_context_count_during_microtasks_ == entered_contexts_.size();
406   }
407 
408   inline void SaveContext(Context* context);
409   inline Context* RestoreContext();
410   inline bool HasSavedContexts();
411 
blocks()412   inline DetachableVector<Object**>* blocks() { return &blocks_; }
isolate()413   Isolate* isolate() const { return isolate_; }
414 
ReturnBlock(Object ** block)415   void ReturnBlock(Object** block) {
416     DCHECK_NOT_NULL(block);
417     if (spare_ != nullptr) DeleteArray(spare_);
418     spare_ = block;
419   }
420 
421  private:
ResetAfterArchive()422   void ResetAfterArchive() {
423     blocks_.detach();
424     entered_contexts_.detach();
425     saved_contexts_.detach();
426     microtask_context_ = nullptr;
427     entered_context_count_during_microtasks_ = 0;
428     spare_ = nullptr;
429     last_handle_before_deferred_block_ = nullptr;
430     call_depth_ = 0;
431   }
432 
Free()433   void Free() {
434     DCHECK(blocks_.empty());
435     DCHECK(entered_contexts_.empty());
436     DCHECK(saved_contexts_.empty());
437     DCHECK(!microtask_context_);
438 
439     blocks_.free();
440     entered_contexts_.free();
441     saved_contexts_.free();
442     if (spare_ != nullptr) {
443       DeleteArray(spare_);
444       spare_ = nullptr;
445     }
446     DCHECK_EQ(call_depth_, 0);
447   }
448 
449   void BeginDeferredScope();
450   DeferredHandles* Detach(Object** prev_limit);
451 
452   Isolate* isolate_;
453   DetachableVector<Object**> blocks_;
454   // Used as a stack to keep track of entered contexts.
455   DetachableVector<Context*> entered_contexts_;
456   // Used as a stack to keep track of saved contexts.
457   DetachableVector<Context*> saved_contexts_;
458   Context* microtask_context_;
459   Object** spare_;
460   int call_depth_;
461   int microtasks_depth_;
462   int microtasks_suppressions_;
463   size_t entered_contexts_count_;
464   size_t entered_context_count_during_microtasks_;
465 #ifdef DEBUG
466   int debug_microtasks_depth_;
467 #endif
468   v8::MicrotasksPolicy microtasks_policy_;
469   Object** last_handle_before_deferred_block_;
470   // This is only used for threading support.
471   HandleScopeData handle_scope_data_;
472 
473   void IterateThis(RootVisitor* v);
474   char* RestoreThreadHelper(char* from);
475   char* ArchiveThreadHelper(char* to);
476 
477   friend class DeferredHandles;
478   friend class DeferredHandleScope;
479   friend class HandleScopeImplementerOffsets;
480 
481   DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer);
482 };
483 
484 class HandleScopeImplementerOffsets {
485  public:
486   enum Offsets {
487     kMicrotaskContext = offsetof(HandleScopeImplementer, microtask_context_),
488     kEnteredContexts = offsetof(HandleScopeImplementer, entered_contexts_),
489     kEnteredContextsCount =
490         offsetof(HandleScopeImplementer, entered_contexts_count_),
491     kEnteredContextCountDuringMicrotasks = offsetof(
492         HandleScopeImplementer, entered_context_count_during_microtasks_)
493   };
494 
495  private:
496   DISALLOW_IMPLICIT_CONSTRUCTORS(HandleScopeImplementerOffsets);
497 };
498 
499 const int kHandleBlockSize = v8::internal::KB - 2;  // fit in one page
500 
501 
set_microtasks_policy(v8::MicrotasksPolicy policy)502 void HandleScopeImplementer::set_microtasks_policy(
503     v8::MicrotasksPolicy policy) {
504   microtasks_policy_ = policy;
505 }
506 
507 
microtasks_policy()508 v8::MicrotasksPolicy HandleScopeImplementer::microtasks_policy() const {
509   return microtasks_policy_;
510 }
511 
512 
SaveContext(Context * context)513 void HandleScopeImplementer::SaveContext(Context* context) {
514   saved_contexts_.push_back(context);
515 }
516 
517 
RestoreContext()518 Context* HandleScopeImplementer::RestoreContext() {
519   Context* last_context = saved_contexts_.back();
520   saved_contexts_.pop_back();
521   return last_context;
522 }
523 
524 
HasSavedContexts()525 bool HandleScopeImplementer::HasSavedContexts() {
526   return !saved_contexts_.empty();
527 }
528 
529 
EnterContext(Handle<Context> context)530 void HandleScopeImplementer::EnterContext(Handle<Context> context) {
531   entered_contexts_.push_back(*context);
532   entered_contexts_count_ = entered_contexts_.size();
533 }
534 
LeaveContext()535 void HandleScopeImplementer::LeaveContext() {
536   entered_contexts_.pop_back();
537   entered_contexts_count_ = entered_contexts_.size();
538 }
539 
LastEnteredContextWas(Handle<Context> context)540 bool HandleScopeImplementer::LastEnteredContextWas(Handle<Context> context) {
541   return !entered_contexts_.empty() && entered_contexts_.back() == *context;
542 }
543 
EnterMicrotaskContext(Handle<Context> context)544 void HandleScopeImplementer::EnterMicrotaskContext(Handle<Context> context) {
545   DCHECK(!microtask_context_);
546   microtask_context_ = *context;
547   entered_context_count_during_microtasks_ = entered_contexts_.size();
548 }
549 
LeaveMicrotaskContext()550 void HandleScopeImplementer::LeaveMicrotaskContext() {
551   microtask_context_ = nullptr;
552   entered_context_count_during_microtasks_ = 0;
553 }
554 
555 // If there's a spare block, use it for growing the current scope.
GetSpareOrNewBlock()556 internal::Object** HandleScopeImplementer::GetSpareOrNewBlock() {
557   internal::Object** block =
558       (spare_ != nullptr) ? spare_
559                           : NewArray<internal::Object*>(kHandleBlockSize);
560   spare_ = nullptr;
561   return block;
562 }
563 
564 
DeleteExtensions(internal::Object ** prev_limit)565 void HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) {
566   while (!blocks_.empty()) {
567     internal::Object** block_start = blocks_.back();
568     internal::Object** block_limit = block_start + kHandleBlockSize;
569 
570     // SealHandleScope may make the prev_limit to point inside the block.
571     if (block_start <= prev_limit && prev_limit <= block_limit) {
572 #ifdef ENABLE_HANDLE_ZAPPING
573       internal::HandleScope::ZapRange(prev_limit, block_limit);
574 #endif
575       break;
576     }
577 
578     blocks_.pop_back();
579 #ifdef ENABLE_HANDLE_ZAPPING
580     internal::HandleScope::ZapRange(block_start, block_limit);
581 #endif
582     if (spare_ != nullptr) {
583       DeleteArray(spare_);
584     }
585     spare_ = block_start;
586   }
587   DCHECK((blocks_.empty() && prev_limit == nullptr) ||
588          (!blocks_.empty() && prev_limit != nullptr));
589 }
590 
591 // Interceptor functions called from generated inline caches to notify
592 // CPU profiler that external callbacks are invoked.
593 void InvokeAccessorGetterCallback(
594     v8::Local<v8::Name> property,
595     const v8::PropertyCallbackInfo<v8::Value>& info,
596     v8::AccessorNameGetterCallback getter);
597 
598 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
599                             v8::FunctionCallback callback);
600 
601 class Testing {
602  public:
stress_type()603   static v8::Testing::StressType stress_type() { return stress_type_; }
set_stress_type(v8::Testing::StressType stress_type)604   static void set_stress_type(v8::Testing::StressType stress_type) {
605     stress_type_ = stress_type;
606   }
607 
608  private:
609   static v8::Testing::StressType stress_type_;
610 };
611 
612 }  // namespace internal
613 }  // namespace v8
614 
615 #endif  // V8_API_H_
616