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