Home | History | Annotate | Download | only in gin
      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