#include "bindings/v8/UnsafePersistent.h"
#include "bindings/v8/V8DOMActivityLogger.h"
#include "bindings/v8/WrapperTypeInfo.h"
+#include "gin/public/context_holder.h"
+#include "gin/public/gin_embedders.h"
#include <v8.h>
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
class CustomElementDefinition;
+class DOMWrapperWorld;
+class V8PerContextData;
struct V8NPObject;
typedef WTF::Vector<V8NPObject*> V8NPObjectVector;
typedef WTF::HashMap<int, V8NPObjectVector> V8NPObjectMap;
enum V8ContextEmbedderDataField {
- v8ContextDebugIdIndex,
- v8ContextPerContextDataIndex,
- v8ContextIsolatedWorld,
- // Rather than adding more embedder data fields to v8::Context,
- // consider adding the data to V8PerContextData instead.
+ v8ContextDebugIdIndex = static_cast<int>(gin::kDebugIdIndex),
+ v8ContextPerContextDataIndex = static_cast<int>(gin::kPerContextDataStartIndex + gin::kEmbedderBlink),
+};
+
+class V8PerContextDataHolder {
+ WTF_MAKE_NONCOPYABLE(V8PerContextDataHolder);
+public:
+ static void install(v8::Handle<v8::Context> context, DOMWrapperWorld* world)
+ {
+ new V8PerContextDataHolder(context, world);
+ }
+
+ static V8PerContextDataHolder* from(v8::Handle<v8::Context> context)
+ {
+ return static_cast<V8PerContextDataHolder*>(context->GetAlignedPointerFromEmbedderData(v8ContextPerContextDataIndex));
+ }
+
+ V8PerContextData* perContextData() const { return m_perContextData; }
+ void setPerContextData(V8PerContextData* data) { m_perContextData = data; }
+
+ DOMWrapperWorld* world() const { return m_world; }
+
+private:
+ V8PerContextDataHolder(v8::Handle<v8::Context> context, DOMWrapperWorld* world)
+ : m_context(v8::Isolate::GetCurrent(), context)
+ , m_perContextData(0)
+ , m_world(world)
+ {
+ m_context.setWeak(this, &V8PerContextDataHolder::weakCallback);
+ context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, this);
+ }
+
+ ~V8PerContextDataHolder() {}
+
+ static void weakCallback(const v8::WeakCallbackData<v8::Context, V8PerContextDataHolder>& data)
+ {
+ data.GetValue()->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, 0);
+ delete data.GetParameter();
+ }
+
+ ScopedPersistent<v8::Context> m_context;
+ V8PerContextData* m_perContextData;
+ // This should not be a RefPtr. Otherwise, it creates a cycle:
+ // V8PerContextData => DOMWrapperWorld => DOMDataStore => global objects
+ // => Window or WorkerGlobalScope => V8PerContextData.
+ DOMWrapperWorld* m_world;
};
class V8PerContextData {
return adoptPtr(new V8PerContextData(context));
}
- ~V8PerContextData()
- {
- dispose();
- }
+ ~V8PerContextData();
bool init();
static V8PerContextData* from(v8::Handle<v8::Context> context)
{
- return static_cast<V8PerContextData*>(context->GetAlignedPointerFromEmbedderData(v8ContextPerContextDataIndex));
+ return V8PerContextDataHolder::from(context)->perContextData();
}
// To create JS Wrapper objects, we create a cache of a 'boiler plate'
{
}
- void dispose();
-
v8::Local<v8::Object> createWrapperFromCacheSlowCase(const WrapperTypeInfo*);
v8::Local<v8::Function> constructorForTypeSlowCase(const WrapperTypeInfo*);
// by the DOMActivityLoggerMap in DOMWrapperWorld.
V8DOMActivityLogger* m_activityLogger;
v8::Isolate* m_isolate;
- v8::Persistent<v8::Context> m_context;
+ ScopedPersistent<v8::Context> m_context;
ScopedPersistent<v8::Value> m_errorPrototype;
typedef WTF::HashMap<CustomElementDefinition*, OwnPtr<CustomElementBinding> > CustomElementBindingMap;