Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef GIN_WRAPPABLE_H_ | 5 #ifndef GIN_WRAPPABLE_H_ |
| 6 #define GIN_WRAPPABLE_H_ | 6 #define GIN_WRAPPABLE_H_ |
| 7 | 7 |
| 8 #include "base/template_util.h" | |
| 8 #include "gin/converter.h" | 9 #include "gin/converter.h" |
| 9 #include "gin/public/wrapper_info.h" | 10 #include "gin/public/wrapper_info.h" |
| 10 | 11 |
| 11 namespace gin { | 12 namespace gin { |
| 12 | 13 |
| 13 // Wrappable is an abstract base class for C++ objects that have cooresponding | 14 // Wrappable is an abstract base class for C++ objects that have cooresponding |
| 14 // v8 wrapper objects. To retain a Wrappable object on the stack, use a | 15 // v8 wrapper objects. To retain a Wrappable object on the stack, use a |
| 15 // gin::Handle. | 16 // gin::Handle. |
| 16 class Wrappable { | 17 class Wrappable { |
| 17 public: | 18 public: |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 46 // Create function will enforce that clients actually create a wrapper for | 47 // Create function will enforce that clients actually create a wrapper for |
| 47 // the object. If clients fail to create a wrapper for a wrappable object, | 48 // the object. If clients fail to create a wrapper for a wrappable object, |
| 48 // the object will leak because we use the weak callback from the wrapper | 49 // the object will leak because we use the weak callback from the wrapper |
| 49 // as the signal to delete the wrapped object. | 50 // as the signal to delete the wrapped object. |
| 50 | 51 |
| 51 protected: | 52 protected: |
| 52 Wrappable(); | 53 Wrappable(); |
| 53 virtual ~Wrappable(); | 54 virtual ~Wrappable(); |
| 54 | 55 |
| 55 private: | 56 private: |
| 56 friend struct Converter<Wrappable*>; | |
| 57 | |
| 58 static void WeakCallback( | 57 static void WeakCallback( |
| 59 const v8::WeakCallbackData<v8::Object, Wrappable>& data); | 58 const v8::WeakCallbackData<v8::Object, Wrappable>& data); |
| 60 v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate); | 59 v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate); |
| 61 | 60 |
| 62 v8::Persistent<v8::Object> wrapper_; // Weak | 61 v8::Persistent<v8::Object> wrapper_; // Weak |
| 63 | 62 |
| 64 DISALLOW_COPY_AND_ASSIGN(Wrappable); | 63 DISALLOW_COPY_AND_ASSIGN(Wrappable); |
| 65 }; | 64 }; |
| 66 | 65 |
| 67 template<> | 66 // This converter handles any subclass of Wrappable. |
| 68 struct Converter<Wrappable*> { | 67 template<typename T> |
| 69 static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, | 68 struct Converter<T, typename base::enable_if< |
| 70 Wrappable* val); | 69 base::is_convertible<T, Wrappable*>::value>::type> { |
| 71 static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, | 70 static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, T val) { |
| 72 Wrappable** out); | 71 return val->GetWrapper(isolate); |
| 73 }; | 72 } |
| 74 | 73 |
| 75 template<typename T> | 74 static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, T* out) { |
| 76 struct WrappableConverter { | 75 if (!val->IsObject()) |
| 77 static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, T* val) { | |
| 78 return Converter<Wrappable*>::ToV8(isolate, val); | |
| 79 } | |
| 80 static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, T** out) { | |
| 81 Wrappable* wrappable = NULL; | |
| 82 if (!Converter<Wrappable*>::FromV8(isolate, val, &wrappable) | |
| 83 || wrappable->GetWrapperInfo() != &T::kWrapperInfo) | |
|
abarth-chromium
2013/12/06 01:50:55
I think we're missing this security check. You ne
| |
| 84 return false; | 76 return false; |
| 85 // Currently we require that you unwrap to the exact runtime type of the | 77 v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(val); |
| 86 // wrapped object. | 78 WrapperInfo* info = WrapperInfo::From(obj); |
| 87 // TODO(abarth): Support unwrapping to a base class. | 79 if (!info) |
| 88 *out = static_cast<T*>(wrappable); | 80 return false; |
| 81 void* pointer = obj->GetAlignedPointerFromInternalField(kEncodedValueIndex); | |
| 82 T result = static_cast<T>(pointer); | |
| 83 CHECK(result->GetWrapperInfo() == info); // Security check for cast above. | |
| 84 *out = result; | |
| 89 return true; | 85 return true; |
| 90 } | 86 } |
| 91 }; | 87 }; |
| 92 | 88 |
| 93 } // namespace gin | 89 } // namespace gin |
| 94 | 90 |
| 95 #endif // GIN_WRAPPABLE_H_ | 91 #endif // GIN_WRAPPABLE_H_ |
| OLD | NEW |