【AI 使用案例】如何使用提示词让 AI 提取 CommonStub & 代码迁移
·
背景说明
在编译器中端开发中,需要将 SlowPathLowering 中的字节码 lowering 逻辑迁移到 xxxGraphBuilder。这两者使用不同的 API 和架构:
- SlowPathLowering:基于 Circuit 的门级 IR,使用
GateRef、GateAccessor、CircuitBuilder等 API - xxxGraphBuilder:基于图结构的 IR,使用
ValueVertex、ControlVertex、NewVertex等 API,采用类似 V8 Maglev 的 CFG (控制流图) 结构
迁移难点包括:
- IR 结构差异:从扁平的 Circuit 迁移到分层结构的 CFG
- API 映射:
GateRef→ValueVertex*,CircuitBuilder→NewVertex<XxxVertex> - 参数获取:
acc_.GetValueIn()→GetConstDataId()/GetImmediate()/LoadRegister() - 条件编译:正确处理
#if ECMASCRIPT_ENABLE_IC等宏
AI 需要理解两套 API 的对应关系,并正确处理字节码输入格式。
案例:批量生成 LdLexVar & StLexVar CommonStub
提示词
帮我生成一个 CommonStub,并且加上 call_signature,生成在 standalone/arkcompiler/ets_runtime/ecmascript/compiler/common_stubs.cpp,内容使用 void SlowPathLowering::LowerLdLexVar(GateRef gate),并给 void xxxGraphBuilder::LowerLdLexVar() 使用
同理,StLexVar 也参考 void SlowPathLowering::LowerStLexVar(GateRef gate) 构建 CommonStub,并且 void xxxGraphBuilder::LowerStLexVar() 会调用这个 stub。
AI 生成的代码
1. call_signature.h / common_stub_csigns.h(添加宏定义)
V(LdLexVar)
V(StLexVar)
2. call_signature.cpp(添加签名定义)
DEF_CALL_SIGNATURE(LdLexVar)
{
CallSignature signature("LdLexVar", 0, 4, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
*callSign = signature;
std::array<VariableType, 4> params = {
VariableType::NATIVE_POINTER(), // glue
VariableType::INT32(), // level
VariableType::INT32(), // slot
VariableType::JS_ANY() // currentEnv
};
callSign->SetParameters(params.data());
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
}
DEF_CALL_SIGNATURE(StLexVar)
{
CallSignature signature("StLexVar", 0, 5, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
*callSign = signature;
std::array<VariableType, 5> params = {
VariableType::NATIVE_POINTER(), // glue
VariableType::INT32(), // level
VariableType::INT32(), // slot
VariableType::JS_ANY(), // currentEnv
VariableType::JS_ANY() // value
};
callSign->SetParameters(params.data());
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
}
3. common_stubs.cpp(添加 Stub 实现)
void LdLexVarStubBuilder::GenerateCircuit()
{
auto env = GetEnvironment();
GateRef glue = PtrArgument(0);
GateRef level = Int32Argument(1);
GateRef slot = Int32Argument(2);
DEFVARIABLE(currentEnv, VariableType::JS_ANY(), TaggedArgument(3));
GateRef index = Int32(LexicalEnv::PARENT_ENV_INDEX);
Label exit(env);
Label loopHead(env);
Label loopEnd(env);
DEFVARIABLE(i, VariableType::INT32(), Int32(0));
BRANCH(Int32LessThan(*i, level), &loopHead, &exit);
Bind(&loopHead);
{
currentEnv = GetValueFromTaggedArray(glue, *currentEnv, index);
i = Int32Add(*i, Int32(1));
BRANCH(Int32LessThan(*i, level), &loopEnd, &exit);
}
Bind(&loopEnd);
{
LoopEnd(&loopHead);
}
Bind(&exit);
GateRef valueIndex = Int32Add(slot, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
GateRef result = GetValueFromTaggedArray(glue, *currentEnv, valueIndex);
Return(result);
}
void StLexVarStubBuilder::GenerateCircuit()
{
auto env = GetEnvironment();
GateRef glue = PtrArgument(0);
GateRef level = Int32Argument(1);
GateRef slot = Int32Argument(2);
DEFVARIABLE(currentEnv, VariableType::JS_ANY(), TaggedArgument(3));
GateRef value = TaggedArgument(4);
GateRef index = Int32(LexicalEnv::PARENT_ENV_INDEX);
Label exit(env);
Label loopHead(env);
Label loopEnd(env);
DEFVARIABLE(i, VariableType::INT32(), Int32(0));
BRANCH(Int32LessThan(*i, level), &loopHead, &exit);
Bind(&loopHead);
{
currentEnv = GetValueFromTaggedArray(glue, *currentEnv, index);
i = Int32Add(*i, Int32(1));
BRANCH(Int32LessThan(*i, level), &loopEnd, &exit);
}
Bind(&loopEnd);
{
LoopEnd(&loopHead);
}
Bind(&exit);
GateRef valueIndex = Int32Add(slot, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
SetValueToTaggedArray(VariableType::JS_ANY(), glue, *currentEnv, valueIndex, value);
Return(*currentEnv);
}
4. xxx_graph_builder.cpp(更新调用代码)
void xxxGraphBuilder::LowerLdLexVar()
{
ValueVertex* level = GetInt32Constant(static_cast<int>(GetImmediate(0)));
ValueVertex* slot = GetInt32Constant(static_cast<int>(GetImmediate(1)));
ValueVertex* lexicalEnv = LoadRegister(2);
ValueVertex* glue = GetGlue();
SetAcc(NewVertex<CallCommonStubVertex>({glue, level, slot, lexicalEnv}, CommonStubCSigns::LdLexVar));
}
void xxxGraphBuilder::LowerStLexVar()
{
ValueVertex* level = GetInt32Constant(static_cast<int>(GetImmediate(0)));
ValueVertex* slot = GetInt32Constant(static_cast<int>(GetImmediate(1)));
ValueVertex* lexicalEnv = LoadRegister(2);
ValueVertex* value = GetAcc();
ValueVertex* glue = GetGlue();
SetAcc(NewVertex<CallCommonStubVertex>({glue, level, slot, lexicalEnv, value}, CommonStubCSigns::StLexVar));
}
效率对比
代码统计
| 项目 | 行数 |
|---|---|
| call_signature.h | 2 行 |
| call_signature.cpp | 33 行 |
| common_stub_csigns.h | 2 行 |
| common_stubs.cpp | 60 行 |
| xxx_graph_builder.cpp | 13 行 |
| 总计 | 110 行 |
效率提升
| 指标 | 手动编写 | AI 辅助 | 提升 |
|---|---|---|---|
| 时间消耗 | ~40 分钟 | ~5 分钟 | 8x |
| 代码行数 | 110 行 | 0 行(直接生成) | 100% |
| 正确率 | 需多次调试 | 一次生成正确 | - |
| 文件修改数 | 5 个文件 | 0 个文件(自动修改) | - |
更多推荐

所有评论(0)