This patch changes how to specify ABI and link name of a native module.
Before:
native "cdecl" mod llvm = "rustllvm" {...}
After:
#[abi = "cdecl"]
#[link_name = "rustllvm"]
native mod llvm {...}
The old optional syntax for ABI and link name is no longer supported.
Fixes issue #547
fld: fold::ast_fold) -> ast::native_mod {
let filter = bind filter_native_item(cfg, _);
let filtered_items = vec::filter_map(filter, nm.items);
- ret {native_name: nm.native_name,
- abi: nm.abi,
+ ret {abi: nm.abi,
view_items: vec::map(fld.fold_view_item, nm.view_items),
items: filtered_items};
}
const LLVMRealUNE: uint = 14u;
#[link_args = "-Lrustllvm"]
-native "cdecl" mod llvm = "rustllvm" {
+#[link_name = "rustllvm"]
+#[abi = "cdecl"]
+native mod llvm {
type ModuleRef;
type ContextRef;
ret;
}
let cstore = e.sess.get_cstore();
- if !cstore::add_used_library(cstore, m.native_name) { ret; }
+ let native_name = i.ident;
+ alt attr::get_meta_item_value_str_by_name(i.attrs, "link_name") {
+ some(nn) { native_name = nn; }
+ none. { }
+ }
+ if !cstore::add_used_library(cstore, native_name) { ret; }
for a: ast::attribute in
attr::find_attrs_by_name(i.attrs, "link_args") {
}
type native_mod =
- {native_name: str,
+ {// FIXME: Removing abi from AST. Depends on Issue #1179.
abi: native_abi,
view_items: [@view_item],
items: [@native_item]};
}
fn noop_fold_native_mod(nm: native_mod, fld: ast_fold) -> native_mod {
- ret {native_name: nm.native_name,
- abi: nm.abi,
+ ret {abi: nm.abi,
view_items: vec::map(fld.fold_view_item, nm.view_items),
items: vec::map(fld.fold_native_item, nm.items)}
}
} else { unexpected(p, p.peek()); }
}
-fn parse_native_mod_items(p: parser, native_name: str, abi: ast::native_abi,
+fn parse_native_mod_items(p: parser, abi: ast::native_abi,
first_item_attrs: [ast::attribute]) ->
ast::native_mod {
// Shouldn't be any view items since we've already parsed an item attr
initial_attrs = [];
items += [parse_native_item(p, attrs)];
}
- ret {native_name: native_name,
- abi: abi,
+ ret {abi: abi,
view_items: view_items,
items: items};
}
fn parse_item_native_mod(p: parser, attrs: [ast::attribute]) -> @ast::item {
let lo = p.get_last_lo_pos();
- let abi = ast::native_abi_cdecl;
- if !is_word(p, "mod") {
- let t = parse_str(p);
- if str::eq(t, "rust-intrinsic") {
- abi = ast::native_abi_rust_intrinsic;
- } else if str::eq(t, "cdecl") {
- abi = ast::native_abi_cdecl;
- } else if str::eq(t, "stdcall") {
- abi = ast::native_abi_stdcall;
- } else {
- p.fatal("unsupported abi: " + t);
- }
- } else {
- abi =
- alt attr::get_meta_item_value_str_by_name(attrs, "abi") {
- none. { ast::native_abi_cdecl }
- some("rust-intrinsic") {
- ast::native_abi_rust_intrinsic
- }
- some("cdecl") {
- ast::native_abi_cdecl
- }
- some("stdcall") {
- ast::native_abi_stdcall
- }
- some(t) {
- p.fatal("unsupported abi: " + t);
- }
- };
- }
expect_word(p, "mod");
let id = parse_ident(p);
- let native_name;
- if p.peek() == token::EQ {
- expect(p, token::EQ);
- native_name = parse_str(p);
- } else {
- native_name =
- alt attr::get_meta_item_value_str_by_name(attrs, "link_name") {
- none. { id }
- some(nn) { nn }
- };
- }
expect(p, token::LBRACE);
let more_attrs = parse_inner_attrs_and_next(p);
let inner_attrs = more_attrs.inner;
let first_item_outer_attrs = more_attrs.next;
- let m =
- parse_native_mod_items(p, native_name, abi, first_item_outer_attrs);
+ let abi =
+ alt attr::get_meta_item_value_str_by_name(
+ attrs + inner_attrs, "abi") {
+ none. { ast::native_abi_cdecl }
+ some("rust-intrinsic") {
+ ast::native_abi_rust_intrinsic
+ }
+ some("cdecl") {
+ ast::native_abi_cdecl
+ }
+ some("stdcall") {
+ ast::native_abi_stdcall
+ }
+ some(t) {
+ p.fatal("unsupported abi: " + t);
+ }
+ };
+ let m = parse_native_mod_items(p, abi, first_item_outer_attrs);
let hi = p.get_hi_pos();
expect(p, token::RBRACE);
ret mk_item(p, lo, hi, id, ast::item_native_mod(m), attrs + inner_attrs);
}
ast::item_native_mod(nmod) {
head(s, "native");
- alt nmod.abi {
- ast::native_abi_rust_intrinsic. {
- word_nbsp(s, "\"rust-intrinsic\"");
- }
- ast::native_abi_cdecl. {
- word_nbsp(s, "\"cdecl\"");
- }
- ast::native_abi_stdcall. {
- word_nbsp(s, "\"stdcall\"");
- }
- }
word_nbsp(s, "mod");
word_nbsp(s, item.ident);
- if !str::eq(nmod.native_name, item.ident) {
- word_space(s, "=");
- print_string(s, nmod.native_name);
- nbsp(s);
- }
bopen(s);
print_native_mod(s, nmod, item.attrs);
bclose(s, item.span);
export chan;
export port;
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
type void;
type rust_port;
fn rust_port_size(po: *rust_port) -> ctypes::size_t;
}
-native "rust-intrinsic" mod rusti {
+#[abi = "rust-intrinsic"]
+native mod rusti {
fn recv<uniq T>(port: *rustrt::rust_port) -> T;
}
* logging.
*/
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn debug_tydesc(td: *sys::type_desc);
fn debug_opaque<T>(td: *sys::type_desc, x: T);
fn debug_box<T>(td: *sys::type_desc, x: @T);
import os::getcwd;
import os_fs;
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_file_is_dir(path: str::sbuf) -> int;
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_get_stdin() -> os::libc::FILE;
fn rust_get_stdout() -> os::libc::FILE;
fn rust_get_stderr() -> os::libc::FILE;
// FIXME Somehow merge stuff duplicated here and macosx_os.rs. Made difficult
// by https://github.com/graydon/rust/issues#issue/268
-native "cdecl" mod libc = "" {
+#[link_name = ""]
+#[abi = "cdecl"]
+native mod libc {
fn read(fd: int, buf: *u8, count: uint) -> int;
fn write(fd: int, buf: *u8, count: uint) -> int;
fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint;
ret status;
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_getcwd() -> str;
}
-native "cdecl" mod libc = "" {
+#[link_name = ""]
+#[abi = "cdecl"]
+native mod libc {
fn read(fd: int, buf: *u8, count: uint) -> int;
fn write(fd: int, buf: *u8, count: uint) -> int;
fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint;
ret status;
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_getcwd() -> str;
}
/* Module: math */
-native "cdecl" mod libc = "" {
+#[link_name = ""]
+#[abi = "cdecl"]
+native mod libc {
fn sqrt(n: float) -> float;
fn sin(n: float) -> float;
fn asin(n: float) -> float;
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_list_files(path: str) -> [str];
}
Unsafe pointer utility functions
*/
-native "rust-intrinsic" mod rusti {
+#[abi = "rust-intrinsic"]
+native mod rusti {
fn addr_of<T>(val: T) -> *T;
fn ptr_offset<T>(ptr: *T, count: uint) -> *T;
}
Random number generation
*/
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
type rctx;
fn rand_new() -> rctx;
fn rand_next(c: rctx) -> u32;
export spawn_process;
export waitpid;
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_run_program(argv: *sbuf, in_fd: int, out_fd: int, err_fd: int) ->
int;
}
contains, iter_chars, loop_chars, loop_chars_sub,
escape;
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_str_push(&s: str, ch: u8);
}
type_desc(@type_desc);
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
// Explicitly re-export native stuff we want to be made
// available outside this crate. Otherwise it's
// visible-in-crate, but not re-exported.
fn unsupervise();
}
-native "rust-intrinsic" mod rusti {
+#[abi = "rust-intrinsic"]
+native mod rusti {
fn get_type_desc<T>() -> *type_desc;
}
export spawn_notify;
export spawn_joinable;
-native "rust-intrinsic" mod rusti {
+#[abi = "rust-intrinsic"]
+native mod rusti {
// these must run on the Rust stack so that they can swap stacks etc:
fn task_sleep(time_in_us: uint);
}
-native "cdecl" mod rustrt = "rustrt" {
+#[link_name = "rustrt"]
+#[abi = "cdecl"]
+native mod rustrt {
// these can run on the C stack:
fn pin_task();
fn unpin_task();
export configure_test_task;
export joinable;
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn sched_threads() -> uint;
}
// FIXME: Document what these functions do
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn get_time(&sec: u32, &usec: u32);
fn nano_time(&ns: u64);
}
// FIXME: should be -1, change when compiler supports negative
// constants
- native "cdecl" mod libicu = "icuuc" {
+ #[link_name = "icuuc"]
+ #[abi = "cdecl"]
+ native mod libicu {
fn u_hasBinaryProperty(c: UChar32, which: UProperty) -> UBool;
}
}
Unsafe operations
*/
-native "rust-intrinsic" mod rusti {
+#[abi = "rust-intrinsic"]
+native mod rusti {
fn cast<T, U>(src: T) -> U;
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn leak<T>(-thing: T);
}
import uint::next_power_of_two;
import ptr::addr_of;
-native "rust-intrinsic" mod rusti {
+#[abi = "rust-intrinsic"]
+native mod rusti {
fn vec_len<T>(&&v: [mutable? T]) -> uint;
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn vec_reserve_shared<T>(t: *sys::type_desc,
&v: [mutable? T],
n: uint);
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_list_files(path: str) -> [str];
}
-native "cdecl" mod libc = "" {
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod libc {
fn read(fd: int, buf: *u8, count: uint) -> int;
fn write(fd: int, buf: *u8, count: uint) -> int;
fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint;
type HMODULE = uint;
type LPTSTR = str::sbuf;
-native "stdcall" mod kernel32 {
+#[abi = "stdcall"]
+native mod kernel32 {
fn GetEnvironmentVariableA(n: str::sbuf, v: str::sbuf, nsize: uint) ->
uint;
fn SetEnvironmentVariableA(n: str::sbuf, v: str::sbuf) -> int;
libc::fclose(file)
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn rust_process_wait(handle: int) -> int;
fn rust_getcwd() -> str;
}
// based on:
// http://shootout.alioth.debian.org/u32/benchmark.php?test=nbody&lang=java
-native "cdecl" mod llvm = "" {
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod llvm {
fn sqrt(n: float) -> float;
}
// -*- rust -*-
// error-pattern: safe function calls function marked unsafe
-native "cdecl" mod test {
+#[abi = "cdecl"]
+native mod test {
unsafe fn free();
}
// -*- rust -*-
// error-pattern: unsafe functions can only be called
-native "cdecl" mod test {
+#[abi = "cdecl"]
+native mod test {
unsafe fn free();
}
Can we bind native things?
*/
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn pin_task();
}
assert (h1 >= h2);
}
-native "cdecl" mod native_mod = "" {
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod test {
fn do_gc();
fn unsupervise();
}
// xfail-test
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn unsupervise();
}
use std;
import std::str;
-native "cdecl" mod libc = "" {
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod libc {
fn atol(x: str::sbuf) -> int;
fn atoll(x: str::sbuf) -> i64;
}
const b: bool = true;
#[cfg(bogus)]
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
// This symbol doesn't exist and would be a link error if this
// module was translated
fn bogus();
}
-native "cdecl" mod rustrt { }
+#[abi = "cdecl"]
+native mod rustrt { }
#[cfg(bogus)]
type t = int;
}
mod test_native_items {
- native "cdecl" mod rustrt {
+ #[abi = "cdecl"]
+ native mod rustrt {
#[cfg(bogus)]
fn vec_from_buf_shared<T>(ptr: *T, count: uint) -> [T];
fn vec_from_buf_shared<T>(ptr: *T, count: uint) -> [T];
fn eggs() { }
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
import spam::{ham, eggs};
export ham;
export eggs;
// | | |
mod a2 {
// | | |
- native "cdecl" mod b1 = "" {
+ #[abi = "cdecl"]
+ #[link_name = ""]
+ native mod b1 {
// | | |
import a1::b2::*;
// | <-/ -/
import rusti::vec_len;
-native "rust-intrinsic" mod rusti {
+#[abi = "rust-intrinsic"]
+native mod rusti {
fn vec_len<T>(&&v: [T]) -> uint;
}
use std;
import std::task;
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn task_yield();
}
mod mod1 { }
#[attr = "val"]
- native "cdecl" mod rustrt { }
+ #[abi = "cdecl"]
+ native mod rustrt { }
#[attr = "val"]
type t = obj { };
#[attr1 = "val"]
#[attr2 = "val"]
- native "cdecl" mod rustrt { }
+ #[abi = "cdecl"]
+ native mod rustrt { }
#[attr1 = "val"]
#[attr2 = "val"]
}
#[attr = "val"]
- native "cdecl" mod rustrt {
+ #[abi = "cdecl"]
+ native mod rustrt {
}
*/
#[attr1 = "val"]
#[attr2 = "val"]
- native "cdecl" mod rustrt {
+ #[abi = "cdecl"]
+ native mod rustrt {
}
*/
}
mod test_native_items {
- native "cdecl" mod rustrt {
+ #[abi = "cdecl"]
+ native mod rustrt {
#[attr];
#[attr]
// xfail-fast - Somehow causes check-fast to livelock?? Probably because we're
// calling pin_task and that's having wierd side-effects.
-native "cdecl" mod rustrt1 = "rustrt" {
+#[abi = "cdecl"]
+#[link_name = "rustrt"]
+native mod rustrt1 {
fn pin_task();
}
-native "cdecl" mod rustrt2 = "rustrt" {
+#[abi = "cdecl"]
+#[link_name = "rustrt"]
+native mod rustrt2 {
fn pin_task();
}
import std::vec;
import std::str;
-native "cdecl" mod libc = "" {
+#[link_name = ""]
+#[abi = "cdecl"]
+native mod libc {
#[link_name = "strlen"]
fn my_strlen(str: *u8) -> uint;
}
-native "cdecl" mod libc = "" {
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod libc {
type file_handle;
}
-native "cdecl" mod rustrt {
+#[abi = "cdecl"]
+native mod rustrt {
fn unsupervise();
}
-native "cdecl" mod bar = "" { }
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod bar { }
-native "cdecl" mod zed = "" { }
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod zed { }
-native "cdecl" mod libc = "" {
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod libc {
fn write(fd: int, buf: *u8, count: uint) -> int;
}
-native "cdecl" mod baz = "" { }
+#[abi = "cdecl"]
+#[link_name = ""]
+native mod baz { }
fn main(args: [str]) { }
type BOOL = u8;
#[cfg(target_os = "win32")]
-native "stdcall" mod kernel32 {
+#[abi = "stdcall"]
+native mod kernel32 {
fn GetProcessHeap() -> HANDLE;
fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;