@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.
- package/README.md +55 -3
- package/android/app/src/main/AndroidManifest.xml +15 -0
- package/android/app/src/main/java/dev/crossbind/app/CrossbindActivity.java +366 -0
- package/android/app/src/main/res/xml/network_security_config.xml +8 -0
- package/android/build.gradle +14 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +10 -0
- package/android/gradle.properties +2 -0
- package/android/gradlew +248 -0
- package/android/gradlew.bat +112 -0
- package/android/settings.gradle +14 -0
- package/cpp/CMakeLists.txt +110 -0
- package/cpp/src/android/jni.cpp +167 -0
- package/cpp/src/app.cpp +40 -0
- package/cpp/src/app.h +21 -0
- package/cpp/src/attach.cpp +40 -0
- package/cpp/src/darwin/bundle.mm +19 -0
- package/cpp/src/darwin/channels.mm +196 -0
- package/cpp/src/darwin/navigation.mm +69 -0
- package/cpp/src/host_core.cpp +335 -0
- package/cpp/src/host_core.h +84 -0
- package/cpp/src/ios/bundle.mm +15 -0
- package/cpp/src/ios/main.mm +71 -0
- package/cpp/src/linux/app.cpp +29 -0
- package/cpp/src/linux/channels.cpp +143 -0
- package/cpp/src/linux/main_thread.h +16 -0
- package/cpp/src/linux/navigation.cpp +55 -0
- package/cpp/src/main.cpp +57 -0
- package/cpp/src/platform.h +57 -0
- package/cpp/src/windows/app.cpp +36 -0
- package/cpp/src/windows/app.manifest +8 -0
- package/cpp/src/windows/app.rc +3 -0
- package/cpp/src/windows/channels.cpp +336 -0
- package/cpp/src/windows/com.cpp +92 -0
- package/cpp/src/windows/com.h +57 -0
- package/cpp/src/windows/navigation.cpp +90 -0
- package/js/codec.js +123 -0
- package/js/host.js +8 -0
- package/js/lean-client.js +147 -0
- package/js/lean-host.js +237 -0
- package/js/page.js +79 -0
- package/js/polyfills.js +32 -0
- package/package.json +30 -6
- package/third_party/jsi/LICENSE +21 -0
- package/third_party/jsi/README.md +18 -0
- package/third_party/jsi/include/jsi/hermes-interfaces.h +189 -0
- package/third_party/jsi/include/jsi/instrumentation.h +132 -0
- package/third_party/jsi/include/jsi/jsi-inl.h +434 -0
- package/third_party/jsi/include/jsi/jsi.h +2266 -0
- package/third_party/jsi/jsi.cpp +1110 -0
- package/third_party/webview/LICENSE +22 -0
- package/third_party/webview/README.md +24 -0
- package/third_party/webview/core/include/webview/api.h +251 -0
- package/third_party/webview/core/include/webview/backends.hh +40 -0
- package/third_party/webview/core/include/webview/c_api_impl.hh +258 -0
- package/third_party/webview/core/include/webview/detail/backends/cocoa_webkit.hh +633 -0
- package/third_party/webview/core/include/webview/detail/backends/gtk_webkitgtk.hh +355 -0
- package/third_party/webview/core/include/webview/detail/backends/win32_edge.hh +915 -0
- package/third_party/webview/core/include/webview/detail/basic_result.hh +119 -0
- package/third_party/webview/core/include/webview/detail/engine_base.hh +382 -0
- package/third_party/webview/core/include/webview/detail/exceptions.hh +42 -0
- package/third_party/webview/core/include/webview/detail/json.hh +337 -0
- package/third_party/webview/core/include/webview/detail/native_library.hh +176 -0
- package/third_party/webview/core/include/webview/detail/optional.hh +118 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSApplication.hh +107 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSBundle.hh +56 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSEvent.hh +71 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSInvocation.hh +66 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSMethodSignature.hh +52 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSNotification.hh +51 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSNumber.hh +53 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSObject.hh +51 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSOpenPanel.hh +71 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSPoint.hh +53 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSRect.hh +53 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSSavePanel.hh +52 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSSize.hh +53 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSString.hh +87 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSURL.hh +63 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSURLRequest.hh +52 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSValue.hh +56 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSView.hh +91 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/NSWindow.hh +137 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/cocoa.hh +59 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/cocoa/types.hh +49 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/objc/Class.hh +55 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/objc/autoreleasepool.hh +70 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/objc/invoke.hh +75 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/objc/memory.hh +57 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/objc/objc.hh +47 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKOpenPanelParameters.hh +57 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKScriptMessage.hh +51 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKUserContentController.hh +61 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKUserScript.hh +71 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKWebView.hh +108 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/WKWebViewConfiguration.hh +60 -0
- package/third_party/webview/core/include/webview/detail/platform/darwin/webkit/webkit.hh +46 -0
- package/third_party/webview/core/include/webview/detail/platform/linux/gtk/compat.hh +137 -0
- package/third_party/webview/core/include/webview/detail/platform/linux/webkitgtk/compat.hh +142 -0
- package/third_party/webview/core/include/webview/detail/platform/linux/webkitgtk/dmabuf.hh +167 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/com_init_wrapper.hh +126 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/dpi.hh +161 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/dwmapi.hh +67 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/iid.hh +78 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/ntdll.hh +58 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/reg_key.hh +135 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/shcore.hh +59 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/theme.hh +76 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/user32.hh +90 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/version.hh +151 -0
- package/third_party/webview/core/include/webview/detail/platform/windows/webview2/loader.hh +391 -0
- package/third_party/webview/core/include/webview/detail/user_script.hh +76 -0
- package/third_party/webview/core/include/webview/detail/utility/string.hh +99 -0
- package/third_party/webview/core/include/webview/errors.h +67 -0
- package/third_party/webview/core/include/webview/errors.hh +85 -0
- package/third_party/webview/core/include/webview/json_deprecated.hh +61 -0
- package/third_party/webview/core/include/webview/macros.h +123 -0
- package/third_party/webview/core/include/webview/types.h +81 -0
- package/third_party/webview/core/include/webview/types.hh +48 -0
- package/third_party/webview/core/include/webview/version.h +67 -0
- package/third_party/webview/core/include/webview/webview.h +32 -0
- package/third_party/webview/core/include/webview.h +15 -0
- package/third_party/webview2/LICENSE +27 -0
- 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 };
|
package/js/polyfills.js
ADDED
|
@@ -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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|