Skip to content

Commit 4820937

Browse files
committed
vendor-hermes: advance pin to include upstream napi C-linkage fix
Move the pinned Hermes commit forward from 0ae42446 to efcf68e2 on the static_h branch (a descendant, 18 commits ahead). The only relevant change in that range is facebook/hermes#2106 "give hermes_napi.h public API C linkage", which wraps the public hermes_napi_* entry points in extern "C". That is exactly the fix we were applying locally after cloning: without C linkage the mangled hermes_napi_create_env symbol stayed out of the framework export table under Hermes' global -fvisibility=hidden. Now that the fix is upstream at the pinned commit, drop patchHermesNapiVisibility and its header-anchor constants entirely — the vendored checkout exports the entry points as-is. No commit in the bumped range touches getVMRuntimeUnsafe or the IHermes JSI interface we depend on, so the unstable-accessor rationale for pinning still holds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TVfanKvtyfSsoMgZv3DJtY
1 parent 6d9a70d commit 4820937

1 file changed

Lines changed: 10 additions & 36 deletions

File tree

packages/host/src/node/cli/hermes.ts

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,45 +21,22 @@ const HERMES_GIT_URL = "https://github.com/facebook/hermes.git";
2121
// Node-API implementation under `API/napi`. Bump deliberately: the JSI
2222
// accessor we rely on (`getVMRuntimeUnsafe`) is documented as unstable, so we
2323
// vendor a known-good commit rather than tracking a moving branch.
24-
const HERMES_GIT_SHA = "0ae42446d1ae669508368b0a18e60c789f76735d";
24+
//
25+
// This commit includes facebook/hermes#2106 ("give hermes_napi.h public API C
26+
// linkage"), which wraps the public `hermes_napi_*` entry points (e.g.
27+
// `hermes_napi_create_env`) in `extern "C"`. Without it those declarations got
28+
// C++ linkage: the mangled symbols stayed out of the framework's export table
29+
// under Hermes' global `-fvisibility=hidden`, and consumers linking the
30+
// framework hit "Undefined symbol: hermes_napi_create_env". We used to patch
31+
// the header ourselves after cloning; now that the fix is upstream at this pin,
32+
// no header patching is required.
33+
const HERMES_GIT_SHA = "efcf68e285865fd9d952070b08e751bcad63f25e";
2534

2635
const platformOption = new Option(
2736
"--react-native-package <package-name>",
2837
"The React Native package to vendor Hermes into",
2938
).default("react-native");
3039

31-
// The public `hermes_napi_*` entry points (e.g. `hermes_napi_create_env`) are
32-
// declared in `hermes_napi.h` with `NAPI_EXTERN` (visibility "default") but —
33-
// unlike the sibling `js_native_api.h` / `node_api.h` headers — without any
34-
// `extern "C"` wrapping. So they get C++ linkage: the symbols are name-mangled
35-
// and, because Hermes builds with a global `-fvisibility=hidden`, stay out of
36-
// the shared framework's export table. We reach `hermes_napi_create_env` from
37-
// the host module, so consumers linking the framework hit "Undefined symbol".
38-
//
39-
// Wrapping the declarations in `EXTERN_C_START` / `EXTERN_C_END` (both already
40-
// available via the `node_api.h` include) gives them C linkage, so they export
41-
// under their unmangled C names. This mirrors facebook/hermes#2106.
42-
const HERMES_NAPI_HEADER = "API/napi/hermes_napi.h";
43-
const HERMES_NAPI_INCLUDE = '#include "hermes/napi/node_api.h"';
44-
const HERMES_NAPI_ENDIF = "#endif // HERMES_NAPI_HERMES_NAPI_H";
45-
46-
async function patchHermesNapiVisibility(hermesPath: string) {
47-
const headerPath = path.join(hermesPath, HERMES_NAPI_HEADER);
48-
const contents = await fs.promises.readFile(headerPath, "utf8");
49-
if (contents.includes("EXTERN_C_START")) {
50-
return;
51-
}
52-
assert(
53-
contents.includes(HERMES_NAPI_INCLUDE) &&
54-
contents.includes(HERMES_NAPI_ENDIF),
55-
`Cannot patch ${HERMES_NAPI_HEADER}: expected anchors not found (did the pinned Hermes commit change?)`,
56-
);
57-
const patched = contents
58-
.replace(HERMES_NAPI_INCLUDE, `${HERMES_NAPI_INCLUDE}\n\nEXTERN_C_START`)
59-
.replace(HERMES_NAPI_ENDIF, `EXTERN_C_END\n\n${HERMES_NAPI_ENDIF}`);
60-
await fs.promises.writeFile(headerPath, patched);
61-
}
62-
6340
export const command = new Command("vendor-hermes")
6441
.argument("[from]", "Path to a file inside the app package", process.cwd())
6542
.option("--silent", "Don't print anything except the final path", false)
@@ -147,9 +124,6 @@ export const command = new Command("vendor-hermes")
147124
});
148125
}
149126
}
150-
// Applied unconditionally (idempotent) so an existing checkout from
151-
// before this patch also gets fixed.
152-
await patchHermesNapiVisibility(hermesPath);
153127
console.log(hermesPath);
154128
}),
155129
);

0 commit comments

Comments
 (0)