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.
- package/CHANGELOG.md +6 -0
- package/android/build.gradle +2 -2
- package/android/src/main/cpp/JavaScriptArrayBuffer.cpp +11 -12
- package/android/src/main/cpp/JavaScriptArrayBuffer.h +2 -7
- package/android/src/main/cpp/JavaScriptFunction.cpp +9 -13
- package/android/src/main/cpp/JavaScriptFunction.h +1 -7
- package/android/src/main/cpp/JavaScriptObject.cpp +78 -44
- package/android/src/main/cpp/JavaScriptObject.h +12 -17
- package/android/src/main/cpp/JavaScriptTypedArray.cpp +16 -18
- package/android/src/main/cpp/JavaScriptTypedArray.h +0 -6
- package/android/src/main/cpp/JavaScriptValue.cpp +48 -32
- package/android/src/main/cpp/JavaScriptValue.h +1 -7
- package/android/src/main/cpp/JavaScriptWeakObject.cpp +21 -15
- package/android/src/main/cpp/JavaScriptWeakObject.h +13 -10
- package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +10 -9
- package/android/src/main/java/expo/modules/kotlin/jni/JSIContext.kt +4 -4
- package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptArrayBuffer.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +4 -4
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptWeakObject.kt +4 -3
- package/android/src/main/java/expo/modules/kotlin/jni/NativeArrayBuffer.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/jni/decorators/JSDecoratorsBridgingObject.kt +4 -4
- package/android/src/main/java/expo/modules/kotlin/jni/worklets/Serializable.kt +3 -3
- package/package.json +2 -2
- package/android/src/main/cpp/WeakRuntimeHolder.cpp +0 -24
- 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
|
package/android/build.gradle
CHANGED
|
@@ -29,7 +29,7 @@ if (shouldIncludeCompose) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
group = 'host.exp.exponent'
|
|
32
|
-
version = '55.0.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
50
|
-
|
|
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
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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,
|
|
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
|
-
|
|
51
|
+
rawRuntime,
|
|
56
52
|
(const jsi::Value *) convertedArgs.data(),
|
|
57
53
|
size
|
|
58
54
|
) :
|
|
59
55
|
jsFunction->callWithThis(
|
|
60
|
-
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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
|
|
70
|
-
|
|
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
|
|
75
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
97
|
-
auto size = properties.size(
|
|
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(
|
|
103
|
-
.asString(
|
|
104
|
-
.utf8(
|
|
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
|
-
|
|
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
|
|
132
|
-
|
|
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
|
-
|
|
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
|
|
142
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
201
|
-
|
|
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
|
|
206
|
-
|
|
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
|
|
211
|
-
|
|
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(
|
|
214
|
-
size_t size = jsArray.size(
|
|
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
|
-
|
|
248
|
+
jsiContext,
|
|
220
249
|
runtimeHolder,
|
|
221
|
-
std::make_shared<jsi::Value>(jsArray.getValueAtIndex(
|
|
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
|
|
231
|
-
|
|
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
|
|
236
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
130
|
+
rawRuntime,
|
|
138
131
|
cName.c_str(),
|
|
139
|
-
jsi_type_converter<T>::convert(
|
|
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
|
-
|
|
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(
|
|
152
|
-
descriptor.setProperty(
|
|
153
|
-
common::defineProperty(
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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(
|
|
57
|
+
auto byteLength = typedArrayWrapper->byteLength(rawRuntime);
|
|
60
58
|
|
|
61
59
|
auto byteBuffer = jni::JByteBuffer::wrapBytes(
|
|
62
|
-
static_cast<uint8_t *>(typedArrayWrapper->getRawPointer(
|
|
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.
|
|
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
|
|
117
|
-
|
|
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
|
|
126
|
-
|
|
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
|
-
|
|
139
|
-
|
|
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
|
|
154
|
-
|
|
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
|
|
159
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
181
|
+
jsValue->getObject(rawRuntime).asFunction(rawRuntime));
|
|
171
182
|
return JavaScriptFunction::newInstance(
|
|
172
|
-
|
|
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
|
|
180
|
-
|
|
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(
|
|
184
|
-
.asArray(
|
|
185
|
-
size_t size = jsArray.size(
|
|
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
|
-
|
|
203
|
+
jsiContext,
|
|
191
204
|
runtimeHolder,
|
|
192
|
-
std::make_shared<jsi::Value>(jsArray.getValueAtIndex(
|
|
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
|
|
212
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
28
|
+
std::make_shared<jsi::Object>(value.asObject(rawRuntime));
|
|
27
29
|
if (!objectPtr) {
|
|
28
30
|
return nullptr;
|
|
29
31
|
}
|
|
30
|
-
return JavaScriptObject::newInstance(
|
|
31
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
47
|
-
|
|
50
|
+
const std::weak_ptr<JavaScriptRuntime> &runtime,
|
|
51
|
+
const std::shared_ptr<jsi::Object> &jsObject
|
|
48
52
|
) : _runtimeHolder(std::move(runtime)) {
|
|
49
|
-
_runtimeHolder.
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
24
|
+
: public jni::HybridClass<JavaScriptWeakObject, Destructible> {
|
|
26
25
|
public:
|
|
27
26
|
static auto constexpr kJavaDescriptor =
|
|
28
|
-
|
|
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
|
-
|
|
35
|
-
newInstance(
|
|
36
|
-
|
|
37
|
-
|
|
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(
|
|
45
|
-
|
|
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
|
-
|
|
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
|
|
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>,
|
|
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] =
|
|
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.
|
|
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
|
|
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
|
-
|
|
127
|
+
close()
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
override fun
|
|
130
|
+
override fun close() {
|
|
131
131
|
mHybridData.resetNative()
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
override fun
|
|
135
|
-
|
|
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
|
-
|
|
118
|
+
mHybridData.resetNative()
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
override fun
|
|
122
|
-
mHybridData
|
|
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
|
-
|
|
29
|
+
mHybridData.resetNative()
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
override fun
|
|
33
|
-
mHybridData
|
|
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
|
-
|
|
45
|
+
mHybridData.resetNative()
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
override fun
|
|
49
|
-
mHybridData
|
|
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
|
-
|
|
147
|
+
mHybridData.resetNative()
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
override fun
|
|
151
|
-
mHybridData
|
|
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
|
-
|
|
59
|
+
mHybridData.resetNative()
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
override fun
|
|
63
|
-
mHybridData
|
|
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
|
-
|
|
15
|
+
mHybridData.resetNative()
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
override fun
|
|
19
|
-
mHybridData
|
|
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
|
-
|
|
47
|
+
mHybridData.resetNative()
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
override fun
|
|
51
|
-
mHybridData
|
|
50
|
+
override fun getHybridDataForJNIDeallocator(): HybridData {
|
|
51
|
+
return mHybridData
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
companion object {
|
package/android/src/main/java/expo/modules/kotlin/jni/decorators/JSDecoratorsBridgingObject.kt
CHANGED
|
@@ -98,13 +98,13 @@ class JSDecoratorsBridgingObject(jniDeallocator: JNIDeallocator) : Destructible
|
|
|
98
98
|
)
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
@Throws(Throwable::class)
|
|
102
|
+
protected fun finalize() {
|
|
102
103
|
mHybridData.resetNative()
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
39
|
+
mHybridData.resetNative()
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
override fun
|
|
43
|
-
mHybridData
|
|
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.
|
|
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": "
|
|
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
|