fix c-stack-cdecl when used w/ i64

This commit is contained in:
Niko Matsakis 2011-10-24 17:03:18 -07:00
parent d41385a69b
commit c78b1639b4
5 changed files with 40 additions and 5 deletions

View file

@ -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()),

View 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);

View 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

View 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

View 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");
}