| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 class StackTrace; | 135 class StackTrace; |
| 136 class String; | 136 class String; |
| 137 class StringObject; | 137 class StringObject; |
| 138 class Symbol; | 138 class Symbol; |
| 139 class SymbolObject; | 139 class SymbolObject; |
| 140 class Uint32; | 140 class Uint32; |
| 141 class Utils; | 141 class Utils; |
| 142 class Value; | 142 class Value; |
| 143 template <class T> class Handle; | 143 template <class T> class Handle; |
| 144 template <class T> class Local; | 144 template <class T> class Local; |
| 145 template <class T> class Persistent; | 145 template<class T, class P> class NonCopyablePersistentModifier; |
| 146 template<class T, |
| 147 class M = NonCopyablePersistentModifier<T, void> > class Persistent; |
| 148 template<class T, class P> class WeakCallbackObject; |
| 146 class FunctionTemplate; | 149 class FunctionTemplate; |
| 147 class ObjectTemplate; | 150 class ObjectTemplate; |
| 148 class Data; | 151 class Data; |
| 149 class AccessorInfo; | 152 class AccessorInfo; |
| 150 template<typename T> class PropertyCallbackInfo; | 153 template<typename T> class PropertyCallbackInfo; |
| 151 class StackTrace; | 154 class StackTrace; |
| 152 class StackFrame; | 155 class StackFrame; |
| 153 class Isolate; | 156 class Isolate; |
| 154 class DeclaredAccessorDescriptor; | 157 class DeclaredAccessorDescriptor; |
| 155 class ObjectOperationDescriptor; | 158 class ObjectOperationDescriptor; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 185 } | 188 } |
| 186 | 189 |
| 187 bool operator<(const UniqueId& other) const { | 190 bool operator<(const UniqueId& other) const { |
| 188 return data_ < other.data_; | 191 return data_ < other.data_; |
| 189 } | 192 } |
| 190 | 193 |
| 191 private: | 194 private: |
| 192 intptr_t data_; | 195 intptr_t data_; |
| 193 }; | 196 }; |
| 194 | 197 |
| 195 | |
| 196 // --- Weak Handles --- | |
| 197 | |
| 198 | |
| 199 /** | |
| 200 * A weak reference callback function. | |
| 201 * | |
| 202 * This callback should either explicitly invoke Dispose on |object| if | |
| 203 * V8 wrapper is not needed anymore, or 'revive' it by invocation of MakeWeak. | |
| 204 * | |
| 205 * \param object the weak global object to be reclaimed by the garbage collector | |
| 206 * \param parameter the value passed in when making the weak global object | |
| 207 */ | |
| 208 template<typename T, typename P> | |
| 209 class WeakReferenceCallbacks { | |
| 210 public: | |
| 211 typedef void (*Revivable)(Isolate* isolate, | |
| 212 Persistent<T>* object, | |
| 213 P* parameter); | |
| 214 }; | |
| 215 | |
| 216 // --- Handles --- | 198 // --- Handles --- |
| 217 | 199 |
| 218 #define TYPE_CHECK(T, S) \ | 200 #define TYPE_CHECK(T, S) \ |
| 219 while (false) { \ | 201 while (false) { \ |
| 220 *(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \ | 202 *(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \ |
| 221 } | 203 } |
| 222 | 204 |
| 223 | 205 |
| 224 /** | 206 /** |
| 225 * An object reference managed by the v8 garbage collector. | 207 * An object reference managed by the v8 garbage collector. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 246 * behind the scenes and the same rules apply to these values as to | 228 * behind the scenes and the same rules apply to these values as to |
| 247 * their handles. | 229 * their handles. |
| 248 */ | 230 */ |
| 249 template <class T> class Handle { | 231 template <class T> class Handle { |
| 250 public: | 232 public: |
| 251 /** | 233 /** |
| 252 * Creates an empty handle. | 234 * Creates an empty handle. |
| 253 */ | 235 */ |
| 254 V8_INLINE(Handle()) : val_(0) {} | 236 V8_INLINE(Handle()) : val_(0) {} |
| 255 | 237 |
| 256 #ifdef V8_USE_UNSAFE_HANDLES | |
| 257 /** | |
| 258 * Creates a new handle for the specified value. | |
| 259 */ | |
| 260 V8_INLINE(explicit Handle(T* val)) : val_(val) {} | |
| 261 #endif | |
| 262 | |
| 263 /** | 238 /** |
| 264 * Creates a handle for the contents of the specified handle. This | 239 * Creates a handle for the contents of the specified handle. This |
| 265 * constructor allows you to pass handles as arguments by value and | 240 * constructor allows you to pass handles as arguments by value and |
| 266 * to assign between handles. However, if you try to assign between | 241 * to assign between handles. However, if you try to assign between |
| 267 * incompatible handles, for instance from a Handle<String> to a | 242 * incompatible handles, for instance from a Handle<String> to a |
| 268 * Handle<Number> it will cause a compile-time error. Assigning | 243 * Handle<Number> it will cause a compile-time error. Assigning |
| 269 * between compatible handles, for instance assigning a | 244 * between compatible handles, for instance assigning a |
| 270 * Handle<String> to a variable declared as Handle<Value>, is legal | 245 * Handle<String> to a variable declared as Handle<Value>, is legal |
| 271 * because String is a subclass of Value. | 246 * because String is a subclass of Value. |
| 272 */ | 247 */ |
| (...skipping 28 matching lines...) Expand all Loading... |
| 301 * The handles' references are not checked. | 276 * The handles' references are not checked. |
| 302 */ | 277 */ |
| 303 template <class S> V8_INLINE(bool operator==(const Handle<S> that) const) { | 278 template <class S> V8_INLINE(bool operator==(const Handle<S> that) const) { |
| 304 internal::Object** a = reinterpret_cast<internal::Object**>(**this); | 279 internal::Object** a = reinterpret_cast<internal::Object**>(**this); |
| 305 internal::Object** b = reinterpret_cast<internal::Object**>(*that); | 280 internal::Object** b = reinterpret_cast<internal::Object**>(*that); |
| 306 if (a == 0) return b == 0; | 281 if (a == 0) return b == 0; |
| 307 if (b == 0) return false; | 282 if (b == 0) return false; |
| 308 return *a == *b; | 283 return *a == *b; |
| 309 } | 284 } |
| 310 | 285 |
| 311 #ifndef V8_USE_UNSAFE_HANDLES | |
| 312 template <class S> V8_INLINE( | 286 template <class S> V8_INLINE( |
| 313 bool operator==(const Persistent<S>& that) const) { | 287 bool operator==(const Persistent<S>& that) const) { |
| 314 internal::Object** a = reinterpret_cast<internal::Object**>(**this); | 288 internal::Object** a = reinterpret_cast<internal::Object**>(**this); |
| 315 internal::Object** b = reinterpret_cast<internal::Object**>(*that); | 289 internal::Object** b = reinterpret_cast<internal::Object**>(*that); |
| 316 if (a == 0) return b == 0; | 290 if (a == 0) return b == 0; |
| 317 if (b == 0) return false; | 291 if (b == 0) return false; |
| 318 return *a == *b; | 292 return *a == *b; |
| 319 } | 293 } |
| 320 #endif | |
| 321 | 294 |
| 322 /** | 295 /** |
| 323 * Checks whether two handles are different. | 296 * Checks whether two handles are different. |
| 324 * Returns true if only one of the handles is empty, or if | 297 * Returns true if only one of the handles is empty, or if |
| 325 * the objects to which they refer are different. | 298 * the objects to which they refer are different. |
| 326 * The handles' references are not checked. | 299 * The handles' references are not checked. |
| 327 */ | 300 */ |
| 328 template <class S> V8_INLINE(bool operator!=(Handle<S> that) const) { | 301 template <class S> V8_INLINE(bool operator!=(Handle<S> that) const) { |
| 329 return !operator==(that); | 302 return !operator==(that); |
| 330 } | 303 } |
| 331 | 304 |
| 332 template <class S> V8_INLINE(static Handle<T> Cast(Handle<S> that)) { | 305 template <class S> V8_INLINE(static Handle<T> Cast(Handle<S> that)) { |
| 333 #ifdef V8_ENABLE_CHECKS | 306 #ifdef V8_ENABLE_CHECKS |
| 334 // If we're going to perform the type check then we have to check | 307 // If we're going to perform the type check then we have to check |
| 335 // that the handle isn't empty before doing the checked cast. | 308 // that the handle isn't empty before doing the checked cast. |
| 336 if (that.IsEmpty()) return Handle<T>(); | 309 if (that.IsEmpty()) return Handle<T>(); |
| 337 #endif | 310 #endif |
| 338 return Handle<T>(T::Cast(*that)); | 311 return Handle<T>(T::Cast(*that)); |
| 339 } | 312 } |
| 340 | 313 |
| 341 template <class S> V8_INLINE(Handle<S> As()) { | 314 template <class S> V8_INLINE(Handle<S> As()) { |
| 342 return Handle<S>::Cast(*this); | 315 return Handle<S>::Cast(*this); |
| 343 } | 316 } |
| 344 | 317 |
| 345 #ifndef V8_USE_UNSAFE_HANDLES | |
| 346 V8_INLINE(static Handle<T> New(Isolate* isolate, Handle<T> that)) { | 318 V8_INLINE(static Handle<T> New(Isolate* isolate, Handle<T> that)) { |
| 347 return New(isolate, that.val_); | 319 return New(isolate, that.val_); |
| 348 } | 320 } |
| 349 // TODO(dcarney): remove before cutover | |
| 350 V8_INLINE(static Handle<T> New(Isolate* isolate, const Persistent<T>& that)) { | 321 V8_INLINE(static Handle<T> New(Isolate* isolate, const Persistent<T>& that)) { |
| 351 return New(isolate, that.val_); | 322 return New(isolate, that.val_); |
| 352 } | 323 } |
| 353 | 324 |
| 325 // TODO(dcarney): better name |
| 326 // TODO(dcarney): implement |
| 327 // This is a useful helper function for managing resources tied to |
| 328 // a handle dynamically |
| 329 template<class P> |
| 330 void WeakBind(Isolate* isolate, |
| 331 P* parameter, |
| 332 void (*WeakBindFunction)(Isolate* isolate, P* parameter)); |
| 333 |
| 354 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR | 334 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR |
| 355 | 335 |
| 356 private: | 336 private: |
| 357 #endif | 337 #endif |
| 358 /** | 338 /** |
| 359 * Creates a new handle for the specified value. | 339 * Creates a new handle for the specified value. |
| 360 */ | 340 */ |
| 361 V8_INLINE(explicit Handle(T* val)) : val_(val) {} | 341 V8_INLINE(explicit Handle(T* val)) : val_(val) {} |
| 362 #endif | |
| 363 | 342 |
| 364 private: | 343 private: |
| 365 friend class Utils; | 344 friend class Utils; |
| 366 template<class F> friend class Persistent; | 345 template<class F, class M> friend class Persistent; |
| 367 template<class F> friend class Local; | 346 template<class F> friend class Local; |
| 368 friend class Arguments; | 347 friend class Arguments; |
| 369 template<class F> friend class FunctionCallbackInfo; | 348 template<class F> friend class FunctionCallbackInfo; |
| 370 template<class F> friend class PropertyCallbackInfo; | 349 template<class F> friend class PropertyCallbackInfo; |
| 371 template<class F> friend class internal::CustomArguments; | 350 template<class F> friend class internal::CustomArguments; |
| 372 friend class AccessorInfo; | 351 friend class AccessorInfo; |
| 373 friend Handle<Primitive> Undefined(Isolate* isolate); | 352 friend Handle<Primitive> Undefined(Isolate* isolate); |
| 374 friend Handle<Primitive> Null(Isolate* isolate); | 353 friend Handle<Primitive> Null(Isolate* isolate); |
| 375 friend Handle<Boolean> True(Isolate* isolate); | 354 friend Handle<Boolean> True(Isolate* isolate); |
| 376 friend Handle<Boolean> False(Isolate* isolate); | 355 friend Handle<Boolean> False(Isolate* isolate); |
| 377 friend class Context; | 356 friend class Context; |
| 378 friend class HandleScope; | 357 friend class HandleScope; |
| 379 | 358 |
| 380 #ifndef V8_USE_UNSAFE_HANDLES | |
| 381 V8_INLINE(static Handle<T> New(Isolate* isolate, T* that)); | 359 V8_INLINE(static Handle<T> New(Isolate* isolate, T* that)); |
| 382 #endif | |
| 383 | 360 |
| 384 T* val_; | 361 T* val_; |
| 385 }; | 362 }; |
| 386 | 363 |
| 387 | 364 |
| 388 /** | 365 /** |
| 389 * A light-weight stack-allocated object handle. All operations | 366 * A light-weight stack-allocated object handle. All operations |
| 390 * that return objects from within v8 return them in local handles. They | 367 * that return objects from within v8 return them in local handles. They |
| 391 * are created within HandleScopes, and all local handles allocated within a | 368 * are created within HandleScopes, and all local handles allocated within a |
| 392 * handle scope are destroyed when the handle scope is destroyed. Hence it | 369 * handle scope are destroyed when the handle scope is destroyed. Hence it |
| 393 * is not necessary to explicitly deallocate local handles. | 370 * is not necessary to explicitly deallocate local handles. |
| 394 */ | 371 */ |
| 395 // TODO(dcarney): deprecate entire class | 372 // TODO(dcarney): deprecate entire class |
| 396 template <class T> class Local : public Handle<T> { | 373 template <class T> class Local : public Handle<T> { |
| 397 public: | 374 public: |
| 398 V8_INLINE(Local()); | 375 V8_INLINE(Local()); |
| 399 template <class S> V8_INLINE(Local(Local<S> that)) | 376 template <class S> V8_INLINE(Local(Local<S> that)) |
| 400 : Handle<T>(reinterpret_cast<T*>(*that)) { | 377 : Handle<T>(reinterpret_cast<T*>(*that)) { |
| 401 /** | 378 /** |
| 402 * This check fails when trying to convert between incompatible | 379 * This check fails when trying to convert between incompatible |
| 403 * handles. For example, converting from a Handle<String> to a | 380 * handles. For example, converting from a Handle<String> to a |
| 404 * Handle<Number>. | 381 * Handle<Number>. |
| 405 */ | 382 */ |
| 406 TYPE_CHECK(T, S); | 383 TYPE_CHECK(T, S); |
| 407 } | 384 } |
| 408 | 385 |
| 409 | 386 |
| 410 #ifdef V8_USE_UNSAFE_HANDLES | |
| 411 template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { } | |
| 412 #endif | |
| 413 | |
| 414 template <class S> V8_INLINE(static Local<T> Cast(Local<S> that)) { | 387 template <class S> V8_INLINE(static Local<T> Cast(Local<S> that)) { |
| 415 #ifdef V8_ENABLE_CHECKS | 388 #ifdef V8_ENABLE_CHECKS |
| 416 // If we're going to perform the type check then we have to check | 389 // If we're going to perform the type check then we have to check |
| 417 // that the handle isn't empty before doing the checked cast. | 390 // that the handle isn't empty before doing the checked cast. |
| 418 if (that.IsEmpty()) return Local<T>(); | 391 if (that.IsEmpty()) return Local<T>(); |
| 419 #endif | 392 #endif |
| 420 return Local<T>(T::Cast(*that)); | 393 return Local<T>(T::Cast(*that)); |
| 421 } | 394 } |
| 422 #ifndef V8_USE_UNSAFE_HANDLES | |
| 423 template <class S> V8_INLINE(Local(Handle<S> that)) | 395 template <class S> V8_INLINE(Local(Handle<S> that)) |
| 424 : Handle<T>(reinterpret_cast<T*>(*that)) { | 396 : Handle<T>(reinterpret_cast<T*>(*that)) { |
| 425 TYPE_CHECK(T, S); | 397 TYPE_CHECK(T, S); |
| 426 } | 398 } |
| 427 #endif | |
| 428 | 399 |
| 429 template <class S> V8_INLINE(Local<S> As()) { | 400 template <class S> V8_INLINE(Local<S> As()) { |
| 430 return Local<S>::Cast(*this); | 401 return Local<S>::Cast(*this); |
| 431 } | 402 } |
| 432 | 403 |
| 433 /** | 404 /** |
| 434 * Create a local handle for the content of another handle. | 405 * Create a local handle for the content of another handle. |
| 435 * The referee is kept alive by the local handle even when | 406 * The referee is kept alive by the local handle even when |
| 436 * the original handle is destroyed/disposed. | 407 * the original handle is destroyed/disposed. |
| 437 */ | 408 */ |
| 438 V8_INLINE(static Local<T> New(Handle<T> that)); | 409 V8_INLINE(static Local<T> New(Handle<T> that)); |
| 439 V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that)); | 410 V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that)); |
| 440 #ifndef V8_USE_UNSAFE_HANDLES | 411 template<class M> |
| 441 // TODO(dcarney): remove before cutover | 412 V8_INLINE(static Local<T> New(Isolate* isolate, |
| 442 V8_INLINE(static Local<T> New(Isolate* isolate, const Persistent<T>& that)); | 413 const Persistent<T, M>& that)); |
| 443 | 414 |
| 444 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR | 415 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR |
| 445 | 416 |
| 446 private: | 417 private: |
| 447 #endif | 418 #endif |
| 448 template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { } | 419 template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { } |
| 449 #endif | |
| 450 | 420 |
| 451 private: | 421 private: |
| 452 friend class Utils; | 422 friend class Utils; |
| 453 template<class F> friend class Persistent; | 423 template<class F, class M> friend class Persistent; |
| 454 template<class F> friend class Handle; | 424 template<class F> friend class Handle; |
| 455 friend class Arguments; | 425 friend class Arguments; |
| 456 template<class F> friend class FunctionCallbackInfo; | 426 template<class F> friend class FunctionCallbackInfo; |
| 457 template<class F> friend class PropertyCallbackInfo; | 427 template<class F> friend class PropertyCallbackInfo; |
| 458 friend class String; | 428 friend class String; |
| 459 friend class Object; | 429 friend class Object; |
| 460 friend class AccessorInfo; | 430 friend class AccessorInfo; |
| 461 friend class Context; | 431 friend class Context; |
| 462 template<class F> friend class internal::CustomArguments; | 432 template<class F> friend class internal::CustomArguments; |
| 463 friend class HandleScope; | 433 friend class HandleScope; |
| 464 | 434 |
| 465 V8_INLINE(static Local<T> New(Isolate* isolate, T* that)); | 435 V8_INLINE(static Local<T> New(Isolate* isolate, T* that)); |
| 466 }; | 436 }; |
| 467 | 437 |
| 468 /** | 438 |
| 469 * An object reference that is independent of any handle scope. Where | 439 // TODO(dcarney): better name |
| 470 * a Local handle only lives as long as the HandleScope in which it was | 440 template<class P> |
| 471 * allocated, a Persistent handle remains valid until it is explicitly | 441 class PersistentData { |
| 472 * disposed. | |
| 473 * | |
| 474 * A persistent handle contains a reference to a storage cell within | |
| 475 * the v8 engine which holds an object value and which is updated by | |
| 476 * the garbage collector whenever the object is moved. A new storage | |
| 477 * cell can be created using Persistent::New and existing handles can | |
| 478 * be disposed using Persistent::Dispose. Since persistent handles | |
| 479 * are passed by value you may have many persistent handle objects | |
| 480 * that point to the same storage cell. For instance, if you pass a | |
| 481 * persistent handle as an argument to a function you will not get two | |
| 482 * different storage cells but rather two references to the same | |
| 483 * storage cell. | |
| 484 */ | |
| 485 template <class T> class Persistent // NOLINT | |
| 486 #ifdef V8_USE_UNSAFE_HANDLES | |
| 487 : public Handle<T> { | |
| 488 #else | |
| 489 { // NOLINT | |
| 490 #endif | |
| 491 public: | 442 public: |
| 492 #ifndef V8_USE_UNSAFE_HANDLES | 443 // TODO(dcarney): fill out implementation |
| 444 V8_INLINE(bool IsWeak()); |
| 445 V8_INLINE(bool IsIndependent()); |
| 446 V8_INLINE(P* GetParameter()); |
| 447 private: |
| 448 uint8_t flags_; |
| 449 P* parameter_; |
| 450 }; |
| 451 |
| 452 |
| 453 template<typename T, |
| 454 typename P, |
| 455 typename M = NonCopyablePersistentModifier<T, void> > |
| 456 class WeakReferenceCallbacks { |
| 457 public: |
| 458 typedef void (*Revivable)(Isolate* isolate, |
| 459 Persistent<T, M>* object, |
| 460 P* parameter); |
| 461 // TODO(dcarney): better name |
| 462 typedef void NewCallbackName(const WeakCallbackObject<T, P> &); |
| 463 }; |
| 464 |
| 465 |
| 466 // TODO(dcarney): better name |
| 467 template<class T, class P> |
| 468 class WeakCallbackObject { |
| 469 public: |
| 470 // TODO(dcarney): getters, make members private, etc |
| 471 Isolate* isolate_; |
| 472 // 'handle' for the persistent cell |
| 473 // stack allocated |
| 474 // not handle scoped |
| 475 Handle<T> handle_; |
| 476 const PersistentData<P>& data_; |
| 477 }; |
| 478 |
| 479 |
| 480 // TODO(dcarney): better name |
| 481 // this class should make persistent mimic current behaviour |
| 482 template<class T, class P> |
| 483 class NonCopyablePersistentModifier { |
| 484 typedef Persistent<T, NonCopyablePersistentModifier<T, P> > MyPersistent; |
| 485 // TODO(dcarney): come up with a good compile error here. |
| 486 template<class O> |
| 487 V8_INLINE(static void Uncompilable()) { |
| 488 TYPE_CHECK(O, Primitive); |
| 489 } |
| 490 |
| 491 public: |
| 492 typedef P WeakParameter; |
| 493 // This will be called on copy and assign |
| 494 // in the case the handle is non-empty |
| 495 V8_INLINE(static void Initialize(const PersistentData<P>& data, |
| 496 MyPersistent* persistent)) { |
| 497 Uncompilable<Object>(); |
| 498 } |
| 499 // This will be called on move constructors |
| 500 // in the case the handle is non-empty |
| 501 V8_INLINE(static void Move(P** parameter)) { |
| 502 Uncompilable<Object>(); |
| 503 } |
| 504 // TODO(dcarney): have a static WeakDispose that gc can check against |
| 505 // This will be called in the first sweep to determine if |
| 506 // the persistent can be disposed early |
| 507 static MyPersistent* WeakDispose(P* parameter) { |
| 508 return NULL; |
| 509 } |
| 510 // TODO(dcarney): remove this |
| 511 V8_INLINE(static bool AutoDispose()) { return false; } |
| 512 }; |
| 513 |
| 514 |
| 515 // TODO(dcarney): new comments |
| 516 // M is 'Modifier' - the templated class that |
| 517 // can deal with copying and moving the weak parameter |
| 518 template <class T, class M> class Persistent { |
| 519 public: |
| 520 typedef typename M::WeakParameter WeakParameter; |
| 521 // normal constructors |
| 493 V8_INLINE(Persistent()) : val_(0) { } | 522 V8_INLINE(Persistent()) : val_(0) { } |
| 494 // TODO(dcarney): add this back before cutover. | |
| 495 // V8_INLINE(~Persistent()) { | |
| 496 // Dispose(); | |
| 497 // } | |
| 498 V8_INLINE(bool IsEmpty() const) { return val_ == 0; } | |
| 499 // TODO(dcarney): remove somehow before cutover | |
| 500 // The handle should either be 0, or a pointer to a live cell. | |
| 501 V8_INLINE(void Clear()) { val_ = 0; } | |
| 502 | |
| 503 /** | |
| 504 * A constructor that creates a new global cell pointing to that. In contrast | |
| 505 * to the copy constructor, this creates a new persistent handle which needs | |
| 506 * to be separately disposed. | |
| 507 */ | |
| 508 template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that)) | 523 template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that)) |
| 509 : val_(New(isolate, *that)) { } | 524 : val_(New(isolate, *that)) { } |
| 510 | 525 template <class S, class M2> |
| 511 template <class S> V8_INLINE(Persistent(Isolate* isolate, | 526 V8_INLINE(Persistent(Isolate* isolate, |
| 512 Persistent<S>& that)) // NOLINT | 527 const Persistent<S, M2>& that)) |
| 513 : val_(New(isolate, *that)) { } | 528 : val_(New(that)) { } |
| 514 | 529 // destructor |
| 515 #else | 530 V8_INLINE(~Persistent()) { |
| 516 /** | 531 // TODO(dcarney): Remove this check. Always dispose. |
| 517 * Creates an empty persistent handle that doesn't point to any | 532 if (M::AutoDispose()) Reset(); |
| 518 * storage cell. | 533 } |
| 519 */ | 534 // copy and assign operators |
| 520 V8_INLINE(Persistent()) : Handle<T>() { } | 535 // Duplicate the storage cell and reinitialize |
| 521 | 536 V8_INLINE(Persistent(const Persistent& that)) : val_(0) { |
| 522 /** | 537 Copy(that); |
| 523 * Creates a persistent handle for the same storage cell as the | 538 } |
| 524 * specified handle. This constructor allows you to pass persistent | 539 V8_INLINE(Persistent& operator=(const Persistent& that)) { // NOLINT |
| 525 * handles as arguments by value and to assign between persistent | 540 Copy(that); |
| 526 * handles. However, attempting to assign between incompatible | 541 return *this; |
| 527 * persistent handles, for instance from a Persistent<String> to a | |
| 528 * Persistent<Number> will cause a compile-time error. Assigning | |
| 529 * between compatible persistent handles, for instance assigning a | |
| 530 * Persistent<String> to a variable declared as Persistent<Value>, | |
| 531 * is allowed as String is a subclass of Value. | |
| 532 */ | |
| 533 template <class S> V8_INLINE(Persistent(Persistent<S> that)) | |
| 534 : Handle<T>(reinterpret_cast<T*>(*that)) { | |
| 535 /** | |
| 536 * This check fails when trying to convert between incompatible | |
| 537 * handles. For example, converting from a Handle<String> to a | |
| 538 * Handle<Number>. | |
| 539 */ | |
| 540 TYPE_CHECK(T, S); | |
| 541 } | 542 } |
| 542 | 543 |
| 543 template <class S> V8_INLINE(Persistent(S* that)) : Handle<T>(that) { } | 544 // TODO(dcarney): move into private section at bottom |
| 545 private: |
| 546 template<class S, class M2> |
| 547 V8_INLINE(void Copy(const Persistent<S, M2>& that)) { |
| 548 // TODO(dcarney): New and Copy can be one function |
| 549 this->val_ = New(that); |
| 550 if (this->val_ == NULL) return; |
| 551 const PersistentData<typename M2::WeakParameter>& data = that.GetData(); |
| 552 M::template Initialize<typename M2::WeakParameter>(data, this); |
| 553 } |
| 554 template<class S, class M2> |
| 555 V8_INLINE(static T* New(const Persistent<S, M2>& that)); |
| 556 // TODO(dcarney): implement |
| 557 // maybe this can return a reference into |
| 558 // part of GlobalHandle::Node |
| 559 // it needs to be inlined, and preferably pretty fast |
| 560 const PersistentData<WeakParameter>& GetData(); |
| 544 | 561 |
| 562 public: |
| 545 /** | 563 /** |
| 546 * A constructor that creates a new global cell pointing to that. In contrast | 564 * Disposes the current contents of the handle and replaces it. |
| 547 * to the copy constructor, this creates a new persistent handle which needs | |
| 548 * to be separately disposed. | |
| 549 */ | 565 */ |
| 550 template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that)) | 566 V8_INLINE(void Reset()) { |
| 551 : Handle<T>(New(isolate, that)) { } | 567 Dispose(); |
| 568 } |
| 569 V8_INLINE(void Reset(Isolate* isolate, const Handle<T>& other)); |
| 570 template <class M2> |
| 571 V8_INLINE(void Reset(Isolate* isolate, const Persistent<T, M2>& other)); |
| 572 // TODO(dcarney): deprecate |
| 573 V8_INLINE(void Dispose()); |
| 574 // TODO(dcarney): deprecate |
| 575 V8_INLINE(void Dispose(Isolate* isolate)) { Dispose(); } |
| 552 | 576 |
| 553 /** | 577 V8_INLINE(bool IsEmpty() const) { return val_ == 0; } |
| 554 * "Casts" a plain handle which is known to be a persistent handle | |
| 555 * to a persistent handle. | |
| 556 */ | |
| 557 template <class S> explicit V8_INLINE(Persistent(Handle<S> that)) | |
| 558 : Handle<T>(*that) { } | |
| 559 | 578 |
| 560 #endif | 579 // TODO(dcarney): this is pretty useless, fix or remove |
| 561 | 580 template <class S> |
| 562 #ifdef V8_USE_UNSAFE_HANDLES | 581 static V8_INLINE(Persistent<T>& Cast(Persistent<S>& that)) { // NOLINT |
| 563 template <class S> V8_INLINE(static Persistent<T> Cast(Persistent<S> that)) { | |
| 564 #ifdef V8_ENABLE_CHECKS | 582 #ifdef V8_ENABLE_CHECKS |
| 565 // If we're going to perform the type check then we have to check | 583 // If we're going to perform the type check then we have to check |
| 566 // that the handle isn't empty before doing the checked cast. | 584 // that the handle isn't empty before doing the checked cast. |
| 567 if (that.IsEmpty()) return Persistent<T>(); | |
| 568 #endif | |
| 569 return Persistent<T>(T::Cast(*that)); | |
| 570 } | |
| 571 | |
| 572 template <class S> V8_INLINE(Persistent<S> As()) { | |
| 573 return Persistent<S>::Cast(*this); | |
| 574 } | |
| 575 | |
| 576 #else | |
| 577 template <class S> | |
| 578 V8_INLINE(static Persistent<T>& Cast(Persistent<S>& that)) { // NOLINT | |
| 579 #ifdef V8_ENABLE_CHECKS | |
| 580 // If we're going to perform the type check then we have to check | |
| 581 // that the handle isn't empty before doing the checked cast. | |
| 582 if (!that.IsEmpty()) T::Cast(*that); | 585 if (!that.IsEmpty()) T::Cast(*that); |
| 583 #endif | 586 #endif |
| 584 return reinterpret_cast<Persistent<T>&>(that); | 587 return reinterpret_cast<Persistent<T>&>(that); |
| 585 } | 588 } |
| 586 | 589 |
| 590 // TODO(dcarney): this is pretty useless, fix or remove |
| 587 template <class S> V8_INLINE(Persistent<S>& As()) { // NOLINT | 591 template <class S> V8_INLINE(Persistent<S>& As()) { // NOLINT |
| 588 return Persistent<S>::Cast(*this); | 592 return Persistent<S>::Cast(*this); |
| 589 } | 593 } |
| 590 #endif | |
| 591 | 594 |
| 592 #ifdef V8_USE_UNSAFE_HANDLES | 595 template <class S, class M2> V8_INLINE( |
| 593 V8_DEPRECATED(static Persistent<T> New(Handle<T> that)); | 596 bool operator==(const Persistent<S, M2>& that) const) { |
| 594 V8_INLINE(static Persistent<T> New(Isolate* isolate, Handle<T> that)); | |
| 595 V8_INLINE(static Persistent<T> New(Isolate* isolate, Persistent<T> that)); | |
| 596 #endif | |
| 597 | |
| 598 #ifndef V8_USE_UNSAFE_HANDLES | |
| 599 template <class S> V8_INLINE( | |
| 600 bool operator==(const Persistent<S>& that) const) { | |
| 601 internal::Object** a = reinterpret_cast<internal::Object**>(**this); | 597 internal::Object** a = reinterpret_cast<internal::Object**>(**this); |
| 602 internal::Object** b = reinterpret_cast<internal::Object**>(*that); | 598 internal::Object** b = reinterpret_cast<internal::Object**>(*that); |
| 603 if (a == 0) return b == 0; | 599 if (a == 0) return b == 0; |
| 604 if (b == 0) return false; | 600 if (b == 0) return false; |
| 605 return *a == *b; | 601 return *a == *b; |
| 606 } | 602 } |
| 607 | 603 |
| 608 template <class S> V8_INLINE(bool operator==(const Handle<S> that) const) { | 604 template <class S> |
| 605 V8_INLINE(bool operator==(const Handle<S> that) const) { |
| 609 internal::Object** a = reinterpret_cast<internal::Object**>(**this); | 606 internal::Object** a = reinterpret_cast<internal::Object**>(**this); |
| 610 internal::Object** b = reinterpret_cast<internal::Object**>(*that); | 607 internal::Object** b = reinterpret_cast<internal::Object**>(*that); |
| 611 if (a == 0) return b == 0; | 608 if (a == 0) return b == 0; |
| 612 if (b == 0) return false; | 609 if (b == 0) return false; |
| 613 return *a == *b; | 610 return *a == *b; |
| 614 } | 611 } |
| 615 #endif | |
| 616 | 612 |
| 617 V8_INLINE(void Dispose()); | 613 // New weak callbacks |
| 614 // must be able to static_cast P into P2 |
| 615 // TODO(dcarney): implement |
| 616 template<typename P2> |
| 617 V8_INLINE(void MakeWeak( |
| 618 P2* parameters, |
| 619 typename WeakReferenceCallbacks<T, P2>::NewCallbackName callback)); |
| 618 | 620 |
| 619 /** | 621 // Use a weak callback defined in M |
| 620 * Releases the storage cell referenced by this persistent handle. | 622 V8_INLINE(void MakeWeak(WeakParameter* parameters)) { |
| 621 * Does not remove the reference to the cell from any handles. | 623 MakeWeak<WeakParameter>(parameters, M::WeakCallback); |
| 622 * This handle's reference, and any other references to the storage | 624 } |
| 623 * cell remain and IsEmpty will still return false. | 625 |
| 624 */ | 626 // must be able to static_cast P into P2 |
| 625 // TODO(dcarney): deprecate | 627 // TODO(dcarney): deprecate |
| 626 V8_INLINE(void Dispose(Isolate* isolate)) { Dispose(); } | 628 template<typename S, typename P2> |
| 629 V8_INLINE(void MakeWeak( |
| 630 P2* parameters, |
| 631 typename WeakReferenceCallbacks<S, P2>::Revivable callback)); |
| 627 | 632 |
| 628 /** | 633 // must be able to static_cast P into P2 |
| 629 * Make the reference to this object weak. When only weak handles | 634 // TODO(dcarney): deprecate |
| 630 * refer to the object, the garbage collector will perform a | 635 template<typename P2> |
| 631 * callback to the given V8::NearDeathCallback function, passing | |
| 632 * it the object reference and the given parameters. | |
| 633 */ | |
| 634 template<typename S, typename P> | |
| 635 V8_INLINE(void MakeWeak( | 636 V8_INLINE(void MakeWeak( |
| 636 P* parameters, | 637 P2* parameters, |
| 637 typename WeakReferenceCallbacks<S, P>::Revivable callback)); | 638 typename WeakReferenceCallbacks<T, P2>::Revivable callback)); |
| 638 | 639 |
| 639 template<typename P> | 640 template<typename S, typename P2> |
| 640 V8_INLINE(void MakeWeak( | |
| 641 P* parameters, | |
| 642 typename WeakReferenceCallbacks<T, P>::Revivable callback)); | |
| 643 | |
| 644 template<typename S, typename P> | |
| 645 V8_DEPRECATED(void MakeWeak( | 641 V8_DEPRECATED(void MakeWeak( |
| 646 Isolate* isolate, | 642 Isolate* isolate, |
| 647 P* parameters, | 643 P2* parameters, |
| 648 typename WeakReferenceCallbacks<S, P>::Revivable callback)); | 644 typename WeakReferenceCallbacks<S, P2>::Revivable callback)); |
| 649 | 645 |
| 650 template<typename P> | 646 template<typename P2> |
| 651 V8_DEPRECATED(void MakeWeak( | 647 V8_DEPRECATED(void MakeWeak( |
| 652 Isolate* isolate, | 648 Isolate* isolate, |
| 653 P* parameters, | 649 P2* parameters, |
| 654 typename WeakReferenceCallbacks<T, P>::Revivable callback)); | 650 typename WeakReferenceCallbacks<T, P2>::Revivable callback)); |
| 655 | 651 |
| 656 V8_INLINE(void ClearWeak()); | 652 V8_INLINE(void ClearWeak()); |
| 657 | 653 |
| 658 // TODO(dcarney): deprecate | 654 // TODO(dcarney): deprecate |
| 659 V8_INLINE(void ClearWeak(Isolate* isolate)) { ClearWeak(); } | 655 V8_INLINE(void ClearWeak(Isolate* isolate)) { ClearWeak(); } |
| 660 | 656 |
| 661 /** | 657 /** |
| 662 * Marks the reference to this object independent. Garbage collector is free | 658 * Marks the reference to this object independent. Garbage collector is free |
| 663 * to ignore any object groups containing this object. Weak callback for an | 659 * to ignore any object groups containing this object. Weak callback for an |
| 664 * independent handle should not assume that it will be preceded by a global | 660 * independent handle should not assume that it will be preceded by a global |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 * Returns the class ID previously assigned to this handle or 0 if no class ID | 714 * Returns the class ID previously assigned to this handle or 0 if no class ID |
| 719 * was previously assigned. | 715 * was previously assigned. |
| 720 */ | 716 */ |
| 721 V8_INLINE(uint16_t WrapperClassId() const); | 717 V8_INLINE(uint16_t WrapperClassId() const); |
| 722 | 718 |
| 723 // TODO(dcarney): deprecate | 719 // TODO(dcarney): deprecate |
| 724 V8_INLINE(uint16_t WrapperClassId(Isolate* isolate) const) { | 720 V8_INLINE(uint16_t WrapperClassId(Isolate* isolate) const) { |
| 725 return WrapperClassId(); | 721 return WrapperClassId(); |
| 726 } | 722 } |
| 727 | 723 |
| 728 /** | 724 // TODO(dcarney): remove |
| 729 * Disposes the current contents of the handle and replaces it. | |
| 730 */ | |
| 731 V8_INLINE(void Reset(Isolate* isolate, const Handle<T>& other)); | |
| 732 | |
| 733 #ifndef V8_USE_UNSAFE_HANDLES | |
| 734 V8_INLINE(void Reset(Isolate* isolate, const Persistent<T>& other)); | |
| 735 #endif | |
| 736 | |
| 737 /** | |
| 738 * Returns the underlying raw pointer and clears the handle. The caller is | |
| 739 * responsible of eventually destroying the underlying object (by creating a | |
| 740 * Persistent handle which points to it and Disposing it). In the future, | |
| 741 * destructing a Persistent will also Dispose it. With this function, the | |
| 742 * embedder can let the Persistent go out of scope without it getting | |
| 743 * disposed. | |
| 744 */ | |
| 745 V8_INLINE(T* ClearAndLeak()); | 725 V8_INLINE(T* ClearAndLeak()); |
| 746 | 726 |
| 747 #ifndef V8_USE_UNSAFE_HANDLES | 727 // TODO(dcarney) make private or remove |
| 728 // Only the garbage collector should do this, |
| 729 // and it can just change val_ directly |
| 730 // could temporarily just assert that the node is disposed |
| 731 V8_INLINE(void Clear()) { val_ = 0; } |
| 748 | 732 |
| 749 private: | 733 // TODO(dcarney): remove need for this in chrome |
| 750 // TODO(dcarney): make unlinkable before cutover | |
| 751 V8_INLINE(Persistent(const Persistent& that)) : val_(that.val_) {} | |
| 752 // TODO(dcarney): make unlinkable before cutover | |
| 753 V8_INLINE(Persistent& operator=(const Persistent& that)) { // NOLINT | |
| 754 this->val_ = that.val_; | |
| 755 return *this; | |
| 756 } | |
| 757 | |
| 758 public: | |
| 759 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR | 734 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR |
| 760 | 735 |
| 761 private: | 736 private: |
| 762 #endif | 737 #endif |
| 763 // TODO(dcarney): remove before cutover | |
| 764 template <class S> V8_INLINE(Persistent(S* that)) : val_(that) { } | 738 template <class S> V8_INLINE(Persistent(S* that)) : val_(that) { } |
| 765 | 739 |
| 766 // TODO(dcarney): remove before cutover | |
| 767 V8_INLINE(T* operator*() const) { return val_; } | 740 V8_INLINE(T* operator*() const) { return val_; } |
| 768 | 741 |
| 769 private: | 742 private: |
| 770 // TODO(dcarney): remove before cutover | |
| 771 V8_INLINE(T* operator->() const) { return val_; } | |
| 772 public: | |
| 773 #endif | |
| 774 | |
| 775 private: | |
| 776 friend class Utils; | 743 friend class Utils; |
| 777 template<class F> friend class Handle; | 744 template<class F> friend class Handle; |
| 778 template<class F> friend class Local; | 745 template<class F> friend class Local; |
| 779 template<class F> friend class Persistent; | 746 template<class F1, class F2> friend class Persistent; |
| 780 template<class F> friend class ReturnValue; | 747 template<class F> friend class ReturnValue; |
| 781 | 748 |
| 782 V8_INLINE(static T* New(Isolate* isolate, T* that)); | 749 V8_INLINE(static T* New(Isolate* isolate, T* that)); |
| 783 | 750 |
| 784 #ifndef V8_USE_UNSAFE_HANDLES | |
| 785 T* val_; | 751 T* val_; |
| 786 #endif | |
| 787 }; | 752 }; |
| 788 | 753 |
| 789 | |
| 790 /** | 754 /** |
| 791 * A stack-allocated class that governs a number of local handles. | 755 * A stack-allocated class that governs a number of local handles. |
| 792 * After a handle scope has been created, all local handles will be | 756 * After a handle scope has been created, all local handles will be |
| 793 * allocated within that handle scope until either the handle scope is | 757 * allocated within that handle scope until either the handle scope is |
| 794 * deleted or another handle scope is created. If there is already a | 758 * deleted or another handle scope is created. If there is already a |
| 795 * handle scope and a new one is created, all allocations will take | 759 * handle scope and a new one is created, all allocations will take |
| 796 * place in the new handle scope until it is deleted. After that, | 760 * place in the new handle scope until it is deleted. After that, |
| 797 * new handles will again be allocated in the original handle scope. | 761 * new handles will again be allocated in the original handle scope. |
| 798 * | 762 * |
| 799 * After the handle scope of a local handle has been deleted the | 763 * After the handle scope of a local handle has been deleted the |
| (...skipping 3823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4623 internal::Object** handle); | 4587 internal::Object** handle); |
| 4624 static void DisposeGlobal(internal::Object** global_handle); | 4588 static void DisposeGlobal(internal::Object** global_handle); |
| 4625 typedef WeakReferenceCallbacks<Value, void>::Revivable RevivableCallback; | 4589 typedef WeakReferenceCallbacks<Value, void>::Revivable RevivableCallback; |
| 4626 static void MakeWeak(internal::Object** global_handle, | 4590 static void MakeWeak(internal::Object** global_handle, |
| 4627 void* data, | 4591 void* data, |
| 4628 RevivableCallback weak_reference_callback); | 4592 RevivableCallback weak_reference_callback); |
| 4629 static void ClearWeak(internal::Object** global_handle); | 4593 static void ClearWeak(internal::Object** global_handle); |
| 4630 | 4594 |
| 4631 template <class T> friend class Handle; | 4595 template <class T> friend class Handle; |
| 4632 template <class T> friend class Local; | 4596 template <class T> friend class Local; |
| 4633 template <class T> friend class Persistent; | 4597 template <class T, class M> friend class Persistent; |
| 4634 friend class Context; | 4598 friend class Context; |
| 4635 }; | 4599 }; |
| 4636 | 4600 |
| 4637 | 4601 |
| 4638 /** | 4602 /** |
| 4639 * An external exception handler. | 4603 * An external exception handler. |
| 4640 */ | 4604 */ |
| 4641 class V8EXPORT TryCatch { | 4605 class V8EXPORT TryCatch { |
| 4642 public: | 4606 public: |
| 4643 /** | 4607 /** |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4961 * Stack-allocated class which sets the execution context for all | 4925 * Stack-allocated class which sets the execution context for all |
| 4962 * operations executed within a local scope. | 4926 * operations executed within a local scope. |
| 4963 */ | 4927 */ |
| 4964 class Scope { | 4928 class Scope { |
| 4965 public: | 4929 public: |
| 4966 explicit V8_INLINE(Scope(Handle<Context> context)) : context_(context) { | 4930 explicit V8_INLINE(Scope(Handle<Context> context)) : context_(context) { |
| 4967 context_->Enter(); | 4931 context_->Enter(); |
| 4968 } | 4932 } |
| 4969 // TODO(dcarney): deprecate | 4933 // TODO(dcarney): deprecate |
| 4970 V8_INLINE(Scope(Isolate* isolate, Persistent<Context>& context)) // NOLINT | 4934 V8_INLINE(Scope(Isolate* isolate, Persistent<Context>& context)) // NOLINT |
| 4971 #ifndef V8_USE_UNSAFE_HANDLES | |
| 4972 : context_(Handle<Context>::New(isolate, context)) { | 4935 : context_(Handle<Context>::New(isolate, context)) { |
| 4973 #else | |
| 4974 : context_(Local<Context>::New(isolate, context)) { | |
| 4975 #endif | |
| 4976 context_->Enter(); | 4936 context_->Enter(); |
| 4977 } | 4937 } |
| 4978 V8_INLINE(~Scope()) { context_->Exit(); } | 4938 V8_INLINE(~Scope()) { context_->Exit(); } |
| 4979 | 4939 |
| 4980 private: | 4940 private: |
| 4981 Handle<Context> context_; | 4941 Handle<Context> context_; |
| 4982 }; | 4942 }; |
| 4983 | 4943 |
| 4984 private: | 4944 private: |
| 4985 friend class Value; | 4945 friend class Value; |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5451 } | 5411 } |
| 5452 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p))); | 5412 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p))); |
| 5453 } | 5413 } |
| 5454 | 5414 |
| 5455 | 5415 |
| 5456 template <class T> | 5416 template <class T> |
| 5457 Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) { | 5417 Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) { |
| 5458 return New(isolate, that.val_); | 5418 return New(isolate, that.val_); |
| 5459 } | 5419 } |
| 5460 | 5420 |
| 5461 #ifndef V8_USE_UNSAFE_HANDLES | |
| 5462 template <class T> | 5421 template <class T> |
| 5463 Local<T> Local<T>::New(Isolate* isolate, const Persistent<T>& that) { | 5422 template <class M> |
| 5423 Local<T> Local<T>::New(Isolate* isolate, const Persistent<T, M>& that) { |
| 5464 return New(isolate, that.val_); | 5424 return New(isolate, that.val_); |
| 5465 } | 5425 } |
| 5466 | 5426 |
| 5467 template <class T> | 5427 template <class T> |
| 5468 Handle<T> Handle<T>::New(Isolate* isolate, T* that) { | 5428 Handle<T> Handle<T>::New(Isolate* isolate, T* that) { |
| 5469 if (that == NULL) return Handle<T>(); | 5429 if (that == NULL) return Handle<T>(); |
| 5470 T* that_ptr = that; | 5430 T* that_ptr = that; |
| 5471 internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); | 5431 internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); |
| 5472 return Handle<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( | 5432 return Handle<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( |
| 5473 reinterpret_cast<internal::Isolate*>(isolate), *p))); | 5433 reinterpret_cast<internal::Isolate*>(isolate), *p))); |
| 5474 } | 5434 } |
| 5475 #endif | |
| 5476 | 5435 |
| 5477 | 5436 |
| 5478 template <class T> | 5437 template <class T> |
| 5479 Local<T> Local<T>::New(Isolate* isolate, T* that) { | 5438 Local<T> Local<T>::New(Isolate* isolate, T* that) { |
| 5480 if (that == NULL) return Local<T>(); | 5439 if (that == NULL) return Local<T>(); |
| 5481 T* that_ptr = that; | 5440 T* that_ptr = that; |
| 5482 internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); | 5441 internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); |
| 5483 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( | 5442 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( |
| 5484 reinterpret_cast<internal::Isolate*>(isolate), *p))); | 5443 reinterpret_cast<internal::Isolate*>(isolate), *p))); |
| 5485 } | 5444 } |
| 5486 | 5445 |
| 5487 | 5446 |
| 5488 #ifdef V8_USE_UNSAFE_HANDLES | 5447 template <class T, class M> |
| 5489 template <class T> | 5448 T* Persistent<T, M>::New(Isolate* isolate, T* that) { |
| 5490 Persistent<T> Persistent<T>::New(Handle<T> that) { | |
| 5491 return New(Isolate::GetCurrent(), that.val_); | |
| 5492 } | |
| 5493 | |
| 5494 | |
| 5495 template <class T> | |
| 5496 Persistent<T> Persistent<T>::New(Isolate* isolate, Handle<T> that) { | |
| 5497 return New(Isolate::GetCurrent(), that.val_); | |
| 5498 } | |
| 5499 | |
| 5500 template <class T> | |
| 5501 Persistent<T> Persistent<T>::New(Isolate* isolate, Persistent<T> that) { | |
| 5502 return New(Isolate::GetCurrent(), that.val_); | |
| 5503 } | |
| 5504 #endif | |
| 5505 | |
| 5506 | |
| 5507 template <class T> | |
| 5508 T* Persistent<T>::New(Isolate* isolate, T* that) { | |
| 5509 if (that == NULL) return NULL; | 5449 if (that == NULL) return NULL; |
| 5510 internal::Object** p = reinterpret_cast<internal::Object**>(that); | 5450 internal::Object** p = reinterpret_cast<internal::Object**>(that); |
| 5511 return reinterpret_cast<T*>( | 5451 return reinterpret_cast<T*>( |
| 5512 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), | 5452 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), |
| 5513 p)); | 5453 p)); |
| 5514 } | 5454 } |
| 5515 | 5455 |
| 5516 | 5456 |
| 5517 template <class T> | 5457 template <class T, class M> |
| 5518 bool Persistent<T>::IsIndependent() const { | 5458 template<class S, class M2> |
| 5459 T* Persistent<T, M>::New(const Persistent<S, M2>& that) { |
| 5460 if (*that == NULL) return NULL; |
| 5461 // TODO(dcarney): implement this correctly, |
| 5462 // isolate is available in GlobalHandles::Node, get it from there |
| 5463 // This should not be like current new but should copy everything |
| 5464 // over |
| 5465 return New(Isolate::GetCurrent(), *that); |
| 5466 } |
| 5467 |
| 5468 |
| 5469 template <class T, class M> |
| 5470 bool Persistent<T, M>::IsIndependent() const { |
| 5519 typedef internal::Internals I; | 5471 typedef internal::Internals I; |
| 5520 if (this->IsEmpty()) return false; | 5472 if (this->IsEmpty()) return false; |
| 5521 return I::GetNodeFlag(reinterpret_cast<internal::Object**>(this->val_), | 5473 return I::GetNodeFlag(reinterpret_cast<internal::Object**>(this->val_), |
| 5522 I::kNodeIsIndependentShift); | 5474 I::kNodeIsIndependentShift); |
| 5523 } | 5475 } |
| 5524 | 5476 |
| 5525 | 5477 |
| 5526 template <class T> | 5478 template <class T, class M> |
| 5527 bool Persistent<T>::IsNearDeath() const { | 5479 bool Persistent<T, M>::IsNearDeath() const { |
| 5528 typedef internal::Internals I; | 5480 typedef internal::Internals I; |
| 5529 if (this->IsEmpty()) return false; | 5481 if (this->IsEmpty()) return false; |
| 5530 return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) == | 5482 return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) == |
| 5531 I::kNodeStateIsNearDeathValue; | 5483 I::kNodeStateIsNearDeathValue; |
| 5532 } | 5484 } |
| 5533 | 5485 |
| 5534 | 5486 |
| 5535 template <class T> | 5487 template <class T, class M> |
| 5536 bool Persistent<T>::IsWeak() const { | 5488 bool Persistent<T, M>::IsWeak() const { |
| 5537 typedef internal::Internals I; | 5489 typedef internal::Internals I; |
| 5538 if (this->IsEmpty()) return false; | 5490 if (this->IsEmpty()) return false; |
| 5539 return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) == | 5491 return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) == |
| 5540 I::kNodeStateIsWeakValue; | 5492 I::kNodeStateIsWeakValue; |
| 5541 } | 5493 } |
| 5542 | 5494 |
| 5543 | 5495 |
| 5544 template <class T> | 5496 template <class T, class M> |
| 5545 void Persistent<T>::Dispose() { | 5497 void Persistent<T, M>::Dispose() { |
| 5546 if (this->IsEmpty()) return; | 5498 if (this->IsEmpty()) return; |
| 5547 V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_)); | 5499 V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_)); |
| 5548 #ifndef V8_USE_UNSAFE_HANDLES | |
| 5549 val_ = 0; | 5500 val_ = 0; |
| 5550 #endif | |
| 5551 } | 5501 } |
| 5552 | 5502 |
| 5553 | 5503 |
| 5554 template <class T> | 5504 template <class T, class M> |
| 5555 template <typename S, typename P> | 5505 template <typename S, typename P> |
| 5556 void Persistent<T>::MakeWeak( | 5506 void Persistent<T, M>::MakeWeak( |
| 5557 P* parameters, | 5507 P* parameters, |
| 5558 typename WeakReferenceCallbacks<S, P>::Revivable callback) { | 5508 typename WeakReferenceCallbacks<S, P>::Revivable callback) { |
| 5559 TYPE_CHECK(S, T); | 5509 TYPE_CHECK(S, T); |
| 5560 typedef typename WeakReferenceCallbacks<Value, void>::Revivable Revivable; | 5510 typedef typename WeakReferenceCallbacks<Value, void>::Revivable Revivable; |
| 5561 V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_), | 5511 V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_), |
| 5562 parameters, | 5512 parameters, |
| 5563 reinterpret_cast<Revivable>(callback)); | 5513 reinterpret_cast<Revivable>(callback)); |
| 5564 } | 5514 } |
| 5565 | 5515 |
| 5566 | 5516 |
| 5567 template <class T> | 5517 template <class T, class M> |
| 5568 template <typename P> | 5518 template <typename P> |
| 5569 void Persistent<T>::MakeWeak( | 5519 void Persistent<T, M>::MakeWeak( |
| 5570 P* parameters, | 5520 P* parameters, |
| 5571 typename WeakReferenceCallbacks<T, P>::Revivable callback) { | 5521 typename WeakReferenceCallbacks<T, P>::Revivable callback) { |
| 5572 MakeWeak<T, P>(parameters, callback); | 5522 MakeWeak<T, P>(parameters, callback); |
| 5573 } | 5523 } |
| 5574 | 5524 |
| 5575 | 5525 |
| 5576 template <class T> | 5526 template <class T, class M> |
| 5577 template <typename S, typename P> | 5527 template <typename S, typename P> |
| 5578 void Persistent<T>::MakeWeak( | 5528 void Persistent<T, M>::MakeWeak( |
| 5579 Isolate* isolate, | 5529 Isolate* isolate, |
| 5580 P* parameters, | 5530 P* parameters, |
| 5581 typename WeakReferenceCallbacks<S, P>::Revivable callback) { | 5531 typename WeakReferenceCallbacks<S, P>::Revivable callback) { |
| 5582 MakeWeak<S, P>(parameters, callback); | 5532 MakeWeak<S, P>(parameters, callback); |
| 5583 } | 5533 } |
| 5584 | 5534 |
| 5585 | 5535 |
| 5586 template <class T> | 5536 template <class T, class M> |
| 5587 template<typename P> | 5537 template<typename P> |
| 5588 void Persistent<T>::MakeWeak( | 5538 void Persistent<T, M>::MakeWeak( |
| 5589 Isolate* isolate, | 5539 Isolate* isolate, |
| 5590 P* parameters, | 5540 P* parameters, |
| 5591 typename WeakReferenceCallbacks<T, P>::Revivable callback) { | 5541 typename WeakReferenceCallbacks<T, P>::Revivable callback) { |
| 5592 MakeWeak<P>(parameters, callback); | 5542 MakeWeak<P>(parameters, callback); |
| 5593 } | 5543 } |
| 5594 | 5544 |
| 5595 | 5545 |
| 5596 template <class T> | 5546 template <class T, class M> |
| 5597 void Persistent<T>::ClearWeak() { | 5547 void Persistent<T, M>::ClearWeak() { |
| 5598 V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)); | 5548 V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)); |
| 5599 } | 5549 } |
| 5600 | 5550 |
| 5601 | 5551 |
| 5602 template <class T> | 5552 template <class T, class M> |
| 5603 void Persistent<T>::MarkIndependent() { | 5553 void Persistent<T, M>::MarkIndependent() { |
| 5604 typedef internal::Internals I; | 5554 typedef internal::Internals I; |
| 5605 if (this->IsEmpty()) return; | 5555 if (this->IsEmpty()) return; |
| 5606 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), | 5556 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), |
| 5607 true, | 5557 true, |
| 5608 I::kNodeIsIndependentShift); | 5558 I::kNodeIsIndependentShift); |
| 5609 } | 5559 } |
| 5610 | 5560 |
| 5611 | 5561 |
| 5612 template <class T> | 5562 template <class T, class M> |
| 5613 void Persistent<T>::MarkPartiallyDependent() { | 5563 void Persistent<T, M>::MarkPartiallyDependent() { |
| 5614 typedef internal::Internals I; | 5564 typedef internal::Internals I; |
| 5615 if (this->IsEmpty()) return; | 5565 if (this->IsEmpty()) return; |
| 5616 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), | 5566 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), |
| 5617 true, | 5567 true, |
| 5618 I::kNodeIsPartiallyDependentShift); | 5568 I::kNodeIsPartiallyDependentShift); |
| 5619 } | 5569 } |
| 5620 | 5570 |
| 5621 | 5571 |
| 5622 template <class T> | 5572 template <class T, class M> |
| 5623 void Persistent<T>::Reset(Isolate* isolate, const Handle<T>& other) { | 5573 void Persistent<T, M>::Reset(Isolate* isolate, const Handle<T>& other) { |
| 5624 Dispose(isolate); | 5574 Dispose(); |
| 5625 #ifdef V8_USE_UNSAFE_HANDLES | |
| 5626 *this = *New(isolate, other); | |
| 5627 #else | |
| 5628 if (other.IsEmpty()) { | 5575 if (other.IsEmpty()) { |
| 5629 this->val_ = NULL; | 5576 this->val_ = NULL; |
| 5630 return; | 5577 return; |
| 5631 } | 5578 } |
| 5632 internal::Object** p = reinterpret_cast<internal::Object**>(other.val_); | 5579 internal::Object** p = reinterpret_cast<internal::Object**>(other.val_); |
| 5633 this->val_ = reinterpret_cast<T*>( | 5580 this->val_ = reinterpret_cast<T*>( |
| 5634 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p)); | 5581 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p)); |
| 5635 #endif | |
| 5636 } | 5582 } |
| 5637 | 5583 |
| 5638 | 5584 |
| 5639 #ifndef V8_USE_UNSAFE_HANDLES | 5585 template <class T, class M> |
| 5640 template <class T> | 5586 template <class M2> |
| 5641 void Persistent<T>::Reset(Isolate* isolate, const Persistent<T>& other) { | 5587 void Persistent<T, M>::Reset(Isolate* isolate, |
| 5588 const Persistent<T, M2>& other) { |
| 5642 Dispose(isolate); | 5589 Dispose(isolate); |
| 5643 if (other.IsEmpty()) { | 5590 if (other.IsEmpty()) { |
| 5644 this->val_ = NULL; | 5591 this->val_ = NULL; |
| 5645 return; | 5592 return; |
| 5646 } | 5593 } |
| 5647 internal::Object** p = reinterpret_cast<internal::Object**>(other.val_); | 5594 internal::Object** p = reinterpret_cast<internal::Object**>(other.val_); |
| 5648 this->val_ = reinterpret_cast<T*>( | 5595 this->val_ = reinterpret_cast<T*>( |
| 5649 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p)); | 5596 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p)); |
| 5650 } | 5597 } |
| 5651 #endif | |
| 5652 | 5598 |
| 5653 | 5599 |
| 5654 template <class T> | 5600 template <class T, class M> |
| 5655 T* Persistent<T>::ClearAndLeak() { | 5601 T* Persistent<T, M>::ClearAndLeak() { |
| 5656 T* old; | 5602 T* old; |
| 5657 #ifdef V8_USE_UNSAFE_HANDLES | |
| 5658 old = **this; | |
| 5659 *this = Persistent<T>(); | |
| 5660 #else | |
| 5661 old = val_; | 5603 old = val_; |
| 5662 val_ = NULL; | 5604 val_ = NULL; |
| 5663 #endif | |
| 5664 return old; | 5605 return old; |
| 5665 } | 5606 } |
| 5666 | 5607 |
| 5667 | 5608 |
| 5668 template <class T> | 5609 template <class T, class M> |
| 5669 void Persistent<T>::SetWrapperClassId(uint16_t class_id) { | 5610 void Persistent<T, M>::SetWrapperClassId(uint16_t class_id) { |
| 5670 typedef internal::Internals I; | 5611 typedef internal::Internals I; |
| 5671 if (this->IsEmpty()) return; | 5612 if (this->IsEmpty()) return; |
| 5672 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); | 5613 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); |
| 5673 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; | 5614 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; |
| 5674 *reinterpret_cast<uint16_t*>(addr) = class_id; | 5615 *reinterpret_cast<uint16_t*>(addr) = class_id; |
| 5675 } | 5616 } |
| 5676 | 5617 |
| 5677 | 5618 |
| 5678 template <class T> | 5619 template <class T, class M> |
| 5679 uint16_t Persistent<T>::WrapperClassId() const { | 5620 uint16_t Persistent<T, M>::WrapperClassId() const { |
| 5680 typedef internal::Internals I; | 5621 typedef internal::Internals I; |
| 5681 if (this->IsEmpty()) return 0; | 5622 if (this->IsEmpty()) return 0; |
| 5682 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); | 5623 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); |
| 5683 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; | 5624 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; |
| 5684 return *reinterpret_cast<uint16_t*>(addr); | 5625 return *reinterpret_cast<uint16_t*>(addr); |
| 5685 } | 5626 } |
| 5686 | 5627 |
| 5687 | 5628 |
| 5688 template<typename T> | 5629 template<typename T> |
| 5689 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} | 5630 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} |
| (...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6372 | 6313 |
| 6373 | 6314 |
| 6374 } // namespace v8 | 6315 } // namespace v8 |
| 6375 | 6316 |
| 6376 | 6317 |
| 6377 #undef V8EXPORT | 6318 #undef V8EXPORT |
| 6378 #undef TYPE_CHECK | 6319 #undef TYPE_CHECK |
| 6379 | 6320 |
| 6380 | 6321 |
| 6381 #endif // V8_H_ | 6322 #endif // V8_H_ |
| OLD | NEW |