| Index: gin/foo.cc
|
| diff --git a/gin/foo.cc b/gin/foo.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e993c1e75d1639f2c5150cd359ccaea1f8dafe00
|
| --- /dev/null
|
| +++ b/gin/foo.cc
|
| @@ -0,0 +1,96 @@
|
| +foo.cc
|
| +// Copyright 2013 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 "gin/wrappable.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "gin/object_template_builder.h"
|
| +#include "gin/per_isolate_data.h"
|
| +
|
| +namespace gin {
|
| +
|
| +WrappableBase::WrappableBase() {
|
| +}
|
| +
|
| +WrappableBase::~WrappableBase() {
|
| + wrapper_.Reset();
|
| +}
|
| +
|
| +ObjectTemplateBuilder WrappableBase::GetObjectTemplateBuilder(
|
| + v8::Isolate* isolate) {
|
| + return ObjectTemplateBuilder(isolate);
|
| +}
|
| +
|
| +void WrappableBase::FirstWeakCallback(
|
| + const v8::WeakCallbackInfo<WrappableBase>& data) {
|
| + WrappableBase* wrappable = data.GetParameter();
|
| + wrappable->wrapper_.Reset();
|
| + data.SetSecondPassCallback(SecondWeakCallback);
|
| +}
|
| +
|
| +void WrappableBase::SecondWeakCallback(
|
| + const v8::WeakCallbackInfo<WrappableBase>& data) {
|
| + WrappableBase* wrappable = data.GetParameter();
|
| + delete wrappable;
|
| +}
|
| +
|
| +v8::Local<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
|
| + WrapperInfo* info) {
|
| + if (!wrapper_.IsEmpty()) {
|
| + return v8::Local<v8::Object>::New(isolate, wrapper_);
|
| + }
|
| +
|
| + PerIsolateData* data = PerIsolateData::From(isolate);
|
| + v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(info);
|
| + if (templ.IsEmpty()) {
|
| + templ = GetObjectTemplateBuilder(isolate).Build();
|
| + CHECK(!templ.IsEmpty());
|
| + data->SetObjectTemplate(info, templ);
|
| + }
|
| + CHECK_EQ(kNumberOfInternalFields, templ->InternalFieldCount());
|
| + v8::Local<v8::Object> wrapper;
|
| + // |wrapper| may be empty in some extreme cases, e.g., when
|
| + // Object.prototype.constructor is overwritten.
|
| + if (!templ->NewInstance(isolate->GetCurrentContext()).ToLocal(&wrapper)) {
|
| + // The current wrappable object will be no longer managed by V8. Delete this
|
| + // now.
|
| + delete this;
|
| + return wrapper;
|
| + }
|
| +
|
| + int indices[] = {kWrapperInfoIndex, kEncodedValueIndex};
|
| + void* values[] = {info, this};
|
| + wrapper->SetAlignedPointerInInternalFields(2, indices, values);
|
| + wrapper_.Reset(isolate, wrapper);
|
| + wrapper_.SetWeak(this, FirstWeakCallback, v8::WeakCallbackType::kParameter);
|
| + return wrapper;
|
| +}
|
| +
|
| +namespace internal {
|
| +
|
| +void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
| + WrapperInfo* wrapper_info) {
|
| + if (!val->IsObject())
|
| + return NULL;
|
| + v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(val);
|
| + WrapperInfo* info = WrapperInfo::From(obj);
|
| +
|
| + // If this fails, the object is not managed by Gin. It is either a normal JS
|
| + // object that's not wrapping any external C++ object, or it is wrapping some
|
| + // C++ object, but that object isn't managed by Gin (maybe Blink).
|
| + if (!info)
|
| + return NULL;
|
| +
|
| + // If this fails, the object is managed by Gin, but it's not wrapping an
|
| + // instance of the C++ class associated with wrapper_info.
|
| + if (info != wrapper_info)
|
| + return NULL;
|
| +
|
| + return obj->GetAlignedPointerFromInternalField(kEncodedValueIndex);
|
| +}
|
| +
|
| +} // namespace internal
|
| +
|
| +} // namespace gin
|
|
|