expo-modules-core 55.0.2 → 55.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/cpp/JavaScriptArrayBuffer.cpp +11 -12
  4. package/android/src/main/cpp/JavaScriptArrayBuffer.h +2 -7
  5. package/android/src/main/cpp/JavaScriptFunction.cpp +9 -13
  6. package/android/src/main/cpp/JavaScriptFunction.h +1 -7
  7. package/android/src/main/cpp/JavaScriptObject.cpp +78 -44
  8. package/android/src/main/cpp/JavaScriptObject.h +12 -17
  9. package/android/src/main/cpp/JavaScriptTypedArray.cpp +16 -18
  10. package/android/src/main/cpp/JavaScriptTypedArray.h +0 -6
  11. package/android/src/main/cpp/JavaScriptValue.cpp +48 -32
  12. package/android/src/main/cpp/JavaScriptValue.h +1 -7
  13. package/android/src/main/cpp/JavaScriptWeakObject.cpp +21 -15
  14. package/android/src/main/cpp/JavaScriptWeakObject.h +13 -10
  15. package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +10 -9
  16. package/android/src/main/java/expo/modules/kotlin/jni/JSIContext.kt +4 -4
  17. package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +3 -3
  18. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptArrayBuffer.kt +3 -3
  19. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +3 -3
  20. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +4 -4
  21. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +3 -3
  22. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +3 -3
  23. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptWeakObject.kt +4 -3
  24. package/android/src/main/java/expo/modules/kotlin/jni/NativeArrayBuffer.kt +3 -3
  25. package/android/src/main/java/expo/modules/kotlin/jni/decorators/JSDecoratorsBridgingObject.kt +4 -4
  26. package/android/src/main/java/expo/modules/kotlin/jni/worklets/Serializable.kt +3 -3
  27. package/package.json +2 -2
  28. package/android/src/main/cpp/WeakRuntimeHolder.cpp +0 -24
  29. package/android/src/main/cpp/WeakRuntimeHolder.h +0 -40
package/CHANGELOG.md CHANGED
@@ -10,6 +10,12 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.0.3 — 2026-01-22
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - [Android] Fixed crashes in JavaScriptValue/JavaScriptObject destructor caused by freeing memory after the runtime is destroyed. ([#42440](https://github.com/expo/expo/pull/42440) by [@lukmccall](https://github.com/lukmccall))
18
+
13
19
  ## 55.0.2 — 2026-01-22
14
20
 
15
21
  ### 💡 Others
@@ -29,7 +29,7 @@ if (shouldIncludeCompose) {
29
29
  }
30
30
 
31
31
  group = 'host.exp.exponent'
32
- version = '55.0.2'
32
+ version = '55.0.3'
33
33
 
34
34
  def isExpoModulesCoreTests = {
35
35
  Gradle gradle = getGradle()
@@ -96,7 +96,7 @@ android {
96
96
  defaultConfig {
97
97
  consumerProguardFiles 'proguard-rules.pro'
98
98
  versionCode 1
99
- versionName "55.0.2"
99
+ versionName "55.0.3"
100
100
  buildConfigField "String", "EXPO_MODULES_CORE_VERSION", "\"${versionName}\""
101
101
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true"
102
102
 
@@ -22,14 +22,7 @@ JavaScriptArrayBuffer::JavaScriptArrayBuffer(
22
22
  std::weak_ptr<JavaScriptRuntime> runtime,
23
23
  std::shared_ptr<jsi::ArrayBuffer> jsObject
24
24
  ) : runtimeHolder(std::move(runtime)), arrayBuffer(std::move(jsObject)) {
25
- runtimeHolder.ensureRuntimeIsValid();
26
- }
27
-
28
- JavaScriptArrayBuffer::JavaScriptArrayBuffer(
29
- WeakRuntimeHolder runtime,
30
- std::shared_ptr<jsi::ArrayBuffer> jsObject
31
- ) : runtimeHolder(std::move(runtime)), arrayBuffer(std::move(jsObject)) {
32
- runtimeHolder.ensureRuntimeIsValid();
25
+ assert((!runtimeHolder.expired()) && "JS Runtime was used after deallocation");
33
26
  }
34
27
 
35
28
  jni::local_ref<JavaScriptArrayBuffer::javaobject> JavaScriptArrayBuffer::newInstance(
@@ -46,13 +39,19 @@ jni::local_ref<JavaScriptArrayBuffer::javaobject> JavaScriptArrayBuffer::newInst
46
39
  }
47
40
 
48
41
  int JavaScriptArrayBuffer::size() {
49
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
50
- return (int) arrayBuffer->size(jsRuntime);
42
+ auto runtime = runtimeHolder.lock();
43
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
44
+ auto &rawRuntime = runtime->get();
45
+
46
+ return (int) arrayBuffer->size(rawRuntime);
51
47
  }
52
48
 
53
49
  uint8_t *JavaScriptArrayBuffer::data() {
54
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
55
- return arrayBuffer->data(jsRuntime);
50
+ auto runtime = runtimeHolder.lock();
51
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
52
+ auto &rawRuntime = runtime->get();
53
+
54
+ return arrayBuffer->data(rawRuntime);
56
55
  }
57
56
 
58
57
  jni::local_ref<jni::JByteBuffer> JavaScriptArrayBuffer::toDirectBuffer() {
@@ -1,7 +1,7 @@
1
1
  #pragma once
2
2
 
3
- #include "WeakRuntimeHolder.h"
4
3
  #include "JNIDeallocator.h"
4
+ #include "JavaScriptRuntime.h"
5
5
 
6
6
  #include <fbjni/ByteBuffer.h>
7
7
  #include <fbjni/fbjni.h>
@@ -35,11 +35,6 @@ public:
35
35
  std::shared_ptr<jsi::ArrayBuffer> arrayBuffer
36
36
  );
37
37
 
38
- JavaScriptArrayBuffer(
39
- WeakRuntimeHolder runtime,
40
- std::shared_ptr<jsi::ArrayBuffer> arrayBuffer
41
- );
42
-
43
38
  [[nodiscard]] int size();
44
39
 
45
40
  [[nodiscard]] uint8_t* data();
@@ -54,7 +49,7 @@ public:
54
49
  }
55
50
 
56
51
  private:
57
- WeakRuntimeHolder runtimeHolder;
52
+ std::weak_ptr<JavaScriptRuntime> runtimeHolder;
58
53
  std::shared_ptr<jsi::ArrayBuffer> arrayBuffer;
59
54
  };
60
55
  } // namespace expo
@@ -18,14 +18,7 @@ JavaScriptFunction::JavaScriptFunction(
18
18
  std::weak_ptr<JavaScriptRuntime> runtime,
19
19
  std::shared_ptr<jsi::Function> jsFunction
20
20
  ) : runtimeHolder(std::move(runtime)), jsFunction(std::move(jsFunction)) {
21
- runtimeHolder.ensureRuntimeIsValid();
22
- }
23
-
24
- JavaScriptFunction::JavaScriptFunction(
25
- WeakRuntimeHolder runtime,
26
- std::shared_ptr<jsi::Function> jsFunction
27
- ) : runtimeHolder(std::move(runtime)), jsFunction(std::move(jsFunction)) {
28
- runtimeHolder.ensureRuntimeIsValid();
21
+ assert((!runtimeHolder.expired()) && "JS Runtime was used after deallocation");
29
22
  }
30
23
 
31
24
  std::shared_ptr<jsi::Function> JavaScriptFunction::get() {
@@ -37,7 +30,10 @@ jobject JavaScriptFunction::invoke(
37
30
  jni::alias_ref<jni::JArrayClass<jni::JObject>> args,
38
31
  jni::alias_ref<ExpectedType::javaobject> expectedReturnType
39
32
  ) {
40
- auto &rt = runtimeHolder.getJSRuntime();
33
+ auto runtime = runtimeHolder.lock();
34
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
35
+ auto &rawRuntime = runtime->get();
36
+
41
37
  JNIEnv *env = jni::Environment::current();
42
38
 
43
39
  size_t size = args->size();
@@ -46,25 +42,25 @@ jobject JavaScriptFunction::invoke(
46
42
 
47
43
  for (size_t i = 0; i < size; i++) {
48
44
  jni::local_ref<jobject> arg = args->getElement(i);
49
- convertedArgs.push_back(convert(env, rt, arg));
45
+ convertedArgs.push_back(convert(env, rawRuntime, arg));
50
46
  }
51
47
 
52
48
  // TODO(@lukmccall): add better error handling
53
49
  jsi::Value result = jsThis == nullptr ?
54
50
  jsFunction->call(
55
- rt,
51
+ rawRuntime,
56
52
  (const jsi::Value *) convertedArgs.data(),
57
53
  size
58
54
  ) :
59
55
  jsFunction->callWithThis(
60
- rt,
56
+ rawRuntime,
61
57
  *(jsThis->cthis()->get()),
62
58
  (const jsi::Value *) convertedArgs.data(),
63
59
  size
64
60
  );
65
61
 
66
62
  auto converter = AnyType(jni::make_local(expectedReturnType)).converter;
67
- auto convertedResult = converter->convert(rt, env, result);
63
+ auto convertedResult = converter->convert(rawRuntime, env, result);
68
64
  return convertedResult;
69
65
  }
70
66
 
@@ -4,7 +4,6 @@
4
4
 
5
5
  #include "JSIObjectWrapper.h"
6
6
  #include "JavaScriptRuntime.h"
7
- #include "WeakRuntimeHolder.h"
8
7
  #include "types/ExpectedType.h"
9
8
 
10
9
  #include <fbjni/fbjni.h>
@@ -39,18 +38,13 @@ public:
39
38
  std::shared_ptr<jsi::Function> jsFunction
40
39
  );
41
40
 
42
- JavaScriptFunction(
43
- WeakRuntimeHolder runtime,
44
- std::shared_ptr<jsi::Function> jsFunction
45
- );
46
-
47
41
  std::shared_ptr<jsi::Function> get() override;
48
42
 
49
43
 
50
44
  private:
51
45
  friend HybridBase;
52
46
 
53
- WeakRuntimeHolder runtimeHolder;
47
+ std::weak_ptr<JavaScriptRuntime> runtimeHolder;
54
48
  std::shared_ptr<jsi::Function> jsFunction;
55
49
 
56
50
  jobject invoke(
@@ -51,14 +51,7 @@ JavaScriptObject::JavaScriptObject(
51
51
  std::weak_ptr<JavaScriptRuntime> runtime,
52
52
  std::shared_ptr<jsi::Object> jsObject
53
53
  ) : runtimeHolder(std::move(runtime)), jsObject(std::move(jsObject)) {
54
- runtimeHolder.ensureRuntimeIsValid();
55
- }
56
-
57
- JavaScriptObject::JavaScriptObject(
58
- WeakRuntimeHolder runtime,
59
- std::shared_ptr<jsi::Object> jsObject
60
- ) : runtimeHolder(std::move(runtime)), jsObject(std::move(jsObject)) {
61
- runtimeHolder.ensureRuntimeIsValid();
54
+ assert((!runtimeHolder.expired()) && "JS Runtime was used after deallocation");
62
55
  }
63
56
 
64
57
  std::shared_ptr<jsi::Object> JavaScriptObject::get() {
@@ -66,13 +59,19 @@ std::shared_ptr<jsi::Object> JavaScriptObject::get() {
66
59
  }
67
60
 
68
61
  bool JavaScriptObject::hasProperty(const std::string &name) {
69
- auto &jsRuntime = runtimeHolder.getJSRuntime();
70
- return jsObject->hasProperty(jsRuntime, name.c_str());
62
+ auto runtime = runtimeHolder.lock();
63
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
64
+ auto &rawRuntime = runtime->get();
65
+
66
+ return jsObject->hasProperty(rawRuntime, name.c_str());
71
67
  }
72
68
 
73
69
  jsi::Value JavaScriptObject::getProperty(const std::string &name) {
74
- auto &jsRuntime = runtimeHolder.getJSRuntime();
75
- return jsObject->getProperty(jsRuntime, name.c_str());
70
+ auto runtime = runtimeHolder.lock();
71
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
72
+ auto &rawRuntime = runtime->get();
73
+
74
+ return jsObject->getProperty(rawRuntime, name.c_str());
76
75
  }
77
76
 
78
77
  bool JavaScriptObject::jniHasProperty(jni::alias_ref<jstring> name) {
@@ -82,26 +81,32 @@ bool JavaScriptObject::jniHasProperty(jni::alias_ref<jstring> name) {
82
81
  jni::local_ref<JavaScriptValue::javaobject> JavaScriptObject::jniGetProperty(
83
82
  jni::alias_ref<jstring> name
84
83
  ) {
84
+ auto runtime = runtimeHolder.lock();
85
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
86
+ auto &rawRuntime = runtime->get();
87
+
85
88
  auto result = std::make_shared<jsi::Value>(getProperty(name->toStdString()));
86
89
  return JavaScriptValue::newInstance(
87
- runtimeHolder.getJSIContext(),
90
+ expo::getJSIContext(rawRuntime),
88
91
  runtimeHolder,
89
92
  result
90
93
  );
91
94
  }
92
95
 
93
96
  std::vector<std::string> JavaScriptObject::getPropertyNames() {
94
- auto &jsRuntime = runtimeHolder.getJSRuntime();
97
+ auto runtime = runtimeHolder.lock();
98
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
99
+ auto &rawRuntime = runtime->get();
95
100
 
96
- jsi::Array properties = jsObject->getPropertyNames(jsRuntime);
97
- auto size = properties.size(jsRuntime);
101
+ jsi::Array properties = jsObject->getPropertyNames(rawRuntime);
102
+ auto size = properties.size(rawRuntime);
98
103
 
99
104
  std::vector<std::string> names(size);
100
105
  for (size_t i = 0; i < size; i++) {
101
106
  auto propertyName = properties
102
- .getValueAtIndex(jsRuntime, i)
103
- .asString(jsRuntime)
104
- .utf8(jsRuntime);
107
+ .getValueAtIndex(rawRuntime, i)
108
+ .asString(rawRuntime)
109
+ .utf8(rawRuntime);
105
110
  names[i] = propertyName;
106
111
  }
107
112
 
@@ -120,33 +125,46 @@ jni::local_ref<jni::JArrayClass<jstring>> JavaScriptObject::jniGetPropertyNames(
120
125
 
121
126
  jni::local_ref<jni::HybridClass<JavaScriptWeakObject, Destructible>::javaobject>
122
127
  JavaScriptObject::createWeak() {
128
+ auto runtime = runtimeHolder.lock();
129
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
130
+ auto &rawRuntime = runtime->get();
131
+
123
132
  return JavaScriptWeakObject::newInstance(
124
- runtimeHolder.getJSIContext(),
133
+ expo::getJSIContext(rawRuntime),
125
134
  runtimeHolder,
126
135
  get()
127
136
  );
128
137
  }
129
138
 
130
139
  jni::local_ref<JavaScriptFunction::javaobject> JavaScriptObject::jniAsFunction() {
131
- auto &jsRuntime = runtimeHolder.getJSRuntime();
132
- auto jsFuncion = std::make_shared<jsi::Function>(jsObject->asFunction(jsRuntime));
140
+ auto runtime = runtimeHolder.lock();
141
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
142
+ auto &rawRuntime = runtime->get();
143
+
144
+ auto jsFuncion = std::make_shared<jsi::Function>(jsObject->asFunction(rawRuntime));
133
145
  return JavaScriptFunction::newInstance(
134
- runtimeHolder.getJSIContext(),
146
+ expo::getJSIContext(rawRuntime),
135
147
  runtimeHolder,
136
148
  jsFuncion
137
149
  );
138
150
  }
139
151
 
140
152
  void JavaScriptObject::setProperty(const std::string &name, jsi::Value value) {
141
- auto &jsRuntime = runtimeHolder.getJSRuntime();
142
- jsObject->setProperty(jsRuntime, name.c_str(), value);
153
+ auto runtime = runtimeHolder.lock();
154
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
155
+ auto &rawRuntime = runtime->get();
156
+
157
+ jsObject->setProperty(rawRuntime, name.c_str(), value);
143
158
  }
144
159
 
145
160
  void JavaScriptObject::unsetProperty(jni::alias_ref<jstring> name) {
146
- auto &jsRuntime = runtimeHolder.getJSRuntime();
161
+ auto runtime = runtimeHolder.lock();
162
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
163
+ auto &rawRuntime = runtime->get();
164
+
147
165
  auto cName = name->toStdString();
148
166
  jsObject->setProperty(
149
- jsRuntime,
167
+ rawRuntime,
150
168
  cName.c_str(),
151
169
  jsi::Value::undefined()
152
170
  );
@@ -178,11 +196,14 @@ jni::local_ref<JavaScriptObject::javaobject> JavaScriptObject::newInstance(
178
196
  void JavaScriptObject::defineNativeDeallocator(
179
197
  jni::alias_ref<JNIFunctionBody::javaobject> deallocator
180
198
  ) {
181
- auto &rt = runtimeHolder.getJSRuntime();
199
+ auto runtime = runtimeHolder.lock();
200
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
201
+ auto &rawRuntime = runtime->get();
202
+
182
203
  jni::global_ref<JNIFunctionBody::javaobject> globalRef = jni::make_global(deallocator);
183
204
 
184
205
  common::setDeallocator(
185
- rt,
206
+ rawRuntime,
186
207
  jsObject,
187
208
  [globalRef = std::move(globalRef)]() mutable {
188
209
  auto args = jni::Environment::ensureCurrentThreadIsAttached()->NewObjectArray(
@@ -197,28 +218,36 @@ void JavaScriptObject::defineNativeDeallocator(
197
218
  }
198
219
 
199
220
  void JavaScriptObject::setExternalMemoryPressure(int size) {
200
- auto &jsRuntime = runtimeHolder.getJSRuntime();
201
- jsObject->setExternalMemoryPressure(jsRuntime, size);
221
+ auto runtime = runtimeHolder.lock();
222
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
223
+ auto &rawRuntime = runtime->get();
224
+
225
+ jsObject->setExternalMemoryPressure(rawRuntime, size);
202
226
  }
203
227
 
204
228
  bool JavaScriptObject::isArray() {
205
- auto &jsRuntime = runtimeHolder.getJSRuntime();
206
- return jsObject->isArray(jsRuntime);
229
+ auto runtime = runtimeHolder.lock();
230
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
231
+ auto &rawRuntime = runtime->get();
232
+
233
+ return jsObject->isArray(rawRuntime);
207
234
  }
208
235
 
209
236
  jni::local_ref<jni::JArrayClass<JavaScriptValue::javaobject>> JavaScriptObject::getArray() {
210
- auto &jsRuntime = runtimeHolder.getJSRuntime();
211
- auto moduleRegistry = runtimeHolder.getJSIContext();
237
+ auto runtime = runtimeHolder.lock();
238
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
239
+ auto &rawRuntime = runtime->get();
240
+ auto jsiContext = expo::getJSIContext(rawRuntime);
212
241
 
213
- auto jsArray = jsObject->getArray(jsRuntime);
214
- size_t size = jsArray.size(jsRuntime);
242
+ auto jsArray = jsObject->getArray(rawRuntime);
243
+ size_t size = jsArray.size(rawRuntime);
215
244
 
216
245
  auto result = jni::JArrayClass<JavaScriptValue::javaobject>::newArray(size);
217
246
  for (size_t i = 0; i < size; i++) {
218
247
  auto element = JavaScriptValue::newInstance(
219
- moduleRegistry,
248
+ jsiContext,
220
249
  runtimeHolder,
221
- std::make_shared<jsi::Value>(jsArray.getValueAtIndex(jsRuntime, i))
250
+ std::make_shared<jsi::Value>(jsArray.getValueAtIndex(rawRuntime, i))
222
251
  );
223
252
 
224
253
  result->setElement(i, element.release());
@@ -227,18 +256,23 @@ jni::local_ref<jni::JArrayClass<JavaScriptValue::javaobject>> JavaScriptObject::
227
256
  }
228
257
 
229
258
  bool JavaScriptObject::isArrayBuffer() {
230
- auto &jsRuntime = runtimeHolder.getJSRuntime();
231
- return jsObject->isArrayBuffer(jsRuntime);
259
+ auto runtime = runtimeHolder.lock();
260
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
261
+ auto &rawRuntime = runtime->get();
262
+
263
+ return jsObject->isArrayBuffer(rawRuntime);
232
264
  }
233
265
 
234
266
  jni::local_ref<JavaScriptArrayBuffer::javaobject> JavaScriptObject::getArrayBuffer() {
235
- auto &jsRuntime = runtimeHolder.getJSRuntime();
236
- auto jsiContext = runtimeHolder.getJSIContext();
267
+ auto runtime = runtimeHolder.lock();
268
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
269
+ auto &rawRuntime = runtime->get();
270
+ auto jsiContext = expo::getJSIContext(rawRuntime);
237
271
 
238
272
  return JavaScriptArrayBuffer::newInstance(
239
273
  jsiContext,
240
274
  runtimeHolder,
241
- std::make_shared<jsi::ArrayBuffer>(jsObject->getArrayBuffer(jsRuntime))
275
+ std::make_shared<jsi::ArrayBuffer>(jsObject->getArrayBuffer(rawRuntime))
242
276
  );
243
277
  }
244
278
 
@@ -5,7 +5,6 @@
5
5
  #include "JSIObjectWrapper.h"
6
6
  #include "JSITypeConverter.h"
7
7
  #include "JavaScriptRuntime.h"
8
- #include "WeakRuntimeHolder.h"
9
8
  #include "JNIFunctionBody.h"
10
9
  #include "JNIDeallocator.h"
11
10
  #include "JSIUtils.h"
@@ -47,13 +46,6 @@ public:
47
46
  std::shared_ptr<jsi::Object> jsObject
48
47
  );
49
48
 
50
- JavaScriptObject(
51
- WeakRuntimeHolder runtime,
52
- std::shared_ptr<jsi::Object> jsObject
53
- );
54
-
55
- virtual ~JavaScriptObject() = default;
56
-
57
49
  std::shared_ptr<jsi::Object> get() override;
58
50
 
59
51
  /**
@@ -92,9 +84,8 @@ public:
92
84
  [[nodiscard]] jni::local_ref<jni::HybridClass<JavaScriptArrayBuffer, Destructible>::javaobject> getArrayBuffer();
93
85
 
94
86
  protected:
95
- WeakRuntimeHolder runtimeHolder;
87
+ std::weak_ptr<JavaScriptRuntime> runtimeHolder;
96
88
  std::shared_ptr<jsi::Object> jsObject;
97
-
98
89
  private:
99
90
  friend HybridBase;
100
91
 
@@ -130,13 +121,15 @@ private:
130
121
  typename = std::enable_if_t<is_jsi_type_converter_defined<T>>
131
122
  >
132
123
  void setProperty(jni::alias_ref<jstring> name, T value) {
133
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
124
+ auto runtime = runtimeHolder.lock();
125
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
126
+ auto &rawRuntime = runtime->get();
134
127
 
135
128
  auto cName = name->toStdString();
136
129
  jsObject->setProperty(
137
- jsRuntime,
130
+ rawRuntime,
138
131
  cName.c_str(),
139
- jsi_type_converter<T>::convert(jsRuntime, value)
132
+ jsi_type_converter<T>::convert(rawRuntime, value)
140
133
  );
141
134
  }
142
135
 
@@ -145,12 +138,14 @@ private:
145
138
  typename = std::enable_if_t<is_jsi_type_converter_defined<T>>
146
139
  >
147
140
  void defineProperty(jni::alias_ref<jstring> name, T value, int options) {
148
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
141
+ auto runtime = runtimeHolder.lock();
142
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
143
+ auto &rawRuntime = runtime->get();
149
144
 
150
145
  auto cName = name->toStdString();
151
- jsi::Object descriptor = preparePropertyDescriptor(jsRuntime, options);
152
- descriptor.setProperty(jsRuntime, "value", jsi_type_converter<T>::convert(jsRuntime, value));
153
- common::defineProperty(jsRuntime, jsObject.get(), cName.c_str(), std::move(descriptor));
146
+ jsi::Object descriptor = preparePropertyDescriptor(rawRuntime, options);
147
+ descriptor.setProperty(rawRuntime, "value", jsi_type_converter<T>::convert(rawRuntime, value));
148
+ common::defineProperty(rawRuntime, jsObject.get(), cName.c_str(), std::move(descriptor));
154
149
  }
155
150
  };
156
151
  } // namespace expo
@@ -5,24 +5,17 @@
5
5
 
6
6
  namespace expo {
7
7
 
8
- JavaScriptTypedArray::JavaScriptTypedArray(
9
- WeakRuntimeHolder runtime,
10
- std::shared_ptr<jsi::Object> jsObject
11
- ) : jni::HybridClass<JavaScriptTypedArray, JavaScriptObject>(std::move(runtime),
12
- std::move(jsObject)) {
13
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
14
- typedArrayWrapper = std::make_shared<expo::TypedArray>(jsRuntime, *get());
15
- rawPointer = static_cast<char *>(typedArrayWrapper->getRawPointer(jsRuntime));
16
- }
17
-
18
8
  JavaScriptTypedArray::JavaScriptTypedArray(
19
9
  std::weak_ptr<JavaScriptRuntime> runtime,
20
10
  std::shared_ptr<jsi::Object> jsObject
21
11
  ) : jni::HybridClass<JavaScriptTypedArray, JavaScriptObject>(std::move(runtime),
22
12
  std::move(jsObject)) {
23
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
24
- typedArrayWrapper = std::make_shared<expo::TypedArray>(jsRuntime, *get());
25
- rawPointer = static_cast<char *>(typedArrayWrapper->getRawPointer(jsRuntime));
13
+ auto jsRuntime = runtimeHolder.lock();
14
+ assert((jsRuntime != nullptr) && "JS Runtime was used after deallocation");
15
+ auto &rawRuntime = jsRuntime->get();
16
+
17
+ typedArrayWrapper = std::make_shared<expo::TypedArray>(rawRuntime, *JavaScriptObject::get());
18
+ rawPointer = static_cast<char *>(typedArrayWrapper->getRawPointer(rawRuntime));
26
19
  }
27
20
 
28
21
  void JavaScriptTypedArray::registerNatives() {
@@ -49,17 +42,22 @@ void JavaScriptTypedArray::registerNatives() {
49
42
  }
50
43
 
51
44
  int JavaScriptTypedArray::getRawKind() {
52
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
53
- return (int) typedArrayWrapper->getKind(jsRuntime);
45
+ auto runtime = runtimeHolder.lock();
46
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
47
+ auto &rawRuntime = runtime->get();
48
+
49
+ return (int) typedArrayWrapper->getKind(rawRuntime);
54
50
  }
55
51
 
56
52
  jni::local_ref<jni::JByteBuffer> JavaScriptTypedArray::toDirectBuffer() {
57
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
53
+ auto runtime = runtimeHolder.lock();
54
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
55
+ auto &rawRuntime = runtime->get();
58
56
 
59
- auto byteLength = typedArrayWrapper->byteLength(jsRuntime);
57
+ auto byteLength = typedArrayWrapper->byteLength(rawRuntime);
60
58
 
61
59
  auto byteBuffer = jni::JByteBuffer::wrapBytes(
62
- static_cast<uint8_t *>(typedArrayWrapper->getRawPointer(jsRuntime)),
60
+ static_cast<uint8_t *>(typedArrayWrapper->getRawPointer(rawRuntime)),
63
61
  byteLength
64
62
  );
65
63
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  #include "TypedArray.h"
4
4
  #include "JavaScriptObject.h"
5
- #include "WeakRuntimeHolder.h"
6
5
 
7
6
  #include <fbjni/fbjni.h>
8
7
  #include <fbjni/ByteBuffer.h>
@@ -36,11 +35,6 @@ public:
36
35
  std::shared_ptr<jsi::Object> jsObject
37
36
  );
38
37
 
39
- JavaScriptTypedArray(
40
- WeakRuntimeHolder runtime,
41
- std::shared_ptr<jsi::Object> jsObject
42
- );
43
-
44
38
  /**
45
39
  * Gets a raw kind of the underlying typed array.
46
40
  */
@@ -39,14 +39,7 @@ JavaScriptValue::JavaScriptValue(
39
39
  std::weak_ptr<JavaScriptRuntime> runtime,
40
40
  std::shared_ptr<jsi::Value> jsValue
41
41
  ) : runtimeHolder(std::move(runtime)), jsValue(std::move(jsValue)) {
42
- runtimeHolder.ensureRuntimeIsValid();
43
- }
44
-
45
- JavaScriptValue::JavaScriptValue(
46
- WeakRuntimeHolder runtime,
47
- std::shared_ptr<jsi::Value> jsValue
48
- ) : runtimeHolder(std::move(runtime)), jsValue(std::move(jsValue)) {
49
- runtimeHolder.ensureRuntimeIsValid();
42
+ assert((!runtimeHolder.expired()) && "JS Runtime was used after deallocation");
50
43
  }
51
44
 
52
45
  std::shared_ptr<jsi::Value> JavaScriptValue::get() {
@@ -113,8 +106,11 @@ bool JavaScriptValue::isSymbol() {
113
106
 
114
107
  bool JavaScriptValue::isFunction() {
115
108
  if (jsValue->isObject()) {
116
- auto &jsRuntime = runtimeHolder.getJSRuntime();
117
- return jsValue->asObject(jsRuntime).isFunction(jsRuntime);
109
+ auto runtime = runtimeHolder.lock();
110
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
111
+ auto &rawRuntime = runtime->get();
112
+
113
+ return jsValue->asObject(rawRuntime).isFunction(rawRuntime);
118
114
  }
119
115
 
120
116
  return false;
@@ -122,8 +118,11 @@ bool JavaScriptValue::isFunction() {
122
118
 
123
119
  bool JavaScriptValue::isArray() {
124
120
  if (jsValue->isObject()) {
125
- auto &jsRuntime = runtimeHolder.getJSRuntime();
126
- return jsValue->asObject(jsRuntime).isArray(jsRuntime);
121
+ auto runtime = runtimeHolder.lock();
122
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
123
+ auto &rawRuntime = runtime->get();
124
+
125
+ return jsValue->asObject(rawRuntime).isArray(rawRuntime);
127
126
  }
128
127
 
129
128
  return false;
@@ -135,8 +134,11 @@ bool JavaScriptValue::isObject() {
135
134
 
136
135
  bool JavaScriptValue::isTypedArray() {
137
136
  if (jsValue->isObject()) {
138
- jsi::Runtime &jsRuntime = runtimeHolder.getJSRuntime();
139
- return expo::isTypedArray(jsRuntime, jsValue->getObject(jsRuntime));
137
+ auto runtime = runtimeHolder.lock();
138
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
139
+ auto &rawRuntime = runtime->get();
140
+
141
+ return expo::isTypedArray(rawRuntime, jsValue->getObject(rawRuntime));
140
142
  }
141
143
  return false;
142
144
  }
@@ -150,46 +152,57 @@ double JavaScriptValue::getDouble() {
150
152
  }
151
153
 
152
154
  std::string JavaScriptValue::getString() {
153
- auto &jsRuntime = runtimeHolder.getJSRuntime();
154
- return jsValue->getString(jsRuntime).utf8(jsRuntime);
155
+ auto runtime = runtimeHolder.lock();
156
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
157
+ auto &rawRuntime = runtime->get();
158
+
159
+ return jsValue->getString(rawRuntime).utf8(rawRuntime);
155
160
  }
156
161
 
157
162
  jni::local_ref<JavaScriptObject::javaobject> JavaScriptValue::getObject() {
158
- auto &jsRuntime = runtimeHolder.getJSRuntime();
159
- auto jsObject = std::make_shared<jsi::Object>(jsValue->getObject(jsRuntime));
163
+ auto runtime = runtimeHolder.lock();
164
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
165
+ auto &rawRuntime = runtime->get();
166
+
167
+ auto jsObject = std::make_shared<jsi::Object>(jsValue->getObject(rawRuntime));
160
168
  return JavaScriptObject::newInstance(
161
- runtimeHolder.getJSIContext(),
169
+ expo::getJSIContext(rawRuntime),
162
170
  runtimeHolder,
163
171
  jsObject
164
172
  );
165
173
  }
166
174
 
167
175
  jni::local_ref<JavaScriptFunction::javaobject> JavaScriptValue::jniGetFunction() {
168
- auto &jsRuntime = runtimeHolder.getJSRuntime();
176
+ auto runtime = runtimeHolder.lock();
177
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
178
+ auto &rawRuntime = runtime->get();
179
+
169
180
  auto jsFunction = std::make_shared<jsi::Function>(
170
- jsValue->getObject(jsRuntime).asFunction(jsRuntime));
181
+ jsValue->getObject(rawRuntime).asFunction(rawRuntime));
171
182
  return JavaScriptFunction::newInstance(
172
- runtimeHolder.getJSIContext(),
183
+ expo::getJSIContext(rawRuntime),
173
184
  runtimeHolder,
174
185
  jsFunction
175
186
  );
176
187
  }
177
188
 
178
189
  jni::local_ref<jni::JArrayClass<JavaScriptValue::javaobject>> JavaScriptValue::getArray() {
179
- auto &jsRuntime = runtimeHolder.getJSRuntime();
180
- auto moduleRegistry = runtimeHolder.getJSIContext();
190
+ auto runtime = runtimeHolder.lock();
191
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
192
+ auto &rawRuntime = runtime->get();
193
+ auto jsiContext = expo::getJSIContext(rawRuntime);
181
194
 
182
195
  auto jsArray = jsValue
183
- ->getObject(jsRuntime)
184
- .asArray(jsRuntime);
185
- size_t size = jsArray.size(jsRuntime);
196
+ ->getObject(rawRuntime)
197
+ .asArray(rawRuntime);
198
+ size_t size = jsArray.size(rawRuntime);
186
199
 
187
200
  auto result = jni::JArrayClass<JavaScriptValue::javaobject>::newArray(size);
188
201
  for (size_t i = 0; i < size; i++) {
189
202
  auto element = JavaScriptValue::newInstance(
190
- moduleRegistry,
203
+ jsiContext,
191
204
  runtimeHolder,
192
- std::make_shared<jsi::Value>(jsArray.getValueAtIndex(jsRuntime, i))
205
+ std::make_shared<jsi::Value>(jsArray.getValueAtIndex(rawRuntime, i))
193
206
  );
194
207
 
195
208
  result->setElement(i, element.release());
@@ -208,10 +221,13 @@ jni::local_ref<jstring> JavaScriptValue::jniGetString() {
208
221
  }
209
222
 
210
223
  jni::local_ref<JavaScriptTypedArray::javaobject> JavaScriptValue::getTypedArray() {
211
- auto &jsRuntime = runtimeHolder.getJSRuntime();
212
- auto jsObject = std::make_shared<jsi::Object>(jsValue->getObject(jsRuntime));
224
+ auto runtime = runtimeHolder.lock();
225
+ assert((runtime != nullptr) && "JS Runtime was used after deallocation");
226
+ auto &rawRuntime = runtime->get();
227
+
228
+ auto jsObject = std::make_shared<jsi::Object>(jsValue->getObject(rawRuntime));
213
229
  return JavaScriptTypedArray::newInstance(
214
- runtimeHolder.getJSIContext(),
230
+ expo::getJSIContext(rawRuntime),
215
231
  runtimeHolder,
216
232
  jsObject
217
233
  );
@@ -3,7 +3,6 @@
3
3
  #pragma once
4
4
 
5
5
  #include "JSIObjectWrapper.h"
6
- #include "WeakRuntimeHolder.h"
7
6
  #include "JavaScriptTypedArray.h"
8
7
  #include "JavaScriptArrayBuffer.h"
9
8
  #include "JNIDeallocator.h"
@@ -49,11 +48,6 @@ public:
49
48
  std::shared_ptr<jsi::Value> jsValue
50
49
  );
51
50
 
52
- JavaScriptValue(
53
- WeakRuntimeHolder runtime,
54
- std::shared_ptr<jsi::Value> jsValue
55
- );
56
-
57
51
  std::shared_ptr<jsi::Value> get() override;
58
52
 
59
53
  std::string kind();
@@ -95,7 +89,7 @@ public:
95
89
  private:
96
90
  friend HybridBase;
97
91
 
98
- WeakRuntimeHolder runtimeHolder;
92
+ std::weak_ptr<JavaScriptRuntime> runtimeHolder;
99
93
  std::shared_ptr<jsi::Value> jsValue;
100
94
 
101
95
  jni::local_ref<jstring> jniKind();
@@ -7,8 +7,8 @@ namespace expo {
7
7
 
8
8
  void JavaScriptWeakObject::registerNatives() {
9
9
  registerHybrid({
10
- makeNativeMethod("lock", JavaScriptWeakObject::lock),
11
- });
10
+ makeNativeMethod("lock", JavaScriptWeakObject::lock),
11
+ });
12
12
  }
13
13
 
14
14
  std::shared_ptr<jsi::WeakObject> JavaScriptWeakObject::getWeak() {
@@ -16,26 +16,30 @@ std::shared_ptr<jsi::WeakObject> JavaScriptWeakObject::getWeak() {
16
16
  }
17
17
 
18
18
  jni::local_ref<JavaScriptObject::javaobject> JavaScriptWeakObject::lock() {
19
- jsi::Runtime &rt = _runtimeHolder.getJSRuntime();
19
+ auto jsRuntime = _runtimeHolder.lock();
20
+ assert((jsRuntime != nullptr) && "JS Runtime was used after deallocation");
21
+ auto &rawRuntime = jsRuntime->get();
20
22
 
21
- jsi::Value value = _weakObject->lock(rt);
23
+ jsi::Value value = _weakObject->lock(rawRuntime);
22
24
  if (value.isUndefined()) {
23
25
  return nullptr;
24
26
  }
25
27
  std::shared_ptr<jsi::Object> objectPtr =
26
- std::make_shared<jsi::Object>(value.asObject(rt));
28
+ std::make_shared<jsi::Object>(value.asObject(rawRuntime));
27
29
  if (!objectPtr) {
28
30
  return nullptr;
29
31
  }
30
- return JavaScriptObject::newInstance(_runtimeHolder.getJSIContext(),
31
- _runtimeHolder, objectPtr);
32
+ return JavaScriptObject::newInstance(
33
+ expo::getJSIContext(rawRuntime),
34
+ _runtimeHolder, objectPtr
35
+ );
32
36
  }
33
37
 
34
38
  jni::local_ref<jni::HybridClass<JavaScriptWeakObject, Destructible>::javaobject>
35
39
  JavaScriptWeakObject::newInstance(
36
- JSIContext *jSIContext,
37
- std::weak_ptr<JavaScriptRuntime> runtime,
38
- std::shared_ptr<jsi::Object> jsObject) {
40
+ JSIContext *jSIContext,
41
+ std::weak_ptr<JavaScriptRuntime> runtime,
42
+ std::shared_ptr<jsi::Object> jsObject) {
39
43
  auto weakObject = JavaScriptWeakObject::newObjectCxxArgs(std::move(runtime),
40
44
  std::move(jsObject));
41
45
  jSIContext->jniDeallocator->addReference(weakObject);
@@ -43,12 +47,14 @@ JavaScriptWeakObject::newInstance(
43
47
  }
44
48
 
45
49
  JavaScriptWeakObject::JavaScriptWeakObject(
46
- WeakRuntimeHolder runtime,
47
- const std::shared_ptr<jsi::Object>& jsObject
50
+ const std::weak_ptr<JavaScriptRuntime> &runtime,
51
+ const std::shared_ptr<jsi::Object> &jsObject
48
52
  ) : _runtimeHolder(std::move(runtime)) {
49
- _runtimeHolder.ensureRuntimeIsValid();
50
- jsi::Runtime &rt = _runtimeHolder.getJSRuntime();
51
- _weakObject = std::make_shared<jsi::WeakObject>(rt, *jsObject);
53
+ auto jsRuntime = _runtimeHolder.lock();
54
+ assert((jsRuntime != nullptr) && "JS Runtime was used after deallocation");
55
+ auto &rawRuntime = jsRuntime->get();
56
+
57
+ _weakObject = std::make_shared<jsi::WeakObject>(rawRuntime, *jsObject);
52
58
  }
53
59
 
54
60
  } // namespace expo
@@ -4,7 +4,6 @@
4
4
 
5
5
  #include "JNIDeallocator.h"
6
6
  #include "JavaScriptObject.h"
7
- #include "WeakRuntimeHolder.h"
8
7
 
9
8
  #include <fbjni/fbjni.h>
10
9
  #include <jsi/jsi.h>
@@ -22,32 +21,36 @@ class JavaScriptObject;
22
21
  * Represents to a jsi::WeakObject.
23
22
  */
24
23
  class JavaScriptWeakObject
25
- : public jni::HybridClass<JavaScriptWeakObject, Destructible> {
24
+ : public jni::HybridClass<JavaScriptWeakObject, Destructible> {
26
25
  public:
27
26
  static auto constexpr kJavaDescriptor =
28
- "Lexpo/modules/kotlin/jni/JavaScriptWeakObject;";
27
+ "Lexpo/modules/kotlin/jni/JavaScriptWeakObject;";
29
28
  static auto constexpr TAG = "JavaScriptWeakObject";
30
29
 
31
30
  static void registerNatives();
32
31
 
33
32
  static jni::local_ref<
34
- jni::HybridClass<JavaScriptWeakObject, Destructible>::javaobject>
35
- newInstance(JSIContext *jSIContext,
36
- std::weak_ptr<JavaScriptRuntime> runtime,
37
- std::shared_ptr<jsi::Object> jsObject);
33
+ jni::HybridClass<JavaScriptWeakObject, Destructible>::javaobject
34
+ > newInstance(
35
+ JSIContext *jSIContext,
36
+ std::weak_ptr<JavaScriptRuntime> runtime,
37
+ std::shared_ptr<jsi::Object> jsObject
38
+ );
38
39
 
39
40
  jni::local_ref<JavaScriptObject::javaobject> lock();
40
41
 
41
42
  std::shared_ptr<jsi::WeakObject> getWeak();
42
43
 
43
44
  private:
44
- JavaScriptWeakObject(WeakRuntimeHolder runtime,
45
- const std::shared_ptr<jsi::Object>& jsObject);
45
+ JavaScriptWeakObject(
46
+ const std::weak_ptr<JavaScriptRuntime> &runtime,
47
+ const std::shared_ptr<jsi::Object> &jsObject
48
+ );
46
49
 
47
50
  private:
48
51
  friend HybridBase;
49
52
 
50
- WeakRuntimeHolder _runtimeHolder;
53
+ std::weak_ptr<JavaScriptRuntime> _runtimeHolder;
51
54
  std::shared_ptr<jsi::WeakObject> _weakObject;
52
55
  };
53
56
 
@@ -1,13 +1,13 @@
1
1
  package expo.modules.kotlin.jni
2
2
 
3
+ import com.facebook.jni.HybridData
3
4
  import expo.modules.core.interfaces.DoNotStrip
4
5
  import java.lang.ref.PhantomReference
5
6
  import java.lang.ref.ReferenceQueue
6
- import java.lang.ref.WeakReference
7
7
 
8
8
  @DoNotStrip
9
9
  interface Destructible {
10
- fun deallocate()
10
+ fun getHybridDataForJNIDeallocator(): HybridData
11
11
  }
12
12
 
13
13
  @DoNotStrip
@@ -24,7 +24,7 @@ class JNIDeallocator(shouldCreateDestructorThread: Boolean = true) : AutoCloseab
24
24
  /**
25
25
  * A registry to keep all active [Destructible] objects and their [PhantomReference]s
26
26
  */
27
- private val destructorMap = mutableMapOf<PhantomReference<Destructible>, WeakReference<Destructible>>()
27
+ private val destructorMap = mutableMapOf<PhantomReference<Destructible>, HybridData>()
28
28
 
29
29
  /**
30
30
  * A thread that clears your registry when an object has been garbage collected
@@ -43,9 +43,8 @@ class JNIDeallocator(shouldCreateDestructorThread: Boolean = true) : AutoCloseab
43
43
  */
44
44
  @DoNotStrip
45
45
  fun addReference(destructible: Destructible): Unit = synchronized(this) {
46
- val weakRef = WeakReference(destructible)
47
46
  val phantomRef = PhantomReference(destructible, referenceQueue)
48
- destructorMap[phantomRef] = weakRef
47
+ destructorMap[phantomRef] = destructible.getHybridDataForJNIDeallocator()
49
48
  }
50
49
 
51
50
  /**
@@ -53,7 +52,7 @@ class JNIDeallocator(shouldCreateDestructorThread: Boolean = true) : AutoCloseab
53
52
  */
54
53
  internal fun deallocate() = synchronized(this) {
55
54
  destructorMap.values.forEach {
56
- it.get()?.deallocate()
55
+ it.resetNative()
57
56
  }
58
57
  destructorMap.clear()
59
58
  destructorThread?.interrupt()
@@ -64,15 +63,17 @@ class JNIDeallocator(shouldCreateDestructorThread: Boolean = true) : AutoCloseab
64
63
  * and are present in the memory.
65
64
  */
66
65
  fun inspectMemory() = synchronized(this) {
67
- destructorMap.values.mapNotNull { it.get() }
66
+ destructorMap
67
+ .values
68
+ .filter { synchronized(it) { it.isValid } }
69
+ .map { it }
68
70
  }
69
71
 
70
72
  private fun Thread.deallocator() {
71
73
  while (!isInterrupted) {
72
74
  try {
73
- // Referent of PhantomReference were garbage collected so we can remove it from our registry.
74
- // Note that we don't have to call `deallocate` method - it was called [com.facebook.jni.HybridData].
75
75
  val current = referenceQueue.remove()
76
+ destructorMap[current]?.resetNative()
76
77
  synchronized(this@JNIDeallocator) {
77
78
  destructorMap.remove(current)
78
79
  }
@@ -124,14 +124,14 @@ class JSIContext @DoNotStrip internal constructor(
124
124
 
125
125
  @Throws(Throwable::class)
126
126
  protected fun finalize() {
127
- deallocate()
127
+ close()
128
128
  }
129
129
 
130
- override fun deallocate() {
130
+ override fun close() {
131
131
  mHybridData.resetNative()
132
132
  }
133
133
 
134
- override fun close() {
135
- deallocate()
134
+ override fun getHybridDataForJNIDeallocator(): HybridData {
135
+ return mHybridData
136
136
  }
137
137
  }
@@ -115,10 +115,10 @@ class JavaCallback @DoNotStrip internal constructor(@DoNotStrip private val mHyb
115
115
 
116
116
  @Throws(Throwable::class)
117
117
  protected fun finalize() {
118
- deallocate()
118
+ mHybridData.resetNative()
119
119
  }
120
120
 
121
- override fun deallocate() {
122
- mHybridData.resetNative()
121
+ override fun getHybridDataForJNIDeallocator(): HybridData {
122
+ return mHybridData
123
123
  }
124
124
  }
@@ -26,10 +26,10 @@ class JavaScriptArrayBuffer @DoNotStrip private constructor(@DoNotStrip private
26
26
 
27
27
  @Throws(Throwable::class)
28
28
  protected fun finalize() {
29
- deallocate()
29
+ mHybridData.resetNative()
30
30
  }
31
31
 
32
- override fun deallocate() {
33
- mHybridData.resetNative()
32
+ override fun getHybridDataForJNIDeallocator(): HybridData {
33
+ return mHybridData
34
34
  }
35
35
  }
@@ -42,10 +42,10 @@ class JavaScriptFunction<ReturnType : Any?> @DoNotStrip private constructor(@DoN
42
42
 
43
43
  @Throws(Throwable::class)
44
44
  protected fun finalize() {
45
- deallocate()
45
+ mHybridData.resetNative()
46
46
  }
47
47
 
48
- override fun deallocate() {
49
- mHybridData.resetNative()
48
+ override fun getHybridDataForJNIDeallocator(): HybridData {
49
+ return mHybridData
50
50
  }
51
51
  }
@@ -34,14 +34,14 @@ class JavaScriptModuleObject(
34
34
 
35
35
  @Throws(Throwable::class)
36
36
  protected fun finalize() {
37
- deallocate()
38
- }
39
-
40
- override fun deallocate() {
41
37
  mHybridData.resetNative()
42
38
  }
43
39
 
44
40
  override fun toString(): String {
45
41
  return "JavaScriptModuleObject_$name"
46
42
  }
43
+
44
+ override fun getHybridDataForJNIDeallocator(): HybridData {
45
+ return mHybridData
46
+ }
47
47
  }
@@ -144,11 +144,11 @@ open class JavaScriptObject @DoNotStrip internal constructor(@DoNotStrip private
144
144
 
145
145
  @Throws(Throwable::class)
146
146
  protected fun finalize() {
147
- deallocate()
147
+ mHybridData.resetNative()
148
148
  }
149
149
 
150
- override fun deallocate() {
151
- mHybridData.resetNative()
150
+ override fun getHybridDataForJNIDeallocator(): HybridData {
151
+ return mHybridData
152
152
  }
153
153
  }
154
154
 
@@ -56,10 +56,10 @@ class JavaScriptValue @DoNotStrip private constructor(@DoNotStrip private val mH
56
56
 
57
57
  @Throws(Throwable::class)
58
58
  protected fun finalize() {
59
- deallocate()
59
+ mHybridData.resetNative()
60
60
  }
61
61
 
62
- override fun deallocate() {
63
- mHybridData.resetNative()
62
+ override fun getHybridDataForJNIDeallocator(): HybridData {
63
+ return mHybridData
64
64
  }
65
65
  }
@@ -12,11 +12,12 @@ import expo.modules.core.interfaces.DoNotStrip
12
12
  class JavaScriptWeakObject @DoNotStrip internal constructor(@DoNotStrip private val mHybridData: HybridData) : Destructible {
13
13
  @Throws(Throwable::class)
14
14
  protected fun finalize() {
15
- deallocate()
15
+ mHybridData.resetNative()
16
16
  }
17
17
 
18
- override fun deallocate() {
19
- mHybridData.resetNative()
18
+ override fun getHybridDataForJNIDeallocator(): HybridData {
19
+ return mHybridData
20
20
  }
21
+
21
22
  external fun lock(): JavaScriptObject
22
23
  }
@@ -44,11 +44,11 @@ class NativeArrayBuffer : Destructible, ArrayBuffer {
44
44
 
45
45
  @Throws(Throwable::class)
46
46
  protected fun finalize() {
47
- deallocate()
47
+ mHybridData.resetNative()
48
48
  }
49
49
 
50
- override fun deallocate() {
51
- mHybridData.resetNative()
50
+ override fun getHybridDataForJNIDeallocator(): HybridData {
51
+ return mHybridData
52
52
  }
53
53
 
54
54
  companion object {
@@ -98,13 +98,13 @@ class JSDecoratorsBridgingObject(jniDeallocator: JNIDeallocator) : Destructible
98
98
  )
99
99
  }
100
100
 
101
- override fun deallocate() {
101
+ @Throws(Throwable::class)
102
+ protected fun finalize() {
102
103
  mHybridData.resetNative()
103
104
  }
104
105
 
105
- @Throws(Throwable::class)
106
- protected fun finalize() {
107
- deallocate()
106
+ override fun getHybridDataForJNIDeallocator(): HybridData {
107
+ return mHybridData
108
108
  }
109
109
 
110
110
  fun ObjectDefinitionData.exportConstants() {
@@ -36,10 +36,10 @@ class Serializable @DoNotStrip private constructor(
36
36
 
37
37
  @Throws(Throwable::class)
38
38
  protected fun finalize() {
39
- deallocate()
39
+ mHybridData.resetNative()
40
40
  }
41
41
 
42
- override fun deallocate() {
43
- mHybridData.resetNative()
42
+ override fun getHybridDataForJNIDeallocator(): HybridData {
43
+ return mHybridData
44
44
  }
45
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "55.0.2",
3
+ "version": "55.0.3",
4
4
  "description": "The core of Expo Modules architecture",
5
5
  "main": "src/index.ts",
6
6
  "types": "build/index.d.ts",
@@ -66,5 +66,5 @@
66
66
  "@testing-library/react-native": "^13.2.0",
67
67
  "expo-module-scripts": "^55.0.1"
68
68
  },
69
- "gitHead": "9e6e4e518083f0516edf32a14a39f8afbbd049e4"
69
+ "gitHead": "4728ba25fbd4d5835780306de78a83bd1628e271"
70
70
  }
@@ -1,24 +0,0 @@
1
- #include "WeakRuntimeHolder.h"
2
- #include "JavaScriptRuntime.h"
3
- #include "JSIContext.h"
4
-
5
- namespace expo {
6
- WeakRuntimeHolder::WeakRuntimeHolder(std::weak_ptr<JavaScriptRuntime> runtime)
7
- : std::weak_ptr<JavaScriptRuntime>(std::move(runtime)) {}
8
-
9
- jsi::Runtime &WeakRuntimeHolder::getJSRuntime() const {
10
- auto runtime = lock();
11
- assert((runtime != nullptr) && "JS Runtime was used after deallocation");
12
- return runtime->get();
13
- }
14
-
15
- void WeakRuntimeHolder::ensureRuntimeIsValid() {
16
- assert((!expired()) && "JS Runtime was used after deallocation");
17
- }
18
-
19
- JSIContext *WeakRuntimeHolder::getJSIContext() {
20
- auto runtime = lock();
21
- assert((runtime != nullptr) && "JS Runtime was used after deallocation");
22
- return expo::getJSIContext(runtime->get());
23
- }
24
- } // namespace expo
@@ -1,40 +0,0 @@
1
- // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
-
3
- #pragma once
4
-
5
- #include <jsi/jsi.h>
6
-
7
- #include <memory>
8
-
9
- namespace jsi = facebook::jsi;
10
-
11
- namespace expo {
12
-
13
- class JavaScriptRuntime;
14
-
15
- class JSIContext;
16
-
17
- /**
18
- * A convenient class to access underlying jni::Runtime and hold a weak reference to expo::JavaScriptRuntime.
19
- * It's working like std::weak_ptr but can have more helper methods.
20
- */
21
- class WeakRuntimeHolder : public std::weak_ptr<JavaScriptRuntime> {
22
- public:
23
- WeakRuntimeHolder() = default;
24
-
25
- WeakRuntimeHolder(WeakRuntimeHolder const &) = default;
26
-
27
- WeakRuntimeHolder(WeakRuntimeHolder &&) = default;
28
-
29
- WeakRuntimeHolder(std::weak_ptr<JavaScriptRuntime> runtime);
30
-
31
- /**
32
- * @return an reference to the jsi::Runtime.
33
- */
34
- jsi::Runtime &getJSRuntime() const;
35
-
36
- JSIContext *getJSIContext();
37
-
38
- void ensureRuntimeIsValid();
39
- };
40
- } // namespace expo