Index: src/handles.h |
diff --git a/src/handles.h b/src/handles.h |
index 8f1664bb4e00b8e108a1b1a0908c634ac3dac938..50b2d3f3aae65b7ce0ea0d7259205c247387dd36 100644 |
--- a/src/handles.h |
+++ b/src/handles.h |
@@ -93,55 +93,6 @@ class Handle { |
}; |
-// A handle-scope based variable. The value stored in the variable can change |
-// over time. The value stored in the variable at any time is a root |
-// for garbage collection. |
-// The variable is backed by the current HandleScope. |
-template <typename T> |
-class HandleCell { |
- public: |
- // Create a new HandleCell holding the given value. |
- explicit HandleCell(Handle<T> value); |
- explicit HandleCell(T* value); |
- |
- // Create an alias of an existing HandleCell. |
- explicit HandleCell(const HandleCell<T>& value) |
- : location_(value.location_) { } |
- |
- INLINE(T* operator->() const) { return operator*(); } |
- INLINE(T* operator*() const) { |
- return *location_; |
- } |
- INLINE(void operator=(T* value)) { |
- *location_ = value; |
- } |
- INLINE(void operator=(Handle<T> value)) { |
- *location_ = *value; |
- } |
- INLINE(void operator=(const HandleCell<T>& value)) { |
- *location_ = *value.location_; |
- } |
- |
- // Extract the value of the variable and cast it to a give type. |
- // This is typically used for calling methods on a more specialized type. |
- template <typename S> |
- inline S* cast() { |
- S::cast(*location_); |
- return *reinterpret_cast<S**>(location_); |
- } |
- |
- Handle<T> ToHandle() const { |
- return Handle<T>(*location_); |
- } |
- |
- private: |
- // Prevent implicit constructor from being created. |
- HandleCell(); |
- |
- T** location_; |
-}; |
- |
- |
// A stack-allocated class that governs a number of local handles. |
// After a handle scope has been created, all local handles will be |
// allocated within that handle scope until either the handle scope is |
@@ -161,15 +112,7 @@ class HandleScope { |
} |
~HandleScope() { |
- current_.next = prev_next_; |
- current_.level--; |
- if (current_.limit != prev_limit_) { |
- current_.limit = prev_limit_; |
- DeleteExtensions(); |
- } |
-#ifdef DEBUG |
- ZapRange(prev_next_, prev_limit_); |
-#endif |
+ CloseScope(); |
} |
// Counts the number of allocated handles. |
@@ -197,6 +140,26 @@ class HandleScope { |
static Address current_limit_address(); |
static Address current_level_address(); |
+ // Closes the HandleScope (invalidating all handles |
+ // created in the scope of the HandleScope) and returns |
+ // a Handle backed by the parent scope holding the |
+ // value of the argument handle. |
+ template <typename T> |
+ Handle<T> CloseAndEscape(Handle<T> handle_value) { |
+ T* value = *handle_value; |
+ // Throw away all handles in the current scope. |
+ CloseScope(); |
+ // Allocate one handle in the parent scope. |
+ ASSERT(current_.level > 0); |
+ Handle<T> result(CreateHandle<T>(value)); |
+ // Reinitialize the current scope (so that it's ready |
+ // to be used or closed again). |
+ prev_next_ = current_.next; |
+ prev_limit_ = current_.limit; |
+ current_.level++; |
+ return result; |
+ } |
+ |
private: |
// Prevent heap allocation or illegal handle scopes. |
HandleScope(const HandleScope&); |
@@ -204,9 +167,23 @@ class HandleScope { |
void* operator new(size_t size); |
void operator delete(void* size_t); |
+ inline void CloseScope() { |
+ current_.next = prev_next_; |
+ current_.level--; |
+ if (current_.limit != prev_limit_) { |
+ current_.limit = prev_limit_; |
+ DeleteExtensions(); |
+ } |
+#ifdef DEBUG |
+ ZapRange(prev_next_, prev_limit_); |
+#endif |
+ } |
+ |
static v8::ImplementationUtilities::HandleScopeData current_; |
- Object** const prev_next_; |
- Object** const prev_limit_; |
+ // Holds values on entry. The prev_next_ value is never NULL |
+ // on_entry, but is set to NULL when this scope is closed. |
+ Object** prev_next_; |
+ Object** prev_limit_; |
// Extend the handle scope making room for more handles. |
static internal::Object** Extend(); |