[M120 Migration] Set IO|GPU thread type with higher priorites
[platform/framework/web/chromium-efl.git] / gin / wrappable.h
1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef GIN_WRAPPABLE_H_
6 #define GIN_WRAPPABLE_H_
7
8 #include <type_traits>
9
10 #include "gin/converter.h"
11 #include "gin/gin_export.h"
12 #include "gin/public/wrapper_info.h"
13
14 namespace gin {
15
16 // Wrappable is a base class for C++ objects that have corresponding v8 wrapper
17 // objects. To retain a Wrappable object on the stack, use a gin::Handle.
18 //
19 // USAGE:
20 // // my_class.h
21 // class MyClass : Wrappable<MyClass> {
22 //  public:
23 //   static WrapperInfo kWrapperInfo;
24 //
25 //   // Optional, only required if non-empty template should be used.
26 //   virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
27 //       v8::Isolate* isolate);
28 //   ...
29 // };
30 //
31 // // my_class.cc
32 // WrapperInfo MyClass::kWrapperInfo = {kEmbedderNativeGin};
33 //
34 // gin::ObjectTemplateBuilder MyClass::GetObjectTemplateBuilder(
35 //     v8::Isolate* isolate) {
36 //   return Wrappable<MyClass>::GetObjectTemplateBuilder(isolate)
37 //       .SetValue("foobar", 42);
38 // }
39 //
40 // Subclasses should also typically have private constructors and expose a
41 // static Create function that returns a gin::Handle. Forcing creators through
42 // this static Create function will enforce that clients actually create a
43 // wrapper for the object. If clients fail to create a wrapper for a wrappable
44 // object, the object will leak because we use the weak callback from the
45 // wrapper as the signal to delete the wrapped object.
46 //
47 // Wrappable<T> explicitly does not support further subclassing of T.
48 // Subclasses of Wrappable<T> should be declared final. Because Wrappable<T>
49 // caches the object template using &T::kWrapperInfo as the key, all subclasses
50 // would share a single object template. This will lead to hard to debug crashes
51 // that look like use-after-free errors.
52
53 namespace internal {
54
55 GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
56                             v8::Local<v8::Value> val,
57                             WrapperInfo* info);
58
59 }  // namespace internal
60
61 class ObjectTemplateBuilder;
62
63 // Non-template base class to share code between templates instances.
64 class GIN_EXPORT WrappableBase {
65  public:
66   WrappableBase(const WrappableBase&) = delete;
67   WrappableBase& operator=(const WrappableBase&) = delete;
68
69  protected:
70   WrappableBase();
71   virtual ~WrappableBase();
72
73   // Overrides of this method should be declared final and not overridden again.
74   virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
75
76   // Returns a readable type name that will be used in surfacing errors. The
77   // default implementation returns nullptr, which results in a generic error.
78   virtual const char* GetTypeName();
79
80   v8::MaybeLocal<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
81                                             WrapperInfo* wrapper_info);
82
83  private:
84   static void FirstWeakCallback(
85       const v8::WeakCallbackInfo<WrappableBase>& data);
86   static void SecondWeakCallback(
87       const v8::WeakCallbackInfo<WrappableBase>& data);
88
89   bool dead_ = false;
90   v8::Global<v8::Object> wrapper_;  // Weak
91 };
92
93
94 template<typename T>
95 class Wrappable : public WrappableBase {
96  public:
97   Wrappable(const Wrappable&) = delete;
98   Wrappable& operator=(const Wrappable&) = delete;
99
100   // Retrieve (or create) the v8 wrapper object corresponding to this object.
101   v8::MaybeLocal<v8::Object> GetWrapper(v8::Isolate* isolate) {
102     return GetWrapperImpl(isolate, &T::kWrapperInfo);
103   }
104
105  protected:
106   Wrappable() = default;
107   ~Wrappable() override = default;
108 };
109
110 template <typename T>
111 struct ToV8ReturnsMaybe<
112     T*,
113     typename std::enable_if<
114         std::is_convertible<T*, WrappableBase*>::value>::type> {
115   static const bool value = true;
116 };
117
118 // This converter handles any subclass of Wrappable.
119 template <typename T>
120 struct Converter<T*,
121                  typename std::enable_if<
122                      std::is_convertible<T*, WrappableBase*>::value>::type> {
123   static v8::MaybeLocal<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
124     if (val == nullptr)
125       return v8::Null(isolate);
126     v8::Local<v8::Object> wrapper;
127     if (!val->GetWrapper(isolate).ToLocal(&wrapper))
128       return v8::MaybeLocal<v8::Value>();
129     return v8::MaybeLocal<v8::Value>(wrapper);
130   }
131
132   static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, T** out) {
133     *out = static_cast<T*>(static_cast<WrappableBase*>(
134         internal::FromV8Impl(isolate, val, &T::kWrapperInfo)));
135     return *out != NULL;
136   }
137 };
138
139 }  // namespace gin
140
141 #endif  // GIN_WRAPPABLE_H_