Revision: 16965
Author: [email protected]
Date: Thu Sep 26 13:46:37 2013 UTC
Log: Add EscapableHandleScope to api to fix problems with
HandleScope::Close
[email protected]
BUG=
Review URL: https://codereview.chromium.org/24245005
http://code.google.com/p/v8/source/detail?r=16965
Modified:
/branches/bleeding_edge/include/v8.h
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/test/cctest/test-api.cc
=======================================
--- /branches/bleeding_edge/include/v8.h Thu Sep 26 13:31:19 2013 UTC
+++ /branches/bleeding_edge/include/v8.h Thu Sep 26 13:46:37 2013 UTC
@@ -135,6 +135,7 @@
class ObjectOperationDescriptor;
class RawOperationDescriptor;
class CallHandlerHelper;
+class EscapableHandleScope;
namespace internal {
class Arguments;
@@ -401,6 +402,7 @@
friend class Context;
template<class F> friend class internal::CustomArguments;
friend class HandleScope;
+ friend class EscapableHandleScope;
V8_INLINE static Local<T> New(Isolate* isolate, T* that);
};
@@ -773,10 +775,7 @@
~HandleScope();
- /**
- * Closes the handle scope and returns the value as a handle in the
- * previous scope, which is the new current scope after the call.
- */
+ // TODO(dcarney): deprecated - use EscapableHandleScope::Escape.
template <class T> Local<T> Close(Handle<T> value);
/**
@@ -794,6 +793,9 @@
static internal::Object** CreateHandle(internal::HeapObject* value);
private:
+ V8_INLINE HandleScope() {}
+ void Initialize(Isolate* isolate);
+
// Make it hard to create heap-allocated or illegal handle scopes by
// disallowing certain operations.
HandleScope(const HandleScope&);
@@ -814,19 +816,47 @@
}
};
- void Initialize(Isolate* isolate);
void Leave();
internal::Isolate* isolate_;
internal::Object** prev_next_;
internal::Object** prev_limit_;
+ // TODO(dcarney): remove this field
// Allow for the active closing of HandleScopes which allows to pass a
handle
// from the HandleScope being closed to the next top most HandleScope.
bool is_closed_;
internal::Object** RawClose(internal::Object** value);
friend class ImplementationUtilities;
+ friend class EscapableHandleScope;
+};
+
+
+/**
+ * A HandleScope which first allocates a handle in the current scope
+ * which will be later filled with the escape value.
+ */
+class V8_EXPORT EscapableHandleScope : public HandleScope {
+ public:
+ EscapableHandleScope(Isolate* isolate);
+ V8_INLINE ~EscapableHandleScope() {}
+
+ /**
+ * Pushes the value into the previous scope and returns a handle to it.
+ * Cannot be called twice.
+ */
+ template <class T>
+ V8_INLINE Local<T> Escape(Local<T> value) {
+ internal::Object** slot =
+ Escape(reinterpret_cast<internal::Object**>(*value));
+ return Local<T>(reinterpret_cast<T*>(slot));
+ }
+
+ private:
+ internal::Object** Escape(internal::Object** escape_value);
+
+ internal::Object** escape_slot_;
};
=======================================
--- /branches/bleeding_edge/src/api.cc Thu Sep 26 09:40:13 2013 UTC
+++ /branches/bleeding_edge/src/api.cc Thu Sep 26 13:46:37 2013 UTC
@@ -699,6 +699,26 @@
return reinterpret_cast<i::Object**>(
i::HandleScope::CreateHandle(value->GetIsolate(), value));
}
+
+
+EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+ escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
+ Initialize(v8_isolate);
+}
+
+
+i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
+ ApiCheck(*escape_slot_ == isolate_->heap()->the_hole_value(),
+ "EscapeableHandleScope::Escape",
+ "Escape value set twice");
+ if (escape_value == NULL) {
+ *escape_slot_ = isolate_->heap()->undefined_value();
+ return NULL;
+ }
+ *escape_slot_ = *escape_value;
+ return escape_slot_;
+}
void Context::Enter() {
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Thu Sep 26 08:21:48
2013 UTC
+++ /branches/bleeding_edge/test/cctest/test-api.cc Thu Sep 26 13:46:37
2013 UTC
@@ -20593,3 +20593,24 @@
CHECK_EQ(v8::Integer::New(17, isolate), result2);
}
+
+TEST(EscapeableHandleScope) {
+ HandleScope outer_scope(CcTest::isolate());
+ LocalContext context;
+ const int runs = 10;
+ Local<String> values[runs];
+ for (int i = 0; i < runs; i++) {
+ v8::EscapableHandleScope inner_scope(CcTest::isolate());
+ Local<String> value;
+ if (i != 0) value = v8_str("escape value");
+ values[i] = inner_scope.Escape(value);
+ }
+ for (int i = 0; i < runs; i++) {
+ Local<String> expected;
+ if (i != 0) {
+ CHECK_EQ(v8_str("escape value"), values[i]);
+ } else {
+ CHECK(values[i].IsEmpty());
+ }
+ }
+}
--
--
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.