Chromium Code Reviews| Index: include/v8.h | 
| diff --git a/include/v8.h b/include/v8.h | 
| index 3252602bcf19d8fabba52e0c7fbbd274615f7ff2..7fd5ad2c3f7a276520f4210062faf31a28b4c060 100644 | 
| --- a/include/v8.h | 
| +++ b/include/v8.h | 
| @@ -145,6 +145,7 @@ class Utils; | 
| class Value; | 
| template <class T> class Handle; | 
| template <class T> class Local; | 
| +template <class T> class Eternal; | 
| template <class T> class Persistent; | 
| class FunctionTemplate; | 
| class ObjectTemplate; | 
| @@ -388,11 +389,6 @@ template <class T> class Handle { | 
| }; | 
| -// A value which will never be returned by Local::Eternalize | 
| -// Useful for static initialization | 
| -const int kUninitializedEternalIndex = -1; | 
| - | 
| - | 
| /** | 
| * A light-weight stack-allocated object handle. All operations | 
| * that return objects from within v8 return them in local handles. They | 
| @@ -438,11 +434,6 @@ template <class T> class Local : public Handle<T> { | 
| return Local<S>::Cast(*this); | 
| } | 
| - // Keep this Local alive for the lifetime of the Isolate. | 
| - // It remains retrievable via the returned index, | 
| - V8_INLINE(int Eternalize(Isolate* isolate)); | 
| - V8_INLINE(static Local<T> GetEternal(Isolate* isolate, int index)); | 
| - | 
| /** | 
| * Create a local handle for the content of another handle. | 
| * The referee is kept alive by the local handle even when | 
| @@ -463,6 +454,7 @@ template <class T> class Local : public Handle<T> { | 
| private: | 
| friend class Utils; | 
| + template<class F> friend class Eternal; | 
| template<class F> friend class Persistent; | 
| template<class F> friend class Handle; | 
| friend class Arguments; | 
| @@ -478,6 +470,28 @@ template <class T> class Local : public Handle<T> { | 
| V8_INLINE(static Local<T> New(Isolate* isolate, T* that)); | 
| }; | 
| + | 
| +// Eternal handles are set-once handles that live for the life of the isolate. | 
| +template <class T> class Eternal { | 
| + public: | 
| + V8_INLINE(Eternal()) : index_(kInitialValue) { } | 
| + template<class S> | 
| + V8_INLINE(Eternal(Isolate* isolate, Local<S> handle)) | 
| + : index_(kInitialValue) { | 
| + Set(isolate, handle); | 
| + } | 
| + // Can only be safely called if already set. | 
| + V8_INLINE(Local<T> Get(Isolate* isolate)); | 
| + V8_INLINE(bool IsSet()) { return index_ != kInitialValue; } | 
| + template<class S> | 
| + V8_INLINE(void Set(Isolate* isolate, Local<S> handle)); | 
| + | 
| + private: | 
| + static const int kInitialValue = -1; | 
| + int index_; | 
| +}; | 
| + | 
| + | 
| /** | 
| * An object reference that is independent of any handle scope. Where | 
| * a Local handle only lives as long as the HandleScope in which it was | 
| @@ -4797,12 +4811,14 @@ class V8_EXPORT V8 { | 
| void* data, | 
| RevivableCallback weak_reference_callback); | 
| static void ClearWeak(internal::Object** global_handle); | 
| - static int Eternalize(internal::Isolate* isolate, | 
| - internal::Object** handle); | 
| + static void Eternalize(internal::Isolate* isolate, | 
| + internal::Object** handle, | 
| + int* index); | 
| static internal::Object** GetEternal(internal::Isolate* isolate, int index); | 
| template <class T> friend class Handle; | 
| template <class T> friend class Local; | 
| + template <class T> friend class Eternal; | 
| template <class T> friend class Persistent; | 
| friend class Context; | 
| }; | 
| @@ -5664,16 +5680,19 @@ Local<T> Local<T>::New(Isolate* isolate, T* that) { | 
| template<class T> | 
| -int Local<T>::Eternalize(Isolate* isolate) { | 
| - return V8::Eternalize(reinterpret_cast<internal::Isolate*>(isolate), | 
| - reinterpret_cast<internal::Object**>(this->val_)); | 
| +template<class S> | 
| +void Eternal<T>::Set(Isolate* isolate, Local<S> handle) { | 
| + TYPE_CHECK(T, S); | 
| + V8::Eternalize(reinterpret_cast<internal::Isolate*>(isolate), | 
| 
 
Sven Panne
2013/08/21 10:20:22
I think it would be nicer if we could do all this
 
 | 
| + reinterpret_cast<internal::Object**>(*handle), | 
| + &this->index_); | 
| } | 
| template<class T> | 
| -Local<T> Local<T>::GetEternal(Isolate* isolate, int index) { | 
| +Local<T> Eternal<T>::Get(Isolate* isolate) { | 
| internal::Object** handle = | 
| - V8::GetEternal(reinterpret_cast<internal::Isolate*>(isolate), index); | 
| + V8::GetEternal(reinterpret_cast<internal::Isolate*>(isolate), index_); | 
| return Local<T>(T::Cast(reinterpret_cast<Value*>(handle))); | 
| } |