1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "bindings/core/v8/ScriptWrappable.h"
#include "bindings/core/v8/DOMDataStore.h"
#include "bindings/core/v8/V8DOMWrapper.h"
namespace blink {
struct SameSizeAsScriptWrappable {
virtual ~SameSizeAsScriptWrappable() { }
v8::Persistent<v8::Object> m_wrapper;
};
static_assert(sizeof(ScriptWrappable) <= sizeof(SameSizeAsScriptWrappable), "ScriptWrappable should stay small");
namespace {
class ScriptWrappableProtector final {
WTF_MAKE_NONCOPYABLE(ScriptWrappableProtector);
public:
ScriptWrappableProtector(ScriptWrappable* scriptWrappable, const WrapperTypeInfo* wrapperTypeInfo)
: m_scriptWrappable(scriptWrappable), m_wrapperTypeInfo(wrapperTypeInfo)
{
m_wrapperTypeInfo->refObject(m_scriptWrappable);
}
~ScriptWrappableProtector()
{
m_wrapperTypeInfo->derefObject(m_scriptWrappable);
}
private:
ScriptWrappable* m_scriptWrappable;
const WrapperTypeInfo* m_wrapperTypeInfo;
};
} // namespace
v8::Handle<v8::Object> ScriptWrappable::wrap(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
const WrapperTypeInfo* wrapperTypeInfo = this->wrapperTypeInfo();
// It's possible that no one except for the new wrapper owns this object at
// this moment, so we have to prevent GC to collect this object until the
// object gets associated with the wrapper.
ScriptWrappableProtector protect(this, wrapperTypeInfo);
ASSERT(!DOMDataStore::containsWrapper(this, isolate));
v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(isolate, creationContext, wrapperTypeInfo, this);
if (UNLIKELY(wrapper.IsEmpty()))
return wrapper;
wrapperTypeInfo->installConditionallyEnabledProperties(wrapper, isolate);
return associateWithWrapper(isolate, wrapperTypeInfo, wrapper);
}
v8::Handle<v8::Object> ScriptWrappable::associateWithWrapper(v8::Isolate* isolate, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper)
{
return V8DOMWrapper::associateObjectWithWrapper(isolate, this, wrapperTypeInfo, wrapper);
}
} // namespace blink
|