Allow empty handles to escape handle scopes.
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 25 Mar 2010 14:07:17 +0000 (14:07 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 25 Mar 2010 14:07:17 +0000 (14:07 +0000)
BUG=39170

Review URL: http://codereview.chromium.org/1235002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4278 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/api.cc
src/api.h
test/cctest/test-heap.cc

index d8e85b9..2100480 100644 (file)
@@ -537,10 +537,17 @@ i::Object** v8::HandleScope::RawClose(i::Object** value) {
   LOG_API("CloseHandleScope");
 
   // Read the result before popping the handle block.
-  i::Object* result = *value;
+  i::Object* result = NULL;
+  if (value != NULL) {
+    result = *value;
+  }
   is_closed_ = true;
   i::HandleScope::Leave(&previous_);
 
+  if (value == NULL) {
+    return NULL;
+  }
+
   // Allocate a new handle on the previous handle block.
   i::Handle<i::Object> handle(result);
   return handle.location();
index 2f1f77c..7b88112 100644 (file)
--- a/src/api.h
+++ b/src/api.h
@@ -247,7 +247,11 @@ static inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
 template <class T>
 v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom(
     v8::HandleScope* scope) {
-  return Utils::OpenHandle(*scope->Close(Utils::ToLocal(*this)));
+  v8::internal::Handle<T> handle;
+  if (!is_null()) {
+    handle = *this;
+  }
+  return Utils::OpenHandle(*scope->Close(Utils::ToLocal(handle)));
 }
 
 
@@ -255,7 +259,7 @@ v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom(
 
 #define MAKE_TO_LOCAL(Name, From, To)                                       \
   Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \
-    ASSERT(!obj->IsTheHole());                                              \
+    ASSERT(obj.is_null() || !obj->IsTheHole());                             \
     return Local<To>(reinterpret_cast<To*>(obj.location()));                \
   }
 
index 2b88f0f..6999889 100644 (file)
@@ -852,3 +852,19 @@ TEST(LargeObjectSpaceContains) {
   CHECK(Heap::new_space()->Contains(addr));
   CHECK(!Heap::lo_space()->Contains(addr));
 }
+
+
+TEST(EmptyHandleEscapeFrom) {
+  InitializeVM();
+
+  v8::HandleScope scope;
+  Handle<JSObject> runaway;
+
+  {
+      v8::HandleScope nested;
+      Handle<JSObject> empty;
+      runaway = empty.EscapeFrom(&nested);
+  }
+
+  CHECK(runaway.is_null());
+}