]> git.lizzy.rs Git - rust.git/commitdiff
fix c-stack-cdecl when used w/ i64
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 25 Oct 2011 00:03:18 +0000 (17:03 -0700)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 25 Oct 2011 00:03:18 +0000 (17:03 -0700)
src/comp/back/upcall.rs
src/comp/middle/trans.rs
src/rt/arch/i386/ccall.S
src/rt/rustrt.def.in
src/test/run-pass/c-stack-returning-int64.rs [new file with mode: 0644]

index 04bdebb04a171984e4a44139e86502d82a2fc7a6..0eaef300d80c60ce977d8cee34eb10ecae73cbdf 100644 (file)
@@ -3,7 +3,7 @@
 import middle::trans;
 import trans::decl_cdecl_fn;
 import middle::trans_common::{T_f32, T_f64, T_fn, T_bool, T_i1, T_i8, T_i32,
-                              T_int, T_vec, T_nil, T_opaque_chan_ptr,
+                              T_i64, T_int, T_vec, T_nil, T_opaque_chan_ptr,
                               T_opaque_vec, T_opaque_port_ptr, T_ptr,
                               T_size_t, T_void, T_float};
 import lib::llvm::type_names;
@@ -28,6 +28,7 @@
      dynastack_free: ValueRef,
      alloc_c_stack: ValueRef,
      call_c_stack: ValueRef,
+     call_c_stack_i64: ValueRef,
      call_c_stack_float: ValueRef,
      rust_personality: ValueRef};
 
@@ -76,8 +77,11 @@ fn decl(llmod: ModuleRef, name: str, tys: [TypeRef], rv: TypeRef) ->
           dynastack_free: dv("dynastack_free", [T_ptr(T_i8())]),
           alloc_c_stack: d("alloc_c_stack", [T_size_t()], T_ptr(T_i8())),
           call_c_stack: d("call_c_stack",
-                          [T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
-                          T_int()),
+                              [T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
+                              T_int()),
+          call_c_stack_i64: d("call_c_stack_i64",
+                              [T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
+                              T_i64()),
           call_c_stack_float: d("call_c_stack_float",
                                 [T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
                                 T_float()),
index 11d7d62436a34116e6edfb77769ab981bcb1709d..7fe35776529e5d510dad90f3fe77d4a13c600b78 100644 (file)
@@ -3878,13 +3878,19 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr,
         ccx.upcalls.call_c_stack_float
       }
 
+      7 {
+        // LLVMIntegerTypeKind
+        let width = lib::llvm::llvm::LLVMGetIntTypeWidth(llretty);
+        if width == 64u { ccx.upcalls.call_c_stack_i64 }
+        else { ccx.upcalls.call_c_stack } // on 64-bit target, no diff
+      }
+
       _ { ccx.upcalls.call_c_stack }
     };
 
     // Call and cast the return type.
     // TODO: Invoke instead.
-    let llrawretval = Call(bcx, upcall_fn,
-                           [llfn, llrawargbundle]);
+    let llrawretval = Call(bcx, upcall_fn, [llfn, llrawargbundle]);
     let llretval;
     if lib::llvm::llvm::LLVMGetTypeKind(llretty) as int == 11 { // pointer
         llretval = IntToPtr(bcx, llrawretval, llretty);
index 378ea5e0b67eb8517ff8ccceed96067d212fd0f7..d901666c6a40e26347e7181f5a7a7ffba5f75df1 100644 (file)
@@ -6,13 +6,17 @@
 // slower.
 #if defined(__APPLE__) || defined(_WIN32)
 .globl _upcall_call_c_stack
+.globl _upcall_call_c_stack_i64
 .globl _upcall_call_c_stack_float
 _upcall_call_c_stack:
+_upcall_call_c_stack_i64:
 _upcall_call_c_stack_float:
 #else
 .globl upcall_call_c_stack
+.globl upcall_call_c_stack_i64
 .globl upcall_call_c_stack_float
 upcall_call_c_stack:
+upcall_call_c_stack_i64:
 upcall_call_c_stack_float:
 #endif
     pushl %ebp
index 6b70e283957207ca2af5f4d1f5a27c7ba91bf0ed..8293a23d126cf7a7a6c2a215d188c3a71ec038ea 100644 (file)
@@ -65,6 +65,7 @@ task_join
 unsupervise
 upcall_alloc_c_stack
 upcall_call_c_stack
+upcall_call_c_stack_i64
 upcall_call_c_stack_float
 upcall_cmp_type
 upcall_dynastack_alloc
diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs
new file mode 100644 (file)
index 0000000..33e8b73
--- /dev/null
@@ -0,0 +1,20 @@
+use std;
+import std::str;
+
+native "c-stack-cdecl" mod libc = "" {
+    fn atol(x: str::sbuf) -> int;
+    fn atoll(x: str::sbuf) -> i64;
+}
+
+fn atol(s: str) -> int {
+    ret str::as_buf(s, { |x| libc::atol(x) });
+}
+
+fn atoll(s: str) -> i64 {
+    ret str::as_buf(s, { |x| libc::atoll(x) });
+}
+
+fn main() {
+    assert atol("1024") * 10 == atol("10240");
+    assert (atoll("11111111111111111") * 10i64) == atoll("111111111111111110");
+}