Flutter Engine
The Flutter Engine
dart_wrappable.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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#ifndef LIB_TONIC_DART_WRAPPABLE_H_
6#define LIB_TONIC_DART_WRAPPABLE_H_
7
8#include "third_party/dart/runtime/include/dart_api.h"
11#include "tonic/dart_state.h"
15
16#include <type_traits>
17
18namespace tonic {
19
20// DartWrappable is a base class that you can inherit from in order to be
21// exposed to Dart code as an interface.
23 public:
25 kPeerIndex, // Must be first to work with Dart_GetNativeReceiver.
27 };
28
29 DartWrappable() : dart_wrapper_(DartWeakPersistentValue()) {}
30
31 // Subclasses that wish to expose a new interface must override this function
32 // and provide information about their wrapper. There is no need to call your
33 // base class's implementation of this function.
34 // Implement using IMPLEMENT_WRAPPERTYPEINFO macro
35 virtual const DartWrapperInfo& GetDartWrapperInfo() const = 0;
36
37 virtual void RetainDartWrappableReference() const = 0;
38
39 virtual void ReleaseDartWrappableReference() const = 0;
40
41 // Use this method sparingly. It follows a slower path using Dart_New.
42 // Prefer constructing the object in Dart code and using
43 // AssociateWithDartWrapper.
46 void ClearDartWrapper(); // Warning: Might delete this.
48 return dart_wrapper_.value();
49 }
50
51 protected:
52 virtual ~DartWrappable();
53
55 tonic::DartState* dart_state,
56 const tonic::DartWrapperInfo& wrapper_info);
57
58 private:
59 static void FinalizeDartWrapper(void* isolate_callback_data, void* peer);
60
61 DartWeakPersistentValue dart_wrapper_;
62
63 TONIC_DISALLOW_COPY_AND_ASSIGN(DartWrappable);
64};
65
66#define DEFINE_WRAPPERTYPEINFO() \
67 public: \
68 const tonic::DartWrapperInfo& GetDartWrapperInfo() const override { \
69 return dart_wrapper_info_; \
70 } \
71 static Dart_PersistentHandle GetDartType(tonic::DartState* dart_state) { \
72 return GetTypeForWrapper(dart_state, dart_wrapper_info_); \
73 } \
74 \
75 private: \
76 static const tonic::DartWrapperInfo& dart_wrapper_info_
77
78#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName) \
79 static const tonic::DartWrapperInfo \
80 kDartWrapperInfo_##LibraryName_##ClassName(#LibraryName, #ClassName); \
81 const tonic::DartWrapperInfo& ClassName::dart_wrapper_info_ = \
82 kDartWrapperInfo_##LibraryName_##ClassName;
83
85 static DartWrappable* FromDart(Dart_Handle handle);
87 int index,
88 Dart_Handle& exception);
89};
90
91template <typename T>
93 T*,
94 typename std::enable_if<
97 static constexpr const char* kFfiRepresentation = "Pointer";
98 static constexpr const char* kDartRepresentation = "Pointer";
99 static constexpr bool kAllowedInLeafCall = true;
100
102 if (!val) {
103 return Dart_Null();
104 }
105 if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper()) {
106 auto strong_handle = Dart_HandleFromWeakPersistent(wrapper);
107 if (!Dart_IsNull(strong_handle)) {
108 return strong_handle;
109 }
110 // After the weak referenced object has been GCed, the handle points to
111 // Dart_Null(). Fall through create a new wrapper object.
112 }
114 }
115
117 DartWrappable* val,
118 bool auto_scope = true) {
119 if (!val) {
121 return;
122 } else if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper()) {
123 auto strong_handle = Dart_HandleFromWeakPersistent(wrapper);
124 if (!Dart_IsNull(strong_handle)) {
125 Dart_SetReturnValue(args, strong_handle);
126 return;
127 }
128 // After the weak referenced object has been GCed, the handle points to
129 // Dart_Null(). Fall through create a new wrapper object.
130 }
132 }
133
134 static T* FromDart(Dart_Handle handle) {
135 // TODO(abarth): We're missing a type check.
136 return static_cast<T*>(DartConverterWrappable::FromDart(handle));
137 }
138
140 int index,
141 Dart_Handle& exception,
142 bool auto_scope = true) {
143 // TODO(abarth): We're missing a type check.
144 return static_cast<T*>(
146 }
147
148 static T* FromFfi(FfiType val) { return static_cast<T*>(val); }
149 static FfiType ToFfi(T* val) { return val; }
150 static const char* GetFfiRepresentation() { return kFfiRepresentation; }
151 static const char* GetDartRepresentation() { return kDartRepresentation; }
152 static bool AllowedInLeafCall() { return kAllowedInLeafCall; }
153};
154
155////////////////////////////////////////////////////////////////////////////////
156// Support for generic smart pointers that have a "get" method that returns a
157// pointer to a type that is Dart convertible as well as a constructor that
158// adopts a raw pointer to that type.
159
160template <template <typename T> class PTR, typename T>
161struct DartConverter<PTR<T>> {
162 using NativeType = PTR<T>;
164 static constexpr const char* kFfiRepresentation = "Handle";
165 static constexpr const char* kDartRepresentation = "Object";
166 static constexpr bool kAllowedInLeafCall = false;
167
168 static Dart_Handle ToDart(const NativeType& val) {
169 return DartConverter<T*>::ToDart(val.get());
170 }
171
174 }
175
177 int index,
178 Dart_Handle& exception,
179 bool auto_scope = true) {
180 return NativeType(
181 DartConverter<T*>::FromArguments(args, index, exception, auto_scope));
182 }
183
185 const NativeType& val,
186 bool auto_scope = true) {
188 }
189
190 static NativeType FromFfi(FfiType val) { return FromDart(val); }
191 static FfiType ToFfi(const NativeType& val) { return ToDart(val); }
192 static const char* GetFfiRepresentation() { return kFfiRepresentation; }
193 static const char* GetDartRepresentation() { return kDartRepresentation; }
194 static bool AllowedInLeafCall() { return kAllowedInLeafCall; }
195};
196
197template <typename T>
199 intptr_t receiver;
202 if (!receiver)
203 Dart_ThrowException(ToDart("Object has been disposed."));
204 return static_cast<T*>(reinterpret_cast<DartWrappable*>(receiver));
205}
206
207} // namespace tonic
208
209#endif // LIB_TONIC_DART_WRAPPABLE_H_
GLenum type
static DartState * Current()
Definition: dart_state.cc:56
Dart_WeakPersistentHandle value() const
Dart_Handle CreateDartWrapper(DartState *dart_state)
virtual const DartWrapperInfo & GetDartWrapperInfo() const =0
Dart_WeakPersistentHandle dart_wrapper() const
void AssociateWithDartWrapper(Dart_Handle wrappable)
virtual void ReleaseDartWrappableReference() const =0
virtual void RetainDartWrappableReference() const =0
static Dart_PersistentHandle GetTypeForWrapper(tonic::DartState *dart_state, const tonic::DartWrapperInfo &wrapper_info)
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception)
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
Dart_Handle Dart_PersistentHandle
Definition: dart_api.h:259
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT Dart_Handle Dart_GetNativeReceiver(Dart_NativeArguments args, intptr_t *value)
DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args, Dart_Handle retval)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
struct _Dart_WeakPersistentHandle * Dart_WeakPersistentHandle
Definition: dart_api.h:260
DART_EXPORT Dart_Handle Dart_HandleFromWeakPersistent(Dart_WeakPersistentHandle object)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint8_t value
GAsyncResult * result
Dart_Handle ToDart(const T &object)
T * GetReceiver(Dart_NativeArguments args)
#define T
Definition: precompiler.cc:65
static DartWrappable * FromArguments(Dart_NativeArguments args, int index, Dart_Handle &exception)
static DartWrappable * FromDart(Dart_Handle handle)
static FfiType ToFfi(const NativeType &val)
static NativeType FromDart(Dart_Handle handle)
static Dart_Handle ToDart(const NativeType &val)
static NativeType FromFfi(FfiType val)
static const char * GetDartRepresentation()
static void SetReturnValue(Dart_NativeArguments args, const NativeType &val, bool auto_scope=true)
static const char * GetFfiRepresentation()
static NativeType FromArguments(Dart_NativeArguments args, int index, Dart_Handle &exception, bool auto_scope=true)
static T * FromArguments(Dart_NativeArguments args, int index, Dart_Handle &exception, bool auto_scope=true)
static void SetReturnValue(Dart_NativeArguments args, DartWrappable *val, bool auto_scope=true)
#define TONIC_DCHECK
Definition: macros.h:32