Skip to content

Commit 8112931

Browse files
committed
Update host to create napi_env via jsi
1 parent c8f339d commit 8112931

File tree

2 files changed

+41
-36
lines changed

2 files changed

+41
-36
lines changed

packages/react-native-node-api-modules/cpp/CxxNodeApiHostModule.cpp

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22

33
using namespace facebook;
44

5-
extern napi_status
6-
hermes_create_napi_env(::hermes::vm::Runtime &runtime, bool isInspectable,
7-
std::shared_ptr<jsi::PreparedScriptStore> scriptCache,
8-
const ::hermes::vm::RuntimeConfig &runtimeConfig,
9-
napi_env *env);
10-
115
namespace callstack::nodeapihost {
126

137
CxxNodeApiHostModule::CxxNodeApiHostModule(
@@ -43,10 +37,10 @@ jsi::Value CxxNodeApiHostModule::requireNodeAddon(jsi::Runtime &rt,
4337
// Library has been loaded, make sure that the "exports" was populated.
4438
// If not, then just call the "napi_register_module_v1" function...
4539
NodeAddon &addon = nodeAddons_[pathStr];
46-
if (NULL == addon.cachedExports) {
47-
if (!initializeNodeModule(napiEnv_, addon)) {
48-
return jsi::Value::undefined();
49-
}
40+
41+
// Initialize the addon if it has not already been initialized
42+
if (!rt.global().hasProperty(rt, addon.generatedName.data())) {
43+
initializeNodeModule(rt, addon);
5044
}
5145

5246
// Look the exports up (using JSI) and return it...
@@ -55,46 +49,59 @@ jsi::Value CxxNodeApiHostModule::requireNodeAddon(jsi::Runtime &rt,
5549

5650
bool CxxNodeApiHostModule::loadNodeAddon(NodeAddon &addon,
5751
const std::string &path) const {
58-
typename LoaderPolicy::Symbol registratorFn = NULL;
52+
typename LoaderPolicy::Symbol initFn = NULL;
5953
typename LoaderPolicy::Module library =
6054
LoaderPolicy::loadLibrary(path.c_str());
6155
if (NULL != library) {
6256
addon.moduleHandle = library;
63-
registratorFn = LoaderPolicy::getSymbol(library, "napi_register_module_v1");
64-
if (NULL != registratorFn) {
65-
addon.registerFn = (napi_addon_register_func)registratorFn;
57+
58+
// Generate a name allowing us to reference the exports object from JSI
59+
// later Instead of using random numbers to avoid name clashes, we just use
60+
// the pointer address of the loaded module
61+
addon.generatedName.resize(32, '\0');
62+
snprintf(addon.generatedName.data(), addon.generatedName.size(),
63+
"RN$NodeAddon_%lX", (uintptr_t)addon.moduleHandle);
64+
65+
initFn = LoaderPolicy::getSymbol(library, "napi_register_module_v1");
66+
if (NULL != initFn) {
67+
addon.init = (napi_addon_register_func)initFn;
6668
}
69+
// TODO: Read "node_api_module_get_api_version_v1" to support the addon
70+
// declaring its Node-API version
71+
// @see
72+
// https://github.com/callstackincubator/react-native-node-api-modules/issues/4
6773
}
68-
return NULL != registratorFn;
74+
return NULL != initFn;
6975
}
7076

7177
bool CxxNodeApiHostModule::initializeNodeModule(jsi::Runtime &rt,
7278
NodeAddon &addon) {
73-
// We should check if the module has already been registered
79+
// We should check if the module has already been initialized
7480
assert(NULL != addon.moduleHandle);
75-
assert(NULL != addon.registerFn);
81+
assert(NULL != addon.init);
7682
napi_status status = napi_ok;
77-
napi_value &exports = addon.cachedExports;
83+
// TODO: Read the version from the addon
84+
// @see
85+
// https://github.com/callstackincubator/react-native-node-api-modules/issues/4
86+
napi_env env = reinterpret_cast<napi_env>(rt.createNodeApiEnv(8));
7887

7988
// Create the "exports" object
80-
status = napi_create_object(napiEnv_, &exports);
81-
if (napi_ok != status) {
82-
return false;
83-
}
84-
85-
// Call the addon registration function to populate the "exports" object
86-
addon.registerFn(napiEnv_, exports);
89+
napi_value exports;
90+
status = napi_create_object(env, &exports);
91+
assert(status == napi_ok);
8792

88-
// Instead of using random numbers to avoid name clashes, we just use the
89-
// pointer address of the loaded module
90-
addon.generatedName.resize(32, '\0');
91-
snprintf(addon.generatedName.data(), addon.generatedName.size(),
92-
"RN$NodeAddon_%lX", (uintptr_t)addon.moduleHandle);
93+
// Call the addon init function to populate the "exports" object
94+
// Allowing it to replace the value entirely by its return value
95+
exports = addon.init(env, exports);
9396

9497
napi_value global;
95-
napi_get_global(napiEnv_, &global);
96-
napi_set_named_property(napiEnv_, global, addon.generatedName.data(),
97-
addon.cachedExports);
98+
napi_get_global(env, &global);
99+
assert(status == napi_ok);
100+
101+
status =
102+
napi_set_named_property(env, global, addon.generatedName.data(), exports);
103+
assert(status == napi_ok);
104+
98105
return true;
99106
}
100107

packages/react-native-node-api-modules/cpp/CxxNodeApiHostModule.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,10 @@ class JSI_EXPORT CxxNodeApiHostModule : public facebook::react::TurboModule {
2424
protected:
2525
struct NodeAddon {
2626
void *moduleHandle;
27-
napi_addon_register_func registerFn;
28-
napi_value cachedExports;
27+
napi_addon_register_func init;
2928
std::string generatedName;
3029
};
3130
std::unordered_map<std::string, NodeAddon> nodeAddons_;
32-
napi_env napiEnv_{};
3331
using LoaderPolicy = PosixLoader; // FIXME: HACK: This is temporary workaround
3432
// for my lazyness (work on iOS and Android)
3533

0 commit comments

Comments
 (0)