修改C函数签名为何会导致WASM参数被覆盖?
Emscripten编译WASM时float参数导致指针参数被篡改的原因分析
问题场景
你通过Emscripten将C函数编译为WASM后,调用时发现p2指针参数进入函数后被莫名改为1(即传入的n2的值);但将参数p5的类型从float改为int后,问题完全消失。已排除栈溢出可能,且更换float值后问题依旧。
核心原因
这是WASM调用约定与Emscripten代码生成逻辑交互时的参数布局错位问题:
- WASM的调用约定中,整数类型(包括指针,WASM中指针为i32)和浮点类型参数是分两组处理的:整数参数使用i32/i64寄存器/栈传递,浮点参数使用f32/f64寄存器/栈传递,两者的参数计数、分配逻辑相互独立。
- 当你的C函数中混合了大量整数/指针参数和浮点参数时,Emscripten的代码生成器可能在计算参数的栈偏移或寄存器映射时出现错误,导致前面的指针参数被后续参数(如
n2)的值覆盖。 - 当把
p5改为int后,所有参数均为整数类型,参数传递按顺序线性处理,不会触发分组逻辑的错误,因此问题消失。
验证与解决方向
- 检查生成的WAT代码:查看
test函数的参数接收逻辑,确认是否存在参数索引读取错误——比如将n2的位置错误映射到p2的变量存储位置。 - 调整编译选项:尝试关闭优化(使用
-O0编译),若问题消失则说明是优化阶段的代码生成bug;也可尝试添加-msimd128或-mno-simd128选项,看是否影响参数布局。 - 修改参数传递方式:将
float p5改为float* p5(通过指针传递浮点值),让所有参数均为整数类型(指针/int),绕过WASM的混合参数分组逻辑。 - 升级Emscripten版本:该问题可能是Emscripten旧版本的已知bug,升级到最新稳定版大概率能解决。
内容的提问来源于stack exchange,提问作者M G
相关产品推荐
相关产品推荐

