From 855c99ea758186096a68a8c13edeb0d89105a410 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 20 Mar 2012 16:32:25 -0700 Subject: [PATCH] Some tests for passing and returning structures by value on x64. Close #1402. Close #1970. --- src/rt/rust_builtin.cpp | 37 ++++++++++++++++++++++++++++ src/rt/rustrt.def.in | 2 ++ src/test/run-pass/struct-return.rs | 39 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 src/test/run-pass/struct-return.rs diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index b7abcdd9c265..ee6db7dcf867 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -200,6 +200,43 @@ rand_free(randctx *rctx) { task->free(rctx); } + +/* Debug helpers strictly to verify ABI conformance. + * + * FIXME: move these into a testcase when the testsuite + * understands how to have explicit C files included. + */ + +struct quad { + uint64_t a; + uint64_t b; + uint64_t c; + uint64_t d; +}; + +struct floats { + double a; + uint8_t b; + double c; +}; + +extern "C" quad +debug_abi_1(quad q) { + quad qq = { q.c + 1, + q.d - 1, + q.a + 1, + q.b - 1 }; + return qq; +} + +extern "C" floats +debug_abi_2(floats f) { + floats ff = { f.c + 1.0, + 0xff, + f.a - 1.0 }; + return ff; +} + /* Debug builtins for std::dbg. */ static void diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 4383ebf26571..0bc0fddaca70 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -7,6 +7,8 @@ debug_ptrcast debug_tag debug_tydesc debug_get_stk_seg +debug_abi_1 +debug_abi_2 get_port_id get_task_id get_time diff --git a/src/test/run-pass/struct-return.rs b/src/test/run-pass/struct-return.rs new file mode 100644 index 000000000000..5aa6e56504d0 --- /dev/null +++ b/src/test/run-pass/struct-return.rs @@ -0,0 +1,39 @@ + +type quad = { a: u64, b: u64, c: u64, d: u64 }; +type floats = { a: f64, b: u8, c: f64 }; + +#[nolink] +native mod rustrt { + fn debug_abi_1(++q: quad) -> quad; + fn debug_abi_2(++f: floats) -> floats; +} + +fn main() { + + // First check + let q = { a: 0xaaaa_aaaa_aaaa_aaaa_u64, + b: 0xbbbb_bbbb_bbbb_bbbb_u64, + c: 0xcccc_cccc_cccc_cccc_u64, + d: 0xdddd_dddd_dddd_dddd_u64 }; + let qq = rustrt::debug_abi_1(q); + #error("a: %x", qq.a as uint); + #error("b: %x", qq.b as uint); + #error("c: %x", qq.c as uint); + #error("d: %x", qq.d as uint); + assert qq.a == q.c + 1u64; + assert qq.b == q.d - 1u64; + assert qq.c == q.a + 1u64; + assert qq.d == q.b - 1u64; + + // Second check + let f = { a: 1.234567890e-15_f64, + b: 0b_1010_1010_u8, + c: 1.0987654321e-15_f64 }; + let ff = rustrt::debug_abi_2(f); + #error("a: %f", ff.a as float); + #error("b: %u", ff.b as uint); + #error("c: %f", ff.c as float); + assert ff.a == f.c + 1.0; + assert ff.b == 0xff_u8; + assert ff.c == f.a - 1.0; +} \ No newline at end of file