164f5c95fSŁukasz Kosmaty // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
264f5c95fSŁukasz Kosmaty
364f5c95fSŁukasz Kosmaty #include "JavaScriptModuleObject.h"
464f5c95fSŁukasz Kosmaty #include "JSIInteropModuleRegistry.h"
5e1f25825SŁukasz Kosmaty #include "JSIUtils.h"
664f5c95fSŁukasz Kosmaty
764f5c95fSŁukasz Kosmaty #include <folly/dynamic.h>
864f5c95fSŁukasz Kosmaty #include <jsi/JSIDynamic.h>
964f5c95fSŁukasz Kosmaty #include <react/jni/ReadableNativeArray.h>
1064f5c95fSŁukasz Kosmaty #include <fbjni/detail/Hybrid.h>
1164f5c95fSŁukasz Kosmaty #include <ReactCommon/TurboModuleUtils.h>
1264f5c95fSŁukasz Kosmaty #include <jni/JCallback.h>
1364f5c95fSŁukasz Kosmaty #include <jsi/JSIDynamic.h>
1464f5c95fSŁukasz Kosmaty #include <fbjni/fbjni.h>
1564f5c95fSŁukasz Kosmaty #include <jsi/jsi.h>
1664f5c95fSŁukasz Kosmaty
1764f5c95fSŁukasz Kosmaty #include <utility>
1864f5c95fSŁukasz Kosmaty #include <tuple>
1964f5c95fSŁukasz Kosmaty #include <algorithm>
20cf4fff55SŁukasz Kosmaty #include <sstream>
2164f5c95fSŁukasz Kosmaty
2264f5c95fSŁukasz Kosmaty namespace jni = facebook::jni;
2364f5c95fSŁukasz Kosmaty namespace jsi = facebook::jsi;
2464f5c95fSŁukasz Kosmaty namespace react = facebook::react;
2564f5c95fSŁukasz Kosmaty
2664f5c95fSŁukasz Kosmaty namespace expo {
2764f5c95fSŁukasz Kosmaty
decorateObjectWithFunctions(jsi::Runtime & runtime,JSIInteropModuleRegistry * jsiInteropModuleRegistry,jsi::Object * jsObject,JavaScriptModuleObject * objectData)28cf4fff55SŁukasz Kosmaty void decorateObjectWithFunctions(
29cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime,
30cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry,
31cf4fff55SŁukasz Kosmaty jsi::Object *jsObject,
32cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData) {
33cf4fff55SŁukasz Kosmaty for (auto &[name, method]: objectData->methodsMetadata) {
34cf4fff55SŁukasz Kosmaty jsObject->setProperty(
35cf4fff55SŁukasz Kosmaty runtime,
36cf4fff55SŁukasz Kosmaty jsi::String::createFromUtf8(runtime, name),
37cf4fff55SŁukasz Kosmaty jsi::Value(runtime, *method.toJSFunction(runtime, jsiInteropModuleRegistry))
38cf4fff55SŁukasz Kosmaty );
39cf4fff55SŁukasz Kosmaty }
40cf4fff55SŁukasz Kosmaty }
41cf4fff55SŁukasz Kosmaty
decorateObjectWithProperties(jsi::Runtime & runtime,JSIInteropModuleRegistry * jsiInteropModuleRegistry,jsi::Object * jsObject,JavaScriptModuleObject * objectData)42cf4fff55SŁukasz Kosmaty void decorateObjectWithProperties(
43cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime,
44cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry,
45cf4fff55SŁukasz Kosmaty jsi::Object *jsObject,
46cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData) {
47cf4fff55SŁukasz Kosmaty for (auto &[name, property]: objectData->properties) {
48cf4fff55SŁukasz Kosmaty auto &[getter, setter] = property;
49cf4fff55SŁukasz Kosmaty
50cf4fff55SŁukasz Kosmaty auto descriptor = JavaScriptObject::preparePropertyDescriptor(runtime,
51cf4fff55SŁukasz Kosmaty 1 << 1 /* enumerable */);
52cf4fff55SŁukasz Kosmaty descriptor.setProperty(
53cf4fff55SŁukasz Kosmaty runtime,
54cf4fff55SŁukasz Kosmaty "get",
55cf4fff55SŁukasz Kosmaty jsi::Value(runtime, *getter.toJSFunction(runtime,
56cf4fff55SŁukasz Kosmaty jsiInteropModuleRegistry))
57cf4fff55SŁukasz Kosmaty );
58cf4fff55SŁukasz Kosmaty descriptor.setProperty(
59cf4fff55SŁukasz Kosmaty runtime,
60cf4fff55SŁukasz Kosmaty "set",
61cf4fff55SŁukasz Kosmaty jsi::Value(runtime, *setter.toJSFunction(runtime,
62cf4fff55SŁukasz Kosmaty jsiInteropModuleRegistry))
63cf4fff55SŁukasz Kosmaty );
64e1f25825SŁukasz Kosmaty common::definePropertyOnJSIObject(runtime, jsObject, name.c_str(), std::move(descriptor));
65cf4fff55SŁukasz Kosmaty }
66cf4fff55SŁukasz Kosmaty }
67cf4fff55SŁukasz Kosmaty
decorateObjectWithConstants(jsi::Runtime & runtime,JSIInteropModuleRegistry * jsiInteropModuleRegistry,jsi::Object * jsObject,JavaScriptModuleObject * objectData)68cf4fff55SŁukasz Kosmaty void decorateObjectWithConstants(
69cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime,
70cf4fff55SŁukasz Kosmaty JSIInteropModuleRegistry *jsiInteropModuleRegistry,
71cf4fff55SŁukasz Kosmaty jsi::Object *jsObject,
72cf4fff55SŁukasz Kosmaty JavaScriptModuleObject *objectData) {
73cf4fff55SŁukasz Kosmaty for (const auto &[name, value]: objectData->constants) {
74cf4fff55SŁukasz Kosmaty jsObject->setProperty(
75cf4fff55SŁukasz Kosmaty runtime,
76cf4fff55SŁukasz Kosmaty jsi::String::createFromUtf8(runtime, name),
77cf4fff55SŁukasz Kosmaty jsi::valueFromDynamic(runtime, value)
78cf4fff55SŁukasz Kosmaty );
79cf4fff55SŁukasz Kosmaty }
80cf4fff55SŁukasz Kosmaty }
81cf4fff55SŁukasz Kosmaty
8264f5c95fSŁukasz Kosmaty jni::local_ref<jni::HybridClass<JavaScriptModuleObject>::jhybriddata>
initHybrid(jni::alias_ref<jhybridobject> jThis)8364f5c95fSŁukasz Kosmaty JavaScriptModuleObject::initHybrid(jni::alias_ref<jhybridobject> jThis) {
8464f5c95fSŁukasz Kosmaty return makeCxxInstance(jThis);
8564f5c95fSŁukasz Kosmaty }
8664f5c95fSŁukasz Kosmaty
registerNatives()8764f5c95fSŁukasz Kosmaty void JavaScriptModuleObject::registerNatives() {
8864f5c95fSŁukasz Kosmaty registerHybrid({
8964f5c95fSŁukasz Kosmaty makeNativeMethod("initHybrid", JavaScriptModuleObject::initHybrid),
90a764be12SŁukasz Kosmaty makeNativeMethod("exportConstants", JavaScriptModuleObject::exportConstants),
9164f5c95fSŁukasz Kosmaty makeNativeMethod("registerSyncFunction",
9264f5c95fSŁukasz Kosmaty JavaScriptModuleObject::registerSyncFunction),
9364f5c95fSŁukasz Kosmaty makeNativeMethod("registerAsyncFunction",
9464f5c95fSŁukasz Kosmaty JavaScriptModuleObject::registerAsyncFunction),
9547a022e6SŁukasz Kosmaty makeNativeMethod("registerProperty",
9647a022e6SŁukasz Kosmaty JavaScriptModuleObject::registerProperty),
97cf4fff55SŁukasz Kosmaty makeNativeMethod("registerClass",
983852c14fSŁukasz Kosmaty JavaScriptModuleObject::registerClass),
993852c14fSŁukasz Kosmaty makeNativeMethod("registerViewPrototype",
1003852c14fSŁukasz Kosmaty JavaScriptModuleObject::registerViewPrototype)
10164f5c95fSŁukasz Kosmaty });
10264f5c95fSŁukasz Kosmaty }
10364f5c95fSŁukasz Kosmaty
getJSIObject(jsi::Runtime & runtime)10464f5c95fSŁukasz Kosmaty std::shared_ptr<jsi::Object> JavaScriptModuleObject::getJSIObject(jsi::Runtime &runtime) {
105cb63a94cSŁukasz Kosmaty if (auto object = jsiObject.lock()) {
106cb63a94cSŁukasz Kosmaty return object;
10764f5c95fSŁukasz Kosmaty }
10864f5c95fSŁukasz Kosmaty
109b627df43SŁukasz Kosmaty auto moduleObject = std::make_shared<jsi::Object>(runtime);
110b627df43SŁukasz Kosmaty
111cf4fff55SŁukasz Kosmaty decorateObjectWithConstants(
112b627df43SŁukasz Kosmaty runtime,
113cf4fff55SŁukasz Kosmaty jsiInteropModuleRegistry,
114cf4fff55SŁukasz Kosmaty moduleObject.get(),
115cf4fff55SŁukasz Kosmaty this
116b627df43SŁukasz Kosmaty );
117cf4fff55SŁukasz Kosmaty decorateObjectWithProperties(
118cf4fff55SŁukasz Kosmaty runtime,
119cf4fff55SŁukasz Kosmaty jsiInteropModuleRegistry,
120cf4fff55SŁukasz Kosmaty moduleObject.get(),
121cf4fff55SŁukasz Kosmaty this
122cf4fff55SŁukasz Kosmaty );
123cf4fff55SŁukasz Kosmaty decorateObjectWithFunctions(
124cf4fff55SŁukasz Kosmaty runtime,
125cf4fff55SŁukasz Kosmaty jsiInteropModuleRegistry,
126cf4fff55SŁukasz Kosmaty moduleObject.get(),
127cf4fff55SŁukasz Kosmaty this
128cf4fff55SŁukasz Kosmaty );
129b627df43SŁukasz Kosmaty
1303852c14fSŁukasz Kosmaty if (viewPrototype) {
1313852c14fSŁukasz Kosmaty auto viewPrototypeObject = viewPrototype->cthis();
1323852c14fSŁukasz Kosmaty viewPrototypeObject->jsiInteropModuleRegistry = jsiInteropModuleRegistry;
1333852c14fSŁukasz Kosmaty auto viewPrototypeJSIObject = viewPrototypeObject->getJSIObject(runtime);
1343852c14fSŁukasz Kosmaty moduleObject->setProperty(
1353852c14fSŁukasz Kosmaty runtime,
1363852c14fSŁukasz Kosmaty "ViewPrototype",
1373852c14fSŁukasz Kosmaty jsi::Value(runtime, *viewPrototypeJSIObject)
1383852c14fSŁukasz Kosmaty );
1393852c14fSŁukasz Kosmaty }
1403852c14fSŁukasz Kosmaty
141ecb7f347SŁukasz Kosmaty for (auto &[name, classInfo]: classes) {
142ecb7f347SŁukasz Kosmaty auto &[classRef, constructor] = classInfo;
143ecb7f347SŁukasz Kosmaty auto classObject = classRef->cthis();
1443852c14fSŁukasz Kosmaty classObject->jsiInteropModuleRegistry = jsiInteropModuleRegistry;
145b627df43SŁukasz Kosmaty
146cf4fff55SŁukasz Kosmaty std::string nativeConstructorKey("__native_constructor__");
147b627df43SŁukasz Kosmaty
148cf4fff55SŁukasz Kosmaty // Create a string buffer of the source code to evaluate.
149cf4fff55SŁukasz Kosmaty std::stringstream source;
150cf4fff55SŁukasz Kosmaty source << "(function " << name << "(...args) { this." << nativeConstructorKey
151cf4fff55SŁukasz Kosmaty << "(...args); return this; })";
152cf4fff55SŁukasz Kosmaty std::shared_ptr<jsi::StringBuffer> sourceBuffer = std::make_shared<jsi::StringBuffer>(
153cf4fff55SŁukasz Kosmaty source.str());
154cf4fff55SŁukasz Kosmaty
155cf4fff55SŁukasz Kosmaty // Evaluate the code and obtain returned value (the constructor function).
156cf4fff55SŁukasz Kosmaty jsi::Object klass = runtime.evaluateJavaScript(sourceBuffer, "").asObject(runtime);
157cf4fff55SŁukasz Kosmaty
158cf4fff55SŁukasz Kosmaty // Set the native constructor in the prototype.
159cf4fff55SŁukasz Kosmaty jsi::Object prototype = klass.getPropertyAsObject(runtime, "prototype");
160cf4fff55SŁukasz Kosmaty jsi::PropNameID nativeConstructorPropId = jsi::PropNameID::forAscii(runtime,
161cf4fff55SŁukasz Kosmaty nativeConstructorKey);
162cf4fff55SŁukasz Kosmaty jsi::Function nativeConstructor = jsi::Function::createFromHostFunction(
163cf4fff55SŁukasz Kosmaty runtime,
164cf4fff55SŁukasz Kosmaty nativeConstructorPropId,
165cf4fff55SŁukasz Kosmaty // The paramCount is not obligatory to match, it only affects the `length` property of the function.
166cf4fff55SŁukasz Kosmaty 0,
167ecb7f347SŁukasz Kosmaty [classObject, &constructor = constructor, jsiInteropModuleRegistry = jsiInteropModuleRegistry](
168cf4fff55SŁukasz Kosmaty jsi::Runtime &runtime,
169cf4fff55SŁukasz Kosmaty const jsi::Value &thisValue,
170cf4fff55SŁukasz Kosmaty const jsi::Value *args,
171cf4fff55SŁukasz Kosmaty size_t count
172cf4fff55SŁukasz Kosmaty ) -> jsi::Value {
173ecb7f347SŁukasz Kosmaty auto thisObject = std::make_shared<jsi::Object>(thisValue.asObject(runtime));
174ecb7f347SŁukasz Kosmaty decorateObjectWithProperties(runtime, jsiInteropModuleRegistry, thisObject.get(),
175ecb7f347SŁukasz Kosmaty classObject);
176ecb7f347SŁukasz Kosmaty try {
177ecb7f347SŁukasz Kosmaty JNIEnv *env = jni::Environment::current();
178ecb7f347SŁukasz Kosmaty /**
179ecb7f347SŁukasz Kosmaty * This will push a new JNI stack frame for the LocalReferences in this
180ecb7f347SŁukasz Kosmaty * function call. When the stack frame for this lambda is popped,
181ecb7f347SŁukasz Kosmaty * all LocalReferences are deleted.
182ecb7f347SŁukasz Kosmaty */
183ecb7f347SŁukasz Kosmaty jni::JniLocalScope scope(env, (int) count);
184ecb7f347SŁukasz Kosmaty auto result = constructor.callJNISync(
185ecb7f347SŁukasz Kosmaty env,
186ecb7f347SŁukasz Kosmaty runtime,
187ecb7f347SŁukasz Kosmaty jsiInteropModuleRegistry,
188ecb7f347SŁukasz Kosmaty thisValue,
189ecb7f347SŁukasz Kosmaty args,
190ecb7f347SŁukasz Kosmaty count
191ecb7f347SŁukasz Kosmaty );
192ecb7f347SŁukasz Kosmaty if (result == nullptr) {
193ecb7f347SŁukasz Kosmaty return jsi::Value::undefined();
194ecb7f347SŁukasz Kosmaty }
195ecb7f347SŁukasz Kosmaty jobject unpackedResult = result.get();
196ecb7f347SŁukasz Kosmaty jclass resultClass = env->GetObjectClass(unpackedResult);
197ecb7f347SŁukasz Kosmaty if (env->IsAssignableFrom(
198ecb7f347SŁukasz Kosmaty resultClass,
199ecb7f347SŁukasz Kosmaty JavaReferencesCache::instance()->getJClass(
200ecb7f347SŁukasz Kosmaty "expo/modules/kotlin/sharedobjects/SharedObject").clazz
201ecb7f347SŁukasz Kosmaty )) {
20229e8b6f8SŁukasz Kosmaty auto jsThisObject = JavaScriptObject::newInstance(
20329e8b6f8SŁukasz Kosmaty jsiInteropModuleRegistry,
204ecb7f347SŁukasz Kosmaty jsiInteropModuleRegistry->runtimeHolder,
205ecb7f347SŁukasz Kosmaty thisObject
206ecb7f347SŁukasz Kosmaty );
207ecb7f347SŁukasz Kosmaty jsiInteropModuleRegistry->registerSharedObject(result, jsThisObject);
208ecb7f347SŁukasz Kosmaty }
209ecb7f347SŁukasz Kosmaty } catch (jni::JniException &jniException) {
210ecb7f347SŁukasz Kosmaty rethrowAsCodedError(runtime, jniException);
211ecb7f347SŁukasz Kosmaty }
212cf4fff55SŁukasz Kosmaty return jsi::Value::undefined();
213cf4fff55SŁukasz Kosmaty });
214cf4fff55SŁukasz Kosmaty
215cf4fff55SŁukasz Kosmaty auto descriptor = JavaScriptObject::preparePropertyDescriptor(runtime, 0);
216cf4fff55SŁukasz Kosmaty descriptor.setProperty(runtime, "value", jsi::Value(runtime, nativeConstructor));
217cf4fff55SŁukasz Kosmaty
218*b1cbccf5SŁukasz Kosmaty common::definePropertyOnJSIObject(runtime, &prototype, nativeConstructorKey.c_str(),
219*b1cbccf5SŁukasz Kosmaty std::move(descriptor));
220cf4fff55SŁukasz Kosmaty
221b627df43SŁukasz Kosmaty moduleObject->setProperty(
222b627df43SŁukasz Kosmaty runtime,
223b627df43SŁukasz Kosmaty jsi::String::createFromUtf8(runtime, name),
224cf4fff55SŁukasz Kosmaty jsi::Value(runtime, klass.asFunction(runtime))
225cf4fff55SŁukasz Kosmaty );
226cf4fff55SŁukasz Kosmaty
227cf4fff55SŁukasz Kosmaty decorateObjectWithFunctions(
228cf4fff55SŁukasz Kosmaty runtime,
229cf4fff55SŁukasz Kosmaty jsiInteropModuleRegistry,
230cf4fff55SŁukasz Kosmaty &prototype,
231cf4fff55SŁukasz Kosmaty classObject
232b627df43SŁukasz Kosmaty );
233b627df43SŁukasz Kosmaty }
234b627df43SŁukasz Kosmaty
235b627df43SŁukasz Kosmaty jsiObject = moduleObject;
236b627df43SŁukasz Kosmaty return moduleObject;
23764f5c95fSŁukasz Kosmaty }
23864f5c95fSŁukasz Kosmaty
exportConstants(jni::alias_ref<react::NativeMap::javaobject> constants)2399ebf31e6SŁukasz Kosmaty void JavaScriptModuleObject::exportConstants(
2409ebf31e6SŁukasz Kosmaty jni::alias_ref<react::NativeMap::javaobject> constants
2419ebf31e6SŁukasz Kosmaty ) {
242a764be12SŁukasz Kosmaty auto dynamic = constants->cthis()->consume();
243a764be12SŁukasz Kosmaty assert(dynamic.isObject());
244a764be12SŁukasz Kosmaty
245a764be12SŁukasz Kosmaty for (const auto &[key, value]: dynamic.items()) {
246a764be12SŁukasz Kosmaty this->constants[key.asString()] = value;
247a764be12SŁukasz Kosmaty }
248a764be12SŁukasz Kosmaty }
249a764be12SŁukasz Kosmaty
registerSyncFunction(jni::alias_ref<jstring> name,jboolean takesOwner,jint args,jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,jni::alias_ref<JNIFunctionBody::javaobject> body)25064f5c95fSŁukasz Kosmaty void JavaScriptModuleObject::registerSyncFunction(
25164f5c95fSŁukasz Kosmaty jni::alias_ref<jstring> name,
252cf4fff55SŁukasz Kosmaty jboolean takesOwner,
25364f5c95fSŁukasz Kosmaty jint args,
25465a981ddSŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
25564f5c95fSŁukasz Kosmaty jni::alias_ref<JNIFunctionBody::javaobject> body
25664f5c95fSŁukasz Kosmaty ) {
2579ebf31e6SŁukasz Kosmaty std::string cName = name->toStdString();
2586f5b8a20SŁukasz Kosmaty
2599ebf31e6SŁukasz Kosmaty methodsMetadata.try_emplace(
2609ebf31e6SŁukasz Kosmaty cName,
2619ebf31e6SŁukasz Kosmaty cName,
262cf4fff55SŁukasz Kosmaty takesOwner,
2639ebf31e6SŁukasz Kosmaty args,
2649ebf31e6SŁukasz Kosmaty false,
26565a981ddSŁukasz Kosmaty jni::make_local(expectedArgTypes),
2669ebf31e6SŁukasz Kosmaty jni::make_global(body)
2679ebf31e6SŁukasz Kosmaty );
26864f5c95fSŁukasz Kosmaty }
26964f5c95fSŁukasz Kosmaty
registerAsyncFunction(jni::alias_ref<jstring> name,jboolean takesOwner,jint args,jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,jni::alias_ref<JNIAsyncFunctionBody::javaobject> body)27064f5c95fSŁukasz Kosmaty void JavaScriptModuleObject::registerAsyncFunction(
27164f5c95fSŁukasz Kosmaty jni::alias_ref<jstring> name,
272cf4fff55SŁukasz Kosmaty jboolean takesOwner,
27364f5c95fSŁukasz Kosmaty jint args,
27465a981ddSŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
27564f5c95fSŁukasz Kosmaty jni::alias_ref<JNIAsyncFunctionBody::javaobject> body
27664f5c95fSŁukasz Kosmaty ) {
27765a981ddSŁukasz Kosmaty std::string cName = name->toStdString();
2789ebf31e6SŁukasz Kosmaty
2799ebf31e6SŁukasz Kosmaty methodsMetadata.try_emplace(
2809ebf31e6SŁukasz Kosmaty cName,
2819ebf31e6SŁukasz Kosmaty cName,
282cf4fff55SŁukasz Kosmaty takesOwner,
2839ebf31e6SŁukasz Kosmaty args,
2849ebf31e6SŁukasz Kosmaty true,
28565a981ddSŁukasz Kosmaty jni::make_local(expectedArgTypes),
2869ebf31e6SŁukasz Kosmaty jni::make_global(body)
2879ebf31e6SŁukasz Kosmaty );
28864f5c95fSŁukasz Kosmaty }
28964f5c95fSŁukasz Kosmaty
registerClass(jni::alias_ref<jstring> name,jni::alias_ref<JavaScriptModuleObject::javaobject> classObject,jboolean takesOwner,jint args,jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,jni::alias_ref<JNIFunctionBody::javaobject> body)290cf4fff55SŁukasz Kosmaty void JavaScriptModuleObject::registerClass(
291cf4fff55SŁukasz Kosmaty jni::alias_ref<jstring> name,
292ecb7f347SŁukasz Kosmaty jni::alias_ref<JavaScriptModuleObject::javaobject> classObject,
293ecb7f347SŁukasz Kosmaty jboolean takesOwner,
294ecb7f347SŁukasz Kosmaty jint args,
295ecb7f347SŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes,
296ecb7f347SŁukasz Kosmaty jni::alias_ref<JNIFunctionBody::javaobject> body
297cf4fff55SŁukasz Kosmaty ) {
298cf4fff55SŁukasz Kosmaty std::string cName = name->toStdString();
299ecb7f347SŁukasz Kosmaty MethodMetadata constructor(
300ecb7f347SŁukasz Kosmaty "constructor",
301ecb7f347SŁukasz Kosmaty takesOwner,
302ecb7f347SŁukasz Kosmaty args,
303ecb7f347SŁukasz Kosmaty false,
304ecb7f347SŁukasz Kosmaty jni::make_local(expectedArgTypes),
305ecb7f347SŁukasz Kosmaty jni::make_global(body)
306ecb7f347SŁukasz Kosmaty );
307ecb7f347SŁukasz Kosmaty
308ecb7f347SŁukasz Kosmaty auto pair = std::make_pair(jni::make_global(classObject), std::move(constructor));
309ecb7f347SŁukasz Kosmaty
310ecb7f347SŁukasz Kosmaty classes.try_emplace(
311ecb7f347SŁukasz Kosmaty cName,
312ecb7f347SŁukasz Kosmaty std::move(pair)
313ecb7f347SŁukasz Kosmaty );
314cf4fff55SŁukasz Kosmaty }
315cf4fff55SŁukasz Kosmaty
registerViewPrototype(jni::alias_ref<JavaScriptModuleObject::javaobject> viewPrototype)3163852c14fSŁukasz Kosmaty void JavaScriptModuleObject::registerViewPrototype(
3173852c14fSŁukasz Kosmaty jni::alias_ref<JavaScriptModuleObject::javaobject> viewPrototype
3183852c14fSŁukasz Kosmaty ) {
3193852c14fSŁukasz Kosmaty this->viewPrototype = jni::make_global(viewPrototype);
3203852c14fSŁukasz Kosmaty }
3213852c14fSŁukasz Kosmaty
registerProperty(jni::alias_ref<jstring> name,jboolean getterTakesOwner,jni::alias_ref<jni::JArrayClass<ExpectedType>> getterExpectedArgsTypes,jni::alias_ref<JNIFunctionBody::javaobject> getter,jboolean setterTakesOwner,jni::alias_ref<jni::JArrayClass<ExpectedType>> setterExpectedArgsTypes,jni::alias_ref<JNIFunctionBody::javaobject> setter)32247a022e6SŁukasz Kosmaty void JavaScriptModuleObject::registerProperty(
32347a022e6SŁukasz Kosmaty jni::alias_ref<jstring> name,
324*b1cbccf5SŁukasz Kosmaty jboolean getterTakesOwner,
325*b1cbccf5SŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> getterExpectedArgsTypes,
32647a022e6SŁukasz Kosmaty jni::alias_ref<JNIFunctionBody::javaobject> getter,
327*b1cbccf5SŁukasz Kosmaty jboolean setterTakesOwner,
328*b1cbccf5SŁukasz Kosmaty jni::alias_ref<jni::JArrayClass<ExpectedType>> setterExpectedArgsTypes,
32947a022e6SŁukasz Kosmaty jni::alias_ref<JNIFunctionBody::javaobject> setter
33047a022e6SŁukasz Kosmaty ) {
33147a022e6SŁukasz Kosmaty auto cName = name->toStdString();
33247a022e6SŁukasz Kosmaty
33347a022e6SŁukasz Kosmaty auto getterMetadata = MethodMetadata(
33447a022e6SŁukasz Kosmaty cName,
335*b1cbccf5SŁukasz Kosmaty getterTakesOwner,
336*b1cbccf5SŁukasz Kosmaty getterExpectedArgsTypes->size(),
337cf4fff55SŁukasz Kosmaty false,
338*b1cbccf5SŁukasz Kosmaty jni::make_local(getterExpectedArgsTypes),
33947a022e6SŁukasz Kosmaty jni::make_global(getter)
34047a022e6SŁukasz Kosmaty );
34147a022e6SŁukasz Kosmaty
34247a022e6SŁukasz Kosmaty auto setterMetadata = MethodMetadata(
34347a022e6SŁukasz Kosmaty cName,
344*b1cbccf5SŁukasz Kosmaty setterTakesOwner,
345*b1cbccf5SŁukasz Kosmaty setterExpectedArgsTypes->size(),
346cf4fff55SŁukasz Kosmaty false,
347*b1cbccf5SŁukasz Kosmaty jni::make_local(setterExpectedArgsTypes),
34847a022e6SŁukasz Kosmaty jni::make_global(setter)
34947a022e6SŁukasz Kosmaty );
35047a022e6SŁukasz Kosmaty
35147a022e6SŁukasz Kosmaty auto functions = std::make_pair(
35247a022e6SŁukasz Kosmaty std::move(getterMetadata),
35347a022e6SŁukasz Kosmaty std::move(setterMetadata)
35447a022e6SŁukasz Kosmaty );
35547a022e6SŁukasz Kosmaty
35647a022e6SŁukasz Kosmaty properties.insert({cName, std::move(functions)});
35747a022e6SŁukasz Kosmaty }
35847a022e6SŁukasz Kosmaty
JavaScriptModuleObject(jni::alias_ref<jhybridobject> jThis)359aaf1c10dSKudo Chien JavaScriptModuleObject::JavaScriptModuleObject(jni::alias_ref<jhybridobject> jThis)
360aaf1c10dSKudo Chien : javaPart_(jni::make_global(jThis)) {
361aaf1c10dSKudo Chien }
36264f5c95fSŁukasz Kosmaty } // namespace expo
363