#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsi = facebook::jsi; int main(int argc, char **argv) { // JSError owns runtime values; keep the runtime alive through its catch handler. std::unique_ptr runtime; int status = 0; try { int firstScript = 1; const bool blockScoping = argc > 1 && std::string(argv[1]) == "--es6-block-scoping"; if (blockScoping) ++firstScript; runtime = facebook::hermes::makeHermesRuntime( ::hermes::vm::RuntimeConfig::Builder().withES6BlockScoping(blockScoping).build()); auto &rt = *runtime; auto print = jsi::Function::createFromHostFunction( rt, jsi::PropNameID::forAscii(rt, "print"), 0, [](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *args, size_t count) -> jsi::Value { for (size_t i = 0; i < count; ++i) { if (i) std::cout << ' '; std::cout << args[i].toString(rt).utf8(rt); } std::cout << '\n'; return jsi::Value::undefined(); }); rt.global().setProperty(rt, "print", std::move(print)); auto now = jsi::Function::createFromHostFunction( rt, jsi::PropNameID::forAscii(rt, "now"), 0, [](jsi::Runtime &, const jsi::Value &, const jsi::Value *, size_t) -> jsi::Value { return std::chrono::duration( std::chrono::steady_clock::now().time_since_epoch()) .count(); }); jsi::Object performance(rt); performance.setProperty(rt, "now", std::move(now)); rt.global().setProperty(rt, "performance", std::move(performance)); if (argc < 2) { std::cerr << "Usage: hermes_runner script.js [script.js ...]\n"; return 2; } auto evaluateFile = [&](const std::string &path) { std::ifstream file(path, std::ios::binary); if (!file) throw std::runtime_error("Cannot open " + path); std::string source((std::istreambuf_iterator(file)), std::istreambuf_iterator()); return rt.evaluateJavaScript(std::make_shared(std::move(source)), path); }; std::unique_ptr datetimeInstallation; formatjs::installCanonicalLocales(rt); while (firstScript < argc && std::string(argv[firstScript]).rfind("--prelude=", 0) == 0) { evaluateFile(std::string(argv[firstScript]).substr(10)); ++firstScript; } if (firstScript != 1) formatjs::installCanonicalLocales(rt); formatjs::installSupportedValuesOf(rt); formatjs::installLocale(rt); formatjs::installCanonicalLocales(rt); while (firstScript < argc) { const std::string flag(argv[firstScript]); if (flag == "--native-durationformat") { formatjs::installDurationFormat(rt); ++firstScript; continue; } if (flag == "--native-datetimeformat") { datetimeInstallation = formatjs::installDateTimeFormat(rt); ++firstScript; continue; } if (flag == "--native-relativetimeformat") { formatjs::installRelativeTimeFormat(rt); ++firstScript; continue; } if (flag == "--native-numberformat") { formatjs::installNumberFormat(rt); ++firstScript; continue; } if (flag == "--native-collator") { formatjs::installCollator(rt); ++firstScript; continue; } if (flag == "--native-segmenter") { formatjs::installSegmenter(rt); ++firstScript; continue; } if (flag == "--native-displaynames") { formatjs::installDisplayNames(rt); ++firstScript; continue; } if (std::string(argv[firstScript]) == "--native-listformat") { formatjs::installListFormat(rt); ++firstScript; continue; } if (std::string(argv[firstScript]) == "--native-pluralrules") { formatjs::installPluralRules(rt); ++firstScript; continue; } if (flag.rfind("--extensions=", 0) != 0) break; auto extensions = evaluateFile(flag.substr(13)).asObject(rt); if (extensions.hasProperty(rt, "IntlSupportedValuesOf")) formatjs::installSupportedValuesOf(rt, extensions); if (extensions.hasProperty(rt, "IntlLocale")) formatjs::installLocale(rt, extensions); if (extensions.hasProperty(rt, "IntlGetCanonicalLocales")) formatjs::installCanonicalLocales(rt, extensions); if (extensions.hasProperty(rt, "IntlPluralRules")) formatjs::installPluralRules(rt, extensions); if (extensions.hasProperty(rt, "IntlListFormat")) formatjs::installListFormat(rt, extensions); if (extensions.hasProperty(rt, "IntlDisplayNames")) formatjs::installDisplayNames(rt, extensions); if (extensions.hasProperty(rt, "IntlSegmenter")) formatjs::installSegmenter(rt, extensions); if (extensions.hasProperty(rt, "IntlCollator")) formatjs::installCollator(rt, extensions); if (extensions.hasProperty(rt, "IntlNumberFormat")) formatjs::installNumberFormat(rt, extensions); if (extensions.hasProperty(rt, "IntlRelativeTimeFormat")) formatjs::installRelativeTimeFormat(rt, extensions); if (extensions.hasProperty(rt, "IntlDateTimeFormat")) datetimeInstallation = formatjs::installDateTimeFormat(rt, extensions); if (extensions.hasProperty(rt, "IntlDurationFormat")) formatjs::installDurationFormat(rt, extensions); ++firstScript; } for (int i = firstScript; i < argc; ++i) { evaluateFile(argv[i]); } return 0; } catch (const std::exception &error) { std::cerr << error.what() << '\n'; status = 1; } return status; }