Flutter Engine
dart_wrappable.cc
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 #include "tonic/dart_wrappable.h"
6 
8 #include "tonic/dart_state.h"
11 
12 namespace tonic {
13 
15  TONIC_CHECK(!dart_wrapper_);
16 }
17 
18 // TODO(dnfield): Delete this. https://github.com/flutter/flutter/issues/50997
19 Dart_Handle DartWrappable::CreateDartWrapper(DartState* dart_state) {
20  TONIC_DCHECK(!dart_wrapper_);
21  const DartWrapperInfo& info = GetDartWrapperInfo();
22 
23  Dart_PersistentHandle type = dart_state->class_library().GetClass(info);
24  TONIC_DCHECK(!LogIfError(type));
25 
26  Dart_Handle wrapper =
27  Dart_New(type, dart_state->private_constructor_name(), 0, nullptr);
28 
29  TONIC_DCHECK(!LogIfError(wrapper));
30 
31  Dart_Handle res = Dart_SetNativeInstanceField(
32  wrapper, kPeerIndex, reinterpret_cast<intptr_t>(this));
33  TONIC_DCHECK(!LogIfError(res));
34  res = Dart_SetNativeInstanceField(wrapper, kWrapperInfoIndex,
35  reinterpret_cast<intptr_t>(&info));
36  TONIC_DCHECK(!LogIfError(res));
37 
38  this->RetainDartWrappableReference(); // Balanced in FinalizeDartWrapper.
39  dart_wrapper_ = Dart_NewWeakPersistentHandle(
40  wrapper, this, GetAllocationSize(), &FinalizeDartWrapper);
41 
42  return wrapper;
43 }
44 
45 void DartWrappable::AssociateWithDartWrapper(Dart_Handle wrapper) {
46  TONIC_DCHECK(!dart_wrapper_);
47  TONIC_CHECK(!LogIfError(wrapper));
48 
49  const DartWrapperInfo& info = GetDartWrapperInfo();
50 
51  TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(
52  wrapper, kPeerIndex, reinterpret_cast<intptr_t>(this))));
53  TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(
54  wrapper, kWrapperInfoIndex, reinterpret_cast<intptr_t>(&info))));
55 
56  this->RetainDartWrappableReference(); // Balanced in FinalizeDartWrapper.
57  dart_wrapper_ = Dart_NewWeakPersistentHandle(
58  wrapper, this, GetAllocationSize(), &FinalizeDartWrapper);
59 }
60 
62  TONIC_DCHECK(dart_wrapper_);
63  Dart_Handle wrapper = Dart_HandleFromWeakPersistent(dart_wrapper_);
64  TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(wrapper, kPeerIndex, 0)));
66  !LogIfError(Dart_SetNativeInstanceField(wrapper, kWrapperInfoIndex, 0)));
67  Dart_DeleteWeakPersistentHandle(dart_wrapper_);
68  dart_wrapper_ = nullptr;
70 }
71 
72 void DartWrappable::FinalizeDartWrapper(void* isolate_callback_data,
73  Dart_WeakPersistentHandle wrapper,
74  void* peer) {
75  DartWrappable* wrappable = reinterpret_cast<DartWrappable*>(peer);
76  wrappable->dart_wrapper_ = nullptr;
77  wrappable->ReleaseDartWrappableReference(); // Balanced in CreateDartWrapper.
78 }
79 
82 }
83 
84 Dart_PersistentHandle DartWrappable::GetTypeForWrapper(
85  tonic::DartState* dart_state,
86  const tonic::DartWrapperInfo& wrapper_info) {
87  return dart_state->class_library().GetClass(wrapper_info);
88 }
89 
91  intptr_t peer = 0;
92  Dart_Handle result =
93  Dart_GetNativeInstanceField(handle, DartWrappable::kPeerIndex, &peer);
94  if (Dart_IsError(result))
95  return nullptr;
96  return reinterpret_cast<DartWrappable*>(peer);
97 }
98 
100  int index,
101  Dart_Handle& exception) {
102  intptr_t native_fields[DartWrappable::kNumberOfNativeFields];
103  Dart_Handle result = Dart_GetNativeFieldsOfArgument(
104  args, index, DartWrappable::kNumberOfNativeFields, native_fields);
105  if (Dart_IsError(result)) {
106  exception = Dart_NewStringFromCString(DartError::kInvalidArgument);
107  return nullptr;
108  }
109  if (!native_fields[DartWrappable::kPeerIndex])
110  return nullptr;
111  return reinterpret_cast<DartWrappable*>(
112  native_fields[DartWrappable::kPeerIndex]);
113 }
114 
115 } // namespace tonic
const char kInvalidArgument[]
Definition: dart_error.cc:12
G_BEGIN_DECLS FlValue * args
static DartWrappable * FromArguments(Dart_NativeArguments args, int index, Dart_Handle &exception)
virtual const DartWrapperInfo & GetDartWrapperInfo() const =0
#define TONIC_DCHECK
Definition: macros.h:32
Dart_PersistentHandle GetClass(const DartWrapperInfo &info)
virtual void RetainDartWrappableReference() const =0
DartClassLibrary & class_library()
Definition: dart_state.h:58
void AssociateWithDartWrapper(Dart_Handle wrappable)
virtual size_t GetAllocationSize() const
#define TONIC_CHECK(condition)
Definition: macros.h:23
static Dart_PersistentHandle GetTypeForWrapper(tonic::DartState *dart_state, const tonic::DartWrapperInfo &wrapper_info)
static DartWrappable * FromDart(Dart_Handle handle)
Dart_Handle CreateDartWrapper(DartState *dart_state)
Dart_PersistentHandle private_constructor_name()
Definition: dart_state.h:54
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
virtual void ReleaseDartWrappableReference() const =0