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 10 namespace gin { 11 12 WrappableBase::WrappableBase() { 13 } 14 15 WrappableBase::~WrappableBase() { 16 wrapper_.Reset(); 17 } 18 19 v8::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 26 void WrappableBase::WeakCallback( 27 const v8::WeakCallbackData<v8::Object, WrappableBase>& data) { 28 WrappableBase* wrappable = data.GetParameter(); 29 wrappable->wrapper_.Reset(); 30 delete wrappable; 31 } 32 33 v8::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 47 namespace internal { 48 49 void* 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