wrappable.cc revision f2477e01787aa58f445919b809d89e252beef54f
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
12Wrappable::Wrappable() {
13}
14
15Wrappable::~Wrappable() {
16  wrapper_.Reset();
17}
18
19v8::Handle<v8::Object> Wrappable::GetWrapper(v8::Isolate* isolate) {
20  v8::Handle<v8::Value> wrapper = ConvertToV8(isolate, this);
21  DCHECK(wrapper->IsObject());
22  return v8::Handle<v8::Object>::Cast(wrapper);
23}
24
25void Wrappable::WeakCallback(
26    const v8::WeakCallbackData<v8::Object, Wrappable>& data) {
27  Wrappable* wrappable = data.GetParameter();
28  wrappable->wrapper_.Reset();
29  wrappable->Release();  // Balanced in Wrappable::ConfigureWrapper.
30}
31
32v8::Handle<v8::Object> Wrappable::CreateWrapper(v8::Isolate* isolate) {
33  WrapperInfo* info = GetWrapperInfo();
34  PerIsolateData* data = PerIsolateData::From(isolate);
35  v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(info);
36  CHECK(!templ.IsEmpty());  // Don't forget to register an object template.
37  CHECK(templ->InternalFieldCount() == kNumberOfInternalFields);
38  v8::Handle<v8::Object> wrapper = templ->NewInstance();
39  wrapper->SetAlignedPointerInInternalField(kWrapperInfoIndex, info);
40  wrapper->SetAlignedPointerInInternalField(kEncodedValueIndex, this);
41  wrapper_.Reset(isolate, wrapper);
42  AddRef();  // Balanced in Wrappable::WeakCallback.
43  wrapper_.SetWeak(this, WeakCallback);
44  return wrapper;
45}
46
47v8::Handle<v8::Value> Converter<Wrappable*>::ToV8(v8::Isolate* isolate,
48                                                  Wrappable* val) {
49  if (val->wrapper_.IsEmpty())
50    return val->CreateWrapper(isolate);
51  return v8::Local<v8::Object>::New(isolate, val->wrapper_);
52}
53
54bool Converter<Wrappable*>::FromV8(v8::Isolate* isolate,
55                                   v8::Handle<v8::Value> val, Wrappable** out) {
56  if (!val->IsObject())
57    return false;
58  v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(val);
59  WrapperInfo* info = WrapperInfo::From(obj);
60  if (!info)
61    return false;
62  void* pointer = obj->GetAlignedPointerFromInternalField(kEncodedValueIndex);
63  Wrappable* wrappable = static_cast<Wrappable*>(pointer);
64  CHECK(wrappable->GetWrapperInfo() == info);  // Security check for cast above.
65  *out = wrappable;
66  return true;
67}
68
69}  // namespace gin
70