From 91dba79c48f0a309e014062f2fe311a5c46b1084 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Fri, 26 Aug 2022 21:01:05 +0200 Subject: [PATCH] wasm: fix abi size of c_longdouble According to https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md the size of c's long double is 16 bytes for Wasm, rather than 8 bytes which was the value previously in the compiler. This ensures we not only pass the correct value, but also creates the correct function signature needed to pass the Wasm validator. This also adds an additional test case in c_abi tests. --- src/type.zig | 4 ++++ test/c_abi/cfuncs.c | 6 ++++++ test/c_abi/main.zig | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/type.zig b/src/type.zig index cc6e5706ee..215011df8d 100644 --- a/src/type.zig +++ b/src/type.zig @@ -6592,6 +6592,8 @@ pub const CType = enum { .powerpcle, .powerpc64, .powerpc64le, + .wasm32, + .wasm64, => return 128, else => return 64, @@ -6640,6 +6642,8 @@ pub const CType = enum { .powerpcle, .powerpc64, .powerpc64le, + .wasm32, + .wasm64, => return 128, else => return 64, diff --git a/test/c_abi/cfuncs.c b/test/c_abi/cfuncs.c index f5c90adba0..391e87fc67 100644 --- a/test/c_abi/cfuncs.c +++ b/test/c_abi/cfuncs.c @@ -33,6 +33,7 @@ void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); void zig_f32(float); void zig_f64(double); +void zig_longdouble(long double); void zig_five_floats(float, float, float, float, float); bool zig_ret_bool(); @@ -157,6 +158,7 @@ void run_c_tests(void) { zig_f32(12.34f); zig_f64(56.78); + zig_longdouble(12.34l); zig_five_floats(1.0f, 2.0f, 3.0f, 4.0f, 5.0f); zig_ptr((void*)0xdeadbeefL); @@ -271,6 +273,10 @@ void c_f64(double x) { assert_or_panic(x == 56.78); } +void c_long_double(long double x) { + assert_or_panic(x == 12.34l); +} + void c_ptr(void *x) { assert_or_panic(x == (void*)0xdeadbeefL); } diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig index 71a53bedea..8450d19a99 100644 --- a/test/c_abi/main.zig +++ b/test/c_abi/main.zig @@ -89,6 +89,7 @@ export fn zig_struct_u128(a: U128) void { extern fn c_f32(f32) void; extern fn c_f64(f64) void; +extern fn c_long_double(c_longdouble) void; // On windows x64, the first 4 are passed via registers, others on the stack. extern fn c_five_floats(f32, f32, f32, f32, f32) void; @@ -105,6 +106,7 @@ test "C ABI floats" { c_f32(12.34); c_f64(56.78); c_five_floats(1.0, 2.0, 3.0, 4.0, 5.0); + c_long_double(12.34); } export fn zig_f32(x: f32) void { @@ -113,6 +115,9 @@ export fn zig_f32(x: f32) void { export fn zig_f64(x: f64) void { expect(x == 56.78) catch @panic("test failure: zig_f64"); } +export fn zig_longdouble(x: c_longdouble) void { + expect(x == 12.34) catch @panic("test failure: zig_longdouble"); +} extern fn c_ptr(*anyopaque) void;