Skip to content

Commit dd01d6a

Browse files
committed
---
yaml --- r: 3977 b: refs/heads/master c: c40d626 h: refs/heads/master i: 3975: a6e94f9 v: v3
1 parent b3f42e1 commit dd01d6a

File tree

8 files changed

+62
-7
lines changed

8 files changed

+62
-7
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 682875929efe558b42318d6ae8b2ef8dc625e94a
2+
refs/heads/master: c40d6265ce2ae093b3bb9e15177f60b375a158fa

trunk/src/comp/lib/llvm.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,15 @@ obj builder(BuilderRef B, @mutable bool terminated) {
13141314
ret v;
13151315
}
13161316

1317+
fn CallWithConv(ValueRef Fn, &ValueRef[] Args,
1318+
uint Conv) -> ValueRef {
1319+
assert !(*terminated);
1320+
auto v = llvm::LLVMBuildCall(B, Fn, ivec::to_ptr(Args),
1321+
ivec::len(Args), str::buf(""));
1322+
llvm::LLVMSetInstructionCallConv(v, Conv);
1323+
ret v;
1324+
}
1325+
13171326
fn Select(ValueRef If, ValueRef Then, ValueRef Else) -> ValueRef {
13181327
assert (!*terminated);
13191328
ret llvm::LLVMBuildSelect(B, If, Then, Else, str::buf(""));

trunk/src/comp/metadata/tydecode.rs

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ fn parse_ty(@pstate st, str_def sd) -> ty::t {
221221
case ('i') { abi = ast::native_abi_rust_intrinsic; }
222222
case ('c') { abi = ast::native_abi_cdecl; }
223223
case ('l') { abi = ast::native_abi_llvm; }
224+
case ('s') { abi = ast::native_abi_x86stdcall; }
224225
}
225226
auto func = parse_ty_fn(st, sd);
226227
ret ty::mk_native_fn(st.tcx, abi, func._0, func._1);

trunk/src/comp/metadata/tyencode.rs

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ fn enc_sty(&ioivec::writer w, &@ctxt cx, &ty::sty st) {
155155
}
156156
case (native_abi_cdecl) { w.write_char('c'); }
157157
case (native_abi_llvm) { w.write_char('l'); }
158+
case (native_abi_x86stdcall) { w.write_char('s'); }
158159
}
159160
enc_ty_fn(w, cx, args, out, return, ~[]);
160161
}

trunk/src/comp/middle/trans.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,8 @@ fn trans_native_call(&builder b, @glue_fns glues, ValueRef lltaskptr,
751751
ModuleRef llmod, &str name, bool pass_task,
752752
&ValueRef[] args) -> ValueRef {
753753
let int n = std::ivec::len[ValueRef](args) as int;
754-
let ValueRef llnative = get_simple_extern_fn(externs, llmod, name, n);
754+
let ValueRef llnative = get_simple_extern_fn(externs, llmod,
755+
name, n);
755756
let ValueRef[] call_args = ~[];
756757
for (ValueRef a in args) { call_args += ~[b.ZExtOrBitCast(a, T_int())]; }
757758
ret b.Call(llnative, call_args);
@@ -8142,6 +8143,11 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx, &span sp, &str[] path, str name,
81428143
uses_retptr = false;
81438144
cast_to_i32 = false;
81448145
}
8146+
case (ast::native_abi_x86stdcall) {
8147+
pass_task = false;
8148+
uses_retptr = false;
8149+
cast_to_i32 = true;
8150+
}
81458151
}
81468152

81478153
auto lltaskptr;
@@ -8185,7 +8191,7 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx, &span sp, &str[] path, str name,
81858191
fn trans_simple_native_abi(&@block_ctxt bcx, str name,
81868192
&mutable ValueRef[] call_args,
81878193
ty::t fn_type, uint first_arg_n,
8188-
bool uses_retptr) ->
8194+
bool uses_retptr, uint cc) ->
81898195
tup(ValueRef, ValueRef) {
81908196
let TypeRef[] call_arg_tys = ~[];
81918197
for (ValueRef arg in call_args) { call_arg_tys += ~[val_ty(arg)]; }
@@ -8202,8 +8208,12 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx, &span sp, &str[] path, str name,
82028208

82038209
auto llnativefn =
82048210
get_extern_fn(bcx.fcx.lcx.ccx.externs, bcx.fcx.lcx.ccx.llmod,
8205-
name, lib::llvm::LLVMCCallConv, llnativefnty);
8206-
auto r = bcx.build.Call(llnativefn, call_args);
8211+
name, cc, llnativefnty);
8212+
auto r = if (cc == lib::llvm::LLVMCCallConv) {
8213+
bcx.build.Call(llnativefn, call_args)
8214+
} else {
8215+
bcx.build.CallWithConv(llnativefn, call_args, cc)
8216+
};
82078217
auto rptr = bcx.fcx.llretptr;
82088218
ret tup(r, rptr);
82098219
}
@@ -8231,15 +8241,25 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx, &span sp, &str[] path, str name,
82318241
case (ast::native_abi_llvm) {
82328242
auto result =
82338243
trans_simple_native_abi(bcx, name, call_args, fn_type, arg_n,
8234-
uses_retptr);
8244+
uses_retptr,
8245+
lib::llvm::LLVMCCallConv);
82358246
r = result._0;
82368247
rptr = result._1;
82378248
}
82388249
case (ast::native_abi_rust_intrinsic) {
82398250
auto external_name = "rust_intrinsic_" + name;
82408251
auto result =
82418252
trans_simple_native_abi(bcx, external_name, call_args,
8242-
fn_type, arg_n, uses_retptr);
8253+
fn_type, arg_n, uses_retptr,
8254+
lib::llvm::LLVMCCallConv);
8255+
r = result._0;
8256+
rptr = result._1;
8257+
}
8258+
case (ast::native_abi_x86stdcall) {
8259+
auto result =
8260+
trans_simple_native_abi(bcx, name, call_args, fn_type, arg_n,
8261+
uses_retptr,
8262+
lib::llvm::LLVMX86StdcallCallConv);
82438263
r = result._0;
82448264
rptr = result._1;
82458265
}

trunk/src/comp/syntax/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ tag native_abi {
526526
native_abi_cdecl;
527527
native_abi_llvm;
528528
native_abi_rust_intrinsic;
529+
native_abi_x86stdcall;
529530
}
530531

531532
type native_mod =

trunk/src/comp/syntax/parse/parser.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,8 @@ fn parse_item_native_mod(&parser p, &ast::attribute[] attrs) -> @ast::item {
20042004
abi = ast::native_abi_llvm;
20052005
} else if (str::eq(t, "rust-intrinsic")) {
20062006
abi = ast::native_abi_rust_intrinsic;
2007+
} else if (str::eq(t, "x86stdcall")) {
2008+
abi = ast::native_abi_x86stdcall;
20072009
} else { p.fatal("unsupported abi: " + t); fail; }
20082010
}
20092011
expect_word(p, "mod");

trunk/src/test/run-pass/x86stdcall.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// xfail-stage0
2+
3+
#[cfg(target_os = "win32")]
4+
mod m {
5+
native "x86stdcall" mod kernel32 {
6+
fn SetLastError(uint err);
7+
fn GetLastError() -> uint;
8+
}
9+
10+
fn main() {
11+
auto expected = 10u;
12+
kernel32::SetLastError(expected);
13+
auto actual = kernel32::GetLastError();
14+
assert expected == actual;
15+
}
16+
}
17+
18+
#[cfg(target_os = "macos")]
19+
#[cfg(target_os = "linux")]
20+
fn main() {
21+
}

0 commit comments

Comments
 (0)