Skip to content

Commit 063acf7

Browse files
committed
Add AbiSet and integrate it into the AST.
I believe this patch incorporates all expected syntax changes from extern function reform (rust-lang#3678). You can now write things like: extern "<abi>" fn foo(s: S) -> T { ... } extern "<abi>" mod { ... } extern "<abi>" fn(S) -> T The ABI for foreign functions is taken from this syntax (rather than from an annotation). We support the full ABI specification I described on the mailing list. The correct ABI is chosen based on the target architecture. Calls by pointer to C functions are not yet supported, and the Rust type of crust fns is still *u8.
1 parent 6d4499c commit 063acf7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+854
-339
lines changed

src/libcore/cast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
pub mod rusti {
1212
#[abi = "rust-intrinsic"]
1313
#[link_name = "rusti"]
14-
pub extern {
14+
pub extern "rust-intrinsic" {
1515
fn forget<T>(+x: T);
1616
fn reinterpret_cast<T, U>(&&e: T) -> U;
1717
}

src/libcore/libc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1617,7 +1617,7 @@ pub mod funcs {
16171617
use libc::types::os::arch::extra::{HANDLE};
16181618

16191619
#[abi = "stdcall"]
1620-
pub extern {
1620+
pub extern "stdcall" {
16211621
unsafe fn GetEnvironmentVariableW(n: LPCWSTR,
16221622
v: LPWSTR,
16231623
nsize: DWORD)

src/libcore/os.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ pub fn errno() -> uint {
944944
945945
#[link_name = "kernel32"]
946946
#[abi = "stdcall"]
947-
extern {
947+
extern "stdcall" {
948948
unsafe fn GetLastError() -> DWORD;
949949
}
950950
@@ -1006,7 +1006,7 @@ pub fn last_os_error() -> ~str {
10061006
10071007
#[link_name = "kernel32"]
10081008
#[abi = "stdcall"]
1009-
extern {
1009+
extern "stdcall" {
10101010
unsafe fn FormatMessageA(flags: DWORD, lpSrc: LPVOID,
10111011
msgId: DWORD, langId: DWORD,
10121012
buf: LPSTR, nsize: DWORD,

src/libcore/ptr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub mod libc_ {
4444

4545
pub mod rusti {
4646
#[abi = "rust-intrinsic"]
47-
pub extern {
47+
pub extern "rust-intrinsic" {
4848
fn addr_of<T>(&&val: T) -> *T;
4949
}
5050
}

src/libcore/rt/thread_local_storage.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub unsafe fn get(key: Key) -> *mut c_void {
7373

7474
#[cfg(windows)]
7575
#[abi = "stdcall"]
76-
extern {
76+
extern "stdcall" {
7777
fn TlsAlloc() -> DWORD;
7878
fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
7979
fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;

src/libcore/stackwalk.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub mod rustrt {
9494

9595
pub mod rusti {
9696
#[abi = "rust-intrinsic"]
97-
pub extern {
97+
pub extern "rust-intrinsic" {
9898
pub fn frame_address(f: &once fn(++x: *u8));
9999
}
100100
}

src/libcore/sys.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub struct Closure {
3939

4040
pub mod rusti {
4141
#[abi = "rust-intrinsic"]
42-
pub extern {
42+
pub extern "rust-intrinsic" {
4343
fn get_tydesc<T>() -> *();
4444
fn size_of<T>() -> uint;
4545
fn pref_align_of<T>() -> uint;

src/libcore/unstable/intrinsics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The intrinsics are defined in librustc/middle/trans/foreign.rs.
1515
*/
1616

1717
#[abi = "rust-intrinsic"]
18-
pub extern {
18+
pub extern "rust-intrinsic" {
1919
pub fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
2020
pub fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
2121
pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;

src/librustc/back/link.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub mod jit {
9797
pub mod rusti {
9898
#[nolink]
9999
#[abi = "rust-intrinsic"]
100-
pub extern {
100+
pub extern "rust-intrinsic" {
101101
pub fn morestack_addr() -> *();
102102
}
103103
}

src/librustc/driver/driver.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use std::getopts::groups::{optopt, optmulti, optflag, optflagopt, getopts};
3434
use std::getopts::{opt_present};
3535
use std::getopts;
3636
use syntax::ast;
37+
use syntax::abi;
3738
use syntax::attr;
3839
use syntax::codemap;
3940
use syntax::diagnostic;
@@ -86,10 +87,10 @@ pub fn default_configuration(sess: Session, +argv0: ~str, input: input) ->
8687
// ARM is bi-endian, however using NDK seems to default
8788
// to little-endian unless a flag is provided.
8889
let (end,arch,wordsz) = match sess.targ_cfg.arch {
89-
session::arch_x86 => (~"little",~"x86",~"32"),
90-
session::arch_x86_64 => (~"little",~"x86_64",~"64"),
91-
session::arch_arm => (~"little",~"arm",~"32"),
92-
session::arch_mips => (~"little",~"arm",~"32")
90+
abi::X86 => (~"little",~"x86",~"32"),
91+
abi::X86_64 => (~"little",~"x86_64",~"64"),
92+
abi::Arm => (~"little",~"arm",~"32"),
93+
abi::Mips => (~"little",~"arm",~"32")
9394
};
9495

9596
return ~[ // Target bindings.
@@ -309,7 +310,7 @@ pub fn compile_rest(sess: Session, cfg: ast::crate_cfg,
309310
};
310311

311312
// NOTE: Android hack
312-
if sess.targ_cfg.arch == session::arch_arm &&
313+
if sess.targ_cfg.arch == abi::Arm &&
313314
(sess.opts.output_type == link::output_type_object ||
314315
sess.opts.output_type == link::output_type_exe) {
315316
let output_type = link::output_type_assembly;
@@ -454,20 +455,20 @@ pub fn get_os(triple: &str) -> Option<session::os> {
454455
} else { None }
455456
}
456457

457-
pub fn get_arch(triple: &str) -> Option<session::arch> {
458+
pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
458459
if str::contains(triple, ~"i386") ||
459460
str::contains(triple, ~"i486") ||
460461
str::contains(triple, ~"i586") ||
461462
str::contains(triple, ~"i686") ||
462463
str::contains(triple, ~"i786") {
463-
Some(session::arch_x86)
464+
Some(abi::X86)
464465
} else if str::contains(triple, ~"x86_64") {
465-
Some(session::arch_x86_64)
466+
Some(abi::X86_64)
466467
} else if str::contains(triple, ~"arm") ||
467468
str::contains(triple, ~"xscale") {
468-
Some(session::arch_arm)
469+
Some(abi::Arm)
469470
} else if str::contains(triple, ~"mips") {
470-
Some(session::arch_mips)
471+
Some(abi::Mips)
471472
} else { None }
472473
}
473474

@@ -484,16 +485,16 @@ pub fn build_target_config(sopts: @session::options,
484485
~"unknown architecture: " + sopts.target_triple)
485486
};
486487
let (int_type, uint_type, float_type) = match arch {
487-
session::arch_x86 => (ast::ty_i32, ast::ty_u32, ast::ty_f64),
488-
session::arch_x86_64 => (ast::ty_i64, ast::ty_u64, ast::ty_f64),
489-
session::arch_arm => (ast::ty_i32, ast::ty_u32, ast::ty_f64),
490-
session::arch_mips => (ast::ty_i32, ast::ty_u32, ast::ty_f64)
488+
abi::X86 => (ast::ty_i32, ast::ty_u32, ast::ty_f64),
489+
abi::X86_64 => (ast::ty_i64, ast::ty_u64, ast::ty_f64),
490+
abi::Arm => (ast::ty_i32, ast::ty_u32, ast::ty_f64),
491+
abi::Mips => (ast::ty_i32, ast::ty_u32, ast::ty_f64)
491492
};
492493
let target_strs = match arch {
493-
session::arch_x86 => x86::get_target_strs(os),
494-
session::arch_x86_64 => x86_64::get_target_strs(os),
495-
session::arch_arm => arm::get_target_strs(os),
496-
session::arch_mips => mips::get_target_strs(os)
494+
abi::X86 => x86::get_target_strs(os),
495+
abi::X86_64 => x86_64::get_target_strs(os),
496+
abi::Arm => arm::get_target_strs(os),
497+
abi::Mips => mips::get_target_strs(os)
497498
};
498499
let target_cfg = @session::config {
499500
os: os,

src/librustc/driver/session.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,17 @@ use syntax::codemap::span;
2525
use syntax::diagnostic;
2626
use syntax::parse::ParseSess;
2727
use syntax::{ast, codemap};
28+
use syntax::abi;
2829
use syntax;
2930

3031
#[deriving(Eq)]
3132
pub enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, }
3233

33-
#[deriving(Eq)]
34-
pub enum arch { arch_x86, arch_x86_64, arch_arm, arch_mips, }
35-
3634
pub enum crate_type { bin_crate, lib_crate, unknown_crate, }
3735

3836
pub struct config {
3937
os: os,
40-
arch: arch,
38+
arch: abi::Architecture,
4139
target_strs: target_strs::t,
4240
int_type: int_ty,
4341
uint_type: uint_ty,

src/librustc/front/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ fn fold_foreign_mod(
9292
nm.view_items.filter_mapped(|a| filter_view_item(cx, *a));
9393
ast::foreign_mod {
9494
sort: nm.sort,
95-
abi: nm.abi,
95+
abis: nm.abis,
9696
view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(*x)),
9797
items: filtered_items
9898
}

src/librustc/front/intrinsic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ pub mod intrinsic {
126126
use super::{TyDesc, TyVisitor};
127127

128128
#[abi = "rust-intrinsic"]
129-
pub extern {
129+
pub extern "rust-intrinsic" {
130130
pub fn get_tydesc<T>() -> *();
131131
pub fn visit_tydesc(++td: *TyDesc, &&tv: @TyVisitor);
132132
}

src/librustc/front/test.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ fn fold_item(cx: @mut TestCtxt, &&i: @ast::item, fld: @fold::ast_fold)
146146

147147
if is_test_fn(i) || is_bench_fn(i) {
148148
match i.node {
149-
ast::item_fn(_, purity, _, _) if purity == ast::unsafe_fn => {
149+
ast::item_fn(_, purity, _, _, _) if purity == ast::unsafe_fn => {
150150
let sess = cx.sess;
151151
sess.span_fatal(
152152
i.span,
@@ -178,7 +178,7 @@ fn is_test_fn(i: @ast::item) -> bool {
178178

179179
fn has_test_signature(i: @ast::item) -> bool {
180180
match &i.node {
181-
&ast::item_fn(ref decl, _, ref generics, _) => {
181+
&ast::item_fn(ref decl, _, _, ref generics, _) => {
182182
let no_output = match decl.output.node {
183183
ast::ty_nil => true,
184184
_ => false
@@ -200,7 +200,7 @@ fn is_bench_fn(i: @ast::item) -> bool {
200200

201201
fn has_test_signature(i: @ast::item) -> bool {
202202
match i.node {
203-
ast::item_fn(ref decl, _, ref generics, _) => {
203+
ast::item_fn(ref decl, _, _, ref generics, _) => {
204204
let input_cnt = vec::len(decl.inputs);
205205
let no_output = match decl.output.node {
206206
ast::ty_nil => true,

src/librustc/metadata/creader.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,8 @@ fn visit_view_item(e: @mut Env, i: @ast::view_item) {
156156
fn visit_item(e: @mut Env, i: @ast::item) {
157157
match i.node {
158158
ast::item_foreign_mod(ref fm) => {
159-
match attr::foreign_abi(i.attrs) {
160-
either::Right(abi) => {
161-
if abi != ast::foreign_abi_cdecl &&
162-
abi != ast::foreign_abi_stdcall { return; }
163-
}
164-
either::Left(ref msg) => e.diag.span_fatal(i.span, (*msg))
159+
if fm.abis.is_rust() || fm.abis.is_intrinsic() {
160+
return;
165161
}
166162

167163
let cstore = e.cstore;

src/librustc/metadata/encoder.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use std::oldmap::HashMap;
3535
use std::serialize::Encodable;
3636
use std::{ebml, oldmap};
3737
use std;
38+
use syntax::abi::AbiSet;
3839
use syntax::ast::*;
3940
use syntax::ast;
4041
use syntax::ast_map;
@@ -657,7 +658,7 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
657658
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
658659
ebml_w.end_tag();
659660
}
660-
item_fn(_, purity, ref generics, _) => {
661+
item_fn(_, purity, _, ref generics, _) => {
661662
add_to_index();
662663
ebml_w.start_tag(tag_items_data_item);
663664
encode_def_id(ebml_w, local_def(item.id));
@@ -983,7 +984,7 @@ fn encode_info_for_foreign_item(ecx: @EncodeContext,
983984
nitem: @foreign_item,
984985
index: @mut ~[entry<int>],
985986
+path: ast_map::path,
986-
abi: foreign_abi) {
987+
abi: AbiSet) {
987988
if !reachable(ecx, nitem.id) { return; }
988989
index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() });
989990
@@ -994,7 +995,7 @@ fn encode_info_for_foreign_item(ecx: @EncodeContext,
994995
encode_family(ebml_w, purity_fn_family(purity));
995996
encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
996997
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
997-
if abi == foreign_abi_rust_intrinsic {
998+
if abi.is_intrinsic() {
998999
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem));
9991000
} else {
10001001
encode_symbol(ecx, ebml_w, nitem.id);

src/librustc/metadata/tydecode.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use middle::ty;
2121
use core::str;
2222
use core::uint;
2323
use core::vec;
24+
use syntax::abi::AbiSet;
25+
use syntax::abi;
2426
use syntax::ast;
2527
use syntax::ast::*;
2628
use syntax::codemap::{respan, dummy_sp};
@@ -74,17 +76,28 @@ fn next_byte(st: @mut PState) -> u8 {
7476
return b;
7577
}
7678

79+
fn scan<R>(st: &mut PState, is_last: &fn(char) -> bool,
80+
op: &fn(&[u8]) -> R) -> R
81+
{
82+
let start_pos = st.pos;
83+
debug!("scan: '%c' (start)", st.data[st.pos] as char);
84+
while !is_last(st.data[st.pos] as char) {
85+
st.pos += 1;
86+
debug!("scan: '%c'", st.data[st.pos] as char);
87+
}
88+
let end_pos = st.pos;
89+
st.pos += 1;
90+
return op(st.data.slice(start_pos, end_pos));
91+
}
92+
7793
pub fn parse_ident(st: @mut PState, last: char) -> ast::ident {
7894
fn is_last(b: char, c: char) -> bool { return c == b; }
7995
return parse_ident_(st, |a| is_last(last, a) );
8096
}
8197

8298
fn parse_ident_(st: @mut PState, is_last: @fn(char) -> bool) ->
8399
ast::ident {
84-
let mut rslt = ~"";
85-
while !is_last(peek(st)) {
86-
rslt += str::from_byte(next_byte(st));
87-
}
100+
let rslt = scan(st, is_last, str::from_bytes);
88101
return st.tcx.sess.ident_of(rslt);
89102
}
90103

@@ -415,11 +428,17 @@ fn parse_purity(c: char) -> purity {
415428
}
416429
}
417430
418-
fn parse_abi(c: char) -> Abi {
419-
match c {
420-
'r' => ast::RustAbi,
421-
_ => fail!(fmt!("parse_abi: bad ABI '%c'", c))
431+
fn parse_abi_set(st: @mut PState) -> AbiSet {
432+
fail_unless!(next(st) == '[');
433+
let mut abis = AbiSet::empty();
434+
while peek(st) != ']' {
435+
// FIXME(#5422) str API should not force this copy
436+
let abi_str = scan(st, |c| c == ',', str::from_bytes);
437+
let abi = abi::lookup(abi_str).expect(abi_str);
438+
abis.add(abi);
422439
}
440+
fail_unless!(next(st) == ']');
441+
return abis;
423442
}
424443
425444
fn parse_onceness(c: char) -> ast::Onceness {
@@ -460,11 +479,11 @@ fn parse_closure_ty(st: @mut PState, conv: conv_did) -> ty::ClosureTy {
460479
461480
fn parse_bare_fn_ty(st: @mut PState, conv: conv_did) -> ty::BareFnTy {
462481
let purity = parse_purity(next(st));
463-
let abi = parse_abi(next(st));
482+
let abi = parse_abi_set(st);
464483
let sig = parse_sig(st, conv);
465484
ty::BareFnTy {
466485
purity: purity,
467-
abi: abi,
486+
abis: abi,
468487
sig: sig
469488
}
470489
}

0 commit comments

Comments
 (0)