@@ -649,53 +649,78 @@ it exists. The marker is the attribute `#[lang="..."]` and there are
649649various different values of ` ... ` , i.e. various different 'lang
650650items'.
651651
652- For example, ` Box ` pointers require two lang items, one for allocation
653- and one for deallocation. A freestanding program that uses the ` Box `
654- sugar for dynamic allocations via ` malloc ` and ` free ` :
652+ For example, there are three lang items related to task panicking:
653+ one, ` panic_bounds_check ` , is called on panics due to out-of-bounds
654+ array accesses; the second, ` panic ` , is used by explicit invocations
655+ of ` panic! ` , and a third, ` panic_fmt ` , handles unwinding the stack in
656+ the Rust standard library.
657+
658+ A freestanding program that provides its own definition of the
659+ ` panic_bounds_check ` lang item:
655660
656661```
657- #![feature(lang_items, box_syntax , start, no_std)]
662+ #![feature(lang_items, intrinsics , start, no_std)]
658663#![no_std]
659664
660- extern crate libc;
661-
662- extern {
663- fn abort() -> !;
664- }
665+ // To be able to print to standard output from this demonstration
666+ // program, we link with `printf` from the C standard library. Note
667+ // that this requires we null-terminate our strings with "\0".
665668
666- #[lang = "owned_box"]
667- pub struct Box<T>(*mut T);
669+ mod printf {
670+ #[link(name="c")]
671+ extern { fn printf(f: *const u8, ...); }
668672
669- #[lang="exchange_malloc"]
670- unsafe fn allocate(size: usize, _align: usize ) -> *mut u8 {
671- let p = libc::malloc(size as libc::size_t) as *mut u8;
673+ extern "rust-intrinsic" {
674+ pub fn transmute<T,U>(e: T ) -> U;
675+ }
672676
673- // malloc failed
674- if p as usize == 0 {
675- abort( );
677+ pub unsafe fn print0(s: &str) {
678+ let (bytes, _len): (*const u8, usize) = transmute(s);
679+ printf(bytes );
676680 }
677681
678- p
682+ pub unsafe fn print2(s: &str, arg1: u32, arg2: u32) {
683+ let (bytes, _len): (*const u8, usize) = transmute(s);
684+ printf(bytes, arg1, arg2);
685+ }
679686}
680- #[lang="exchange_free"]
681- unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
682- libc::free(ptr as *mut libc::c_void)
687+
688+ #[lang="panic_bounds_check"]
689+ fn panic_bounds_check(_file_line: &(&'static str, usize),
690+ index: usize, len: usize) {
691+ // For simplicity of demonstration, just print message and exit.
692+ extern { fn exit(status: u32) -> !; }
693+
694+ let index = index as u32;
695+ let len = len as u32;
696+ unsafe {
697+ printf::print2("panic_bounds_check index: %d len: %d\n\0", index, len);
698+
699+ // (we pass 0 since this is expected behavior for the demonstration.)
700+ exit(0);
701+ }
683702}
684703
685704#[start]
686- fn main(argc: isize, argv: *const *const u8) -> isize {
687- let x = box 1;
688-
689- 0
705+ fn main(_argc: isize, _argv: *const *const u8) -> isize {
706+ let a = [100, 200, 300];
707+ unsafe { printf::print0("doing a[4] for a.len() == 3\n\0"); }
708+ a[4];
709+ unsafe { printf::print0("Should not get here.\n\0"); }
710+ return 0;
690711}
691712
713+ // Again, these functions and traits are used by the compiler, and are
714+ // normally provided by libstd. (The `Sized` and `Copy` lang_items
715+ // require definitions due to the type-parametric code above.)
716+
692717#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
693718#[lang = "eh_personality"] extern fn eh_personality() {}
694719#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
695- ```
696720
697- Note the use of ` abort ` : the ` exchange_malloc ` lang item is assumed to
698- return a valid pointer, and so needs to do the check internally.
721+ #[lang="sized"] pub trait Sized {}
722+ #[lang="copy"] pub trait Copy {}
723+ ```
699724
700725Other features provided by lang items include:
701726
@@ -712,6 +737,6 @@ Other features provided by lang items include:
712737 ` contravariant_lifetime ` , etc.
713738
714739Lang items are loaded lazily by the compiler; e.g. if one never uses
715- ` Box ` then there is no need to define functions for ` exchange_malloc `
716- and ` exchange_free ` . ` rustc ` will emit an error when an item is needed
717- but not found in the current crate or any that it depends on.
740+ array indexing ` a[i] ` then there is no need to define a function for
741+ ` panic_bounds_check ` . ` rustc ` will emit an error when an item is
742+ needed but not found in the current crate or any that it depends on.
0 commit comments