- DispatcherProfile.kt - Kotlin 端枚举
- js_vm_dispatcher.h - Native 头文件
- js_vm_dispatcher.c - 框架代码
- 技术规格和实施计划文档
目标:将 js_vm_core.c 的主循环提取为独立函数
步骤:
- 阅读 js_vm_core.c 找到主执行循环
- 识别循环的边界(开始/结束点)
- 复制循环体到 dispatch_switch
- 调整参数和上下文访问
- 验证语义等价
预期输出:
jvalue dispatch_switch(JNIEnv* env, js_vm_context_t* ctx,
const uint8_t* program, uint32_t program_size) {
uint32_t pc = 0;
while (pc < program_size) {
uint8_t opcode = program[pc++];
switch (opcode) {
case 0x01: /* LOAD */ break;
case 0x02: /* STORE */ break;
// ... 所有现有 opcodes
}
}
return result;
}目标:函数指针表 dispatch
步骤:
- 定义 handler 函数类型
- 为每个 opcode 创建 handler 函数
- 构建函数指针数组
- 实现基于数组的 dispatch 循环
预期输出:
typedef jvalue (*opcode_handler_t)(JNIEnv*, js_vm_context_t*, const uint8_t**);
static opcode_handler_t handlers[256] = {
handler_load,
handler_store,
// ...
};
jvalue dispatch_indirect_threaded(...) {
uint32_t pc = 0;
while (pc < program_size) {
uint8_t opcode = program[pc++];
result = handlers[opcode](env, ctx, &program[pc]);
}
}目标:二叉树 if-else dispatch
步骤:
- 构建 opcode 二叉决策树
- 实现 if-else 嵌套结构
预期输出:
jvalue dispatch_if_nest(...) {
while (pc < program_size) {
uint8_t op = program[pc++];
if (op < 128) {
if (op < 64) {
if (op < 32) {
// handle 0-31
} else {
// handle 32-63
}
} else {
// handle 64-127
}
} else {
// handle 128-255
}
}
}目标:改为 dispatcher 选择器
步骤:
- 修改 js_vm_execute 函数签名(如需要)
- 添加 profile 读取逻辑
- 添加 profile 验证逻辑
- 调用 js_vm_get_dispatcher()
- 执行选定的 dispatcher
预期输出:
jvalue js_vm_execute(JNIEnv* env, js_vm_context_t* ctx,
const uint8_t* program, uint32_t size) {
// 1. Read profile
dispatcher_profile_t profile = js_vm_read_dispatcher_profile(ctx);
// 2. Verify
if (!js_vm_verify_dispatcher_auth(ctx, profile)) {
return fail_closed();
}
// 3. Get dispatcher
dispatcher_fn dispatcher = js_vm_get_dispatcher(profile);
if (!dispatcher) {
return fail_closed();
}
// 4. Execute
return dispatcher(env, ctx, program, size);
}目标:包含新文件
文件:core-engine/src/main/native/build-native-kernel.bat
修改:
添加 js_vm_dispatcher.c 到编译列表
命令:
.\core-engine\build-native.bat
.\gradlew.bat :core-engine:test --tests "*Vm*"预期结果:
- 编译成功
- 至少 528 tests passed
- 无新增失败
目标:将 profile 写入 VMBC 资源
步骤:
- 修改 VmBytecodeSerializer.kt
- 在序列化时调用 selectFromAuth()
- 写入 profile 到资源
- 修改 js_vm_read_dispatcher_profile() 读取
目标:实现完整认证链
步骤:
- 设计认证 tag 格式
- 在 Kotlin 端生成 tag
- 在 Native 端验证 tag
- 实现 fail-closed 逻辑
- 编译通过
- 至少 3 个 dispatcher 实现
- 测试套件通过
- 默认 SWITCH profile 正常工作
- Profile 序列化和读取
- Profile 认证生效
- 发散测试通过(不同构建不同 profile)
- Tamper 测试通过(错误 profile 拒绝)
缓解:先创建简化版本,逐步对齐现有行为
缓解:保留 SWITCH 作为默认,性能敏感场景使用
缓解:逐步迁移,先保持双路径并存
- 最小可行版本(Task 1-6):4-6 小时
- 完整 Phase 1(Task 1-8):6-9 小时
- 包含测试和修复:8-12 小时
Phase 1 成功完成的标志:
- ✅ 至少 3 种 dispatcher 实现并工作
- ✅ 测试套件保持绿色(>=528 passed)
- ✅ Profile 选择机制生效
- ✅ 代码编译无警告
- ✅ 基本发散性验证通过
达到这些标志后,即可进入 Phase 2!
📍 E:\XiangMu\JavaShroud-public 🎯 准备开始 Task 1 ⏱️ 预计 Phase 1 剩余:6-9 小时