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;
dynastack_free: ValueRef,
alloc_c_stack: ValueRef,
call_c_stack: ValueRef,
+ call_c_stack_i64: ValueRef,
call_c_stack_float: ValueRef,
rust_personality: ValueRef};
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()),
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);
// 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
--- /dev/null
+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");
+}