about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-04-17 18:45:58 -0700
committerbors <bors@rust-lang.org>2013-04-17 18:45:58 -0700
commitfdb4ef321ed5eee681c2b723dcb157c280aa72f2 (patch)
tree7f38fcabd13cba2ff4577b32360abe43720490fc /src/rt
parent68dea752967fa2c7e0c4b82f476086457c93fff7 (diff)
parenta5ddc009829bef149a9e2f127e80609589604443 (diff)
downloadrust-fdb4ef321ed5eee681c2b723dcb157c280aa72f2.tar.gz
rust-fdb4ef321ed5eee681c2b723dcb157c280aa72f2.zip
auto merge of #5726 : brson/rust/struct-return, r=brson
r? @nikomatsakis

This doesn't completely fix the x86 ABI for structs, but it does fix some cases. On linux, structs appear to be returned correctly now. On windows, structs are only returned by pointer when they are greater than 8 bytes. That scenario works now.

In the case where the struct is less than 8 bytes our generated code looks peculiar. When returning a pair of u16, C packs both variables into %eax to return them. Our generated code though expects to find one of the pair in %ax and the other in %dx. Similar for u8. I haven't looked into it yet.

There appears to also be struct passing problems on linux, where my `extern-pass-TwoU8s` and `extern-pass-TwoU16s` tests are failing.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust_builtin.cpp86
-rw-r--r--src/rt/rust_test_helpers.cpp167
-rw-r--r--src/rt/rustrt.def.in8
3 files changed, 174 insertions, 87 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 3c6cc9d9245..475c030e8f2 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -589,50 +589,6 @@ rust_log_console_off() {
     log_console_off(task->kernel->env);
 }
 
-extern "C" CDECL lock_and_signal *
-rust_dbg_lock_create() {
-    return new lock_and_signal();
-}
-
-extern "C" CDECL void
-rust_dbg_lock_destroy(lock_and_signal *lock) {
-    assert(lock);
-    delete lock;
-}
-
-extern "C" CDECL void
-rust_dbg_lock_lock(lock_and_signal *lock) {
-    assert(lock);
-    lock->lock();
-}
-
-extern "C" CDECL void
-rust_dbg_lock_unlock(lock_and_signal *lock) {
-    assert(lock);
-    lock->unlock();
-}
-
-extern "C" CDECL void
-rust_dbg_lock_wait(lock_and_signal *lock) {
-    assert(lock);
-    lock->wait();
-}
-
-extern "C" CDECL void
-rust_dbg_lock_signal(lock_and_signal *lock) {
-    assert(lock);
-    lock->signal();
-}
-
-typedef void *(*dbg_callback)(void*);
-
-extern "C" CDECL void *
-rust_dbg_call(dbg_callback cb, void *data) {
-    return cb(data);
-}
-
-extern "C" CDECL void rust_dbg_do_nothing() { }
-
 extern "C" CDECL void
 rust_dbg_breakpoint() {
     BREAKPOINT_AWESOME;
@@ -844,48 +800,6 @@ rust_readdir() {
 
 #endif
 
-// These functions are used in the unit tests for C ABI calls.
-
-extern "C" CDECL uint32_t
-rust_dbg_extern_identity_u32(uint32_t u) {
-    return u;
-}
-
-extern "C" CDECL uint64_t
-rust_dbg_extern_identity_u64(uint64_t u) {
-    return u;
-}
-
-struct TwoU64s {
-    uint64_t one;
-    uint64_t two;
-};
-
-extern "C" CDECL TwoU64s
-rust_dbg_extern_identity_TwoU64s(TwoU64s u) {
-    return u;
-}
-
-struct TwoDoubles {
-    double one;
-    double two;
-};
-
-extern "C" CDECL TwoDoubles
-rust_dbg_extern_identity_TwoDoubles(TwoDoubles u) {
-    return u;
-}
-
-extern "C" CDECL double
-rust_dbg_extern_identity_double(double u) {
-    return u;
-}
-
-extern "C" CDECL char
-rust_dbg_extern_identity_u8(char u) {
-    return u;
-}
-
 extern "C" rust_env*
 rust_get_rt_env() {
     rust_task *task = rust_get_current_task();
diff --git a/src/rt/rust_test_helpers.cpp b/src/rt/rust_test_helpers.cpp
new file mode 100644
index 00000000000..64966bd3454
--- /dev/null
+++ b/src/rt/rust_test_helpers.cpp
@@ -0,0 +1,167 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Helper functions used only in tests
+
+#include "rust_sched_loop.h"
+#include "rust_task.h"
+#include "rust_util.h"
+#include "rust_scheduler.h"
+#include "sync/timer.h"
+#include "sync/rust_thread.h"
+#include "rust_abi.h"
+
+// These functions are used in the unit tests for C ABI calls.
+
+extern "C" CDECL uint32_t
+rust_dbg_extern_identity_u32(uint32_t u) {
+    return u;
+}
+
+extern "C" CDECL uint64_t
+rust_dbg_extern_identity_u64(uint64_t u) {
+    return u;
+}
+
+extern "C" CDECL double
+rust_dbg_extern_identity_double(double u) {
+    return u;
+}
+
+extern "C" CDECL char
+rust_dbg_extern_identity_u8(char u) {
+    return u;
+}
+
+extern "C" CDECL lock_and_signal *
+rust_dbg_lock_create() {
+    return new lock_and_signal();
+}
+
+extern "C" CDECL void
+rust_dbg_lock_destroy(lock_and_signal *lock) {
+    assert(lock);
+    delete lock;
+}
+
+extern "C" CDECL void
+rust_dbg_lock_lock(lock_and_signal *lock) {
+    assert(lock);
+    lock->lock();
+}
+
+extern "C" CDECL void
+rust_dbg_lock_unlock(lock_and_signal *lock) {
+    assert(lock);
+    lock->unlock();
+}
+
+extern "C" CDECL void
+rust_dbg_lock_wait(lock_and_signal *lock) {
+    assert(lock);
+    lock->wait();
+}
+
+extern "C" CDECL void
+rust_dbg_lock_signal(lock_and_signal *lock) {
+    assert(lock);
+    lock->signal();
+}
+
+typedef void *(*dbg_callback)(void*);
+
+extern "C" CDECL void *
+rust_dbg_call(dbg_callback cb, void *data) {
+    return cb(data);
+}
+
+extern "C" CDECL void rust_dbg_do_nothing() { }
+
+struct TwoU8s {
+    uint8_t one;
+    uint8_t two;
+};
+
+extern "C" CDECL TwoU8s
+rust_dbg_extern_return_TwoU8s() {
+    struct TwoU8s s;
+    s.one = 10;
+    s.two = 20;
+    return s;
+}
+
+extern "C" CDECL TwoU8s
+rust_dbg_extern_identity_TwoU8s(TwoU8s u) {
+    return u;
+}
+
+struct TwoU16s {
+    uint16_t one;
+    uint16_t two;
+};
+
+extern "C" CDECL TwoU16s
+rust_dbg_extern_return_TwoU16s() {
+    struct TwoU16s s;
+    s.one = 10;
+    s.two = 20;
+    return s;
+}
+
+extern "C" CDECL TwoU16s
+rust_dbg_extern_identity_TwoU16s(TwoU16s u) {
+    return u;
+}
+
+struct TwoU32s {
+    uint32_t one;
+    uint32_t two;
+};
+
+extern "C" CDECL TwoU32s
+rust_dbg_extern_return_TwoU32s() {
+    struct TwoU32s s;
+    s.one = 10;
+    s.two = 20;
+    return s;
+}
+
+extern "C" CDECL TwoU32s
+rust_dbg_extern_identity_TwoU32s(TwoU32s u) {
+    return u;
+}
+
+struct TwoU64s {
+    uint64_t one;
+    uint64_t two;
+};
+
+extern "C" CDECL TwoU64s
+rust_dbg_extern_return_TwoU64s() {
+    struct TwoU64s s;
+    s.one = 10;
+    s.two = 20;
+    return s;
+}
+
+extern "C" CDECL TwoU64s
+rust_dbg_extern_identity_TwoU64s(TwoU64s u) {
+    return u;
+}
+
+struct TwoDoubles {
+    double one;
+    double two;
+};
+
+extern "C" CDECL TwoDoubles
+rust_dbg_extern_identity_TwoDoubles(TwoDoubles u) {
+    return u;
+}
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 73dbe661d3f..f63e3f53a7c 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -198,8 +198,15 @@ rust_readdir
 rust_opendir
 rust_dbg_extern_identity_u32
 rust_dbg_extern_identity_u64
+rust_dbg_extern_identity_TwoU8s
+rust_dbg_extern_identity_TwoU16s
+rust_dbg_extern_identity_TwoU32s
 rust_dbg_extern_identity_TwoU64s
 rust_dbg_extern_identity_TwoDoubles
+rust_dbg_extern_return_TwoU8s
+rust_dbg_extern_return_TwoU16s
+rust_dbg_extern_return_TwoU32s
+rust_dbg_extern_return_TwoU64s
 rust_dbg_extern_identity_double
 rust_dbg_extern_identity_u8
 rust_get_rt_env
@@ -214,4 +221,3 @@ rust_uv_free_ip6_addr
 rust_call_nullary_fn
 rust_initialize_global_state
 
-