Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: include/v8.h

Issue 17443004: new persistent semantics (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698