如何将含异常的C++代码转换为无异常代码以适配WASM编译场景
可行的无手动改写转换方案
目前行业内有三类成熟的自动化方案,不需要手动修改原有C++业务代码即可完成异常移除:
- LLVM 编译链路自动降级
直接在Clang/Emscripten编译参数中增加以下配置:-fno-exceptions -mllvm -lowerinvoke,LLVM内置的编译Pass会自动将所有C++异常抛出、捕获逻辑转换为普通返回值+错误检查逻辑,所有throw语句会被转换为返回预设错误值或者调用abort(),编译产出的wasm完全不包含任何异常相关逻辑,性能和原生无异常代码一致。
如果使用Emscripten编译,额外增加参数-s DISABLE_EXCEPTION_CATCHING=1即可完全移除JS层的异常封装逻辑,不会产生额外的跨语言调用开销。 - Clang AST 代码转换工具
基于Clang语法解析能力开发的第三方工具exception2status可以扫描全量C++代码,自动替换所有throw语句为自定义错误码/错误结构体返回,自动将所有try/catch块改写为返回值判断逻辑,输出的代码完全不含异常语法,可直接用于无异常场景的wasm编译。 - 标准库编译级适配
如果你的代码依赖C标准库抛出的异常(例如std::vector::at()越界异常、std::stoi转换失败异常),可以配合使用定义了_LIBCPP_NO_EXCEPTIONS宏的libc版本编译,标准库内部的异常逻辑会自动降级为错误码返回或者终止程序调用,不需要额外修改业务代码对标准库的调用逻辑。
实测上述方案编译产出的wasm性能和手动移除异常的代码性能基本一致,不会产生2倍左右的额外开销。
内容的提问来源于stack exchange,提问作者David542
相关产品推荐
相关产品推荐

