言語アイテム

注意 : 言語アイテムは大抵Rustの配布物内のクレートから提供されていますし言語アイテムのインターフェース自体安定していません。 自身で言語アイテムを定義するのではなく公式の配布物のクレートを使うことが推奨されています。

rustc コンパイラはあるプラガブルな操作、つまり機能が言語にハードコードされているのではなくライブラリで実装されているものを持っており、特別なマーカによってそれが存在することをコンパイラに伝えます。 マーカとは #[lang = "..."] アトリビュートで、 ... には様々な値が、つまり様々な「言語アイテム」あります。

例えば、 Box ポインタは2つの言語アイテムを必要とします。1つはアロケーションのため、もう1つはデアロケーションのため。 フリースタンディング環境で動くプログラムは Boxmallocfree による動的アロケーションの糖衣として使います。

#![feature(lang_items, box_syntax, start, libc)] #![no_std] extern crate libc; extern { fn abort() -> !; } #[lang = "owned_box"] pub struct Box<T>(*mut T); #[lang = "exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { let p = libc::malloc(size as libc::size_t) as *mut u8; // malloc failed if p as usize == 0 { abort(); } p } #[lang = "exchange_free"] unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) { libc::free(ptr as *mut libc::c_void) } #[start] fn main(argc: isize, argv: *const *const u8) -> isize { let x = box 1; 0 } #[lang = "eh_personality"] extern fn eh_personality() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} #[no_mangle] pub extern fn rust_eh_register_frames () {} #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
#![feature(lang_items, box_syntax, start, libc)]
#![no_std]

extern crate libc;

extern {
    fn abort() -> !;
}

#[lang = "owned_box"]
pub struct Box<T>(*mut T);

#[lang = "exchange_malloc"]
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
    let p = libc::malloc(size as libc::size_t) as *mut u8;

    // malloc failed
    if p as usize == 0 {
        abort();
    }

    p
}
#[lang = "exchange_free"]
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
    libc::free(ptr as *mut libc::c_void)
}

#[start]
fn main(argc: isize, argv: *const *const u8) -> isize {
    let x = box 1;

    0
}

#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }

abort を使ってることに注意して下さい: exchange_malloc 言語アイテムは有効なポインタを返すものとされており、内部でその検査をする必要があるのです。

言語アイテムによって提供される機能には以下のようなものがあります。:

言語アイテムはコンパイラによって必要に応じてロードされます、例えば、 Box を一度も使わないなら exchange_mallocexchange_free の関数を定義する必要はありません。 rustc はアイテムが必要なのに現在のクレートあるいはその依存するクレート内で見付からないときにエラーを出します。