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

Side by Side Diff: include/v8.h

Issue 23401003: new persistent semantics (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: comments, etc Created 7 years, 3 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 | src/api.cc » ('j') | 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 class String; 113 class String;
114 class StringObject; 114 class StringObject;
115 class Symbol; 115 class Symbol;
116 class SymbolObject; 116 class SymbolObject;
117 class Uint32; 117 class Uint32;
118 class Utils; 118 class Utils;
119 class Value; 119 class Value;
120 template <class T> class Handle; 120 template <class T> class Handle;
121 template <class T> class Local; 121 template <class T> class Local;
122 template <class T> class Eternal; 122 template <class T> class Eternal;
123 template <class T> class Persistent; 123 template<class T> class NonCopyablePersistentTraits;
124 template<class T,
125 class M = NonCopyablePersistentTraits<T> > class Persistent;
126 template<class T, class P> class WeakCallbackObject;
124 class FunctionTemplate; 127 class FunctionTemplate;
125 class ObjectTemplate; 128 class ObjectTemplate;
126 class Data; 129 class Data;
127 template<typename T> class PropertyCallbackInfo; 130 template<typename T> class PropertyCallbackInfo;
128 class StackTrace; 131 class StackTrace;
129 class StackFrame; 132 class StackFrame;
130 class Isolate; 133 class Isolate;
131 class DeclaredAccessorDescriptor; 134 class DeclaredAccessorDescriptor;
132 class ObjectOperationDescriptor; 135 class ObjectOperationDescriptor;
133 class RawOperationDescriptor; 136 class RawOperationDescriptor;
134 class CallHandlerHelper; 137 class CallHandlerHelper;
135 138
136 namespace internal { 139 namespace internal {
137 class Arguments; 140 class Arguments;
138 class Heap; 141 class Heap;
139 class HeapObject; 142 class HeapObject;
140 class Isolate; 143 class Isolate;
141 class Object; 144 class Object;
142 template<typename T> class CustomArguments; 145 template<typename T> class CustomArguments;
143 class PropertyCallbackArguments; 146 class PropertyCallbackArguments;
144 class FunctionCallbackArguments; 147 class FunctionCallbackArguments;
148 class GlobalHandles;
145 } 149 }
146 150
147 151
148 /** 152 /**
149 * General purpose unique identifier. 153 * General purpose unique identifier.
150 */ 154 */
151 class UniqueId { 155 class UniqueId {
152 public: 156 public:
153 explicit UniqueId(intptr_t data) 157 explicit UniqueId(intptr_t data)
154 : data_(data) {} 158 : data_(data) {}
155 159
156 bool operator==(const UniqueId& other) const { 160 bool operator==(const UniqueId& other) const {
157 return data_ == other.data_; 161 return data_ == other.data_;
158 } 162 }
159 163
160 bool operator!=(const UniqueId& other) const { 164 bool operator!=(const UniqueId& other) const {
161 return data_ != other.data_; 165 return data_ != other.data_;
162 } 166 }
163 167
164 bool operator<(const UniqueId& other) const { 168 bool operator<(const UniqueId& other) const {
165 return data_ < other.data_; 169 return data_ < other.data_;
166 } 170 }
167 171
168 private: 172 private:
169 intptr_t data_; 173 intptr_t data_;
170 }; 174 };
171 175
172
173 // --- Weak Handles ---
174
175
176 /**
177 * A weak reference callback function.
178 *
179 * This callback should either explicitly invoke Dispose on |object| if
180 * V8 wrapper is not needed anymore, or 'revive' it by invocation of MakeWeak.
181 *
182 * \param object the weak global object to be reclaimed by the garbage collector
183 * \param parameter the value passed in when making the weak global object
184 */
185 template<typename T, typename P>
186 class WeakReferenceCallbacks {
187 public:
188 typedef void (*Revivable)(Isolate* isolate,
189 Persistent<T>* object,
190 P* parameter);
191 };
192
193 // --- Handles --- 176 // --- Handles ---
194 177
195 #define TYPE_CHECK(T, S) \ 178 #define TYPE_CHECK(T, S) \
196 while (false) { \ 179 while (false) { \
197 *(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \ 180 *(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \
198 } 181 }
199 182
200 183
201 /** 184 /**
202 * An object reference managed by the v8 garbage collector. 185 * An object reference managed by the v8 garbage collector.
(...skipping 20 matching lines...) Expand all
223 * behind the scenes and the same rules apply to these values as to 206 * behind the scenes and the same rules apply to these values as to
224 * their handles. 207 * their handles.
225 */ 208 */
226 template <class T> class Handle { 209 template <class T> class Handle {
227 public: 210 public:
228 /** 211 /**
229 * Creates an empty handle. 212 * Creates an empty handle.
230 */ 213 */
231 V8_INLINE(Handle()) : val_(0) {} 214 V8_INLINE(Handle()) : val_(0) {}
232 215
233 #ifdef V8_USE_UNSAFE_HANDLES
234 /**
235 * Creates a new handle for the specified value.
236 */
237 V8_INLINE(explicit Handle(T* val)) : val_(val) {}
238 #endif
239
240 /** 216 /**
241 * Creates a handle for the contents of the specified handle. This 217 * Creates a handle for the contents of the specified handle. This
242 * constructor allows you to pass handles as arguments by value and 218 * constructor allows you to pass handles as arguments by value and
243 * to assign between handles. However, if you try to assign between 219 * to assign between handles. However, if you try to assign between
244 * incompatible handles, for instance from a Handle<String> to a 220 * incompatible handles, for instance from a Handle<String> to a
245 * Handle<Number> it will cause a compile-time error. Assigning 221 * Handle<Number> it will cause a compile-time error. Assigning
246 * between compatible handles, for instance assigning a 222 * between compatible handles, for instance assigning a
247 * Handle<String> to a variable declared as Handle<Value>, is legal 223 * Handle<String> to a variable declared as Handle<Value>, is legal
248 * because String is a subclass of Value. 224 * because String is a subclass of Value.
249 */ 225 */
(...skipping 28 matching lines...) Expand all
278 * The handles' references are not checked. 254 * The handles' references are not checked.
279 */ 255 */
280 template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const) { 256 template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const) {
281 internal::Object** a = reinterpret_cast<internal::Object**>(**this); 257 internal::Object** a = reinterpret_cast<internal::Object**>(**this);
282 internal::Object** b = reinterpret_cast<internal::Object**>(*that); 258 internal::Object** b = reinterpret_cast<internal::Object**>(*that);
283 if (a == 0) return b == 0; 259 if (a == 0) return b == 0;
284 if (b == 0) return false; 260 if (b == 0) return false;
285 return *a == *b; 261 return *a == *b;
286 } 262 }
287 263
288 #ifndef V8_USE_UNSAFE_HANDLES
289 template <class S> V8_INLINE( 264 template <class S> V8_INLINE(
290 bool operator==(const Persistent<S>& that) const) { 265 bool operator==(const Persistent<S>& that) const) {
291 internal::Object** a = reinterpret_cast<internal::Object**>(**this); 266 internal::Object** a = reinterpret_cast<internal::Object**>(**this);
292 internal::Object** b = reinterpret_cast<internal::Object**>(*that); 267 internal::Object** b = reinterpret_cast<internal::Object**>(*that);
293 if (a == 0) return b == 0; 268 if (a == 0) return b == 0;
294 if (b == 0) return false; 269 if (b == 0) return false;
295 return *a == *b; 270 return *a == *b;
296 } 271 }
297 #endif
298 272
299 /** 273 /**
300 * Checks whether two handles are different. 274 * Checks whether two handles are different.
301 * Returns true if only one of the handles is empty, or if 275 * Returns true if only one of the handles is empty, or if
302 * the objects to which they refer are different. 276 * the objects to which they refer are different.
303 * The handles' references are not checked. 277 * The handles' references are not checked.
304 */ 278 */
305 template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const) { 279 template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const) {
306 return !operator==(that); 280 return !operator==(that);
307 } 281 }
308 282
309 #ifndef V8_USE_UNSAFE_HANDLES
310 template <class S> V8_INLINE( 283 template <class S> V8_INLINE(
311 bool operator!=(const Persistent<S>& that) const) { 284 bool operator!=(const Persistent<S>& that) const) {
312 return !operator==(that); 285 return !operator==(that);
313 } 286 }
314 #endif
315 287
316 template <class S> V8_INLINE(static Handle<T> Cast(Handle<S> that)) { 288 template <class S> V8_INLINE(static Handle<T> Cast(Handle<S> that)) {
317 #ifdef V8_ENABLE_CHECKS 289 #ifdef V8_ENABLE_CHECKS
318 // If we're going to perform the type check then we have to check 290 // If we're going to perform the type check then we have to check
319 // that the handle isn't empty before doing the checked cast. 291 // that the handle isn't empty before doing the checked cast.
320 if (that.IsEmpty()) return Handle<T>(); 292 if (that.IsEmpty()) return Handle<T>();
321 #endif 293 #endif
322 return Handle<T>(T::Cast(*that)); 294 return Handle<T>(T::Cast(*that));
323 } 295 }
324 296
325 template <class S> V8_INLINE(Handle<S> As()) { 297 template <class S> V8_INLINE(Handle<S> As()) {
326 return Handle<S>::Cast(*this); 298 return Handle<S>::Cast(*this);
327 } 299 }
328 300
329 #ifndef V8_USE_UNSAFE_HANDLES
330 V8_INLINE(static Handle<T> New(Isolate* isolate, Handle<T> that)) { 301 V8_INLINE(static Handle<T> New(Isolate* isolate, Handle<T> that)) {
331 return New(isolate, that.val_); 302 return New(isolate, that.val_);
332 } 303 }
333 // TODO(dcarney): remove before cutover
334 V8_INLINE(static Handle<T> New(Isolate* isolate, const Persistent<T>& that)) { 304 V8_INLINE(static Handle<T> New(Isolate* isolate, const Persistent<T>& that)) {
335 return New(isolate, that.val_); 305 return New(isolate, that.val_);
336 } 306 }
337 307
338 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR 308 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
339 309
340 private: 310 private:
341 #endif 311 #endif
342 /** 312 /**
343 * Creates a new handle for the specified value. 313 * Creates a new handle for the specified value.
344 */ 314 */
345 V8_INLINE(explicit Handle(T* val)) : val_(val) {} 315 V8_INLINE(explicit Handle(T* val)) : val_(val) {}
346 #endif
347 316
348 private: 317 private:
349 friend class Utils; 318 friend class Utils;
350 template<class F> friend class Persistent; 319 template<class F, class M> friend class Persistent;
351 template<class F> friend class Local; 320 template<class F> friend class Local;
352 template<class F> friend class FunctionCallbackInfo; 321 template<class F> friend class FunctionCallbackInfo;
353 template<class F> friend class PropertyCallbackInfo; 322 template<class F> friend class PropertyCallbackInfo;
354 template<class F> friend class internal::CustomArguments; 323 template<class F> friend class internal::CustomArguments;
355 friend Handle<Primitive> Undefined(Isolate* isolate); 324 friend Handle<Primitive> Undefined(Isolate* isolate);
356 friend Handle<Primitive> Null(Isolate* isolate); 325 friend Handle<Primitive> Null(Isolate* isolate);
357 friend Handle<Boolean> True(Isolate* isolate); 326 friend Handle<Boolean> True(Isolate* isolate);
358 friend Handle<Boolean> False(Isolate* isolate); 327 friend Handle<Boolean> False(Isolate* isolate);
359 friend class Context; 328 friend class Context;
360 friend class HandleScope; 329 friend class HandleScope;
361 330
362 #ifndef V8_USE_UNSAFE_HANDLES
363 V8_INLINE(static Handle<T> New(Isolate* isolate, T* that)); 331 V8_INLINE(static Handle<T> New(Isolate* isolate, T* that));
364 #endif
365 332
366 T* val_; 333 T* val_;
367 }; 334 };
368 335
369 336
370 /** 337 /**
371 * A light-weight stack-allocated object handle. All operations 338 * A light-weight stack-allocated object handle. All operations
372 * that return objects from within v8 return them in local handles. They 339 * that return objects from within v8 return them in local handles. They
373 * are created within HandleScopes, and all local handles allocated within a 340 * are created within HandleScopes, and all local handles allocated within a
374 * handle scope are destroyed when the handle scope is destroyed. Hence it 341 * handle scope are destroyed when the handle scope is destroyed. Hence it
375 * is not necessary to explicitly deallocate local handles. 342 * is not necessary to explicitly deallocate local handles.
376 */ 343 */
377 // TODO(dcarney): deprecate entire class
378 template <class T> class Local : public Handle<T> { 344 template <class T> class Local : public Handle<T> {
379 public: 345 public:
380 V8_INLINE(Local()); 346 V8_INLINE(Local());
381 template <class S> V8_INLINE(Local(Local<S> that)) 347 template <class S> V8_INLINE(Local(Local<S> that))
382 : Handle<T>(reinterpret_cast<T*>(*that)) { 348 : Handle<T>(reinterpret_cast<T*>(*that)) {
383 /** 349 /**
384 * This check fails when trying to convert between incompatible 350 * This check fails when trying to convert between incompatible
385 * handles. For example, converting from a Handle<String> to a 351 * handles. For example, converting from a Handle<String> to a
386 * Handle<Number>. 352 * Handle<Number>.
387 */ 353 */
388 TYPE_CHECK(T, S); 354 TYPE_CHECK(T, S);
389 } 355 }
390 356
391 357
392 #ifdef V8_USE_UNSAFE_HANDLES
393 template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { }
394 #endif
395
396 template <class S> V8_INLINE(static Local<T> Cast(Local<S> that)) { 358 template <class S> V8_INLINE(static Local<T> Cast(Local<S> that)) {
397 #ifdef V8_ENABLE_CHECKS 359 #ifdef V8_ENABLE_CHECKS
398 // If we're going to perform the type check then we have to check 360 // If we're going to perform the type check then we have to check
399 // that the handle isn't empty before doing the checked cast. 361 // that the handle isn't empty before doing the checked cast.
400 if (that.IsEmpty()) return Local<T>(); 362 if (that.IsEmpty()) return Local<T>();
401 #endif 363 #endif
402 return Local<T>(T::Cast(*that)); 364 return Local<T>(T::Cast(*that));
403 } 365 }
404 #ifndef V8_USE_UNSAFE_HANDLES
405 template <class S> V8_INLINE(Local(Handle<S> that)) 366 template <class S> V8_INLINE(Local(Handle<S> that))
406 : Handle<T>(reinterpret_cast<T*>(*that)) { 367 : Handle<T>(reinterpret_cast<T*>(*that)) {
407 TYPE_CHECK(T, S); 368 TYPE_CHECK(T, S);
408 } 369 }
409 #endif
410 370
411 template <class S> V8_INLINE(Local<S> As()) { 371 template <class S> V8_INLINE(Local<S> As()) {
412 return Local<S>::Cast(*this); 372 return Local<S>::Cast(*this);
413 } 373 }
414 374
415 /** 375 /**
416 * Create a local handle for the content of another handle. 376 * Create a local handle for the content of another handle.
417 * The referee is kept alive by the local handle even when 377 * The referee is kept alive by the local handle even when
418 * the original handle is destroyed/disposed. 378 * the original handle is destroyed/disposed.
419 */ 379 */
420 V8_INLINE(static Local<T> New(Handle<T> that)); 380 V8_INLINE(static Local<T> New(Handle<T> that));
421 V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that)); 381 V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that));
422 #ifndef V8_USE_UNSAFE_HANDLES 382 template<class M>
423 // TODO(dcarney): remove before cutover 383 V8_INLINE(static Local<T> New(Isolate* isolate,
424 V8_INLINE(static Local<T> New(Isolate* isolate, const Persistent<T>& that)); 384 const Persistent<T, M>& that));
425 385
426 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR 386 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
427 387
428 private: 388 private:
429 #endif 389 #endif
430 template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { } 390 template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { }
431 #endif
432 391
433 private: 392 private:
434 friend class Utils; 393 friend class Utils;
435 template<class F> friend class Eternal; 394 template<class F> friend class Eternal;
436 template<class F> friend class Persistent; 395 template<class F, class M> friend class Persistent;
437 template<class F> friend class Handle; 396 template<class F> friend class Handle;
438 template<class F> friend class FunctionCallbackInfo; 397 template<class F> friend class FunctionCallbackInfo;
439 template<class F> friend class PropertyCallbackInfo; 398 template<class F> friend class PropertyCallbackInfo;
440 friend class String; 399 friend class String;
441 friend class Object; 400 friend class Object;
442 friend class Context; 401 friend class Context;
443 template<class F> friend class internal::CustomArguments; 402 template<class F> friend class internal::CustomArguments;
444 friend class HandleScope; 403 friend class HandleScope;
445 404
446 V8_INLINE(static Local<T> New(Isolate* isolate, T* that)); 405 V8_INLINE(static Local<T> New(Isolate* isolate, T* that));
(...skipping 14 matching lines...) Expand all
461 V8_INLINE(bool IsEmpty()) { return index_ == kInitialValue; } 420 V8_INLINE(bool IsEmpty()) { return index_ == kInitialValue; }
462 template<class S> 421 template<class S>
463 V8_INLINE(void Set(Isolate* isolate, Local<S> handle)); 422 V8_INLINE(void Set(Isolate* isolate, Local<S> handle));
464 423
465 private: 424 private:
466 static const int kInitialValue = -1; 425 static const int kInitialValue = -1;
467 int index_; 426 int index_;
468 }; 427 };
469 428
470 429
430 template<class T, class P>
431 class WeakCallbackData {
432 public:
433 typedef void (*Callback)(const WeakCallbackData<T, P>& data);
434
435 V8_INLINE(Isolate* GetIsolate()) const { return isolate_; }
436 V8_INLINE(Local<T> GetValue()) const { return handle_; }
437 V8_INLINE(P* GetParameter()) const { return parameter_; }
438
439 private:
440 friend class internal::GlobalHandles;
441 WeakCallbackData(Isolate* isolate, Local<T> handle, P* parameter)
442 : isolate_(isolate), handle_(handle), parameter_(parameter) { }
443 Isolate* isolate_;
444 Local<T> handle_;
445 P* parameter_;
446 };
447
448
449 // TODO(dcarney): Remove this class.
450 template<typename T,
451 typename P,
452 typename M = NonCopyablePersistentTraits<T> >
453 class WeakReferenceCallbacks {
454 public:
455 typedef void (*Revivable)(Isolate* isolate,
456 Persistent<T, M>* object,
457 P* parameter);
458 };
459
460
461 /**
462 * Default traits for Persistent. This class does not allow
463 * use of the copy constructor or assignment operator.
464 * At present kResetInDestructor is not set, but that will change in a future
465 * version.
466 */
467 template<class T>
468 class NonCopyablePersistentTraits {
469 public:
470 typedef Persistent<T, NonCopyablePersistentTraits<T> > NonCopyablePersistent;
471 static const bool kResetInDestructor = false;
472 template<class S, class M>
473 V8_INLINE(static void Copy(const Persistent<S, M>& source,
474 NonCopyablePersistent* dest)) {
475 Uncompilable<Object>();
476 }
477 // TODO(dcarney): come up with a good compile error here.
478 template<class O>
479 V8_INLINE(static void Uncompilable()) {
480 TYPE_CHECK(O, Primitive);
481 }
482 };
483
484
471 /** 485 /**
472 * An object reference that is independent of any handle scope. Where 486 * An object reference that is independent of any handle scope. Where
473 * a Local handle only lives as long as the HandleScope in which it was 487 * a Local handle only lives as long as the HandleScope in which it was
474 * allocated, a Persistent handle remains valid until it is explicitly 488 * allocated, a Persistent handle remains valid until it is explicitly
475 * disposed. 489 * disposed.
476 * 490 *
477 * A persistent handle contains a reference to a storage cell within 491 * A persistent handle contains a reference to a storage cell within
478 * the v8 engine which holds an object value and which is updated by 492 * the v8 engine which holds an object value and which is updated by
479 * the garbage collector whenever the object is moved. A new storage 493 * the garbage collector whenever the object is moved. A new storage
480 * cell can be created using Persistent::New and existing handles can 494 * cell can be created using the constructor or Persistent::Reset and
481 * be disposed using Persistent::Dispose. Since persistent handles 495 * existing handles can be disposed using Persistent::Reset.
482 * are passed by value you may have many persistent handle objects 496 *
483 * that point to the same storage cell. For instance, if you pass a 497 * Copy, assignment and destructor bevavior is controlled by the traits
484 * persistent handle as an argument to a function you will not get two 498 * class M.
485 * different storage cells but rather two references to the same
486 * storage cell.
487 */ 499 */
488 template <class T> class Persistent // NOLINT 500 template <class T, class M> class Persistent {
489 #ifdef V8_USE_UNSAFE_HANDLES
490 : public Handle<T> {
491 #else
492 { // NOLINT
493 #endif
494 public: 501 public:
495 #ifndef V8_USE_UNSAFE_HANDLES 502 /**
503 * A Persistent with no storage cell.
504 */
496 V8_INLINE(Persistent()) : val_(0) { } 505 V8_INLINE(Persistent()) : val_(0) { }
497 // TODO(dcarney): add this back before cutover. 506 /**
498 // V8_INLINE(~Persistent()) { 507 * Construct a Persistent from a Handle.
499 // Dispose(); 508 * When the Handle is non-empty, a new storage cell is created
500 // } 509 * pointing to the same object, and no flags are set.
501 V8_INLINE(bool IsEmpty() const) { return val_ == 0; } 510 */
502 // TODO(dcarney): remove somehow before cutover 511 template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that))
503 // The handle should either be 0, or a pointer to a live cell. 512 : val_(New(isolate, *that)) {
504 V8_INLINE(void Clear()) { val_ = 0; } 513 TYPE_CHECK(T, S);
514 }
515 /**
516 * Construct a Persistent from a Persistent.
517 * When the Persistent is non-empty, a new storage cell is created
518 * pointing to the same object, and no flags are set.
519 */
520 template <class S, class M2>
521 V8_INLINE(Persistent(Isolate* isolate, const Persistent<S, M2>& that))
522 : val_(New(isolate, *that)) {
523 TYPE_CHECK(T, S);
524 }
525 /**
526 * The copy constructors and assignment operator create a Persistent
527 * exactly as the Persistent constructor, but the Copy function from the
528 * traits class is called, allowing the setting of flags based on the
529 * copied Persistent.
530 */
531 V8_INLINE(Persistent(const Persistent& that)) : val_(0) {
532 Copy(that);
533 }
534 template <class S, class M2>
535 V8_INLINE(Persistent(const Persistent<S, M2>& that)) : val_(0) {
536 Copy(that);
537 }
538 V8_INLINE(Persistent& operator=(const Persistent& that)) { // NOLINT
539 Copy(that);
540 return *this;
541 }
542 template <class S, class M2>
543 V8_INLINE(Persistent& operator=(const Persistent<S, M2>& that)) { // NOLINT
544 Copy(that);
545 return *this;
546 }
547 /**
548 * The destructor will dispose the Persistent based on the
549 * kResetInDestructor flags in the traits class. Since not calling dispose
550 * can result in a memory leak, it is recommended to always set this flag.
551 */
552 V8_INLINE(~Persistent()) {
553 if (M::kResetInDestructor) Reset();
554 }
505 555
506 /** 556 /**
507 * A constructor that creates a new global cell pointing to that. In contrast 557 * If non-empty, destroy the underlying storage cell
508 * to the copy constructor, this creates a new persistent handle which needs 558 * IsEmpty() will return true after this call.
509 * to be separately disposed.
510 */ 559 */
511 template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that)) 560 V8_INLINE(void Reset());
512 : val_(New(isolate, *that)) { } 561 template <class S>
562 /**
563 * If non-empty, destroy the underlying storage cell
564 * and create a new one with the contents of other if other is non empty
565 */
566 V8_INLINE(void Reset(Isolate* isolate, const Handle<S>& other));
567 /**
568 * If non-empty, destroy the underlying storage cell
569 * and create a new one with the contents of other if other is non empty
570 */
571 template <class S, class M2>
572 V8_INLINE(void Reset(Isolate* isolate, const Persistent<S, M2>& other));
573 // TODO(dcarney): deprecate
574 V8_INLINE(void Dispose()) { Reset(); }
575 V8_DEPRECATED(V8_INLINE(void Dispose(Isolate* isolate))) { Reset(); }
513 576
514 template <class S> V8_INLINE(Persistent(Isolate* isolate, 577 V8_INLINE(bool IsEmpty() const) { return val_ == 0; }
515 const Persistent<S>& that)) // NOLINT
516 : val_(New(isolate, *that)) { }
517 578
518 #else 579 // TODO(dcarney): this is pretty useless, fix or remove
519 /**
520 * Creates an empty persistent handle that doesn't point to any
521 * storage cell.
522 */
523 V8_INLINE(Persistent()) : Handle<T>() { }
524
525 /**
526 * Creates a persistent handle for the same storage cell as the
527 * specified handle. This constructor allows you to pass persistent
528 * handles as arguments by value and to assign between persistent
529 * handles. However, attempting to assign between incompatible
530 * persistent handles, for instance from a Persistent<String> to a
531 * Persistent<Number> will cause a compile-time error. Assigning
532 * between compatible persistent handles, for instance assigning a
533 * Persistent<String> to a variable declared as Persistent<Value>,
534 * is allowed as String is a subclass of Value.
535 */
536 template <class S> V8_INLINE(Persistent(Persistent<S> that))
537 : Handle<T>(reinterpret_cast<T*>(*that)) {
538 /**
539 * This check fails when trying to convert between incompatible
540 * handles. For example, converting from a Handle<String> to a
541 * Handle<Number>.
542 */
543 TYPE_CHECK(T, S);
544 }
545
546 template <class S> V8_INLINE(Persistent(S* that)) : Handle<T>(that) { }
547
548 /**
549 * A constructor that creates a new global cell pointing to that. In contrast
550 * to the copy constructor, this creates a new persistent handle which needs
551 * to be separately disposed.
552 */
553 template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that))
554 : Handle<T>(New(isolate, that)) { }
555
556 /**
557 * "Casts" a plain handle which is known to be a persistent handle
558 * to a persistent handle.
559 */
560 template <class S> explicit V8_INLINE(Persistent(Handle<S> that))
561 : Handle<T>(*that) { }
562
563 #endif
564
565 #ifdef V8_USE_UNSAFE_HANDLES
566 template <class S> V8_INLINE(static Persistent<T> Cast(Persistent<S> that)) {
567 #ifdef V8_ENABLE_CHECKS
568 // If we're going to perform the type check then we have to check
569 // that the handle isn't empty before doing the checked cast.
570 if (that.IsEmpty()) return Persistent<T>();
571 #endif
572 return Persistent<T>(T::Cast(*that));
573 }
574
575 template <class S> V8_INLINE(Persistent<S> As()) {
576 return Persistent<S>::Cast(*this);
577 }
578
579 #else
580 template <class S> 580 template <class S>
581 V8_INLINE(static Persistent<T>& Cast(Persistent<S>& that)) { // NOLINT 581 V8_INLINE(static Persistent<T>& Cast(Persistent<S>& that)) { // NOLINT
582 #ifdef V8_ENABLE_CHECKS 582 #ifdef V8_ENABLE_CHECKS
583 // 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
584 // that the handle isn't empty before doing the checked cast. 584 // that the handle isn't empty before doing the checked cast.
585 if (!that.IsEmpty()) T::Cast(*that); 585 if (!that.IsEmpty()) T::Cast(*that);
586 #endif 586 #endif
587 return reinterpret_cast<Persistent<T>&>(that); 587 return reinterpret_cast<Persistent<T>&>(that);
588 } 588 }
589 589
590 // TODO(dcarney): this is pretty useless, fix or remove
590 template <class S> V8_INLINE(Persistent<S>& As()) { // NOLINT 591 template <class S> V8_INLINE(Persistent<S>& As()) { // NOLINT
591 return Persistent<S>::Cast(*this); 592 return Persistent<S>::Cast(*this);
592 } 593 }
593 #endif
594 594
595 #ifdef V8_USE_UNSAFE_HANDLES 595 template <class S, class M2> V8_INLINE(
596 V8_DEPRECATED(static Persistent<T> New(Handle<T> that)); 596 bool operator==(const Persistent<S, M2>& that) const) {
597 V8_INLINE(static Persistent<T> New(Isolate* isolate, Handle<T> that));
598 V8_INLINE(static Persistent<T> New(Isolate* isolate, Persistent<T> that));
599 #endif
600
601 #ifndef V8_USE_UNSAFE_HANDLES
602 template <class S> V8_INLINE(
603 bool operator==(const Persistent<S>& that) const) {
604 internal::Object** a = reinterpret_cast<internal::Object**>(**this); 597 internal::Object** a = reinterpret_cast<internal::Object**>(**this);
605 internal::Object** b = reinterpret_cast<internal::Object**>(*that); 598 internal::Object** b = reinterpret_cast<internal::Object**>(*that);
606 if (a == 0) return b == 0; 599 if (a == 0) return b == 0;
607 if (b == 0) return false; 600 if (b == 0) return false;
608 return *a == *b; 601 return *a == *b;
609 } 602 }
610 603
611 template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const) { 604 template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const) {
612 internal::Object** a = reinterpret_cast<internal::Object**>(**this); 605 internal::Object** a = reinterpret_cast<internal::Object**>(**this);
613 internal::Object** b = reinterpret_cast<internal::Object**>(*that); 606 internal::Object** b = reinterpret_cast<internal::Object**>(*that);
614 if (a == 0) return b == 0; 607 if (a == 0) return b == 0;
615 if (b == 0) return false; 608 if (b == 0) return false;
616 return *a == *b; 609 return *a == *b;
617 } 610 }
618 611
619 template <class S> V8_INLINE( 612 template <class S, class M2> V8_INLINE(
620 bool operator!=(const Persistent<S>& that) const) { 613 bool operator!=(const Persistent<S, M2>& that) const) {
621 return !operator==(that); 614 return !operator==(that);
622 } 615 }
623 616
624 template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const) { 617 template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const) {
625 return !operator==(that); 618 return !operator==(that);
626 } 619 }
627 #endif
628 620
629 V8_INLINE(void Dispose()); 621 template<typename P>
622 V8_INLINE(void SetWeak(
623 P* parameter,
624 typename WeakCallbackData<T, P>::Callback callback));
630 625
631 /** 626 template<typename S, typename P>
632 * Releases the storage cell referenced by this persistent handle. 627 V8_INLINE(void SetWeak(
633 * Does not remove the reference to the cell from any handles. 628 P* parameter,
634 * This handle's reference, and any other references to the storage 629 typename WeakCallbackData<S, P>::Callback callback));
635 * cell remain and IsEmpty will still return false.
636 */
637 V8_DEPRECATED(V8_INLINE(void Dispose(Isolate* isolate))) { Dispose(); }
638 630
639 /** 631 // TODO(dcarney): deprecate
640 * Make the reference to this object weak. When only weak handles
641 * refer to the object, the garbage collector will perform a
642 * callback to the given V8::NearDeathCallback function, passing
643 * it the object reference and the given parameters.
644 */
645 template<typename S, typename P> 632 template<typename S, typename P>
646 V8_INLINE(void MakeWeak( 633 V8_INLINE(void MakeWeak(
647 P* parameters, 634 P* parameter,
648 typename WeakReferenceCallbacks<S, P>::Revivable callback)); 635 typename WeakReferenceCallbacks<S, P>::Revivable callback));
649 636
637 // TODO(dcarney): deprecate
650 template<typename P> 638 template<typename P>
651 V8_INLINE(void MakeWeak( 639 V8_INLINE(void MakeWeak(
652 P* parameters, 640 P* parameter,
653 typename WeakReferenceCallbacks<T, P>::Revivable callback));
654
655 template<typename S, typename P>
656 V8_DEPRECATED(void MakeWeak(
657 Isolate* isolate,
658 P* parameters,
659 typename WeakReferenceCallbacks<S, P>::Revivable callback));
660
661 template<typename P>
662 V8_DEPRECATED(void MakeWeak(
663 Isolate* isolate,
664 P* parameters,
665 typename WeakReferenceCallbacks<T, P>::Revivable callback)); 641 typename WeakReferenceCallbacks<T, P>::Revivable callback));
666 642
667 V8_INLINE(void ClearWeak()); 643 V8_INLINE(void ClearWeak());
668 644
669 V8_DEPRECATED(V8_INLINE(void ClearWeak(Isolate* isolate))) { ClearWeak(); } 645 V8_DEPRECATED(V8_INLINE(void ClearWeak(Isolate* isolate))) { ClearWeak(); }
670 646
671 /** 647 /**
672 * Marks the reference to this object independent. Garbage collector is free 648 * Marks the reference to this object independent. Garbage collector is free
673 * to ignore any object groups containing this object. Weak callback for an 649 * to ignore any object groups containing this object. Weak callback for an
674 * independent handle should not assume that it will be preceded by a global 650 * 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
728 /** 704 /**
729 * Returns the class ID previously assigned to this handle or 0 if no class ID 705 * Returns the class ID previously assigned to this handle or 0 if no class ID
730 * was previously assigned. 706 * was previously assigned.
731 */ 707 */
732 V8_INLINE(uint16_t WrapperClassId() const); 708 V8_INLINE(uint16_t WrapperClassId() const);
733 709
734 V8_DEPRECATED(V8_INLINE(uint16_t WrapperClassId(Isolate* isolate)) const) { 710 V8_DEPRECATED(V8_INLINE(uint16_t WrapperClassId(Isolate* isolate)) const) {
735 return WrapperClassId(); 711 return WrapperClassId();
736 } 712 }
737 713
738 /** 714 // TODO(dcarney): remove
739 * Disposes the current contents of the handle and replaces it.
740 */
741 V8_INLINE(void Reset(Isolate* isolate, const Handle<T>& other));
742
743 #ifndef V8_USE_UNSAFE_HANDLES
744 V8_INLINE(void Reset(Isolate* isolate, const Persistent<T>& other));
745 #endif
746
747 /**
748 * Returns the underlying raw pointer and clears the handle. The caller is
749 * responsible of eventually destroying the underlying object (by creating a
750 * Persistent handle which points to it and Disposing it). In the future,
751 * destructing a Persistent will also Dispose it. With this function, the
752 * embedder can let the Persistent go out of scope without it getting
753 * disposed.
754 */
755 V8_INLINE(T* ClearAndLeak()); 715 V8_INLINE(T* ClearAndLeak());
756 716
757 #ifndef V8_USE_UNSAFE_HANDLES 717 // TODO(dcarney): remove
718 V8_INLINE(void Clear()) { val_ = 0; }
758 719
759 private: 720 // TODO(dcarney): remove
760 // TODO(dcarney): make unlinkable before cutover
761 V8_INLINE(Persistent(const Persistent& that)) : val_(that.val_) {}
762 // TODO(dcarney): make unlinkable before cutover
763 V8_INLINE(Persistent& operator=(const Persistent& that)) { // NOLINT
764 this->val_ = that.val_;
765 return *this;
766 }
767
768 public:
769 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR 721 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
770 722
771 private: 723 private:
772 #endif 724 #endif
773 // TODO(dcarney): remove before cutover
774 template <class S> V8_INLINE(Persistent(S* that)) : val_(that) { } 725 template <class S> V8_INLINE(Persistent(S* that)) : val_(that) { }
775 726
776 // TODO(dcarney): remove before cutover
777 V8_INLINE(T* operator*() const) { return val_; } 727 V8_INLINE(T* operator*() const) { return val_; }
778 728
779 private: 729 private:
780 // TODO(dcarney): remove before cutover
781 V8_INLINE(T* operator->() const) { return val_; }
782 public:
783 #endif
784
785 private:
786 friend class Utils; 730 friend class Utils;
787 template<class F> friend class Handle; 731 template<class F> friend class Handle;
788 template<class F> friend class Local; 732 template<class F> friend class Local;
789 template<class F> friend class Persistent; 733 template<class F1, class F2> friend class Persistent;
790 template<class F> friend class ReturnValue; 734 template<class F> friend class ReturnValue;
791 735
792 V8_INLINE(static T* New(Isolate* isolate, T* that)); 736 V8_INLINE(static T* New(Isolate* isolate, T* that));
737 template<class S, class M2>
738 V8_INLINE(void Copy(const Persistent<S, M2>& that));
793 739
794 #ifndef V8_USE_UNSAFE_HANDLES
795 T* val_; 740 T* val_;
796 #endif
797 }; 741 };
798 742
799
800 /** 743 /**
801 * A stack-allocated class that governs a number of local handles. 744 * A stack-allocated class that governs a number of local handles.
802 * After a handle scope has been created, all local handles will be 745 * After a handle scope has been created, all local handles will be
803 * allocated within that handle scope until either the handle scope is 746 * allocated within that handle scope until either the handle scope is
804 * deleted or another handle scope is created. If there is already a 747 * deleted or another handle scope is created. If there is already a
805 * handle scope and a new one is created, all allocations will take 748 * handle scope and a new one is created, all allocations will take
806 * place in the new handle scope until it is deleted. After that, 749 * place in the new handle scope until it is deleted. After that,
807 * new handles will again be allocated in the original handle scope. 750 * new handles will again be allocated in the original handle scope.
808 * 751 *
809 * After the handle scope of a local handle has been deleted the 752 * After the handle scope of a local handle has been deleted the
(...skipping 3902 matching lines...) Expand 10 before | Expand all | Expand 10 after
4712 * Initialize the ICU library bundled with V8. The embedder should only 4655 * Initialize the ICU library bundled with V8. The embedder should only
4713 * invoke this method when using the bundled ICU. Returns true on success. 4656 * invoke this method when using the bundled ICU. Returns true on success.
4714 */ 4657 */
4715 static bool InitializeICU(); 4658 static bool InitializeICU();
4716 4659
4717 private: 4660 private:
4718 V8(); 4661 V8();
4719 4662
4720 static internal::Object** GlobalizeReference(internal::Isolate* isolate, 4663 static internal::Object** GlobalizeReference(internal::Isolate* isolate,
4721 internal::Object** handle); 4664 internal::Object** handle);
4665 static internal::Object** CopyPersistent(internal::Object** handle);
4722 static void DisposeGlobal(internal::Object** global_handle); 4666 static void DisposeGlobal(internal::Object** global_handle);
4723 typedef WeakReferenceCallbacks<Value, void>::Revivable RevivableCallback; 4667 typedef WeakReferenceCallbacks<Value, void>::Revivable RevivableCallback;
4668 typedef WeakCallbackData<Value, void>::Callback WeakCallback;
4724 static void MakeWeak(internal::Object** global_handle, 4669 static void MakeWeak(internal::Object** global_handle,
4725 void* data, 4670 void* data,
4671 WeakCallback weak_callback,
4726 RevivableCallback weak_reference_callback); 4672 RevivableCallback weak_reference_callback);
4727 static void ClearWeak(internal::Object** global_handle); 4673 static void ClearWeak(internal::Object** global_handle);
4728 static void Eternalize(Isolate* isolate, 4674 static void Eternalize(Isolate* isolate,
4729 Value* handle, 4675 Value* handle,
4730 int* index); 4676 int* index);
4731 static Local<Value> GetEternal(Isolate* isolate, int index); 4677 static Local<Value> GetEternal(Isolate* isolate, int index);
4732 4678
4733 template <class T> friend class Handle; 4679 template <class T> friend class Handle;
4734 template <class T> friend class Local; 4680 template <class T> friend class Local;
4735 template <class T> friend class Eternal; 4681 template <class T> friend class Eternal;
4736 template <class T> friend class Persistent; 4682 template <class T, class M> friend class Persistent;
4737 friend class Context; 4683 friend class Context;
4738 }; 4684 };
4739 4685
4740 4686
4741 /** 4687 /**
4742 * An external exception handler. 4688 * An external exception handler.
4743 */ 4689 */
4744 class V8_EXPORT TryCatch { 4690 class V8_EXPORT TryCatch {
4745 public: 4691 public:
4746 /** 4692 /**
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
5067 * Stack-allocated class which sets the execution context for all 5013 * Stack-allocated class which sets the execution context for all
5068 * operations executed within a local scope. 5014 * operations executed within a local scope.
5069 */ 5015 */
5070 class Scope { 5016 class Scope {
5071 public: 5017 public:
5072 explicit V8_INLINE(Scope(Handle<Context> context)) : context_(context) { 5018 explicit V8_INLINE(Scope(Handle<Context> context)) : context_(context) {
5073 context_->Enter(); 5019 context_->Enter();
5074 } 5020 }
5075 // TODO(dcarney): deprecate 5021 // TODO(dcarney): deprecate
5076 V8_INLINE(Scope(Isolate* isolate, Persistent<Context>& context)) // NOLINT 5022 V8_INLINE(Scope(Isolate* isolate, Persistent<Context>& context)) // NOLINT
5077 #ifndef V8_USE_UNSAFE_HANDLES
5078 : context_(Handle<Context>::New(isolate, context)) { 5023 : context_(Handle<Context>::New(isolate, context)) {
5079 #else
5080 : context_(Local<Context>::New(isolate, context)) {
5081 #endif
5082 context_->Enter(); 5024 context_->Enter();
5083 } 5025 }
5084 V8_INLINE(~Scope()) { context_->Exit(); } 5026 V8_INLINE(~Scope()) { context_->Exit(); }
5085 5027
5086 private: 5028 private:
5087 Handle<Context> context_; 5029 Handle<Context> context_;
5088 }; 5030 };
5089 5031
5090 private: 5032 private:
5091 friend class Value; 5033 friend class Value;
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
5561 } 5503 }
5562 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p))); 5504 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p)));
5563 } 5505 }
5564 5506
5565 5507
5566 template <class T> 5508 template <class T>
5567 Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) { 5509 Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) {
5568 return New(isolate, that.val_); 5510 return New(isolate, that.val_);
5569 } 5511 }
5570 5512
5571 #ifndef V8_USE_UNSAFE_HANDLES
5572 template <class T> 5513 template <class T>
5573 Local<T> Local<T>::New(Isolate* isolate, const Persistent<T>& that) { 5514 template <class M>
5515 Local<T> Local<T>::New(Isolate* isolate, const Persistent<T, M>& that) {
5574 return New(isolate, that.val_); 5516 return New(isolate, that.val_);
5575 } 5517 }
5576 5518
5577 template <class T> 5519 template <class T>
5578 Handle<T> Handle<T>::New(Isolate* isolate, T* that) { 5520 Handle<T> Handle<T>::New(Isolate* isolate, T* that) {
5579 if (that == NULL) return Handle<T>(); 5521 if (that == NULL) return Handle<T>();
5580 T* that_ptr = that; 5522 T* that_ptr = that;
5581 internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); 5523 internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
5582 return Handle<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( 5524 return Handle<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
5583 reinterpret_cast<internal::Isolate*>(isolate), *p))); 5525 reinterpret_cast<internal::Isolate*>(isolate), *p)));
5584 } 5526 }
5585 #endif
5586 5527
5587 5528
5588 template <class T> 5529 template <class T>
5589 Local<T> Local<T>::New(Isolate* isolate, T* that) { 5530 Local<T> Local<T>::New(Isolate* isolate, T* that) {
5590 if (that == NULL) return Local<T>(); 5531 if (that == NULL) return Local<T>();
5591 T* that_ptr = that; 5532 T* that_ptr = that;
5592 internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); 5533 internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
5593 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( 5534 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
5594 reinterpret_cast<internal::Isolate*>(isolate), *p))); 5535 reinterpret_cast<internal::Isolate*>(isolate), *p)));
5595 } 5536 }
5596 5537
5597 5538
5598 template<class T> 5539 template<class T>
5599 template<class S> 5540 template<class S>
5600 void Eternal<T>::Set(Isolate* isolate, Local<S> handle) { 5541 void Eternal<T>::Set(Isolate* isolate, Local<S> handle) {
5601 TYPE_CHECK(T, S); 5542 TYPE_CHECK(T, S);
5602 V8::Eternalize(isolate, reinterpret_cast<Value*>(*handle), &this->index_); 5543 V8::Eternalize(isolate, reinterpret_cast<Value*>(*handle), &this->index_);
5603 } 5544 }
5604 5545
5605 5546
5606 template<class T> 5547 template<class T>
5607 Local<T> Eternal<T>::Get(Isolate* isolate) { 5548 Local<T> Eternal<T>::Get(Isolate* isolate) {
5608 return Local<T>(reinterpret_cast<T*>(*V8::GetEternal(isolate, index_))); 5549 return Local<T>(reinterpret_cast<T*>(*V8::GetEternal(isolate, index_)));
5609 } 5550 }
5610 5551
5611 5552
5612 #ifdef V8_USE_UNSAFE_HANDLES 5553 template <class T, class M>
5613 template <class T> 5554 T* Persistent<T, M>::New(Isolate* isolate, T* that) {
5614 Persistent<T> Persistent<T>::New(Handle<T> that) {
5615 return New(Isolate::GetCurrent(), that.val_);
5616 }
5617
5618
5619 template <class T>
5620 Persistent<T> Persistent<T>::New(Isolate* isolate, Handle<T> that) {
5621 return New(Isolate::GetCurrent(), that.val_);
5622 }
5623
5624 template <class T>
5625 Persistent<T> Persistent<T>::New(Isolate* isolate, Persistent<T> that) {
5626 return New(Isolate::GetCurrent(), that.val_);
5627 }
5628 #endif
5629
5630
5631 template <class T>
5632 T* Persistent<T>::New(Isolate* isolate, T* that) {
5633 if (that == NULL) return NULL; 5555 if (that == NULL) return NULL;
5634 internal::Object** p = reinterpret_cast<internal::Object**>(that); 5556 internal::Object** p = reinterpret_cast<internal::Object**>(that);
5635 return reinterpret_cast<T*>( 5557 return reinterpret_cast<T*>(
5636 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), 5558 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate),
5637 p)); 5559 p));
5638 } 5560 }
5639 5561
5640 5562
5641 template <class T> 5563 template <class T, class M>
5642 bool Persistent<T>::IsIndependent() const { 5564 template <class S, class M2>
5565 void Persistent<T, M>::Copy(const Persistent<S, M2>& that) {
5566 TYPE_CHECK(T, S);
5567 Reset();
5568 if (that.IsEmpty()) return;
5569 internal::Object** p = reinterpret_cast<internal::Object**>(that.val_);
5570 this->val_ = reinterpret_cast<T*>(V8::CopyPersistent(p));
5571 M::Copy(that, this);
5572 }
5573
5574
5575 template <class T, class M>
5576 bool Persistent<T, M>::IsIndependent() const {
5643 typedef internal::Internals I; 5577 typedef internal::Internals I;
5644 if (this->IsEmpty()) return false; 5578 if (this->IsEmpty()) return false;
5645 return I::GetNodeFlag(reinterpret_cast<internal::Object**>(this->val_), 5579 return I::GetNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
5646 I::kNodeIsIndependentShift); 5580 I::kNodeIsIndependentShift);
5647 } 5581 }
5648 5582
5649 5583
5650 template <class T> 5584 template <class T, class M>
5651 bool Persistent<T>::IsNearDeath() const { 5585 bool Persistent<T, M>::IsNearDeath() const {
5652 typedef internal::Internals I; 5586 typedef internal::Internals I;
5653 if (this->IsEmpty()) return false; 5587 if (this->IsEmpty()) return false;
5654 uint8_t node_state = 5588 uint8_t node_state =
5655 I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)); 5589 I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_));
5656 return node_state == I::kNodeStateIsNearDeathValue || 5590 return node_state == I::kNodeStateIsNearDeathValue ||
5657 node_state == I::kNodeStateIsPendingValue; 5591 node_state == I::kNodeStateIsPendingValue;
5658 } 5592 }
5659 5593
5660 5594
5661 template <class T> 5595 template <class T, class M>
5662 bool Persistent<T>::IsWeak() const { 5596 bool Persistent<T, M>::IsWeak() const {
5663 typedef internal::Internals I; 5597 typedef internal::Internals I;
5664 if (this->IsEmpty()) return false; 5598 if (this->IsEmpty()) return false;
5665 return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) == 5599 return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) ==
5666 I::kNodeStateIsWeakValue; 5600 I::kNodeStateIsWeakValue;
5667 } 5601 }
5668 5602
5669 5603
5670 template <class T> 5604 template <class T, class M>
5671 void Persistent<T>::Dispose() { 5605 void Persistent<T, M>::Reset() {
5672 if (this->IsEmpty()) return; 5606 if (this->IsEmpty()) return;
5673 V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_)); 5607 V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_));
5674 #ifndef V8_USE_UNSAFE_HANDLES
5675 val_ = 0; 5608 val_ = 0;
5676 #endif
5677 } 5609 }
5678 5610
5679 5611
5680 template <class T> 5612 template <class T, class M>
5613 template <class S>
5614 void Persistent<T, M>::Reset(Isolate* isolate, const Handle<S>& other) {
5615 TYPE_CHECK(T, S);
5616 Reset();
5617 if (other.IsEmpty()) return;
5618 this->val_ = New(isolate, other.val_);
5619 }
5620
5621
5622 template <class T, class M>
5623 template <class S, class M2>
5624 void Persistent<T, M>::Reset(Isolate* isolate,
5625 const Persistent<S, M2>& other) {
5626 TYPE_CHECK(T, S);
5627 Reset();
5628 if (other.IsEmpty()) return;
5629 this->val_ = New(isolate, other.val_);
5630 }
5631
5632
5633 template <class T, class M>
5681 template <typename S, typename P> 5634 template <typename S, typename P>
5682 void Persistent<T>::MakeWeak( 5635 void Persistent<T, M>::SetWeak(
5636 P* parameter,
5637 typename WeakCallbackData<S, P>::Callback callback) {
5638 TYPE_CHECK(S, T);
5639 typedef typename WeakCallbackData<Value, void>::Callback Callback;
5640 V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_),
5641 parameter,
5642 reinterpret_cast<Callback>(callback),
5643 NULL);
5644 }
5645
5646
5647 template <class T, class M>
5648 template <typename P>
5649 void Persistent<T, M>::SetWeak(
5650 P* parameter,
5651 typename WeakCallbackData<T, P>::Callback callback) {
5652 SetWeak<T, P>(parameter, callback);
5653 }
5654
5655
5656 template <class T, class M>
5657 template <typename S, typename P>
5658 void Persistent<T, M>::MakeWeak(
5683 P* parameters, 5659 P* parameters,
5684 typename WeakReferenceCallbacks<S, P>::Revivable callback) { 5660 typename WeakReferenceCallbacks<S, P>::Revivable callback) {
5685 TYPE_CHECK(S, T); 5661 TYPE_CHECK(S, T);
5686 typedef typename WeakReferenceCallbacks<Value, void>::Revivable Revivable; 5662 typedef typename WeakReferenceCallbacks<Value, void>::Revivable Revivable;
5687 V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_), 5663 V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_),
5688 parameters, 5664 parameters,
5665 NULL,
5689 reinterpret_cast<Revivable>(callback)); 5666 reinterpret_cast<Revivable>(callback));
5690 } 5667 }
5691 5668
5692 5669
5693 template <class T> 5670 template <class T, class M>
5694 template <typename P> 5671 template <typename P>
5695 void Persistent<T>::MakeWeak( 5672 void Persistent<T, M>::MakeWeak(
5696 P* parameters, 5673 P* parameters,
5697 typename WeakReferenceCallbacks<T, P>::Revivable callback) { 5674 typename WeakReferenceCallbacks<T, P>::Revivable callback) {
5698 MakeWeak<T, P>(parameters, callback); 5675 MakeWeak<T, P>(parameters, callback);
5699 } 5676 }
5700 5677
5701 5678
5702 template <class T> 5679 template <class T, class M>
5703 template <typename S, typename P> 5680 void Persistent<T, M>::ClearWeak() {
5704 void Persistent<T>::MakeWeak(
5705 Isolate* isolate,
5706 P* parameters,
5707 typename WeakReferenceCallbacks<S, P>::Revivable callback) {
5708 MakeWeak<S, P>(parameters, callback);
5709 }
5710
5711
5712 template <class T>
5713 template<typename P>
5714 void Persistent<T>::MakeWeak(
5715 Isolate* isolate,
5716 P* parameters,
5717 typename WeakReferenceCallbacks<T, P>::Revivable callback) {
5718 MakeWeak<P>(parameters, callback);
5719 }
5720
5721
5722 template <class T>
5723 void Persistent<T>::ClearWeak() {
5724 V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)); 5681 V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_));
5725 } 5682 }
5726 5683
5727 5684
5728 template <class T> 5685 template <class T, class M>
5729 void Persistent<T>::MarkIndependent() { 5686 void Persistent<T, M>::MarkIndependent() {
5730 typedef internal::Internals I; 5687 typedef internal::Internals I;
5731 if (this->IsEmpty()) return; 5688 if (this->IsEmpty()) return;
5732 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), 5689 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
5733 true, 5690 true,
5734 I::kNodeIsIndependentShift); 5691 I::kNodeIsIndependentShift);
5735 } 5692 }
5736 5693
5737 5694
5738 template <class T> 5695 template <class T, class M>
5739 void Persistent<T>::MarkPartiallyDependent() { 5696 void Persistent<T, M>::MarkPartiallyDependent() {
5740 typedef internal::Internals I; 5697 typedef internal::Internals I;
5741 if (this->IsEmpty()) return; 5698 if (this->IsEmpty()) return;
5742 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), 5699 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
5743 true, 5700 true,
5744 I::kNodeIsPartiallyDependentShift); 5701 I::kNodeIsPartiallyDependentShift);
5745 } 5702 }
5746 5703
5747 5704
5748 template <class T> 5705 template <class T, class M>
5749 void Persistent<T>::Reset(Isolate* isolate, const Handle<T>& other) { 5706 T* Persistent<T, M>::ClearAndLeak() {
5750 Dispose();
5751 #ifdef V8_USE_UNSAFE_HANDLES
5752 *this = *New(isolate, other);
5753 #else
5754 if (other.IsEmpty()) {
5755 this->val_ = NULL;
5756 return;
5757 }
5758 internal::Object** p = reinterpret_cast<internal::Object**>(other.val_);
5759 this->val_ = reinterpret_cast<T*>(
5760 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p));
5761 #endif
5762 }
5763
5764
5765 #ifndef V8_USE_UNSAFE_HANDLES
5766 template <class T>
5767 void Persistent<T>::Reset(Isolate* isolate, const Persistent<T>& other) {
5768 Dispose();
5769 if (other.IsEmpty()) {
5770 this->val_ = NULL;
5771 return;
5772 }
5773 internal::Object** p = reinterpret_cast<internal::Object**>(other.val_);
5774 this->val_ = reinterpret_cast<T*>(
5775 V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p));
5776 }
5777 #endif
5778
5779
5780 template <class T>
5781 T* Persistent<T>::ClearAndLeak() {
5782 T* old; 5707 T* old;
5783 #ifdef V8_USE_UNSAFE_HANDLES
5784 old = **this;
5785 *this = Persistent<T>();
5786 #else
5787 old = val_; 5708 old = val_;
5788 val_ = NULL; 5709 val_ = NULL;
5789 #endif
5790 return old; 5710 return old;
5791 } 5711 }
5792 5712
5793 5713
5794 template <class T> 5714 template <class T, class M>
5795 void Persistent<T>::SetWrapperClassId(uint16_t class_id) { 5715 void Persistent<T, M>::SetWrapperClassId(uint16_t class_id) {
5796 typedef internal::Internals I; 5716 typedef internal::Internals I;
5797 if (this->IsEmpty()) return; 5717 if (this->IsEmpty()) return;
5798 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); 5718 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_);
5799 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; 5719 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
5800 *reinterpret_cast<uint16_t*>(addr) = class_id; 5720 *reinterpret_cast<uint16_t*>(addr) = class_id;
5801 } 5721 }
5802 5722
5803 5723
5804 template <class T> 5724 template <class T, class M>
5805 uint16_t Persistent<T>::WrapperClassId() const { 5725 uint16_t Persistent<T, M>::WrapperClassId() const {
5806 typedef internal::Internals I; 5726 typedef internal::Internals I;
5807 if (this->IsEmpty()) return 0; 5727 if (this->IsEmpty()) return 0;
5808 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); 5728 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_);
5809 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; 5729 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
5810 return *reinterpret_cast<uint16_t*>(addr); 5730 return *reinterpret_cast<uint16_t*>(addr);
5811 } 5731 }
5812 5732
5813 5733
5814 template<typename T> 5734 template<typename T>
5815 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} 5735 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {}
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
6510 */ 6430 */
6511 6431
6512 6432
6513 } // namespace v8 6433 } // namespace v8
6514 6434
6515 6435
6516 #undef TYPE_CHECK 6436 #undef TYPE_CHECK
6517 6437
6518 6438
6519 #endif // V8_H_ 6439 #endif // V8_H_
OLDNEW
« no previous file with comments | « no previous file | src/api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698