fix c-stack-cdecl when used w/ i64
This commit is contained in:
parent
d41385a69b
commit
c78b1639b4
5 changed files with 40 additions and 5 deletions
|
@ -3,7 +3,7 @@ import std::str;
|
|||
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 @@ type upcalls =
|
|||
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 declare_upcalls(_tn: type_names, tydesc_type: 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()),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
20
src/test/run-pass/c-stack-returning-int64.rs
Normal file
20
src/test/run-pass/c-stack-returning-int64.rs
Normal file
|
@ -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");
|
||||
}
|
Loading…
Add table
Reference in a new issue