帮助开发者编写和审查符合 Hermes VM 垃圾回收安全规范的 C++ 代码
该技能材料显示其为开源的纯提示/规范类内容,不要求密钥,也未声明任何网络端点、代码执行或数据读写能力,整体风险较低。主要不确定性在于仓库社区采用度低、许可证未声明且维护状态未知,属于供应链层面的轻度留意点。
材料明确标注无需密钥或环境变量;作为纯提示/规范类技能,未见凭证收集、存储、传输或滥用路径。
未声明任何远程端点,系统检查项也表明为 prompt-only;从材料看不存在将用户数据外发到第三方服务的行为。
该技能内容是关于 Hermes VM 中 GC-safe C++ 编码规范的说明文档,不包含本机起进程、执行脚本或调用系统能力的描述。
材料未显示其可读取、修改或写入本地文件、工程数据或其他资源;内容仅提供代码审查与编写规则,不涉及数据面授权。
正面因素是其指向 GitHub 上可审计的开源仓库,且描述与 Facebook Hermes 项目上下文一致;但当前提供信息中许可证未声明、社区 star 为 0、维护状态未知,因此供应链可信度仍需留意。
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "gc-safe-coding" 技能: 1. 下载 https://raw.githubusercontent.com/facebook/hermes/static_h/.claude/skills/gc-safe-coding/SKILL.md 2. 保存为 ~/.claude/skills/gc-safe-coding/SKILL.md 3. 装好后重载技能,告诉我可以用了
请审查下面这段 Hermes VM C++ 代码是否满足 GC-safe 规则,重点检查 Handle、GCScope、PseudoHandle、CallResult 和 _RJS 函数调用的使用是否安全,并给出逐条修改建议。
指出潜在的 GC 不安全问题,并给出符合 Hermes VM 规范的修改建议。
请根据 Hermes VM 的 GC-safe 编码规则,帮我实现一段 C++ 代码:在运行时中访问 JSObject 和 StringPrimitive,并确保在可能触发 GC 的操作前后正确使用 Handle 或其他安全封装。
生成一段遵循 GC-safe 约束的 C++ 示例代码,并解释关键保护措施。
下面这段位于 lib/VM/ 的代码直接保存了 HermesValue 并在后续调用 _RJS 函数后继续使用。请按照 Hermes VM GC-safe 规范重构它,避免悬垂引用或对象移动导致的问题。
输出重构后的安全代码,并说明原实现为何违反 GC-safe 规则。
For the full explanation and rationale, see doc/GCSafeCoding.md.
A GC safepoint is either a GC heap allocation or a function call that might
transitively reach one (regular C heap allocations like malloc are not
safepoints). Any function that takes Runtime & or PointerBase &
may trigger GC, unless documented otherwise or named with _noalloc/_nogc.
Functions with _RJS suffix invoke JavaScript recursively and always trigger
GC.
All raw pointers and PseudoHandles to GC objects must be rooted before any
GC safepoint. PseudoHandle<T> is not a root — it is just as dangerous as
a raw pointer across a safepoint. The same applies to bare SymbolID values
extracted from a non-uniqued source (e.g., the SymbolID pulled out of the
Handle<SymbolID> returned by getSymbolHandleFromPrimitive for a
freshly-allocated StringPrimitive): once nothing roots it, the lookup-table
slot is reclaimed by freeUnmarkedSymbols during sweep. Pin via
PinnedValue<SymbolID>.
All new code must use Locals + PinnedValue<T>. Do not introduce new
GCScope instances or makeHandle() calls.
struct : public Locals {
PinnedValue<JSObject> obj;
PinnedValue<StringPrimitive> str;
PinnedValue<SymbolID> sym;
PinnedValue<> genericValue;
} lv;
LocalsRAII lraii(runtime, &lv);
lv.obj = std::move(*callResult);lv.obj.castAndSetHermesValue<JSObject>(hv);lv.obj = somePtr;lv.obj = nullptr;lv.obj.template castAndSetHermesValue<T>(hv);PinnedValue<T> implicitly converts to Handle<T>. Pass directly to functions
that accept Handle<T>.
Always check for exceptions before using the value:
auto result = someOperation_RJS(runtime, args);
if (LLVM_UNLIKELY(result == ExecutionStatus::EXCEPTION))
return ExecutionStatus::EXCEPTION;
lv.obj = std::move(*result);
Not every use of Handle<> needs to be converted to PinnedValue. The rule
"use Locals, not GCScope" applies to creating new rooted values — allocating
new PinnedHermesValue slots via makeHandle() or Handle<> constructors.
The following are not allocating new handles and do not need conversion:
vmcast<>(handle) — casts an existing handle to a different type. It does
not take Runtime & and does not allocate a GCScope slot. The result points
to the same PinnedHermesValue as the input.args.getArgHandle(n) — returns a handle pointing into the register
stack, which is already a root. No new allocation.Handle<> parameter — the handle was allocated by
the caller; the callee is just using it.Only flag handle usage when a new PinnedHermesValue slot is being
allocated (via makeHandle(), makeMutableHandle(), or Handle<>/
MutableHandle<> constructors that take Runtime &).
PseudoHandle<T> — must be stored in
a PinnedValue before any call that takes Runtime & or is _RJS.
Watch for multi-step creation patterns: if Foo::create() returns a
PseudoHandle and the next line calls Bar::create(runtime), the first
PseudoHandle is stale after the second allocation.
Equally watch for capture-via-deref: auto *x = vmcast<T>(*pinned) extracts
a raw pointer from a pinned location (e.g., a PinnedHermesValue * such as
a napi_value). The pinned slot stays GC-safe, but the local raw pointer
does not. Re-deref *pinned at each use site, or pin via PinnedValue<T>.…
无需交互式编辑器,程序化重排、拆分、删除或修订任意 Git 历史提交。
分析 hermesvm 在一段提交范围内的二进制体积变化与回归原因
指导在 JSI Runtime 层新增方法与功能,并同步 Hermes 与 SynthTrace 支持。
Guide for adding a new IR instruction to the Hermes compiler. Use when the user asks to add, create, or define a new IR instruction (Inst/Instruction) in the Hermes intermediate representation. Covers all required files and the patterns for each.
帮助开发者提取并核对 React 错误信息与错误码映射,排查未知错误码警告。
用于运行 Flow 类型检查并定位修复 React 代码中的类型错误。
基于 C++ Core Guidelines 提供现代、安全、惯用的 C++ 编码规范建议
依据C++核心指南辅助编写、审查与重构更现代安全的C++代码。
为代码仓库与 React、Kubernetes、Rust 提供带引用的决策原因解答。
为多种 AI 编码助手提供跨会话持久记忆,避免上下文重置丢失状态。
帮助开发者用 C++ 构建安全、可观测且易集成的 MCP 服务与工具