@crossbind/core-app-host 0.0.0-bootstrap.0 → 2.0.0-beta.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +55 -3
  2. package/android/app/src/main/AndroidManifest.xml +15 -0
  3. package/android/app/src/main/java/dev/crossbind/app/CrossbindActivity.java +366 -0
  4. package/android/app/src/main/res/xml/network_security_config.xml +8 -0
  5. package/android/build.gradle +14 -0
  6. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  7. package/android/gradle/wrapper/gradle-wrapper.properties +10 -0
  8. package/android/gradle.properties +2 -0
  9. package/android/gradlew +248 -0
  10. package/android/gradlew.bat +112 -0
  11. package/android/settings.gradle +14 -0
  12. package/cpp/CMakeLists.txt +110 -0
  13. package/cpp/src/android/jni.cpp +167 -0
  14. package/cpp/src/app.cpp +40 -0
  15. package/cpp/src/app.h +21 -0
  16. package/cpp/src/attach.cpp +40 -0
  17. package/cpp/src/darwin/bundle.mm +19 -0
  18. package/cpp/src/darwin/channels.mm +196 -0
  19. package/cpp/src/darwin/navigation.mm +69 -0
  20. package/cpp/src/host_core.cpp +335 -0
  21. package/cpp/src/host_core.h +84 -0
  22. package/cpp/src/ios/bundle.mm +15 -0
  23. package/cpp/src/ios/main.mm +71 -0
  24. package/cpp/src/linux/app.cpp +29 -0
  25. package/cpp/src/linux/channels.cpp +143 -0
  26. package/cpp/src/linux/main_thread.h +16 -0
  27. package/cpp/src/linux/navigation.cpp +55 -0
  28. package/cpp/src/main.cpp +57 -0
  29. package/cpp/src/platform.h +57 -0
  30. package/cpp/src/windows/app.cpp +36 -0
  31. package/cpp/src/windows/app.manifest +8 -0
  32. package/cpp/src/windows/app.rc +3 -0
  33. package/cpp/src/windows/channels.cpp +336 -0
  34. package/cpp/src/windows/com.cpp +92 -0
  35. package/cpp/src/windows/com.h +57 -0
  36. package/cpp/src/windows/navigation.cpp +90 -0
  37. package/js/codec.js +123 -0
  38. package/js/host.js +8 -0
  39. package/js/lean-client.js +147 -0
  40. package/js/lean-host.js +237 -0
  41. package/js/page.js +79 -0
  42. package/js/polyfills.js +32 -0
  43. package/package.json +30 -6
  44. package/third_party/jsi/LICENSE +21 -0
  45. package/third_party/jsi/README.md +18 -0
  46. package/third_party/jsi/include/jsi/hermes-interfaces.h +189 -0
  47. package/third_party/jsi/include/jsi/instrumentation.h +132 -0
  48. package/third_party/jsi/include/jsi/jsi-inl.h +434 -0
  49. package/third_party/jsi/include/jsi/jsi.h +2266 -0
  50. package/third_party/jsi/jsi.cpp +1110 -0
  51. package/third_party/webview/LICENSE +22 -0
  52. package/third_party/webview/README.md +24 -0
  53. package/third_party/webview/core/include/webview/api.h +251 -0
  54. package/third_party/webview/core/include/webview/backends.hh +40 -0
  55. package/third_party/webview/core/include/webview/c_api_impl.hh +258 -0
  56. package/third_party/webview/core/include/webview/detail/backends/cocoa_webkit.hh +633 -0
  57. package/third_party/webview/core/include/webview/detail/backends/gtk_webkitgtk.hh +355 -0
  58. package/third_party/webview/core/include/webview/detail/backends/win32_edge.hh +915 -0
  59. package/third_party/webview/core/include/webview/detail/basic_result.hh +119 -0
  60. package/third_party/webview/core/include/webview/detail/engine_base.hh +382 -0
  61. package/third_party/webview/core/include/webview/detail/exceptions.hh +42 -0
  62. package/third_party/webview/core/include/webview/detail/json.hh +337 -0
  63. package/third_party/webview/core/include/webview/detail/native_library.hh +176 -0
  64. package/third_party/webview/core/include/webview/detail/optional.hh +118 -0
  65. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSApplication.hh +107 -0
  66. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSBundle.hh +56 -0
  67. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSEvent.hh +71 -0
  68. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSInvocation.hh +66 -0
  69. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSMethodSignature.hh +52 -0
  70. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSNotification.hh +51 -0
  71. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSNumber.hh +53 -0
  72. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSObject.hh +51 -0
  73. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSOpenPanel.hh +71 -0
  74. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSPoint.hh +53 -0
  75. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSRect.hh +53 -0
  76. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSSavePanel.hh +52 -0
  77. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSSize.hh +53 -0
  78. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSString.hh +87 -0
  79. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSURL.hh +63 -0
  80. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSURLRequest.hh +52 -0
  81. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSValue.hh +56 -0
  82. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSView.hh +91 -0
  83. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSWindow.hh +137 -0
  84. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/cocoa.hh +59 -0
  85. package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/types.hh +49 -0
  86. package/third_party/webview/core/include/webview/detail/platform/darwin/objc/Class.hh +55 -0
  87. package/third_party/webview/core/include/webview/detail/platform/darwin/objc/autoreleasepool.hh +70 -0
  88. package/third_party/webview/core/include/webview/detail/platform/darwin/objc/invoke.hh +75 -0
  89. package/third_party/webview/core/include/webview/detail/platform/darwin/objc/memory.hh +57 -0
  90. package/third_party/webview/core/include/webview/detail/platform/darwin/objc/objc.hh +47 -0
  91. package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKOpenPanelParameters.hh +57 -0
  92. package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKScriptMessage.hh +51 -0
  93. package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKUserContentController.hh +61 -0
  94. package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKUserScript.hh +71 -0
  95. package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKWebView.hh +108 -0
  96. package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKWebViewConfiguration.hh +60 -0
  97. package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/webkit.hh +46 -0
  98. package/third_party/webview/core/include/webview/detail/platform/linux/gtk/compat.hh +137 -0
  99. package/third_party/webview/core/include/webview/detail/platform/linux/webkitgtk/compat.hh +142 -0
  100. package/third_party/webview/core/include/webview/detail/platform/linux/webkitgtk/dmabuf.hh +167 -0
  101. package/third_party/webview/core/include/webview/detail/platform/windows/com_init_wrapper.hh +126 -0
  102. package/third_party/webview/core/include/webview/detail/platform/windows/dpi.hh +161 -0
  103. package/third_party/webview/core/include/webview/detail/platform/windows/dwmapi.hh +67 -0
  104. package/third_party/webview/core/include/webview/detail/platform/windows/iid.hh +78 -0
  105. package/third_party/webview/core/include/webview/detail/platform/windows/ntdll.hh +58 -0
  106. package/third_party/webview/core/include/webview/detail/platform/windows/reg_key.hh +135 -0
  107. package/third_party/webview/core/include/webview/detail/platform/windows/shcore.hh +59 -0
  108. package/third_party/webview/core/include/webview/detail/platform/windows/theme.hh +76 -0
  109. package/third_party/webview/core/include/webview/detail/platform/windows/user32.hh +90 -0
  110. package/third_party/webview/core/include/webview/detail/platform/windows/version.hh +151 -0
  111. package/third_party/webview/core/include/webview/detail/platform/windows/webview2/loader.hh +391 -0
  112. package/third_party/webview/core/include/webview/detail/user_script.hh +76 -0
  113. package/third_party/webview/core/include/webview/detail/utility/string.hh +99 -0
  114. package/third_party/webview/core/include/webview/errors.h +67 -0
  115. package/third_party/webview/core/include/webview/errors.hh +85 -0
  116. package/third_party/webview/core/include/webview/json_deprecated.hh +61 -0
  117. package/third_party/webview/core/include/webview/macros.h +123 -0
  118. package/third_party/webview/core/include/webview/types.h +81 -0
  119. package/third_party/webview/core/include/webview/types.hh +48 -0
  120. package/third_party/webview/core/include/webview/version.h +67 -0
  121. package/third_party/webview/core/include/webview/webview.h +32 -0
  122. package/third_party/webview/core/include/webview.h +15 -0
  123. package/third_party/webview2/LICENSE +27 -0
  124. package/third_party/webview2/README.md +13 -0
package/js/page.js ADDED
@@ -0,0 +1,79 @@
1
+ // The page's crossbind.js in an app: initNative() resolves to the module the app's host runs, with the contract of a
2
+ // worker-backed web build.
3
+ import { connect } from './lean-client.js';
4
+
5
+ // The app's host gives this to the top frame of its page alone.
6
+ const token = globalThis.__crossbind_token;
7
+
8
+ // A request the host refuses fails its call with what the host answered.
9
+ async function checked(response) {
10
+ if (!response.ok) throw new Error((await response.text()) || `crossbind: the app's host answered ${response.status}`);
11
+ return response;
12
+ }
13
+
14
+ // macOS, iOS and Linux: WebKit's message handler, and crossbind:// requests for the bytes.
15
+ const WEBKIT = {
16
+ send: (text) => window.webkit.messageHandlers.crossbind.postMessage(text),
17
+ frame: (query, body) => fetch(`crossbind://app/b/frame?${query}`, { method: 'POST', body }).then(checked).then((response) => response.text()),
18
+ result: (query) => fetch(`crossbind://app/b/result?${query}`).then(checked).then((response) => response.arrayBuffer()),
19
+ attachBytes: 16384,
20
+ token,
21
+ };
22
+
23
+ // Android: the port the app hands the top frame as the page starts. A message goes as "<id>|m|<text>", a large result's
24
+ // request as "<id>|r|<query>", and a frame as one ArrayBuffer, "<header length><id>|<query>" and the bytes; an answer
25
+ // is "<id>|<text>", "<id>|!<what the host refused>", or an ArrayBuffer whose first four bytes hold the id.
26
+ function androidTransport(port) {
27
+ const pending = new Map();
28
+ let nextId = 1;
29
+ port.onmessage = ({ data }) => {
30
+ const isBytes = data instanceof ArrayBuffer;
31
+ const bar = isBytes ? 0 : data.indexOf('|');
32
+ const id = isBytes ? new DataView(data).getUint32(0, true) : Number(data.slice(0, bar));
33
+ const { resolve, reject } = pending.get(id);
34
+ pending.delete(id);
35
+ if (isBytes) resolve(data.slice(4));
36
+ else if (data[bar + 1] === '!') reject(new Error(data.slice(bar + 2)));
37
+ else resolve(data.slice(bar + 1));
38
+ };
39
+ const call = (post) => new Promise((resolve, reject) => {
40
+ const id = nextId;
41
+ nextId += 1;
42
+ pending.set(id, { resolve, reject });
43
+ post(id);
44
+ });
45
+ const encoder = new TextEncoder();
46
+ return {
47
+ send: (text) => call((id) => port.postMessage(`${id}|m|${text}`)),
48
+ frame: (query, body) => call((id) => {
49
+ const header = encoder.encode(`${id}|${query}`);
50
+ const bytes = new Uint8Array(4 + header.length + body.length);
51
+ new DataView(bytes.buffer).setUint32(0, header.length, true);
52
+ bytes.set(header, 4);
53
+ bytes.set(body, 4 + header.length);
54
+ port.postMessage(bytes.buffer, [bytes.buffer]);
55
+ }),
56
+ result: (query) => call((id) => port.postMessage(`${id}|r|${query}`)),
57
+ attachBytes: 16384,
58
+ token,
59
+ };
60
+ }
61
+
62
+ const transport = globalThis.__crossbind_port ? globalThis.__crossbind_port.then(androidTransport) : WEBKIT;
63
+
64
+ let booted = null;
65
+
66
+ function initNative(config = {}) {
67
+ if (!booted) {
68
+ booted = token
69
+ ? Promise.resolve(transport).then((chosen) => connect(chosen, config.env))
70
+ : Promise.reject(new Error("crossbind: only the top frame of an app's own page reaches the app's module"));
71
+ }
72
+ return booted;
73
+ }
74
+
75
+ initNative.terminate = () => {
76
+ booted = null;
77
+ };
78
+
79
+ globalThis.Crossbind = { initNative };
@@ -0,0 +1,32 @@
1
+ // What a Hermes runtime embedded without React Native lacks; the host functions come from host_core.cpp.
2
+ /* global __host_log, __host_timer */
3
+ const consoleObject = {};
4
+ for (const level of ['log', 'info', 'warn', 'error', 'debug']) {
5
+ consoleObject[level] = (...args) => __host_log(level, args.map((arg) => (arg instanceof Error ? `${arg.message}\n${arg.stack}` : String(arg))).join(' '));
6
+ }
7
+ globalThis.console = consoleObject;
8
+
9
+ let nextTimer = 1;
10
+ const timers = new Map();
11
+ globalThis.setTimeout = (fn, ms = 0, ...args) => {
12
+ const id = nextTimer;
13
+ nextTimer += 1;
14
+ timers.set(id, () => fn(...args));
15
+ // As a browser reads the delay: a number from 0 up to 32 bits, 0 for anything else.
16
+ __host_timer(id, Math.min(Math.max(Number(ms) || 0, 0), 2 ** 31 - 1));
17
+ return id;
18
+ };
19
+ globalThis.clearTimeout = (id) => {
20
+ timers.delete(id);
21
+ };
22
+ globalThis.__host_timer_fire = (id) => {
23
+ const fn = timers.get(id);
24
+ timers.delete(id);
25
+ if (fn) fn();
26
+ };
27
+
28
+ if (typeof globalThis.queueMicrotask !== 'function') {
29
+ globalThis.queueMicrotask = (fn) => {
30
+ Promise.resolve().then(fn);
31
+ };
32
+ }
package/package.json CHANGED
@@ -1,7 +1,31 @@
1
1
  {
2
- "name": "@crossbind/core-app-host",
3
- "version": "0.0.0-bootstrap.0",
4
- "description": "Placeholder that let npm trust the crossbind release workflow; install @crossbind/core-app-host@beta.",
5
- "license": "MIT",
6
- "repository": "https://github.com/crossbind/crossbind.git"
7
- }
2
+ "name": "@crossbind/core-app-host",
3
+ "version": "2.0.0-beta.65",
4
+ "description": "App host for the crossbind embind runtime: a desktop app whose page runs in the system webview and whose bindings run natively in Hermes.",
5
+ "homepage": "https://github.com/crossbind/crossbind/tree/main/core/app-host#readme",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/crossbind/crossbind.git"
9
+ },
10
+ "license": "MIT",
11
+ "files": [
12
+ "android",
13
+ "cpp",
14
+ "js",
15
+ "third_party"
16
+ ],
17
+ "dependencies": {
18
+ "@crossbind/core-embind-jsi": "^2.0.0-beta.65"
19
+ },
20
+ "keywords": [
21
+ "embind",
22
+ "hermes",
23
+ "webview",
24
+ "desktop",
25
+ "app",
26
+ "bind",
27
+ "c++",
28
+ "rust",
29
+ "macos"
30
+ ]
31
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Meta Platforms, Inc. and affiliates.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,18 @@
1
+ # JSI (vendored)
2
+
3
+ `jsi.cpp`, the out-of-line part of JSI (`facebook::jsi`), which Hermes' prebuilt framework does not export. The JSI
4
+ headers come with Hermes, so this file is taken from the same Hermes release. React Native's Android package of Hermes
5
+ carries no JSI headers, so the three `jsi.cpp` includes and the one `hermes.h` adds are in `include/jsi/`, from the
6
+ same tag.
7
+
8
+ - Upstream: https://github.com/facebook/hermes, `API/jsi/jsi/`
9
+ - Tag: `hermes-v250829098.0.17`, commit `3477757eb2475555cf8d8df24bfb1deb0613880d`
10
+ - Files, from `https://raw.githubusercontent.com/facebook/hermes/3477757eb2475555cf8d8df24bfb1deb0613880d/API/jsi/jsi/`:
11
+ - `jsi.cpp`, sha256 `cb6274a22abc93ecc970066539815e716d3e47716e8f93a9971cf4eb5918ffc1`
12
+ - `include/jsi/jsi.h`, sha256 `db2f1ee9291340f3d05b11abdcdc3d12ac84c239e58599d4ef2ac06dbaa14d92`
13
+ - `include/jsi/jsi-inl.h`, sha256 `a6cbf72ee25991a25cd43049e96fb275c900e24da67d5c2b9581faaca11f06a4`
14
+ - `include/jsi/instrumentation.h`, sha256 `1395779ad53ec372518b977d077e65a876215bc31a94cf049ed55d0a3d2426f4`
15
+ - `include/jsi/hermes-interfaces.h`, sha256 `2cd4b50cdcdb9cf61bd5940b257d7878ceb018438cc2ea8b34acdb552d56d56d`
16
+ - License: MIT, see `LICENSE`
17
+
18
+ No local patches. A Hermes update takes these files from the new release's tag.
@@ -0,0 +1,189 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <jsi/jsi.h>
11
+
12
+ struct SHUnit;
13
+ struct SHRuntime;
14
+ using SHUnitCreator = SHUnit* (*)();
15
+ namespace hermes::vm {
16
+ class GCExecTrace;
17
+ }
18
+
19
+ namespace facebook::hermes {
20
+
21
+ namespace sampling_profiler {
22
+ class Profile;
23
+ }
24
+
25
+ namespace debugger {
26
+ class Debugger;
27
+ }
28
+
29
+ /// Interface for Hermes-specific runtime methods.The actual implementations of
30
+ /// the pure virtual methods are provided by Hermes API.
31
+ class JSI_EXPORT IHermes : public jsi::ICast {
32
+ public:
33
+ static constexpr jsi::UUID uuid{
34
+ 0xe85cfa22,
35
+ 0xdfae,
36
+ 0x11ef,
37
+ 0xa6f7,
38
+ 0x325096b39f47};
39
+
40
+ struct DebugFlags {
41
+ // Looking for the .lazy flag? It's no longer necessary.
42
+ // Source is evaluated lazily by default. See
43
+ // RuntimeConfig::CompilationMode.
44
+ };
45
+
46
+ /// Evaluate the given code in an unoptimized form, used for debugging.
47
+ /// This will be no-op if the implementation does not have debugger enabled.
48
+ virtual void debugJavaScript(
49
+ const std::string& src,
50
+ const std::string& sourceURL,
51
+ const DebugFlags& debugFlags) = 0;
52
+
53
+ /// Return a ICast pointer to an object that be cast into the interface
54
+ /// IHermesRootAPI. This root API object has static lifetime.
55
+ virtual ICast* getHermesRootAPI() = 0;
56
+
57
+ /// Dump sampled stack trace for a given runtime to a data structure that can
58
+ /// be used by third parties.
59
+ virtual sampling_profiler::Profile dumpSampledTraceToProfile() = 0;
60
+
61
+ /// Serialize the sampled stack to the format expected by DevTools'
62
+ /// Profiler.stop return type.
63
+ virtual void sampledTraceToStreamInDevToolsFormat(std::ostream& stream) = 0;
64
+
65
+ /// Resets the timezone offset cache used by Hermes for performance
66
+ /// optimization. Hermes maintains a cached timezone offset to accelerate date
67
+ /// and time calculations. However, this cache does not automatically detect
68
+ /// changes to the system timezone. When the system timezone changes, the
69
+ /// integration layer (e.g., React Native) must call this method to invalidate
70
+ /// the cache and ensure correct time calculations.
71
+ ///
72
+ /// \note Call this method immediately after detecting any timezone change in
73
+ /// the integrator.
74
+ virtual void resetTimezoneCache() = 0;
75
+
76
+ /// Load a new segment into the Runtime.
77
+ /// The \param context must be a valid RequireContext retrieved from JS
78
+ /// using `require.context`.
79
+ virtual void loadSegment(
80
+ std::unique_ptr<const jsi::Buffer> buffer,
81
+ const jsi::Value& context) = 0;
82
+
83
+ /// Gets a guaranteed unique id for an Object (or, respectively, String
84
+ /// or PropNameId), which is assigned at allocation time and is
85
+ /// static throughout that object's (or string's, or PropNameID's)
86
+ /// lifetime.
87
+ virtual uint64_t getUniqueID(const jsi::Object& o) const = 0;
88
+ virtual uint64_t getUniqueID(const jsi::BigInt& s) const = 0;
89
+ virtual uint64_t getUniqueID(const jsi::String& s) const = 0;
90
+ virtual uint64_t getUniqueID(const jsi::PropNameID& pni) const = 0;
91
+ virtual uint64_t getUniqueID(const jsi::Symbol& sym) const = 0;
92
+
93
+ /// Same as the other \c getUniqueID, except it can return 0 for some values.
94
+ /// 0 means there is no ID associated with the value.
95
+ virtual uint64_t getUniqueID(const jsi::Value& val) const = 0;
96
+
97
+ /// From an ID retrieved from \p getUniqueID, go back to the object.
98
+ /// NOTE: This is much slower in general than the reverse operation, and takes
99
+ /// up more memory. Don't use this unless it's absolutely necessary.
100
+ /// \return a jsi::Object if a matching object is found, else returns null.
101
+ virtual jsi::Value getObjectForID(uint64_t id) = 0;
102
+
103
+ /// Get a structure representing the execution history (currently just of
104
+ /// GC, but will be generalized as necessary), to aid in debugging
105
+ /// non-deterministic execution.
106
+ virtual const ::hermes::vm::GCExecTrace& getGCExecTrace() const = 0;
107
+
108
+ /// Get IO tracking (aka HBC page access) info as a JSON string.
109
+ /// See hermes::vm::Runtime::getIOTrackingInfoJSON() for conditions
110
+ /// needed for there to be useful output.
111
+ virtual std::string getIOTrackingInfoJSON() = 0;
112
+
113
+ /// \return a reference to the Debugger for this Runtime.
114
+ virtual debugger::Debugger& getDebugger() = 0;
115
+
116
+ /// Register this runtime and thread for sampling profiler. Before using the
117
+ /// runtime on another thread, invoke this function again from the new thread
118
+ /// to make the sampling profiler target the new thread (and forget the old
119
+ /// thread).
120
+ virtual void registerForProfiling() = 0;
121
+ /// Unregister this runtime for sampling profiler.
122
+ virtual void unregisterForProfiling() = 0;
123
+
124
+ /// Define methods to interrupt JS execution and set time limits.
125
+ /// All JS compiled to bytecode via prepareJS, or evaluateJS, will support
126
+ /// interruption and time limit monitoring if the runtime is configured with
127
+ /// AsyncBreakCheckInEval. If JS prepared in other ways is executed, care must
128
+ /// be taken to ensure that it is compiled in a mode that supports it (i.e.,
129
+ /// the emitted code contains async break checks).
130
+
131
+ /// Asynchronously terminates the current execution. This can be called on
132
+ /// any thread.
133
+ virtual void asyncTriggerTimeout() = 0;
134
+
135
+ /// Register this runtime for execution time limit monitoring, with a time
136
+ /// limit of \p timeoutInMs milliseconds.
137
+ /// See compilation notes above.
138
+ virtual void watchTimeLimit(uint32_t timeoutInMs) = 0;
139
+ /// Unregister this runtime for execution time limit monitoring.
140
+ virtual void unwatchTimeLimit() = 0;
141
+
142
+ /// Same as \c evaluate JavaScript but with a source map, which will be
143
+ /// applied to exception traces and debug information.
144
+ ///
145
+ /// This is an experimental Hermes-specific API. In the future it may be
146
+ /// renamed, moved or combined with another API, but the provided
147
+ /// functionality will continue to be available in some form.
148
+ virtual jsi::Value evaluateJavaScriptWithSourceMap(
149
+ const std::shared_ptr<const jsi::Buffer>& buffer,
150
+ const std::shared_ptr<const jsi::Buffer>& sourceMapBuf,
151
+ const std::string& sourceURL) = 0;
152
+
153
+ /// Associate the SHUnit returned by \p shUnitCreator with this runtime and
154
+ /// run its initialization code. The unit will be freed when the runtime is
155
+ /// destroyed.
156
+ virtual jsi::Value evaluateSHUnit(SHUnitCreator shUnitCreator) = 0;
157
+
158
+ /// Retrieve the underlying SHRuntime.
159
+ virtual SHRuntime* getSHRuntime() noexcept = 0;
160
+
161
+ /// Returns the underlying low level Hermes VM runtime instance.
162
+ /// This function is considered unsafe and unstable.
163
+ /// Direct use of a vm::Runtime should be avoided as the lower level APIs are
164
+ /// unsafe and they can change without notice.
165
+ virtual void* getVMRuntimeUnsafe() const = 0;
166
+
167
+ protected:
168
+ ~IHermes() = default;
169
+ };
170
+
171
+ /// Interface for provide Hermes backend specific methods.
172
+ class IHermesSHUnit : public jsi::ICast {
173
+ public:
174
+ static constexpr jsi::UUID uuid{
175
+ 0x52a2d522,
176
+ 0xcbc6,
177
+ 0x4236,
178
+ 0x8d5d,
179
+ 0x2636c320ed65,
180
+ };
181
+
182
+ /// Get the unit creating function pointer which can be passed to
183
+ /// evaluateSHUnit() for evaluation.
184
+ virtual SHUnitCreator getSHUnitCreator() const = 0;
185
+
186
+ protected:
187
+ ~IHermesSHUnit() = default;
188
+ };
189
+ } // namespace facebook::hermes
@@ -0,0 +1,132 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <chrono>
11
+ #include <iosfwd>
12
+ #include <string>
13
+ #include <tuple>
14
+ #include <unordered_map>
15
+
16
+ #include <jsi/jsi.h>
17
+
18
+ namespace facebook {
19
+ namespace jsi {
20
+
21
+ /// Methods for starting and collecting instrumentation, an \c Instrumentation
22
+ /// instance is associated with a particular \c Runtime instance, which it
23
+ /// controls the instrumentation of.
24
+ /// None of these functions should return newly created jsi values, nor should
25
+ /// it modify the values of any jsi values in the heap (although GCs are fine).
26
+ class JSI_EXPORT Instrumentation {
27
+ public:
28
+ /// Additional options controlling what to include when capturing a heap
29
+ /// snapshot.
30
+ struct HeapSnapshotOptions {
31
+ bool captureNumericValue{false};
32
+ };
33
+
34
+ virtual ~Instrumentation() = default;
35
+
36
+ /// Returns GC statistics as a JSON-encoded string, with an object containing
37
+ /// "type" and "version" fields outermost. "type" is a string, unique to a
38
+ /// particular implementation of \c jsi::Instrumentation, and "version" is a
39
+ /// number to indicate any revision to that implementation and its output
40
+ /// format.
41
+ ///
42
+ /// \pre This call can only be made on the instrumentation instance of a
43
+ /// runtime initialised to collect GC statistics.
44
+ ///
45
+ /// \post All cumulative measurements mentioned in the output are accumulated
46
+ /// across the entire lifetime of the Runtime.
47
+ ///
48
+ /// \return the GC statistics collected so far, as a JSON-encoded string.
49
+ virtual std::string getRecordedGCStats() = 0;
50
+
51
+ /// Request statistics about the current state of the runtime's heap. This
52
+ /// function can be called at any time, and should produce information that is
53
+ /// correct at the instant it is called (i.e, not stale).
54
+ ///
55
+ /// \return a map from a string key to a number associated with that
56
+ /// statistic.
57
+ virtual std::unordered_map<std::string, int64_t> getHeapInfo(
58
+ bool includeExpensive) = 0;
59
+
60
+ /// Perform a full garbage collection.
61
+ /// \param cause The cause of this collection, as it should be reported in
62
+ /// logs.
63
+ virtual void collectGarbage(std::string cause) = 0;
64
+
65
+ /// A HeapStatsUpdate is a tuple of the fragment index, the number of objects
66
+ /// in that fragment, and the number of bytes used by those objects.
67
+ /// A "fragment" is a view of all objects allocated within a time slice.
68
+ using HeapStatsUpdate = std::tuple<uint64_t, uint64_t, uint64_t>;
69
+
70
+ /// Start capturing JS stack-traces for all JS heap allocated objects. These
71
+ /// can be accessed via \c ::createSnapshotToFile().
72
+ /// \param fragmentCallback If present, invoke this callback every so often
73
+ /// with the most recently seen object ID, and a list of fragments that have
74
+ /// been updated. This callback will be invoked on the same thread that the
75
+ /// runtime is using.
76
+ virtual void startTrackingHeapObjectStackTraces(
77
+ std::function<void(
78
+ uint64_t lastSeenObjectID,
79
+ std::chrono::microseconds timestamp,
80
+ std::vector<HeapStatsUpdate> stats)> fragmentCallback) = 0;
81
+
82
+ /// Stop capture JS stack-traces for JS heap allocated objects.
83
+ virtual void stopTrackingHeapObjectStackTraces() = 0;
84
+
85
+ /// Start a heap sampling profiler that will sample heap allocations, and the
86
+ /// stack trace they were allocated at. Reports a summary of which functions
87
+ /// allocated the most.
88
+ /// \param samplingInterval The number of bytes allocated to wait between
89
+ /// samples. This will be used as the expected value of a poisson
90
+ /// distribution.
91
+ virtual void startHeapSampling(size_t samplingInterval) = 0;
92
+
93
+ /// Turns off the heap sampling profiler previously enabled via
94
+ /// \c startHeapSampling. Writes the output of the sampling heap profiler to
95
+ /// \p os. The output is a JSON formatted string.
96
+ virtual void stopHeapSampling(std::ostream& os) = 0;
97
+
98
+ /// Captures the heap to a file
99
+ ///
100
+ /// \param path to save the heap capture.
101
+ /// \param options additional options for what to capture.
102
+ virtual void createSnapshotToFile(
103
+ const std::string& path,
104
+ const HeapSnapshotOptions& options = {false}) = 0;
105
+
106
+ /// Captures the heap to an output stream
107
+ ///
108
+ /// \param os output stream to write to.
109
+ /// \param options additional options for what to capture.
110
+ virtual void createSnapshotToStream(
111
+ std::ostream& os,
112
+ const HeapSnapshotOptions& options = {false}) = 0;
113
+
114
+ /// If the runtime has been created to trace to a temp file, flush
115
+ /// any unwritten parts of the trace of bridge traffic to the file,
116
+ /// and return the name of the file. Otherwise, return the empty string.
117
+ /// Tracing is disabled after this call.
118
+ virtual std::string flushAndDisableBridgeTrafficTrace() = 0;
119
+
120
+ /// Write basic block profile trace to the given file name.
121
+ virtual void writeBasicBlockProfileTraceToFile(
122
+ const std::string& fileName) const = 0;
123
+
124
+ /// Write the opcode stats to the given stream.
125
+ virtual void dumpOpcodeStats(std::ostream& os) const = 0;
126
+
127
+ /// Dump external profiler symbols to the given file name.
128
+ virtual void dumpProfilerSymbolsToFile(const std::string& fileName) const = 0;
129
+ };
130
+
131
+ } // namespace jsi
132
+ } // namespace facebook