Skip to content

Commit 64eb709

Browse files
committed
fix: generic loading of host functions in C++ (#315)
## Description Add generic loading of host functions in C++. ### Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Documentation update (improves or adds clarity to existing documentation) ### Tested on - [x] iOS - [x] Android
1 parent 4d8e2c9 commit 64eb709

File tree

5 files changed

+64
-52
lines changed

5 files changed

+64
-52
lines changed
Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#include "RnExecutorchInstaller.h"
22

33
#include <rnexecutorch/host_objects/JsiConversions.h>
4-
#include <rnexecutorch/host_objects/ModelHostObject.h>
5-
#include <rnexecutorch/models/StyleTransfer.h>
4+
#include <rnexecutorch/models/style_transfer/StyleTransfer.h>
65

76
namespace rnexecutorch {
87

@@ -11,50 +10,14 @@ namespace rnexecutorch {
1110
// SSL intricacies manually, as it is done automagically in ObjC++/Kotlin.
1211
FetchUrlFunc_t fetchUrlFunc;
1312

14-
jsi::Function RnExecutorchInstaller::loadStyleTransfer(
15-
jsi::Runtime *jsiRuntime,
16-
const std::shared_ptr<react::CallInvoker> &jsCallInvoker) {
17-
return jsi::Function::createFromHostFunction(
18-
*jsiRuntime, jsi::PropNameID::forAscii(*jsiRuntime, "loadStyleTransfer"),
19-
0,
20-
[jsCallInvoker](jsi::Runtime &runtime, const jsi::Value &thisValue,
21-
const jsi::Value *args, size_t count) -> jsi::Value {
22-
assert(count == 1);
23-
try {
24-
auto source = jsiconversion::getValue<std::string>(args[0], runtime);
25-
26-
auto styleTransferPtr =
27-
std::make_shared<StyleTransfer>(source, &runtime);
28-
auto styleTransferHostObject =
29-
std::make_shared<ModelHostObject<StyleTransfer>>(styleTransferPtr,
30-
jsCallInvoker);
31-
32-
return jsi::Object::createFromHostObject(runtime,
33-
styleTransferHostObject);
34-
} catch (const std::runtime_error &e) {
35-
// This catch should be merged with the next one
36-
// (std::runtime_error inherits from std::exception) HOWEVER react
37-
// native has broken RTTI which breaks proper exception type
38-
// checking. Remove when the following change is present in our
39-
// version:
40-
// https://github.com/facebook/react-native/commit/3132cc88dd46f95898a756456bebeeb6c248f20e
41-
throw jsi::JSError(runtime, e.what());
42-
} catch (const std::exception &e) {
43-
throw jsi::JSError(runtime, e.what());
44-
} catch (...) {
45-
throw jsi::JSError(runtime, "Unknown error");
46-
}
47-
});
48-
}
49-
5013
void RnExecutorchInstaller::injectJSIBindings(
51-
jsi::Runtime *jsiRuntime,
52-
const std::shared_ptr<react::CallInvoker> &jsCallInvoker,
14+
jsi::Runtime *jsiRuntime, std::shared_ptr<react::CallInvoker> jsCallInvoker,
5315
FetchUrlFunc_t fetchDataFromUrl) {
5416
fetchUrlFunc = fetchDataFromUrl;
5517

5618
jsiRuntime->global().setProperty(
5719
*jsiRuntime, "loadStyleTransfer",
58-
loadStyleTransfer(jsiRuntime, jsCallInvoker));
20+
RnExecutorchInstaller::loadModel<StyleTransfer>(jsiRuntime, jsCallInvoker,
21+
"loadStyleTransfer"));
5922
}
6023
} // namespace rnexecutorch

common/rnexecutorch/RnExecutorchInstaller.h

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,71 @@
77
#include <ReactCommon/CallInvoker.h>
88
#include <jsi/jsi.h>
99

10+
#include <rnexecutorch/host_objects/JsiConversions.h>
11+
#include <rnexecutorch/host_objects/ModelHostObject.h>
12+
1013
namespace rnexecutorch {
1114

1215
using FetchUrlFunc_t = std::function<std::vector<std::byte>(std::string)>;
16+
extern FetchUrlFunc_t fetchUrlFunc;
1317

1418
using namespace facebook;
1519

1620
class RnExecutorchInstaller {
1721
public:
1822
static void
1923
injectJSIBindings(jsi::Runtime *jsiRuntime,
20-
const std::shared_ptr<react::CallInvoker> &jsCallInvoker,
24+
std::shared_ptr<react::CallInvoker> jsCallInvoker,
2125
FetchUrlFunc_t fetchDataFromUrl);
2226

2327
private:
28+
template <typename ModelT>
2429
static jsi::Function
25-
loadStyleTransfer(jsi::Runtime *jsiRuntime,
26-
const std::shared_ptr<react::CallInvoker> &jsCallInvoker);
30+
loadModel(jsi::Runtime *jsiRuntime,
31+
std::shared_ptr<react::CallInvoker> jsCallInvoker,
32+
const std::string &loadFunctionName) {
33+
34+
return jsi::Function::createFromHostFunction(
35+
*jsiRuntime, jsi::PropNameID::forAscii(*jsiRuntime, loadFunctionName),
36+
0,
37+
[jsCallInvoker](jsi::Runtime &runtime, const jsi::Value &thisValue,
38+
const jsi::Value *args, size_t count) -> jsi::Value {
39+
if (count != 1) {
40+
char errorMessage[100];
41+
std::snprintf(
42+
errorMessage, sizeof(errorMessage),
43+
"Argument count mismatch, was expecting: 1 but got: %zu",
44+
count);
45+
throw jsi::JSError(runtime, errorMessage);
46+
}
47+
try {
48+
auto source =
49+
jsiconversion::getValue<std::string>(args[0], runtime);
50+
51+
auto modelImplementationPtr =
52+
std::make_shared<ModelT>(source, &runtime);
53+
auto modelHostObject = std::make_shared<ModelHostObject<ModelT>>(
54+
modelImplementationPtr, jsCallInvoker);
55+
56+
return jsi::Object::createFromHostObject(runtime, modelHostObject);
57+
} catch (const std::runtime_error &e) {
58+
// This catch should be merged with the next one
59+
// (std::runtime_error inherits from std::exception) HOWEVER react
60+
// native has broken RTTI which breaks proper exception type
61+
// checking. Remove when the following change is present in our
62+
// version:
63+
// https://github.com/facebook/react-native/commit/3132cc88dd46f95898a756456bebeeb6c248f20e
64+
throw jsi::JSError(runtime, e.what());
65+
return jsi::Value();
66+
} catch (const std::exception &e) {
67+
throw jsi::JSError(runtime, e.what());
68+
return jsi::Value();
69+
} catch (...) {
70+
throw jsi::JSError(runtime, "Unknown error");
71+
return jsi::Value();
72+
}
73+
});
74+
}
2775
};
2876

2977
} // namespace rnexecutorch

common/rnexecutorch/host_objects/JsiConversions.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,23 @@ using namespace facebook;
1212
template <typename T> T getValue(const jsi::Value &val, jsi::Runtime &runtime);
1313

1414
template <>
15-
double getValue<double>(const jsi::Value &val, jsi::Runtime &runtime) {
15+
inline double getValue<double>(const jsi::Value &val, jsi::Runtime &runtime) {
1616
return val.asNumber();
1717
}
1818

19-
template <> bool getValue<bool>(const jsi::Value &val, jsi::Runtime &runtime) {
19+
template <>
20+
inline bool getValue<bool>(const jsi::Value &val, jsi::Runtime &runtime) {
2021
return val.asBool();
2122
}
2223

2324
template <>
24-
std::string getValue<std::string>(const jsi::Value &val,
25-
jsi::Runtime &runtime) {
25+
inline std::string getValue<std::string>(const jsi::Value &val,
26+
jsi::Runtime &runtime) {
2627
return val.getString(runtime).utf8(runtime);
2728
}
2829

2930
template <>
30-
std::vector<std::string>
31+
inline std::vector<std::string>
3132
getValue<std::vector<std::string>>(const jsi::Value &val,
3233
jsi::Runtime &runtime) {
3334
jsi::Array array = val.asObject(runtime).asArray(runtime);
@@ -49,15 +50,15 @@ getValue<std::vector<std::string>>(const jsi::Value &val,
4950
// we add a function here.
5051

5152
// Identity function for the sake of completeness
52-
jsi::Value getJsiValue(jsi::Value &&value, jsi::Runtime &runtime) {
53+
inline jsi::Value getJsiValue(jsi::Value &&value, jsi::Runtime &runtime) {
5354
return std::move(value);
5455
}
5556

56-
jsi::Value getJsiValue(jsi::Object &&value, jsi::Runtime &runtime) {
57+
inline jsi::Value getJsiValue(jsi::Object &&value, jsi::Runtime &runtime) {
5758
return jsi::Value(std::move(value));
5859
}
5960

60-
jsi::Value getJsiValue(const std::string &str, jsi::Runtime &runtime) {
61+
inline jsi::Value getJsiValue(const std::string &str, jsi::Runtime &runtime) {
6162
return jsi::String::createFromAscii(runtime, str);
6263
}
6364

File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)