forked from tmikov/hermes-jsi-demos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhf-runner.cpp
146 lines (127 loc) · 3.9 KB
/
hf-runner.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* This is free and unencumbered software released into the public domain.
* For more information, please refer to the LICENSE file in the root directory
* or at <http://unlicense.org/>
*/
#include <fstream>
#include <iostream>
#include <optional>
#include <sstream>
#ifndef _WIN32
#include <dlfcn.h>
#else
#include <windows.h>
#endif
#include <hermes/hermes.h>
/// Read the contents of a file into a string.
static std::optional<std::string> readFile(const char *path) {
std::ifstream fileStream(path);
std::stringstream stringStream;
if (fileStream) {
stringStream << fileStream.rdbuf();
fileStream.close();
} else {
// Handle error - file opening failed
std::cerr << path << ": error opening file" << std::endl;
return std::nullopt;
}
return stringStream.str();
}
/// The signature of the function that initializes the library.
typedef void (*RegisterNativesFN)(facebook::jsi::Runtime &rt);
#ifndef _WIN32
/// Load the library and return the "registerNatives()" function.
static RegisterNativesFN loadRegisterNatives(const char *libraryPath) {
// Open the library.
void *handle = dlopen(libraryPath, RTLD_LAZY);
if (!handle) {
std::cerr << "*** Cannot open library: " << dlerror() << '\n';
return nullptr;
}
// Clear any existing error.
dlerror();
// Load the symbol (function).
auto func = (RegisterNativesFN)dlsym(handle, "registerNatives");
if (const char *dlsym_error = dlerror()) {
std::cerr << "Cannot load symbol 'registerNatives': " << dlsym_error
<< '\n';
dlclose(handle);
return nullptr;
}
return func;
}
#else
/// Load the library and return the "registerNatives()" function.
static RegisterNativesFN loadRegisterNatives(const char *libraryPath) {
// Load the library
HMODULE hModule = LoadLibraryA(libraryPath);
if (!hModule) {
std::cerr << "Cannot open library: " << GetLastError() << '\n';
return nullptr;
}
// Get the function address
auto func = (RegisterNativesFN)GetProcAddress(hModule, "registerNatives");
if (!func) {
std::cerr << "Cannot load symbol 'registerNatives': " << GetLastError()
<< '\n';
FreeLibrary(hModule);
return nullptr;
}
return func;
}
#endif
/// Load all the libraries and call their "registerNatives()" function.
/// \return true if all libraries were loaded successfully.
static bool
loadNativeLibraries(facebook::jsi::Runtime &rt, int argc, char **argv) {
try {
for (int i = 2; i < argc; i++) {
auto func = loadRegisterNatives(argv[i]);
if (!func)
return false;
func(rt);
}
} catch (facebook::jsi::JSIException &e) {
// Handle JSI exceptions here.
std::cerr << "JSI Exception: " << e.what() << std::endl;
return false;
}
return true;
}
int main(int argc, char **argv) {
// If no argument is provided, print usage and exit.
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " <path-to-js-file> [<shared-lib>...]"
<< std::endl;
return 1;
}
const char *jsPath = argv[1];
// Read the file.
auto optCode = readFile(jsPath);
if (!optCode)
return 1;
// You can Customize the runtime config here.
auto runtimeConfig =
hermes::vm::RuntimeConfig::Builder().withIntl(false).build();
// Create the Hermes runtime.
auto runtime = facebook::hermes::makeHermesRuntime(runtimeConfig);
// Register host functions.
if (!loadNativeLibraries(*runtime, argc, argv))
return 1;
// Execute some JS.
int status = 0;
try {
runtime->evaluateJavaScript(
std::make_unique<facebook::jsi::StringBuffer>(std::move(*optCode)),
jsPath);
} catch (facebook::jsi::JSError &e) {
// Handle JS exceptions here.
std::cerr << "JS Exception: " << e.getStack() << std::endl;
status = 1;
} catch (facebook::jsi::JSIException &e) {
// Handle JSI exceptions here.
std::cerr << "JSI Exception: " << e.what() << std::endl;
status = 1;
}
return status;
}