指导你为 Hermes 编译器新增 IR 指令并补齐相关代码与测试。
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "add-ir-instruction" 技能: 1. 下载 https://raw.githubusercontent.com/facebook/hermes/static_h/.claude/skills/add-ir-instruction/SKILL.md 2. 保存为 ~/.claude/skills/add-ir-instruction/SKILL.md 3. 装好后重载技能,告诉我可以用了
请指导我在 Hermes 中新增一条名为 MyNewInst 的 IR 指令,按正确顺序列出需要修改的文件,并说明每个文件要做什么。
一份分步骤清单,覆盖文档、指令注册、类定义、Builder、验证、类型推断、后端生成与测试。
我新增的 Hermes IR 指令不能直接映射到字节码,请告诉我还要在哪些 Lowering 相关文件中声明、实现并注册该 pass。
额外的 Lowering 文件清单,以及在 HBC 和 SH pipeline 中注册该 pass 的说明。
请根据 Hermes 新增 IR 指令的规范,帮我检查当前改动是否遗漏了验证逻辑、类型推断、代码生成桩和测试。
一个按文件和职责组织的核对结果,指出常见遗漏点和应补充的位置。
开发者在 Hermes 中引入新的中间表示指令时,可用它快速确认需要修改的源码文件、定义模式和接入顺序,减少漏改风险。
当新指令不仅要声明,还要通过验证、类型推断和后端代码生成时,它可作为检查清单,帮助补全相关桩代码或实现。
如果新指令不能直接映射到字节码,这个技能会提示还需修改 Lowering 声明、实现以及 HBC、SH 流水线注册位置。
文档说明了在 Hermes 编译器中新增 IR 指令时需要修改的完整文件清单,并按步骤介绍如何在文档、指令注册、类定义、Builder、验证、类型推断、后端代码生成和测试中接入新指令。对于不能直接映射到字节码的指令,还补充了 Lowering 声明、实现和在 HBC、SH 流水线中注册 pass 的要求。
When adding a new IR instruction, you must touch a specific set of files. This skill describes each file, the pattern to follow, and important conventions.
doc/IR.md — Documentation (the only place for doc-comments)include/hermes/IR/Instrs.def — Instruction registrationinclude/hermes/IR/Instrs.h — Class definition (NO doc-comments here)include/hermes/IR/IRBuilder.h — Builder declarationlib/IR/IRBuilder.cpp — Builder implementationlib/IR/IRVerifier.cpp — Verification logiclib/Optimizer/Scalar/TypeInference.cpp — Type inference stublib/BCGen/HBC/ISel.cpp — HBC instruction selection (stub or implementation)lib/BCGen/SH/SH.cpp — Static Hermes codegen (stub or implementation)lib/BCGen/facebook/Mins/Mins.cpp — Mins codegen (stub or implementation)test/If the instruction needs lowering (i.e., it does not map directly to a bytecode opcode), you also need:
include/hermes/BCGen/Lowering.h — Lowering pass declarationlib/BCGen/Lowering.cpp — Lowering pass implementationlib/BCGen/HBC/LoweringPipelines.cpp — Register pass in HBC pipelinelib/BCGen/SH/SH.cpp (in lowerModuleIR) — Register pass in SH pipelinedoc/IR.mdThis is the ONLY place to put documentation for the instruction. Do NOT add
doc-comments to Instrs.h.
Add a markdown table entry in the appropriate section:
### MyNewInst
MyNewInst | _
--- | --- |
Description | Brief description of what the instruction does.
Example | `MyNewInst %arg1, %arg2 : type`
Arguments | *%arg1* is ... *%arg2* is ...
Semantics | Describe the semantics, referencing the spec where appropriate.
Effects | Describe side effects (e.g., "May read and write memory.", "May read memory and throw.", "Does not read or write memory.").
Instrs.defAdd a DEF_VALUE entry. Place it near related instructions:
DEF_VALUE(MyNewInst, Instruction)
If it's a subclass of another instruction, use the parent as the second argument.
If it's a terminator, use TERMINATOR instead of DEF_VALUE.
Instrs.hDo NOT add doc-comments to this file. Documentation belongs in doc/IR.md.
Follow this exact pattern:
class MyNewInst : public Instruction {
MyNewInst(const MyNewInst &) = delete;
void operator=(const MyNewInst &) = delete;
public:
enum { Arg1Idx, Arg2Idx };
explicit MyNewInst(Value *arg1, Value *arg2)
: Instruction(ValueKind::MyNewInstKind) {
// Optional assertions on operand types:
// assert(arg2->getType().isSomeType() && "message");
// Set the result type:
setType(Type::createNoType()); // for instructions with no output
// or: setType(Type::createFoo()); for typed instructions
pushOperand(arg1);
pushOperand(arg2);
}
explicit MyNewInst(
const MyNewInst *src,
llvh::ArrayRef<Value *> operands)
: Instruction(src, operands) {}
Value *getArg1() const {
return getOperand(Arg1Idx);
}
Value *getArg2() const {
return getOperand(Arg2Idx);
}
static bool hasOutput() {
return false; // true if the instruction produces a value
}
static bool isTyped() {
return false; // true if the output type is meaningful
}
SideEffect getSideEffectImpl() const {
// Compose side effects. Common patterns:
// return {}; // pure
// return SideEffect{}.setReadHeap(); // reads memory
// return SideEffect{}.setReadHeap().setWriteHeap(); // reads+writes
// return SideEffect{}.setThrow().setReadHeap(); // may throw + read
return SideEffect{}.setThrow().setReadHeap();
}
static bool classof(const Value *V) {
ValueKind kind = V->getKind();
return kind == ValueKind::MyNewInstKind;
}
…
它用于指导在 Hermes 编译器中新增 IR 指令,说明必须修改的文件、各文件的模式,以及在需要时如何接入 lowering 与测试。
文档节选列出了核心文件,包括 doc/IR.md、Instrs.def、Instrs.h、IRBuilder.h、IRBuilder.cpp、IRVerifier.cpp、TypeInference.cpp、多个代码生成文件以及 test/。若指令需要 lowering,还要改 Lowering 相关声明、实现与流水线注册文件。
根据文档节选,指令文档应写在 doc/IR.md,并明确说明不要把 doc-comments 写到 Instrs.h 中。
无需交互式编辑器,程序化重排、拆分、删除或修订任意 Git 历史提交。
帮助开发者编写和审查符合 Hermes VM 垃圾回收安全规范的 C++ 代码
分析 hermesvm 在一段提交范围内的二进制体积变化与回归原因
指导在 JSI Runtime 层新增方法与功能,并同步 Hermes 与 SynthTrace 支持。
快速修复代码格式、Lint与常见错误,帮助提交前顺利通过 CI 检查
用于运行 Flow 类型检查并定位修复 React 代码中的类型错误。