expo-modules-core 1.2.6 → 1.3.0
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 +33 -4
- package/ExpoModulesCore.podspec +1 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +16 -0
- package/android/build.gradle +3 -2
- package/android/src/main/cpp/Exceptions.cpp +8 -0
- package/android/src/main/cpp/Exceptions.h +11 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
- package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
- package/android/src/main/cpp/JNIInjector.cpp +2 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
- package/android/src/main/cpp/JSITypeConverter.h +3 -2
- package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
- package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
- package/android/src/main/cpp/JavaScriptFunction.h +54 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
- package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
- package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
- package/android/src/main/cpp/JavaScriptObject.h +17 -13
- package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
- package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
- package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
- package/android/src/main/cpp/JavaScriptValue.h +4 -0
- package/android/src/main/cpp/MethodMetadata.cpp +66 -87
- package/android/src/main/cpp/MethodMetadata.h +18 -16
- package/android/src/main/cpp/ObjectDeallocator.h +25 -0
- package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
- package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
- package/android/src/main/cpp/types/CppType.h +4 -1
- package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
- package/android/src/main/cpp/types/FrontendConverter.h +45 -0
- package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
- package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +18 -25
- package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +34 -21
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +13 -3
- package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -4
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
- package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
- package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
- package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +7 -8
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
- package/android-annotation/build.gradle +45 -0
- package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
- package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
- package/android-annotation-processor/build.gradle +51 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
- package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
- package/build/NativeViewManagerAdapter.native.js +36 -23
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/requireNativeModule.js +2 -2
- package/build/requireNativeModule.js.map +1 -1
- package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
- package/common/cpp/fabric/ExpoViewProps.h +4 -1
- package/ios/Fabric/ExpoFabricView.swift +10 -10
- package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
- package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
- package/ios/JSI/EXJSIInstaller.mm +1 -1
- package/ios/JSI/EXJSIUtils.h +5 -0
- package/ios/JSI/EXJSIUtils.mm +17 -0
- package/ios/JSI/EXJavaScriptRuntime.h +5 -0
- package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
- package/ios/JSI/EXJavaScriptValue.h +2 -0
- package/ios/JSI/EXJavaScriptValue.mm +8 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
- package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
- package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
- package/ios/JSI/ExpoModulesHostObject.mm +1 -1
- package/ios/JSI/JavaScriptValue.swift +28 -1
- package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
- package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
- package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
- package/ios/Swift/AppContext.swift +46 -6
- package/ios/Swift/Arguments/Convertible.swift +3 -3
- package/ios/Swift/Arguments/Convertibles.swift +5 -5
- package/ios/Swift/Classes/ClassComponent.swift +18 -12
- package/ios/Swift/Classes/ClassRegistry.swift +31 -0
- package/ios/Swift/Conversions.swift +19 -3
- package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
- package/ios/Swift/Convertibles/Either.swift +6 -4
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
- package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
- package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
- package/ios/Swift/ExpoBridgeModule.swift +1 -1
- package/ios/Swift/Functions/AnyFunction.swift +5 -4
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
- package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
- package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
- package/ios/Swift/JavaScriptFunction.swift +68 -0
- package/ios/Swift/JavaScriptUtils.swift +57 -18
- package/ios/Swift/ModuleHolder.swift +22 -10
- package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
- package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
- package/ios/Swift/Objects/PropertyComponent.swift +23 -17
- package/ios/Swift/Records/AnyField.swift +1 -1
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/Records/Record.swift +5 -5
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
- package/ios/Swift/Views/AnyViewProp.swift +1 -1
- package/ios/Swift/Views/ComponentData.swift +37 -2
- package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
- package/ios/Swift/Views/ViewDefinition.swift +39 -0
- package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
- package/ios/Tests/ClassComponentSpec.swift +39 -27
- package/ios/Tests/ConvertiblesSpec.swift +75 -49
- package/ios/Tests/DynamicTypeSpec.swift +29 -27
- package/ios/Tests/EitherSpec.swift +9 -7
- package/ios/Tests/ExpoModulesSpec.swift +13 -13
- package/ios/Tests/FunctionSpec.swift +38 -22
- package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
- package/ios/Tests/PropertyComponentSpec.swift +33 -30
- package/ios/Tests/RecordSpec.swift +7 -5
- package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
- package/ios/Tests/TypedArraysSpec.swift +1 -1
- package/ios/Tests/ViewDefinitionSpec.swift +4 -2
- package/package.json +2 -2
- package/src/NativeViewManagerAdapter.native.tsx +33 -29
- package/src/requireNativeModule.ts +2 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
- package/ios/EXViewManager.h +0 -21
- package/ios/EXViewManager.m +0 -128
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#include "JavaScriptModuleObject.h"
|
|
4
4
|
#include "JSIInteropModuleRegistry.h"
|
|
5
|
+
#include "ObjectDeallocator.h"
|
|
5
6
|
|
|
6
7
|
#include <folly/dynamic.h>
|
|
7
8
|
#include <jsi/JSIDynamic.h>
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
#include <utility>
|
|
17
18
|
#include <tuple>
|
|
18
19
|
#include <algorithm>
|
|
20
|
+
#include <sstream>
|
|
19
21
|
|
|
20
22
|
namespace jni = facebook::jni;
|
|
21
23
|
namespace jsi = facebook::jsi;
|
|
@@ -23,6 +25,60 @@ namespace react = facebook::react;
|
|
|
23
25
|
|
|
24
26
|
namespace expo {
|
|
25
27
|
|
|
28
|
+
void decorateObjectWithFunctions(
|
|
29
|
+
jsi::Runtime &runtime,
|
|
30
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
31
|
+
jsi::Object *jsObject,
|
|
32
|
+
JavaScriptModuleObject *objectData) {
|
|
33
|
+
for (auto &[name, method]: objectData->methodsMetadata) {
|
|
34
|
+
jsObject->setProperty(
|
|
35
|
+
runtime,
|
|
36
|
+
jsi::String::createFromUtf8(runtime, name),
|
|
37
|
+
jsi::Value(runtime, *method.toJSFunction(runtime, jsiInteropModuleRegistry))
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void decorateObjectWithProperties(
|
|
43
|
+
jsi::Runtime &runtime,
|
|
44
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
45
|
+
jsi::Object *jsObject,
|
|
46
|
+
JavaScriptModuleObject *objectData) {
|
|
47
|
+
for (auto &[name, property]: objectData->properties) {
|
|
48
|
+
auto &[getter, setter] = property;
|
|
49
|
+
|
|
50
|
+
auto descriptor = JavaScriptObject::preparePropertyDescriptor(runtime,
|
|
51
|
+
1 << 1 /* enumerable */);
|
|
52
|
+
descriptor.setProperty(
|
|
53
|
+
runtime,
|
|
54
|
+
"get",
|
|
55
|
+
jsi::Value(runtime, *getter.toJSFunction(runtime,
|
|
56
|
+
jsiInteropModuleRegistry))
|
|
57
|
+
);
|
|
58
|
+
descriptor.setProperty(
|
|
59
|
+
runtime,
|
|
60
|
+
"set",
|
|
61
|
+
jsi::Value(runtime, *setter.toJSFunction(runtime,
|
|
62
|
+
jsiInteropModuleRegistry))
|
|
63
|
+
);
|
|
64
|
+
JavaScriptObject::defineProperty(runtime, jsObject, name, std::move(descriptor));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void decorateObjectWithConstants(
|
|
69
|
+
jsi::Runtime &runtime,
|
|
70
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
71
|
+
jsi::Object *jsObject,
|
|
72
|
+
JavaScriptModuleObject *objectData) {
|
|
73
|
+
for (const auto &[name, value]: objectData->constants) {
|
|
74
|
+
jsObject->setProperty(
|
|
75
|
+
runtime,
|
|
76
|
+
jsi::String::createFromUtf8(runtime, name),
|
|
77
|
+
jsi::valueFromDynamic(runtime, value)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
26
82
|
jni::local_ref<jni::HybridClass<JavaScriptModuleObject>::jhybriddata>
|
|
27
83
|
JavaScriptModuleObject::initHybrid(jni::alias_ref<jhybridobject> jThis) {
|
|
28
84
|
return makeCxxInstance(jThis);
|
|
@@ -38,6 +94,10 @@ void JavaScriptModuleObject::registerNatives() {
|
|
|
38
94
|
JavaScriptModuleObject::registerAsyncFunction),
|
|
39
95
|
makeNativeMethod("registerProperty",
|
|
40
96
|
JavaScriptModuleObject::registerProperty),
|
|
97
|
+
makeNativeMethod("registerClass",
|
|
98
|
+
JavaScriptModuleObject::registerClass),
|
|
99
|
+
makeNativeMethod("registerViewPrototype",
|
|
100
|
+
JavaScriptModuleObject::registerViewPrototype)
|
|
41
101
|
});
|
|
42
102
|
}
|
|
43
103
|
|
|
@@ -46,11 +106,133 @@ std::shared_ptr<jsi::Object> JavaScriptModuleObject::getJSIObject(jsi::Runtime &
|
|
|
46
106
|
return object;
|
|
47
107
|
}
|
|
48
108
|
|
|
49
|
-
auto
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
109
|
+
auto moduleObject = std::make_shared<jsi::Object>(runtime);
|
|
110
|
+
|
|
111
|
+
decorateObjectWithConstants(
|
|
112
|
+
runtime,
|
|
113
|
+
jsiInteropModuleRegistry,
|
|
114
|
+
moduleObject.get(),
|
|
115
|
+
this
|
|
116
|
+
);
|
|
117
|
+
decorateObjectWithProperties(
|
|
118
|
+
runtime,
|
|
119
|
+
jsiInteropModuleRegistry,
|
|
120
|
+
moduleObject.get(),
|
|
121
|
+
this
|
|
122
|
+
);
|
|
123
|
+
decorateObjectWithFunctions(
|
|
124
|
+
runtime,
|
|
125
|
+
jsiInteropModuleRegistry,
|
|
126
|
+
moduleObject.get(),
|
|
127
|
+
this
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
if (viewPrototype) {
|
|
131
|
+
auto viewPrototypeObject = viewPrototype->cthis();
|
|
132
|
+
viewPrototypeObject->jsiInteropModuleRegistry = jsiInteropModuleRegistry;
|
|
133
|
+
auto viewPrototypeJSIObject = viewPrototypeObject->getJSIObject(runtime);
|
|
134
|
+
moduleObject->setProperty(
|
|
135
|
+
runtime,
|
|
136
|
+
"ViewPrototype",
|
|
137
|
+
jsi::Value(runtime, *viewPrototypeJSIObject)
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
for (auto &[name, classInfo]: classes) {
|
|
142
|
+
auto &[classRef, constructor] = classInfo;
|
|
143
|
+
auto classObject = classRef->cthis();
|
|
144
|
+
classObject->jsiInteropModuleRegistry = jsiInteropModuleRegistry;
|
|
145
|
+
|
|
146
|
+
std::string nativeConstructorKey("__native_constructor__");
|
|
147
|
+
|
|
148
|
+
// Create a string buffer of the source code to evaluate.
|
|
149
|
+
std::stringstream source;
|
|
150
|
+
source << "(function " << name << "(...args) { this." << nativeConstructorKey
|
|
151
|
+
<< "(...args); return this; })";
|
|
152
|
+
std::shared_ptr<jsi::StringBuffer> sourceBuffer = std::make_shared<jsi::StringBuffer>(
|
|
153
|
+
source.str());
|
|
154
|
+
|
|
155
|
+
// Evaluate the code and obtain returned value (the constructor function).
|
|
156
|
+
jsi::Object klass = runtime.evaluateJavaScript(sourceBuffer, "").asObject(runtime);
|
|
157
|
+
|
|
158
|
+
// Set the native constructor in the prototype.
|
|
159
|
+
jsi::Object prototype = klass.getPropertyAsObject(runtime, "prototype");
|
|
160
|
+
jsi::PropNameID nativeConstructorPropId = jsi::PropNameID::forAscii(runtime,
|
|
161
|
+
nativeConstructorKey);
|
|
162
|
+
jsi::Function nativeConstructor = jsi::Function::createFromHostFunction(
|
|
163
|
+
runtime,
|
|
164
|
+
nativeConstructorPropId,
|
|
165
|
+
// The paramCount is not obligatory to match, it only affects the `length` property of the function.
|
|
166
|
+
0,
|
|
167
|
+
[classObject, &constructor = constructor, jsiInteropModuleRegistry = jsiInteropModuleRegistry](
|
|
168
|
+
jsi::Runtime &runtime,
|
|
169
|
+
const jsi::Value &thisValue,
|
|
170
|
+
const jsi::Value *args,
|
|
171
|
+
size_t count
|
|
172
|
+
) -> jsi::Value {
|
|
173
|
+
auto thisObject = std::make_shared<jsi::Object>(thisValue.asObject(runtime));
|
|
174
|
+
decorateObjectWithProperties(runtime, jsiInteropModuleRegistry, thisObject.get(),
|
|
175
|
+
classObject);
|
|
176
|
+
try {
|
|
177
|
+
JNIEnv *env = jni::Environment::current();
|
|
178
|
+
/**
|
|
179
|
+
* This will push a new JNI stack frame for the LocalReferences in this
|
|
180
|
+
* function call. When the stack frame for this lambda is popped,
|
|
181
|
+
* all LocalReferences are deleted.
|
|
182
|
+
*/
|
|
183
|
+
jni::JniLocalScope scope(env, (int) count);
|
|
184
|
+
auto result = constructor.callJNISync(
|
|
185
|
+
env,
|
|
186
|
+
runtime,
|
|
187
|
+
jsiInteropModuleRegistry,
|
|
188
|
+
thisValue,
|
|
189
|
+
args,
|
|
190
|
+
count
|
|
191
|
+
);
|
|
192
|
+
if (result == nullptr) {
|
|
193
|
+
return jsi::Value::undefined();
|
|
194
|
+
}
|
|
195
|
+
jobject unpackedResult = result.get();
|
|
196
|
+
jclass resultClass = env->GetObjectClass(unpackedResult);
|
|
197
|
+
if (env->IsAssignableFrom(
|
|
198
|
+
resultClass,
|
|
199
|
+
JavaReferencesCache::instance()->getJClass(
|
|
200
|
+
"expo/modules/kotlin/sharedobjects/SharedObject").clazz
|
|
201
|
+
)) {
|
|
202
|
+
auto jsThisObject = JavaScriptObject::newObjectCxxArgs(
|
|
203
|
+
jsiInteropModuleRegistry->runtimeHolder,
|
|
204
|
+
thisObject
|
|
205
|
+
);
|
|
206
|
+
jsiInteropModuleRegistry->registerSharedObject(result, jsThisObject);
|
|
207
|
+
}
|
|
208
|
+
} catch (jni::JniException &jniException) {
|
|
209
|
+
rethrowAsCodedError(runtime, jniException);
|
|
210
|
+
}
|
|
211
|
+
return jsi::Value::undefined();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
auto descriptor = JavaScriptObject::preparePropertyDescriptor(runtime, 0);
|
|
215
|
+
descriptor.setProperty(runtime, "value", jsi::Value(runtime, nativeConstructor));
|
|
216
|
+
|
|
217
|
+
JavaScriptObject::defineProperty(runtime, &prototype, nativeConstructorKey,
|
|
218
|
+
std::move(descriptor));
|
|
219
|
+
|
|
220
|
+
moduleObject->setProperty(
|
|
221
|
+
runtime,
|
|
222
|
+
jsi::String::createFromUtf8(runtime, name),
|
|
223
|
+
jsi::Value(runtime, klass.asFunction(runtime))
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
decorateObjectWithFunctions(
|
|
227
|
+
runtime,
|
|
228
|
+
jsiInteropModuleRegistry,
|
|
229
|
+
&prototype,
|
|
230
|
+
classObject
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
jsiObject = moduleObject;
|
|
235
|
+
return moduleObject;
|
|
54
236
|
}
|
|
55
237
|
|
|
56
238
|
void JavaScriptModuleObject::exportConstants(
|
|
@@ -66,6 +248,7 @@ void JavaScriptModuleObject::exportConstants(
|
|
|
66
248
|
|
|
67
249
|
void JavaScriptModuleObject::registerSyncFunction(
|
|
68
250
|
jni::alias_ref<jstring> name,
|
|
251
|
+
jboolean takesOwner,
|
|
69
252
|
jint args,
|
|
70
253
|
jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
|
|
71
254
|
jni::alias_ref<JNIFunctionBody::javaobject> body
|
|
@@ -74,8 +257,8 @@ void JavaScriptModuleObject::registerSyncFunction(
|
|
|
74
257
|
|
|
75
258
|
methodsMetadata.try_emplace(
|
|
76
259
|
cName,
|
|
77
|
-
longLivedObjectCollection_,
|
|
78
260
|
cName,
|
|
261
|
+
takesOwner,
|
|
79
262
|
args,
|
|
80
263
|
false,
|
|
81
264
|
jni::make_local(expectedArgTypes),
|
|
@@ -85,6 +268,7 @@ void JavaScriptModuleObject::registerSyncFunction(
|
|
|
85
268
|
|
|
86
269
|
void JavaScriptModuleObject::registerAsyncFunction(
|
|
87
270
|
jni::alias_ref<jstring> name,
|
|
271
|
+
jboolean takesOwner,
|
|
88
272
|
jint args,
|
|
89
273
|
jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
|
|
90
274
|
jni::alias_ref<JNIAsyncFunctionBody::javaobject> body
|
|
@@ -93,8 +277,8 @@ void JavaScriptModuleObject::registerAsyncFunction(
|
|
|
93
277
|
|
|
94
278
|
methodsMetadata.try_emplace(
|
|
95
279
|
cName,
|
|
96
|
-
longLivedObjectCollection_,
|
|
97
280
|
cName,
|
|
281
|
+
takesOwner,
|
|
98
282
|
args,
|
|
99
283
|
true,
|
|
100
284
|
jni::make_local(expectedArgTypes),
|
|
@@ -102,6 +286,38 @@ void JavaScriptModuleObject::registerAsyncFunction(
|
|
|
102
286
|
);
|
|
103
287
|
}
|
|
104
288
|
|
|
289
|
+
void JavaScriptModuleObject::registerClass(
|
|
290
|
+
jni::alias_ref<jstring> name,
|
|
291
|
+
jni::alias_ref<JavaScriptModuleObject::javaobject> classObject,
|
|
292
|
+
jboolean takesOwner,
|
|
293
|
+
jint args,
|
|
294
|
+
jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
|
|
295
|
+
jni::alias_ref<JNIFunctionBody::javaobject> body
|
|
296
|
+
) {
|
|
297
|
+
std::string cName = name->toStdString();
|
|
298
|
+
MethodMetadata constructor(
|
|
299
|
+
"constructor",
|
|
300
|
+
takesOwner,
|
|
301
|
+
args,
|
|
302
|
+
false,
|
|
303
|
+
jni::make_local(expectedArgTypes),
|
|
304
|
+
jni::make_global(body)
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
auto pair = std::make_pair(jni::make_global(classObject), std::move(constructor));
|
|
308
|
+
|
|
309
|
+
classes.try_emplace(
|
|
310
|
+
cName,
|
|
311
|
+
std::move(pair)
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
void JavaScriptModuleObject::registerViewPrototype(
|
|
316
|
+
jni::alias_ref<JavaScriptModuleObject::javaobject> viewPrototype
|
|
317
|
+
) {
|
|
318
|
+
this->viewPrototype = jni::make_global(viewPrototype);
|
|
319
|
+
}
|
|
320
|
+
|
|
105
321
|
void JavaScriptModuleObject::registerProperty(
|
|
106
322
|
jni::alias_ref<jstring> name,
|
|
107
323
|
jni::alias_ref<ExpectedType> expectedArgType,
|
|
@@ -111,8 +327,8 @@ void JavaScriptModuleObject::registerProperty(
|
|
|
111
327
|
auto cName = name->toStdString();
|
|
112
328
|
|
|
113
329
|
auto getterMetadata = MethodMetadata(
|
|
114
|
-
longLivedObjectCollection_,
|
|
115
330
|
cName,
|
|
331
|
+
false,
|
|
116
332
|
0,
|
|
117
333
|
false,
|
|
118
334
|
std::vector<std::unique_ptr<AnyType>>(),
|
|
@@ -122,8 +338,8 @@ void JavaScriptModuleObject::registerProperty(
|
|
|
122
338
|
auto types = std::vector<std::unique_ptr<AnyType>>();
|
|
123
339
|
types.push_back(std::make_unique<AnyType>(jni::make_local(expectedArgType)));
|
|
124
340
|
auto setterMetadata = MethodMetadata(
|
|
125
|
-
longLivedObjectCollection_,
|
|
126
341
|
cName,
|
|
342
|
+
false,
|
|
127
343
|
1,
|
|
128
344
|
false,
|
|
129
345
|
std::move(types),
|
|
@@ -138,103 +354,7 @@ void JavaScriptModuleObject::registerProperty(
|
|
|
138
354
|
properties.insert({cName, std::move(functions)});
|
|
139
355
|
}
|
|
140
356
|
|
|
141
|
-
JavaScriptModuleObject::HostObject::HostObject(
|
|
142
|
-
JavaScriptModuleObject *jsModule) : jsModule(jsModule) {}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Clears all the JSI references held by the `JavaScriptModuleObject`.
|
|
146
|
-
*/
|
|
147
|
-
JavaScriptModuleObject::HostObject::~HostObject() {
|
|
148
|
-
jObjectRef.reset();
|
|
149
|
-
jsModule->jsiObject.reset();
|
|
150
|
-
jsModule->methodsMetadata.clear();
|
|
151
|
-
jsModule->constants.clear();
|
|
152
|
-
jsModule->properties.clear();
|
|
153
|
-
jsModule->longLivedObjectCollection_->clear();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
jsi::Value JavaScriptModuleObject::HostObject::get(jsi::Runtime &runtime,
|
|
157
|
-
const jsi::PropNameID &name) {
|
|
158
|
-
auto cName = name.utf8(runtime);
|
|
159
|
-
|
|
160
|
-
auto constantsRecord = jsModule->constants.find(cName);
|
|
161
|
-
if (constantsRecord != jsModule->constants.end()) {
|
|
162
|
-
auto dynamic = constantsRecord->second;
|
|
163
|
-
return jsi::valueFromDynamic(runtime, dynamic);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
auto propertyRecord = jsModule->properties.find(cName);
|
|
167
|
-
if (propertyRecord != jsModule->properties.end()) {
|
|
168
|
-
auto&[getter, _] = propertyRecord->second;
|
|
169
|
-
return getter.callSync(runtime, jsModule->jsiInteropModuleRegistry, nullptr, 0);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
auto metadataRecord = jsModule->methodsMetadata.find(cName);
|
|
173
|
-
if (metadataRecord == jsModule->methodsMetadata.end()) {
|
|
174
|
-
return jsi::Value::undefined();
|
|
175
|
-
}
|
|
176
|
-
auto &metadata = metadataRecord->second;
|
|
177
|
-
return jsi::Value(runtime, *metadata.toJSFunction(runtime, jsModule->jsiInteropModuleRegistry));
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
void JavaScriptModuleObject::HostObject::set(
|
|
181
|
-
jsi::Runtime &runtime,
|
|
182
|
-
const jsi::PropNameID &name,
|
|
183
|
-
const jsi::Value &value
|
|
184
|
-
) {
|
|
185
|
-
auto cName = name.utf8(runtime);
|
|
186
|
-
auto propertyRecord = jsModule->properties.find(cName);
|
|
187
|
-
if (propertyRecord != jsModule->properties.end()) {
|
|
188
|
-
auto&[_, setter] = propertyRecord->second;
|
|
189
|
-
setter.callSync(runtime, jsModule->jsiInteropModuleRegistry, &value, 1);
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
throw jsi::JSError(
|
|
194
|
-
runtime,
|
|
195
|
-
"RuntimeError: Cannot override the host object for expo module '" + name.utf8(runtime) + "'"
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
std::vector<jsi::PropNameID> JavaScriptModuleObject::HostObject::getPropertyNames(
|
|
200
|
-
jsi::Runtime &rt
|
|
201
|
-
) {
|
|
202
|
-
auto &metadata = jsModule->methodsMetadata;
|
|
203
|
-
std::vector<jsi::PropNameID> result;
|
|
204
|
-
std::transform(
|
|
205
|
-
metadata.begin(),
|
|
206
|
-
metadata.end(),
|
|
207
|
-
std::back_inserter(result),
|
|
208
|
-
[&rt](const auto &kv) {
|
|
209
|
-
return jsi::PropNameID::forUtf8(rt, kv.first);
|
|
210
|
-
}
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
auto &constants = jsModule->constants;
|
|
214
|
-
std::transform(
|
|
215
|
-
constants.begin(),
|
|
216
|
-
constants.end(),
|
|
217
|
-
std::back_inserter(result),
|
|
218
|
-
[&rt](const auto &kv) {
|
|
219
|
-
return jsi::PropNameID::forUtf8(rt, kv.first);
|
|
220
|
-
}
|
|
221
|
-
);
|
|
222
|
-
|
|
223
|
-
auto &properties = jsModule->properties;
|
|
224
|
-
std::transform(
|
|
225
|
-
properties.begin(),
|
|
226
|
-
properties.end(),
|
|
227
|
-
std::back_inserter(result),
|
|
228
|
-
[&rt](const auto &kv) {
|
|
229
|
-
return jsi::PropNameID::forUtf8(rt, kv.first);
|
|
230
|
-
}
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
return result;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
357
|
JavaScriptModuleObject::JavaScriptModuleObject(jni::alias_ref<jhybridobject> jThis)
|
|
237
358
|
: javaPart_(jni::make_global(jThis)) {
|
|
238
|
-
longLivedObjectCollection_ = std::make_shared<react::LongLivedObjectCollection>();
|
|
239
359
|
}
|
|
240
360
|
} // namespace expo
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
#include <fbjni/fbjni.h>
|
|
6
6
|
#include <jsi/jsi.h>
|
|
7
|
-
#include <react/bridging/LongLivedObject.h>
|
|
8
7
|
#include <react/jni/ReadableNativeArray.h>
|
|
9
8
|
#include <jni/JCallback.h>
|
|
10
9
|
|
|
@@ -21,6 +20,29 @@ namespace react = facebook::react;
|
|
|
21
20
|
namespace expo {
|
|
22
21
|
class JSIInteropModuleRegistry;
|
|
23
22
|
|
|
23
|
+
class JavaScriptModuleObject;
|
|
24
|
+
|
|
25
|
+
void decorateObjectWithFunctions(
|
|
26
|
+
jsi::Runtime &runtime,
|
|
27
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
28
|
+
jsi::Object *jsObject,
|
|
29
|
+
JavaScriptModuleObject *objectData
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
void decorateObjectWithProperties(
|
|
33
|
+
jsi::Runtime &runtime,
|
|
34
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
35
|
+
jsi::Object *jsObject,
|
|
36
|
+
JavaScriptModuleObject *objectData
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
void decorateObjectWithConstants(
|
|
40
|
+
jsi::Runtime &runtime,
|
|
41
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
42
|
+
jsi::Object *jsObject,
|
|
43
|
+
JavaScriptModuleObject *objectData
|
|
44
|
+
);
|
|
45
|
+
|
|
24
46
|
/**
|
|
25
47
|
* A CPP part of the module.
|
|
26
48
|
*
|
|
@@ -60,6 +82,7 @@ public:
|
|
|
60
82
|
*/
|
|
61
83
|
void registerSyncFunction(
|
|
62
84
|
jni::alias_ref<jstring> name,
|
|
85
|
+
jboolean takesOwner,
|
|
63
86
|
jint args,
|
|
64
87
|
jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
|
|
65
88
|
jni::alias_ref<JNIFunctionBody::javaobject> body
|
|
@@ -71,11 +94,25 @@ public:
|
|
|
71
94
|
*/
|
|
72
95
|
void registerAsyncFunction(
|
|
73
96
|
jni::alias_ref<jstring> name,
|
|
97
|
+
jboolean takesOwner,
|
|
74
98
|
jint args,
|
|
75
99
|
jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
|
|
76
100
|
jni::alias_ref<JNIAsyncFunctionBody::javaobject> body
|
|
77
101
|
);
|
|
78
102
|
|
|
103
|
+
void registerClass(
|
|
104
|
+
jni::alias_ref<jstring> name,
|
|
105
|
+
jni::alias_ref<JavaScriptModuleObject::javaobject> classObject,
|
|
106
|
+
jboolean takesOwner,
|
|
107
|
+
jint args,
|
|
108
|
+
jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
|
|
109
|
+
jni::alias_ref<JNIFunctionBody::javaobject> body
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
void registerViewPrototype(
|
|
113
|
+
jni::alias_ref<JavaScriptModuleObject::javaobject> viewPrototype
|
|
114
|
+
);
|
|
115
|
+
|
|
79
116
|
/**
|
|
80
117
|
* Registers a property
|
|
81
118
|
* @param name of the property
|
|
@@ -90,41 +127,35 @@ public:
|
|
|
90
127
|
jni::alias_ref<JNIFunctionBody::javaobject> setter
|
|
91
128
|
);
|
|
92
129
|
|
|
93
|
-
/**
|
|
94
|
-
* An inner class of the `JavaScriptModuleObject` that is exported to the JS.
|
|
95
|
-
* It's an additional communication layer between JS and Kotlin.
|
|
96
|
-
* So the high-level view on accessing the exported function will look like this:
|
|
97
|
-
* `JS` --get function--> `JavaScriptModuleObject::HostObject` --access module metadata--> `JavaScriptModuleObject`
|
|
98
|
-
* --create JSI function--> `MethodMetadata`
|
|
99
|
-
*
|
|
100
|
-
* This abstraction wasn't necessary. However, it makes the management of ownership much easier -
|
|
101
|
-
* `JavaScriptModuleObject` is held by the ModuleHolder and `JavaScriptModuleObject::HostObject` is stored in the JS runtime.
|
|
102
|
-
* Without this distinction the `JavaScriptModuleObject` would have to turn into `HostObject` and `HybridObject` at the same time.
|
|
103
|
-
*/
|
|
104
|
-
class HostObject : public jsi::HostObject {
|
|
105
|
-
public:
|
|
106
|
-
HostObject(JavaScriptModuleObject *);
|
|
107
|
-
|
|
108
|
-
~HostObject() override;
|
|
109
|
-
|
|
110
|
-
jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override;
|
|
111
|
-
|
|
112
|
-
void set(jsi::Runtime &, const jsi::PropNameID &name, const jsi::Value &value) override;
|
|
113
|
-
|
|
114
|
-
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
|
115
|
-
|
|
116
|
-
jni::global_ref<jobject> jObjectRef;
|
|
117
|
-
private:
|
|
118
|
-
JavaScriptModuleObject *jsModule;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
130
|
private:
|
|
122
131
|
explicit JavaScriptModuleObject(jni::alias_ref<jhybridobject> jThis);
|
|
123
132
|
|
|
124
133
|
private:
|
|
125
134
|
friend HybridBase;
|
|
135
|
+
|
|
136
|
+
friend void decorateObjectWithFunctions(
|
|
137
|
+
jsi::Runtime &runtime,
|
|
138
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
139
|
+
jsi::Object *jsObject,
|
|
140
|
+
JavaScriptModuleObject *objectData
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
friend void decorateObjectWithProperties(
|
|
144
|
+
jsi::Runtime &runtime,
|
|
145
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
146
|
+
jsi::Object *jsObject,
|
|
147
|
+
JavaScriptModuleObject *objectData
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
friend void decorateObjectWithConstants(
|
|
151
|
+
jsi::Runtime &runtime,
|
|
152
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
153
|
+
jsi::Object *jsObject,
|
|
154
|
+
JavaScriptModuleObject *objectData
|
|
155
|
+
);
|
|
156
|
+
|
|
126
157
|
/**
|
|
127
|
-
* A reference to the `
|
|
158
|
+
* A reference to the `jsi::Object`.
|
|
128
159
|
* Simple we cached that value to return the same object each time.
|
|
129
160
|
* It's a weak reference because the JS runtime holds the actual object.
|
|
130
161
|
* Doing that allows the runtime to deallocate jsi::Object if it's not needed anymore.
|
|
@@ -148,9 +179,11 @@ private:
|
|
|
148
179
|
*/
|
|
149
180
|
std::map<std::string, std::pair<MethodMetadata, MethodMetadata>> properties;
|
|
150
181
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
182
|
+
std::map<
|
|
183
|
+
std::string,
|
|
184
|
+
std::pair<jni::global_ref<JavaScriptModuleObject::javaobject>, MethodMetadata>
|
|
185
|
+
> classes;
|
|
186
|
+
|
|
187
|
+
jni::global_ref<JavaScriptModuleObject::javaobject> viewPrototype;
|
|
155
188
|
};
|
|
156
189
|
} // namespace expo
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
#include "JavaScriptObject.h"
|
|
4
4
|
#include "JavaScriptValue.h"
|
|
5
|
+
#include "JavaScriptFunction.h"
|
|
5
6
|
#include "JavaScriptRuntime.h"
|
|
6
7
|
#include "JSITypeConverter.h"
|
|
8
|
+
#include "ObjectDeallocator.h"
|
|
9
|
+
#include "JavaReferencesCache.h"
|
|
7
10
|
|
|
8
11
|
namespace expo {
|
|
9
12
|
void JavaScriptObject::registerNatives() {
|
|
@@ -29,6 +32,8 @@ void JavaScriptObject::registerNatives() {
|
|
|
29
32
|
JavaScriptObject::defineProperty<jni::alias_ref<JavaScriptValue::javaobject>>),
|
|
30
33
|
makeNativeMethod("defineJSObjectProperty",
|
|
31
34
|
JavaScriptObject::defineProperty<jni::alias_ref<JavaScriptObject::javaobject>>),
|
|
35
|
+
makeNativeMethod("defineNativeDeallocator",
|
|
36
|
+
JavaScriptObject::defineNativeDeallocator),
|
|
32
37
|
});
|
|
33
38
|
}
|
|
34
39
|
|
|
@@ -99,6 +104,12 @@ jni::local_ref<jni::JArrayClass<jstring>> JavaScriptObject::jniGetPropertyNames(
|
|
|
99
104
|
return paredResult;
|
|
100
105
|
}
|
|
101
106
|
|
|
107
|
+
jni::local_ref<JavaScriptFunction::javaobject> JavaScriptObject::jniAsFunction() {
|
|
108
|
+
auto &jsRuntime = runtimeHolder.getJSRuntime();
|
|
109
|
+
auto jsFuncion = std::make_shared<jsi::Function>(jsObject->asFunction(jsRuntime));
|
|
110
|
+
return JavaScriptFunction::newObjectCxxArgs(runtimeHolder, jsFuncion);
|
|
111
|
+
}
|
|
112
|
+
|
|
102
113
|
void JavaScriptObject::setProperty(const std::string &name, jsi::Value value) {
|
|
103
114
|
auto &jsRuntime = runtimeHolder.getJSRuntime();
|
|
104
115
|
jsObject->setProperty(jsRuntime, name.c_str(), value);
|
|
@@ -121,7 +132,50 @@ jsi::Object JavaScriptObject::preparePropertyDescriptor(
|
|
|
121
132
|
jsi::Object descriptor(jsRuntime);
|
|
122
133
|
descriptor.setProperty(jsRuntime, "configurable", (bool) ((1 << 0) & options));
|
|
123
134
|
descriptor.setProperty(jsRuntime, "enumerable", (bool) ((1 << 1) & options));
|
|
124
|
-
|
|
135
|
+
if ((bool) (1 << 2 & options)) {
|
|
136
|
+
descriptor.setProperty(jsRuntime, "writable", true);
|
|
137
|
+
}
|
|
125
138
|
return descriptor;
|
|
126
139
|
}
|
|
140
|
+
|
|
141
|
+
void JavaScriptObject::defineProperty(
|
|
142
|
+
jsi::Runtime &runtime,
|
|
143
|
+
jsi::Object *jsthis,
|
|
144
|
+
const std::string &name,
|
|
145
|
+
jsi::Object descriptor
|
|
146
|
+
) {
|
|
147
|
+
jsi::Object global = runtime.global();
|
|
148
|
+
jsi::Object objectClass = global.getPropertyAsObject(runtime, "Object");
|
|
149
|
+
jsi::Function definePropertyFunction = objectClass.getPropertyAsFunction(
|
|
150
|
+
runtime,
|
|
151
|
+
"defineProperty"
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
// This call is basically the same as `Object.defineProperty(object, name, descriptor)` in JS
|
|
155
|
+
definePropertyFunction.callWithThis(runtime, objectClass, {
|
|
156
|
+
jsi::Value(runtime, *jsthis),
|
|
157
|
+
jsi::String::createFromUtf8(runtime, name),
|
|
158
|
+
std::move(descriptor),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
void JavaScriptObject::defineNativeDeallocator(
|
|
163
|
+
jni::alias_ref<JNIFunctionBody::javaobject> deallocator
|
|
164
|
+
) {
|
|
165
|
+
auto &rt = runtimeHolder.getJSRuntime();
|
|
166
|
+
jni::global_ref<JNIFunctionBody::javaobject> globalRef = jni::make_global(deallocator);
|
|
167
|
+
std::shared_ptr<ObjectDeallocator> nativeDeallocator = std::make_shared<ObjectDeallocator>(
|
|
168
|
+
[globalRef = std::move(globalRef)]() mutable {
|
|
169
|
+
auto args = jni::Environment::current()->NewObjectArray(
|
|
170
|
+
0,
|
|
171
|
+
JavaReferencesCache::instance()->getJClass("java/lang/Object").clazz,
|
|
172
|
+
nullptr
|
|
173
|
+
);
|
|
174
|
+
globalRef->invoke(args);
|
|
175
|
+
globalRef.reset();
|
|
176
|
+
});
|
|
177
|
+
auto descriptor = JavaScriptObject::preparePropertyDescriptor(rt, 0);
|
|
178
|
+
descriptor.setProperty(rt, "value", jsi::Object::createFromHostObject(rt, nativeDeallocator));
|
|
179
|
+
jsObject->setProperty(rt, "__expo_shared_object_deallocator__", std::move(descriptor));
|
|
180
|
+
}
|
|
127
181
|
} // namespace expo
|