Make native "c-stack-stdcall" ABI work

The symbol name is based on the number of arguments, so we have to declare
it correctly.

For some reason GetLastError doesn't work now.
This commit is contained in:
Brian Anderson 2011-11-09 15:27:11 -08:00
parent ae2ce09267
commit 4a4d31cf0e
3 changed files with 49 additions and 3 deletions

View File

@ -3840,6 +3840,7 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr,
let ccx = bcx_ccx(bcx);
let f_res = trans_callee(bcx, f);
let llfn = f_res.val, bcx = f_res.bcx;
let llfn = BitCast(bcx, llfn, T_ptr(T_fn([], bcx_ccx(bcx).int_type)));
// Translate the callee.
let { params: _, ty: fn_ty } = ty::expr_ty_params_and_ty(bcx_tcx(bcx), f);
@ -5651,8 +5652,22 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
ret;
}
ast::native_abi_c_stack_stdcall. {
// The name of stdcall functions depend on their argument count
// so we have to declare them correctly
let fn_args_tys = ty::ty_fn_args(ccx.tcx, fn_type);
let fn_ret_ty = ty::ty_fn_ret(ccx.tcx, fn_type);
let ll_args_tys = [];
for arg in fn_args_tys {
let arg_ty = arg.ty;
check type_has_static_size(ccx, arg_ty);
ll_args_tys += [type_of(ccx, sp, arg_ty)];
}
check type_has_static_size(ccx, fn_ret_ty);
let ll_ret_ty = type_of(ccx, sp, fn_ret_ty);
let native_fn_ty = T_fn(ll_args_tys, ll_ret_ty);
let llfn = decl_fn(ccx.llmod, name, lib::llvm::LLVMX86StdcallCallConv,
T_fn([], ccx.int_type));
native_fn_ty);
ccx.item_ids.insert(id, llfn);
ccx.item_symbols.insert(id, name);
ret;

View File

@ -1,14 +1,19 @@
// GetLastError doesn't seem to work with stack switching
// xfail-test
#[cfg(target_os = "win32")]
native "x86stdcall" mod kernel32 {
native "c-stack-stdcall" mod kernel32 {
fn SetLastError(err: uint);
fn GetLastError() -> uint;
}
#[cfg(target_os = "win32")]
fn main() {
let expected = 10u;
let expected = 1234u;
kernel32::SetLastError(expected);
let actual = kernel32::GetLastError();
log_err actual;
assert (expected == actual);
}

View File

@ -0,0 +1,26 @@
type HANDLE = u32;
type DWORD = u32;
type SIZE_T = u32;
type LPVOID = uint;
type BOOL = u8;
#[cfg(target_os = "win32")]
native "c-stack-stdcall" mod kernel32 {
fn GetProcessHeap() -> HANDLE;
fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
}
#[cfg(target_os = "win32")]
fn main() {
let heap = kernel32::GetProcessHeap();
let mem = kernel32::HeapAlloc(heap, 0u32, 100u32);
assert mem != 0u;
let res = kernel32::HeapFree(heap, 0u32, mem);
assert res != 0u8;
}
#[cfg(target_os = "macos")]
#[cfg(target_os = "linux")]
fn main() { }