Reviewers: Sven Panne,

Description:
expose eternal handle api

[email protected]
BUG=

Please review this at https://codereview.chromium.org/22384003/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M include/v8.h
  M src/api.cc
  M test/cctest/test-global-handles.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index 8a6a8c67a7295decec2587f7220368046e829995..74ab3cfb150bb212899f02aab33adbb5e72337a2 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -430,6 +430,11 @@ 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
@@ -4120,6 +4125,10 @@ class V8EXPORT Isolate {
   Isolate& operator=(const Isolate&);
   void* operator new(size_t size);
   void operator delete(void*, size_t);
+
+  template<class T> friend class Local;
+  int Eternalize(Value* value);
+  Local<Value> GetEternal(int index);
 };


@@ -5647,6 +5656,18 @@ Local<T> Local<T>::New(Isolate* isolate, T* that) {
 }


+template<class T>
+int Local<T>::Eternalize(Isolate* isolate) {
+  return isolate->Eternalize(reinterpret_cast<Value*>(this->val_));
+}
+
+
+template<class T>
+Local<T> Local<T>::GetEternal(Isolate* isolate, int index) {
+  return Local<T>::Cast(isolate->GetEternal(index));
+}
+
+
 #ifdef V8_USE_UNSAFE_HANDLES
 template <class T>
 Persistent<T> Persistent<T>::New(Handle<T> that) {
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index 100ddc21b04df31d8a383d7502602868ae8237f6..d8fcdfb480c8f0fc83c413b26c1cf3c79fc02ae2 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -7047,6 +7047,20 @@ void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
 }


+int Isolate::Eternalize(Value* value) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  i::Object** location = reinterpret_cast<i::Object**>(value);
+  ASSERT(location != NULL);
+  return isolate->eternal_handles()->Create(isolate, *location);
+}
+
+
+Local<Value> Isolate::GetEternal(int index) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  return Utils::ToLocal(isolate->eternal_handles()->Get(index));
+}
+
+
 String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
     : str_(NULL), length_(0) {
   i::Isolate* isolate = i::Isolate::Current();
Index: test/cctest/test-global-handles.cc
diff --git a/test/cctest/test-global-handles.cc b/test/cctest/test-global-handles.cc index 3d79dba7aa1d838a09035dacd4f1947a2116a528..ea11dbcf3ad9d586d6794c27627a08dcec5e0464 100644
--- a/test/cctest/test-global-handles.cc
+++ b/test/cctest/test-global-handles.cc
@@ -484,21 +484,36 @@ TEST(EternalHandles) {
   CHECK_EQ(0, eternals->NumberOfHandles());
   for (int i = 0; i < kArrayLength; i++) {
     HandleScope scope(isolate);
-    v8::Handle<v8::Object> object = v8::Object::New();
+    v8::Local<v8::Object> object = v8::Object::New();
     object->Set(i, v8::Integer::New(i, v8_isolate));
- indices[i] = eternals->Create(isolate, *v8::Utils::OpenHandle(*object));
+    if (i % 2 == 0) {
+      // Create with internal api
+ indices[i] = eternals->Create(isolate, *v8::Utils::OpenHandle(*object));
+    } else {
+      // Create with external api
+      indices[i] = object.Eternalize(v8_isolate);
+    }
   }

   isolate->heap()->CollectAllAvailableGarbage();

   for (int i = 0; i < kArrayLength; i++) {
-    HandleScope scope(isolate);
-    v8::Handle<v8::Value> local =
-        v8::Utils::ToLocal(eternals->Get(indices[i]));
-    v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(local);
-    v8::Handle<v8::Value> value = object->Get(i);
-    CHECK(value->IsInt32());
-    CHECK_EQ(i, value->Int32Value());
+    for (int j = 0; j < 2; j++) {
+      HandleScope scope(isolate);
+      v8::Local<v8::Object> object;
+      if (j == 0) {
+        // Test internal api
+        v8::Local<v8::Value> local =
+            v8::Utils::ToLocal(eternals->Get(indices[i]));
+        object = v8::Handle<v8::Object>::Cast(local);
+      } else {
+        // Test external api
+        object = v8::Local<v8::Object>::GetEternal(v8_isolate, indices[i]);
+      }
+      v8::Local<v8::Value> value = object->Get(i);
+      CHECK(value->IsInt32());
+      CHECK_EQ(i, value->Int32Value());
+    }
   }

   CHECK_EQ(kArrayLength, eternals->NumberOfHandles());


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to