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