Allow empty handles to escape handle scopes.

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
This commit is contained in:
antonm@chromium.org 2010-03-25 14:07:17 +00:00
parent 6a8398cffa
commit f45c35ebd3
3 changed files with 30 additions and 3 deletions

View File

@ -537,10 +537,17 @@ i::Object** v8::HandleScope::RawClose(i::Object** value) {
LOG_API("CloseHandleScope"); LOG_API("CloseHandleScope");
// Read the result before popping the handle block. // Read the result before popping the handle block.
i::Object* result = *value; i::Object* result = NULL;
if (value != NULL) {
result = *value;
}
is_closed_ = true; is_closed_ = true;
i::HandleScope::Leave(&previous_); i::HandleScope::Leave(&previous_);
if (value == NULL) {
return NULL;
}
// Allocate a new handle on the previous handle block. // Allocate a new handle on the previous handle block.
i::Handle<i::Object> handle(result); i::Handle<i::Object> handle(result);
return handle.location(); return handle.location();

View File

@ -247,7 +247,11 @@ static inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
template <class T> template <class T>
v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom( v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom(
v8::HandleScope* scope) { 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) \ #define MAKE_TO_LOCAL(Name, From, To) \
Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \ 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())); \ return Local<To>(reinterpret_cast<To*>(obj.location())); \
} }

View File

@ -852,3 +852,19 @@ TEST(LargeObjectSpaceContains) {
CHECK(Heap::new_space()->Contains(addr)); CHECK(Heap::new_space()->Contains(addr));
CHECK(!Heap::lo_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());
}