wrappable.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "gin/wrappable.h"
6
7#include "base/logging.h"
8#include "gin/per_isolate_data.h"
9
10namespace gin {
11
12WrappableBase::WrappableBase() {
13}
14
15WrappableBase::~WrappableBase() {
16  wrapper_.Reset();
17}
18
19v8::Handle<v8::Object> WrappableBase::GetWrapperImpl(
20    v8::Isolate* isolate, WrapperInfo* wrapper_info) {
21    if (wrapper_.IsEmpty())
22      CreateWrapper(isolate, wrapper_info);
23    return v8::Local<v8::Object>::New(isolate, wrapper_);
24}
25
26void WrappableBase::WeakCallback(
27    const v8::WeakCallbackData<v8::Object, WrappableBase>& data) {
28  WrappableBase* wrappable = data.GetParameter();
29  wrappable->wrapper_.Reset();
30  delete wrappable;
31}
32
33v8::Handle<v8::Object> WrappableBase::CreateWrapper(v8::Isolate* isolate,
34                                                    WrapperInfo* info) {
35  PerIsolateData* data = PerIsolateData::From(isolate);
36  v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(info);
37  CHECK(!templ.IsEmpty());  // Don't forget to register an object template.
38  CHECK_EQ(kNumberOfInternalFields, templ->InternalFieldCount());
39  v8::Handle<v8::Object> wrapper = templ->NewInstance();
40  wrapper->SetAlignedPointerInInternalField(kWrapperInfoIndex, info);
41  wrapper->SetAlignedPointerInInternalField(kEncodedValueIndex, this);
42  wrapper_.Reset(isolate, wrapper);
43  wrapper_.SetWeak(this, WeakCallback);
44  return wrapper;
45}
46
47namespace internal {
48
49void* FromV8Impl(v8::Isolate* isolate, v8::Handle<v8::Value> val,
50                 WrapperInfo* wrapper_info) {
51  if (!val->IsObject())
52    return NULL;
53  v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(val);
54  WrapperInfo* info = WrapperInfo::From(obj);
55
56  // If this fails, the object is not managed by Gin. It is either a normal JS
57  // object that's not wrapping any external C++ object, or it is wrapping some
58  // C++ object, but that object isn't managed by Gin (maybe Blink).
59  if (!info)
60    return NULL;
61
62  // If this fails, the object is managed by Gin, but it's not wrapping an
63  // instance of the C++ class associated with wrapper_info.
64  if (info != wrapper_info)
65    return NULL;
66
67  return obj->GetAlignedPointerFromInternalField(kEncodedValueIndex);
68}
69
70}  // namespace internal
71
72}  // namespace gin
73