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 |