From 91dba79c48f0a309e014062f2fe311a5c46b1084 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Fri, 26 Aug 2022 21:01:05 +0200 Subject: [PATCH 1/2] 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 cc6e5706ee6ad8d0a851601b1d99223e66a2ed5e..215011df8d3e93fb917ba2387af7f988c010e09c 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 f5c90adba039a54869a4fa00f73f05279e237a14..391e87fc6755acff758b6f6e427b2cffc16fcdbf 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 71a53bedea335c977f47a8b462b73f70dff35960..8450d19a99e632660b0fe5d3b8fee0a9a801b8da 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; -- 2.54.0 From 1eb22e7ad6f700a72d34cdb36e614c95bdab0464 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Fri, 26 Aug 2022 22:00:22 +0200 Subject: [PATCH 2/2] wasm: skip unimplemented behavior test Since now the size of a c_longdouble is correctly 16 bytes, the test is no longer passing. It was previously accidentally passing due to incorrect sizing and it not being larger than the size of a f64. disable long_double test for windows --- test/behavior/cast.zig | 1 + test/c_abi/main.zig | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index fa0877258c4069e708787e35129ad39f4c2e740b..4c6dab2dbb91ac9e681ab2314c1ecc70a2851e9d 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1430,6 +1430,7 @@ test "coerce between pointers of compatible differently-named floats" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.os.tag == .windows) { // https://github.com/ziglang/zig/issues/12396 diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig index 8450d19a99e632660b0fe5d3b8fee0a9a801b8da..145bbc384a58a008ab3ecaaf3ad6235c21788771 100644 --- a/test/c_abi/main.zig +++ b/test/c_abi/main.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const print = std.debug.print; const expect = std.testing.expect; @@ -106,6 +107,10 @@ 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); +} + +test "C ABI long double" { + if (!builtin.cpu.arch.isWasm()) return error.SkipZigTest; c_long_double(12.34); } @@ -116,6 +121,7 @@ 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 { + if (!builtin.cpu.arch.isWasm()) return; // waiting for #1481 expect(x == 12.34) catch @panic("test failure: zig_longdouble"); } -- 2.54.0