mkdir -p target/out/clif
echo "[BUILD] mini_core"
-build_lib mini_core examples/mini_core.rs
+build_lib mini_core example/mini_core.rs
-$RUSTC examples/example.rs --crate-type lib
+$RUSTC example/example.rs --crate-type lib
echo "[JIT] mini_core_hello_world"
-run_bin examples/mini_core_hello_world.rs --cfg jit
+run_bin example/mini_core_hello_world.rs --cfg jit
echo "[AOT] mini_core_hello_world"
-build_example_bin mini_core_hello_world examples/mini_core_hello_world.rs
+build_example_bin mini_core_hello_world example/mini_core_hello_world.rs
echo "[BUILD] core"
time $RUSTC target/libcore/src/libcore/lib.rs --crate-type lib --crate-name core -Cincremental=target/incremental_core
--- /dev/null
+#![feature(no_core, unboxed_closures)]
+#![no_core]
+#![allow(dead_code)]
+
+extern crate mini_core;
+
+use mini_core::*;
+
+fn abc(a: u8) -> u8 {
+ a * 2
+}
+
+fn bcd(b: bool, a: u8) -> u8 {
+ if b {
+ a * 2
+ } else {
+ a * 3
+ }
+}
+
+// FIXME make calls work
+fn call() {
+ abc(42);
+}
+
+fn indirect_call() {
+ let f: fn() = call;
+ f();
+}
+
+enum BoolOption {
+ Some(bool),
+ None,
+}
+
+/*
+fn option_unwrap_or(o: BoolOption, d: bool) -> bool {
+ match o {
+ BoolOption::Some(b) => b,
+ BoolOption::None => d,
+ }
+}
+*/
+
+fn ret_42() -> u8 {
+ 42
+}
+
+fn return_str() -> &'static str {
+ "hello world"
+}
+
+fn promoted_val() -> &'static u8 {
+ &(1 * 2)
+}
+
+fn cast_ref_to_raw_ptr(abc: &u8) -> *const u8 {
+ abc as *const u8
+}
+
+fn cmp_raw_ptr(a: *const u8, b: *const u8) -> bool {
+ a == b
+}
+
+/*fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) {
+ (
+ a as u8, a as u16, a as u32, a as usize, a as i8, a as i16, a as i32, a as isize, b as u8,
+ b as u32,
+ )
+}*/
+
+fn char_cast(c: char) -> u8 {
+ c as u8
+}
+
+struct DebugTuple(());
+
+fn debug_tuple() -> DebugTuple {
+ DebugTuple(())
+}
+
+fn size_of<T>() -> usize {
+ unsafe { intrinsics::size_of::<T>() }
+}
+
+fn use_size_of() -> usize {
+ size_of::<u64>()
+}
+
+/*unsafe fn use_copy_intrinsic(src: *const u8, dst: *mut u8) {
+ intrinsics::copy::<u8>(src, dst, 1);
+}*/
+
+/*unsafe fn use_copy_intrinsic_ref(src: *const u8, dst: *mut u8) {
+ let copy2 = ©::<u8>;
+ copy2(src, dst, 1);
+}*/
+
+const Abc: u8 = 6 * 7;
+
+fn use_const() -> u8 {
+ Abc
+}
+
+fn call_closure_3arg() {
+ (|_, _, _| {})(0u8, 42u16, 0u8)
+}
+
+fn call_closure_2arg() {
+ (|_, _| {})(0u8, 42u16)
+}
+
+struct IsNotEmpty;
+
+impl<'a, 'b> FnOnce<(&'a &'b [u16],)> for IsNotEmpty {
+ type Output = bool;
+
+ #[inline]
+ extern "rust-call" fn call_once(mut self, arg: (&'a &'b [u16],)) -> bool {
+ self.call_mut(arg)
+ }
+}
+
+impl<'a, 'b> FnMut<(&'a &'b [u16],)> for IsNotEmpty {
+ #[inline]
+ extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b [u16],)) -> bool {
+ true
+ }
+}
+
+fn eq_char(a: char, b: char) -> bool {
+ a == b
+}
+
+unsafe fn transmute(c: char) -> u32 {
+ intrinsics::transmute(c)
+}
+
+unsafe fn call_uninit() -> u8 {
+ intrinsics::uninit()
+}
+
+// TODO: enable when fat pointers are supported
+unsafe fn deref_str_ptr(s: *const str) -> &'static str {
+ &*s
+}
+
+fn use_array(arr: [u8; 3]) -> u8 {
+ arr[1]
+}
+
+fn repeat_array() -> [u8; 3] {
+ [0; 3]
+}
+
+fn array_as_slice(arr: &[u8; 3]) -> &[u8] {
+ arr
+}
+
+/*unsafe fn use_ctlz_nonzero(a: u16) -> u16 {
+ intrinsics::ctlz_nonzero(a)
+}*/
+
+fn ptr_as_usize(ptr: *const u8) -> usize {
+ ptr as usize
+}
+
+fn float_cast(a: f32, b: f64) -> (f64, f32) {
+ (a as f64, b as f32)
+}
+
+/*fn int_to_float(a: u8, b: i32) -> (f64, f32) {
+ (a as f64, b as f32)
+}*/
+
+fn make_array() -> [u8; 3] {
+ [42, 0, 5]
+}
+
+fn some_promoted_tuple() -> &'static (&'static str, &'static str) {
+ &("abc", "some")
+}
+
+fn index_slice(s: &[u8]) -> u8 {
+ s[2]
+}
+
+pub struct StrWrapper {
+ s: str,
+}
+
+fn str_wrapper_get(w: &StrWrapper) -> &str {
+ &w.s
+}
--- /dev/null
+#![feature(no_core, lang_items, intrinsics, unboxed_closures)]
+#![no_core]
+#![allow(dead_code)]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "unsize"]
+pub trait Unsize<T: ?Sized> {}
+
+#[lang = "coerce_unsized"]
+pub trait CoerceUnsized<T> {}
+
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
+
+#[lang = "copy"]
+pub unsafe trait Copy {}
+
+unsafe impl Copy for bool {}
+unsafe impl Copy for u8 {}
+unsafe impl Copy for u16 {}
+unsafe impl Copy for u32 {}
+unsafe impl Copy for u64 {}
+unsafe impl Copy for usize {}
+unsafe impl Copy for i8 {}
+unsafe impl Copy for i16 {}
+unsafe impl Copy for i32 {}
+unsafe impl Copy for isize {}
+unsafe impl Copy for char {}
+unsafe impl<'a, T: ?Sized> Copy for &'a T {}
+unsafe impl<T: ?Sized> Copy for *const T {}
+
+#[lang = "sync"]
+pub unsafe trait Sync {}
+
+unsafe impl Sync for bool {}
+unsafe impl Sync for u8 {}
+unsafe impl Sync for u16 {}
+unsafe impl Sync for u32 {}
+unsafe impl Sync for u64 {}
+unsafe impl Sync for usize {}
+unsafe impl Sync for i8 {}
+unsafe impl Sync for i16 {}
+unsafe impl Sync for i32 {}
+unsafe impl Sync for isize {}
+unsafe impl Sync for char {}
+unsafe impl<'a, T: ?Sized> Sync for &'a T {}
+unsafe impl Sync for [u8; 16] {}
+
+#[lang = "freeze"]
+trait Freeze {}
+
+#[lang = "not"]
+pub trait Not {
+ type Output;
+
+ fn not(self) -> Self::Output;
+}
+
+impl Not for bool {
+ type Output = bool;
+
+ fn not(self) -> bool {
+ !self
+ }
+}
+
+#[lang = "mul"]
+pub trait Mul<RHS = Self> {
+ type Output;
+
+ #[must_use]
+ fn mul(self, rhs: RHS) -> Self::Output;
+}
+
+impl Mul for u8 {
+ type Output = Self;
+
+ fn mul(self, rhs: Self) -> Self::Output {
+ self * rhs
+ }
+}
+
+#[lang = "add"]
+pub trait Add<RHS = Self> {
+ type Output;
+
+ fn add(self, rhs: RHS) -> Self::Output;
+}
+
+impl Add for u8 {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ self + rhs
+ }
+}
+
+#[lang = "sub"]
+pub trait Sub<RHS = Self> {
+ type Output;
+
+ fn sub(self, rhs: RHS) -> Self::Output;
+}
+
+impl Sub for usize {
+ type Output = Self;
+
+ fn sub(self, rhs: Self) -> Self {
+ self - rhs
+ }
+}
+
+#[lang = "bitor"]
+pub trait BitOr<RHS = Self> {
+ type Output;
+
+ #[must_use]
+ fn bitor(self, rhs: RHS) -> Self::Output;
+}
+
+impl BitOr for bool {
+ type Output = bool;
+
+ fn bitor(self, rhs: bool) -> bool {
+ self | rhs
+ }
+}
+
+impl<'a> BitOr<bool> for &'a bool {
+ type Output = bool;
+
+ fn bitor(self, rhs: bool) -> bool {
+ *self | rhs
+ }
+}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+ fn ne(&self, other: &Rhs) -> bool;
+}
+
+impl PartialEq for u8 {
+ fn eq(&self, other: &u8) -> bool {
+ (*self) == (*other)
+ }
+ fn ne(&self, other: &u8) -> bool {
+ (*self) != (*other)
+ }
+}
+
+impl PartialEq for char {
+ fn eq(&self, other: &char) -> bool {
+ (*self) == (*other)
+ }
+ fn ne(&self, other: &char) -> bool {
+ (*self) != (*other)
+ }
+}
+
+impl<T: ?Sized> PartialEq for *const T {
+ fn eq(&self, other: &*const T) -> bool {
+ *self == *other
+ }
+ fn ne(&self, other: &*const T) -> bool {
+ *self != *other
+ }
+}
+
+pub enum Option<T> {
+ Some(T),
+ None,
+}
+
+pub use Option::*;
+
+#[lang = "phantom_data"]
+pub struct PhantomData<T: ?Sized>;
+
+#[lang = "fn_once"]
+#[rustc_paren_sugar]
+pub trait FnOnce<Args> {
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_mut"]
+#[rustc_paren_sugar]
+pub trait FnMut<Args>: FnOnce<Args> {
+ extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[lang = "panic"]
+pub fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
+ unsafe {
+ intrinsics::abort();
+ }
+}
+
+#[lang = "eh_personality"]
+fn eh_personality() -> ! {
+ loop {}
+}
+
+#[lang = "drop_in_place"]
+#[allow(unconditional_recursion)]
+pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+ // Code here does not matter - this is replaced by the
+ // real drop glue by the compiler.
+ drop_in_place(to_drop);
+}
+
+#[lang = "owned_box"]
+pub struct Box<T: ?Sized>(*mut T);
+
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
+
+static mut MY_TINY_HEAP: [u8; 16] = [0; 16];
+
+#[lang = "exchange_malloc"]
+unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
+ &mut MY_TINY_HEAP as *mut [u8; 16] as *mut u8
+}
+
+#[lang = "drop"]
+pub trait Drop {
+ fn drop(&mut self);
+}
+
+pub mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn abort() -> !;
+ pub fn size_of<T>() -> usize;
+ pub fn size_of_val<T: ?::Sized>(val: &T) -> usize;
+ pub fn min_align_of<T>() -> usize;
+ pub fn min_align_of_val<T: ?::Sized>(val: &T) -> usize;
+ pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
+ pub fn transmute<T, U>(e: T) -> U;
+ pub fn uninit<T>() -> T;
+ pub fn ctlz_nonzero<T>(x: T) -> T;
+ pub fn needs_drop<T>() -> bool;
+ }
+}
+
+#[lang = "index"]
+pub trait Index<Idx: ?Sized> {
+ type Output: ?Sized;
+ fn index(&self, index: Idx) -> &Self::Output;
+}
+
+impl<T> Index<usize> for [T; 3] {
+ type Output = T;
+
+ fn index(&self, index: usize) -> &Self::Output {
+ &self[index]
+ }
+}
+
+impl<T> Index<usize> for [T] {
+ type Output = T;
+
+ fn index(&self, index: usize) -> &Self::Output {
+ &self[index]
+ }
+}
--- /dev/null
+// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
+
+#![feature(no_core, unboxed_closures, start, lang_items, box_syntax)]
+#![no_core]
+#![allow(dead_code)]
+
+extern crate mini_core;
+
+use mini_core::*;
+
+#[link(name = "c")]
+extern "C" {
+ fn puts(s: *const u8);
+}
+
+unsafe extern "C" fn my_puts(s: *const u8) {
+ puts(s);
+}
+
+// TODO remove when jit supports linking rlibs
+#[cfg(jit)]
+extern "C" fn panic<T>(_: T) -> ! {
+ unsafe {
+ intrinsics::abort();
+ }
+}
+
+#[lang = "termination"]
+trait Termination {
+ fn report(self) -> i32;
+}
+
+impl Termination for () {
+ fn report(self) -> i32 {
+ unsafe {
+ NUM = 6 * 7 + 1 + (1u8 == 1u8) as u8; // 44
+ *NUM_REF as i32
+ }
+ }
+}
+
+trait SomeTrait {
+ fn object_safe(&self);
+}
+
+impl SomeTrait for &'static str {
+ fn object_safe(&self) {
+ unsafe {
+ puts(*self as *const str as *const u8);
+ }
+ }
+}
+
+struct NoisyDrop {
+ text: &'static str,
+ inner: NoisyDropInner,
+}
+
+struct NoisyDropInner;
+
+impl Drop for NoisyDrop {
+ fn drop(&mut self) {
+ unsafe {
+ puts(self.text as *const str as *const u8);
+ }
+ }
+}
+
+impl Drop for NoisyDropInner {
+ fn drop(&mut self) {
+ unsafe {
+ puts("Inner got dropped!\0" as *const str as *const u8);
+ }
+ }
+}
+
+#[lang = "start"]
+fn start<T: Termination + 'static>(
+ main: fn() -> T,
+ _argc: isize,
+ _argv: *const *const u8,
+) -> isize {
+ main().report() as isize
+}
+
+static mut NUM: u8 = 6 * 7;
+static NUM_REF: &'static u8 = unsafe { &NUM };
+
+macro_rules! assert {
+ ($e:expr) => {
+ if !$e {
+ panic(&(stringify!(! $e), file!(), line!(), 0));
+ }
+ };
+}
+
+macro_rules! assert_eq {
+ ($l:expr, $r: expr) => {
+ if $l != $r {
+ panic(&(stringify!($l != $r), file!(), line!(), 0));
+ }
+ }
+}
+
+struct Unique<T: ?Sized> {
+ pointer: *const T,
+ _marker: PhantomData<T>,
+}
+
+impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
+
+fn main() {
+ unsafe {
+ let hello: &[u8] = b"Hello\0" as &[u8; 6];
+ let ptr: *const u8 = hello as *const [u8] as *const u8;
+ puts(ptr);
+
+ // TODO remove when jit supports linking rlibs
+ #[cfg(not(jit))]
+ {
+ let world: Box<&str> = box "World!\0";
+ puts(*world as *const str as *const u8);
+ world as Box<SomeTrait>;
+ }
+
+ assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
+
+ let chars = &['C', 'h', 'a', 'r', 's'];
+ let chars = chars as &[char];
+ assert_eq!(intrinsics::size_of_val(chars) as u8, 4 * 5);
+
+ let a: &dyn SomeTrait = &"abc\0";
+ a.object_safe();
+
+ assert_eq!(intrinsics::size_of_val(a) as u8, 16);
+ assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
+
+ assert_eq!(intrinsics::min_align_of::<u16>() as u8, 2);
+ assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8);
+
+ assert!(!intrinsics::needs_drop::<u8>());
+ assert!(intrinsics::needs_drop::<NoisyDrop>());
+
+ Unique {
+ pointer: 0 as *const &str,
+ _marker: PhantomData,
+ } as Unique<dyn SomeTrait>;
+ }
+
+ let _ = NoisyDrop {
+ text: "Outer got dropped!\0",
+ inner: NoisyDropInner,
+ };
+
+ const FUNC_REF: Option<fn()> = Some(main);
+ match FUNC_REF {
+ Some(_) => {},
+ None => assert!(false),
+ }
+}
+++ /dev/null
-#![feature(no_core, unboxed_closures)]
-#![no_core]
-#![allow(dead_code)]
-
-extern crate mini_core;
-
-use mini_core::*;
-
-fn abc(a: u8) -> u8 {
- a * 2
-}
-
-fn bcd(b: bool, a: u8) -> u8 {
- if b {
- a * 2
- } else {
- a * 3
- }
-}
-
-// FIXME make calls work
-fn call() {
- abc(42);
-}
-
-fn indirect_call() {
- let f: fn() = call;
- f();
-}
-
-enum BoolOption {
- Some(bool),
- None,
-}
-
-/*
-fn option_unwrap_or(o: BoolOption, d: bool) -> bool {
- match o {
- BoolOption::Some(b) => b,
- BoolOption::None => d,
- }
-}
-*/
-
-fn ret_42() -> u8 {
- 42
-}
-
-fn return_str() -> &'static str {
- "hello world"
-}
-
-fn promoted_val() -> &'static u8 {
- &(1 * 2)
-}
-
-fn cast_ref_to_raw_ptr(abc: &u8) -> *const u8 {
- abc as *const u8
-}
-
-fn cmp_raw_ptr(a: *const u8, b: *const u8) -> bool {
- a == b
-}
-
-/*fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) {
- (
- a as u8, a as u16, a as u32, a as usize, a as i8, a as i16, a as i32, a as isize, b as u8,
- b as u32,
- )
-}*/
-
-fn char_cast(c: char) -> u8 {
- c as u8
-}
-
-struct DebugTuple(());
-
-fn debug_tuple() -> DebugTuple {
- DebugTuple(())
-}
-
-fn size_of<T>() -> usize {
- unsafe { intrinsics::size_of::<T>() }
-}
-
-fn use_size_of() -> usize {
- size_of::<u64>()
-}
-
-/*unsafe fn use_copy_intrinsic(src: *const u8, dst: *mut u8) {
- intrinsics::copy::<u8>(src, dst, 1);
-}*/
-
-/*unsafe fn use_copy_intrinsic_ref(src: *const u8, dst: *mut u8) {
- let copy2 = ©::<u8>;
- copy2(src, dst, 1);
-}*/
-
-const Abc: u8 = 6 * 7;
-
-fn use_const() -> u8 {
- Abc
-}
-
-fn call_closure_3arg() {
- (|_, _, _| {})(0u8, 42u16, 0u8)
-}
-
-fn call_closure_2arg() {
- (|_, _| {})(0u8, 42u16)
-}
-
-struct IsNotEmpty;
-
-impl<'a, 'b> FnOnce<(&'a &'b [u16],)> for IsNotEmpty {
- type Output = bool;
-
- #[inline]
- extern "rust-call" fn call_once(mut self, arg: (&'a &'b [u16],)) -> bool {
- self.call_mut(arg)
- }
-}
-
-impl<'a, 'b> FnMut<(&'a &'b [u16],)> for IsNotEmpty {
- #[inline]
- extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b [u16],)) -> bool {
- true
- }
-}
-
-fn eq_char(a: char, b: char) -> bool {
- a == b
-}
-
-unsafe fn transmute(c: char) -> u32 {
- intrinsics::transmute(c)
-}
-
-unsafe fn call_uninit() -> u8 {
- intrinsics::uninit()
-}
-
-// TODO: enable when fat pointers are supported
-unsafe fn deref_str_ptr(s: *const str) -> &'static str {
- &*s
-}
-
-fn use_array(arr: [u8; 3]) -> u8 {
- arr[1]
-}
-
-fn repeat_array() -> [u8; 3] {
- [0; 3]
-}
-
-fn array_as_slice(arr: &[u8; 3]) -> &[u8] {
- arr
-}
-
-/*unsafe fn use_ctlz_nonzero(a: u16) -> u16 {
- intrinsics::ctlz_nonzero(a)
-}*/
-
-fn ptr_as_usize(ptr: *const u8) -> usize {
- ptr as usize
-}
-
-fn float_cast(a: f32, b: f64) -> (f64, f32) {
- (a as f64, b as f32)
-}
-
-/*fn int_to_float(a: u8, b: i32) -> (f64, f32) {
- (a as f64, b as f32)
-}*/
-
-fn make_array() -> [u8; 3] {
- [42, 0, 5]
-}
-
-fn some_promoted_tuple() -> &'static (&'static str, &'static str) {
- &("abc", "some")
-}
-
-fn index_slice(s: &[u8]) -> u8 {
- s[2]
-}
-
-pub struct StrWrapper {
- s: str,
-}
-
-fn str_wrapper_get(w: &StrWrapper) -> &str {
- &w.s
-}
+++ /dev/null
-#![feature(no_core, lang_items, intrinsics, unboxed_closures)]
-#![no_core]
-#![allow(dead_code)]
-
-#[lang = "sized"]
-pub trait Sized {}
-
-#[lang = "unsize"]
-pub trait Unsize<T: ?Sized> {}
-
-#[lang = "coerce_unsized"]
-pub trait CoerceUnsized<T> {}
-
-impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
-
-#[lang = "copy"]
-pub unsafe trait Copy {}
-
-unsafe impl Copy for bool {}
-unsafe impl Copy for u8 {}
-unsafe impl Copy for u16 {}
-unsafe impl Copy for u32 {}
-unsafe impl Copy for u64 {}
-unsafe impl Copy for usize {}
-unsafe impl Copy for i8 {}
-unsafe impl Copy for i16 {}
-unsafe impl Copy for i32 {}
-unsafe impl Copy for isize {}
-unsafe impl Copy for char {}
-unsafe impl<'a, T: ?Sized> Copy for &'a T {}
-unsafe impl<T: ?Sized> Copy for *const T {}
-
-#[lang = "sync"]
-pub unsafe trait Sync {}
-
-unsafe impl Sync for bool {}
-unsafe impl Sync for u8 {}
-unsafe impl Sync for u16 {}
-unsafe impl Sync for u32 {}
-unsafe impl Sync for u64 {}
-unsafe impl Sync for usize {}
-unsafe impl Sync for i8 {}
-unsafe impl Sync for i16 {}
-unsafe impl Sync for i32 {}
-unsafe impl Sync for isize {}
-unsafe impl Sync for char {}
-unsafe impl<'a, T: ?Sized> Sync for &'a T {}
-unsafe impl Sync for [u8; 16] {}
-
-#[lang = "freeze"]
-trait Freeze {}
-
-#[lang = "not"]
-pub trait Not {
- type Output;
-
- fn not(self) -> Self::Output;
-}
-
-impl Not for bool {
- type Output = bool;
-
- fn not(self) -> bool {
- !self
- }
-}
-
-#[lang = "mul"]
-pub trait Mul<RHS = Self> {
- type Output;
-
- #[must_use]
- fn mul(self, rhs: RHS) -> Self::Output;
-}
-
-impl Mul for u8 {
- type Output = Self;
-
- fn mul(self, rhs: Self) -> Self::Output {
- self * rhs
- }
-}
-
-#[lang = "add"]
-pub trait Add<RHS = Self> {
- type Output;
-
- fn add(self, rhs: RHS) -> Self::Output;
-}
-
-impl Add for u8 {
- type Output = Self;
-
- fn add(self, rhs: Self) -> Self {
- self + rhs
- }
-}
-
-#[lang = "sub"]
-pub trait Sub<RHS = Self> {
- type Output;
-
- fn sub(self, rhs: RHS) -> Self::Output;
-}
-
-impl Sub for usize {
- type Output = Self;
-
- fn sub(self, rhs: Self) -> Self {
- self - rhs
- }
-}
-
-#[lang = "bitor"]
-pub trait BitOr<RHS = Self> {
- type Output;
-
- #[must_use]
- fn bitor(self, rhs: RHS) -> Self::Output;
-}
-
-impl BitOr for bool {
- type Output = bool;
-
- fn bitor(self, rhs: bool) -> bool {
- self | rhs
- }
-}
-
-impl<'a> BitOr<bool> for &'a bool {
- type Output = bool;
-
- fn bitor(self, rhs: bool) -> bool {
- *self | rhs
- }
-}
-
-#[lang = "eq"]
-pub trait PartialEq<Rhs: ?Sized = Self> {
- fn eq(&self, other: &Rhs) -> bool;
- fn ne(&self, other: &Rhs) -> bool;
-}
-
-impl PartialEq for u8 {
- fn eq(&self, other: &u8) -> bool {
- (*self) == (*other)
- }
- fn ne(&self, other: &u8) -> bool {
- (*self) != (*other)
- }
-}
-
-impl PartialEq for char {
- fn eq(&self, other: &char) -> bool {
- (*self) == (*other)
- }
- fn ne(&self, other: &char) -> bool {
- (*self) != (*other)
- }
-}
-
-impl<T: ?Sized> PartialEq for *const T {
- fn eq(&self, other: &*const T) -> bool {
- *self == *other
- }
- fn ne(&self, other: &*const T) -> bool {
- *self != *other
- }
-}
-
-pub enum Option<T> {
- Some(T),
- None,
-}
-
-pub use Option::*;
-
-#[lang = "phantom_data"]
-pub struct PhantomData<T: ?Sized>;
-
-#[lang = "fn_once"]
-#[rustc_paren_sugar]
-pub trait FnOnce<Args> {
- type Output;
-
- extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-}
-
-#[lang = "fn_mut"]
-#[rustc_paren_sugar]
-pub trait FnMut<Args>: FnOnce<Args> {
- extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
-}
-
-#[lang = "panic"]
-pub fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
- unsafe {
- intrinsics::abort();
- }
-}
-
-#[lang = "eh_personality"]
-fn eh_personality() -> ! {
- loop {}
-}
-
-#[lang = "drop_in_place"]
-#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
- // Code here does not matter - this is replaced by the
- // real drop glue by the compiler.
- drop_in_place(to_drop);
-}
-
-#[lang = "owned_box"]
-pub struct Box<T: ?Sized>(*mut T);
-
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
-
-static mut MY_TINY_HEAP: [u8; 16] = [0; 16];
-
-#[lang = "exchange_malloc"]
-unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
- &mut MY_TINY_HEAP as *mut [u8; 16] as *mut u8
-}
-
-#[lang = "drop"]
-pub trait Drop {
- fn drop(&mut self);
-}
-
-pub mod intrinsics {
- extern "rust-intrinsic" {
- pub fn abort() -> !;
- pub fn size_of<T>() -> usize;
- pub fn size_of_val<T: ?::Sized>(val: &T) -> usize;
- pub fn min_align_of<T>() -> usize;
- pub fn min_align_of_val<T: ?::Sized>(val: &T) -> usize;
- pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
- pub fn transmute<T, U>(e: T) -> U;
- pub fn uninit<T>() -> T;
- pub fn ctlz_nonzero<T>(x: T) -> T;
- pub fn needs_drop<T>() -> bool;
- }
-}
-
-#[lang = "index"]
-pub trait Index<Idx: ?Sized> {
- type Output: ?Sized;
- fn index(&self, index: Idx) -> &Self::Output;
-}
-
-impl<T> Index<usize> for [T; 3] {
- type Output = T;
-
- fn index(&self, index: usize) -> &Self::Output {
- &self[index]
- }
-}
-
-impl<T> Index<usize> for [T] {
- type Output = T;
-
- fn index(&self, index: usize) -> &Self::Output {
- &self[index]
- }
-}
+++ /dev/null
-// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
-
-#![feature(no_core, unboxed_closures, start, lang_items, box_syntax)]
-#![no_core]
-#![allow(dead_code)]
-
-extern crate mini_core;
-
-use mini_core::*;
-
-#[link(name = "c")]
-extern "C" {
- fn puts(s: *const u8);
-}
-
-unsafe extern "C" fn my_puts(s: *const u8) {
- puts(s);
-}
-
-// TODO remove when jit supports linking rlibs
-#[cfg(jit)]
-extern "C" fn panic<T>(_: T) -> ! {
- unsafe {
- intrinsics::abort();
- }
-}
-
-#[lang = "termination"]
-trait Termination {
- fn report(self) -> i32;
-}
-
-impl Termination for () {
- fn report(self) -> i32 {
- unsafe {
- NUM = 6 * 7 + 1 + (1u8 == 1u8) as u8; // 44
- *NUM_REF as i32
- }
- }
-}
-
-trait SomeTrait {
- fn object_safe(&self);
-}
-
-impl SomeTrait for &'static str {
- fn object_safe(&self) {
- unsafe {
- puts(*self as *const str as *const u8);
- }
- }
-}
-
-struct NoisyDrop {
- text: &'static str,
- inner: NoisyDropInner,
-}
-
-struct NoisyDropInner;
-
-impl Drop for NoisyDrop {
- fn drop(&mut self) {
- unsafe {
- puts(self.text as *const str as *const u8);
- }
- }
-}
-
-impl Drop for NoisyDropInner {
- fn drop(&mut self) {
- unsafe {
- puts("Inner got dropped!\0" as *const str as *const u8);
- }
- }
-}
-
-#[lang = "start"]
-fn start<T: Termination + 'static>(
- main: fn() -> T,
- _argc: isize,
- _argv: *const *const u8,
-) -> isize {
- main().report() as isize
-}
-
-static mut NUM: u8 = 6 * 7;
-static NUM_REF: &'static u8 = unsafe { &NUM };
-
-macro_rules! assert {
- ($e:expr) => {
- if !$e {
- panic(&(stringify!(! $e), file!(), line!(), 0));
- }
- };
-}
-
-macro_rules! assert_eq {
- ($l:expr, $r: expr) => {
- if $l != $r {
- panic(&(stringify!($l != $r), file!(), line!(), 0));
- }
- }
-}
-
-struct Unique<T: ?Sized> {
- pointer: *const T,
- _marker: PhantomData<T>,
-}
-
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
-
-fn main() {
- unsafe {
- let hello: &[u8] = b"Hello\0" as &[u8; 6];
- let ptr: *const u8 = hello as *const [u8] as *const u8;
- puts(ptr);
-
- // TODO remove when jit supports linking rlibs
- #[cfg(not(jit))]
- {
- let world: Box<&str> = box "World!\0";
- puts(*world as *const str as *const u8);
- world as Box<SomeTrait>;
- }
-
- assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
-
- let chars = &['C', 'h', 'a', 'r', 's'];
- let chars = chars as &[char];
- assert_eq!(intrinsics::size_of_val(chars) as u8, 4 * 5);
-
- let a: &dyn SomeTrait = &"abc\0";
- a.object_safe();
-
- assert_eq!(intrinsics::size_of_val(a) as u8, 16);
- assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
-
- assert_eq!(intrinsics::min_align_of::<u16>() as u8, 2);
- assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8);
-
- assert!(!intrinsics::needs_drop::<u8>());
- assert!(intrinsics::needs_drop::<NoisyDrop>());
-
- Unique {
- pointer: 0 as *const &str,
- _marker: PhantomData,
- } as Unique<dyn SomeTrait>;
- }
-
- let _ = NoisyDrop {
- text: "Outer got dropped!\0",
- inner: NoisyDropInner,
- };
-
- const FUNC_REF: Option<fn()> = Some(main);
- match FUNC_REF {
- Some(_) => {},
- None => assert!(false),
- }
-}