...(they still don't work).
> items.
~~~~
-# use std::float;
-# use std::num::atan;
+use std::float;
+use std::num::atan;
fn angle(vector: (float, float)) -> float {
let pi = float::consts::pi;
match vector {
`loop` denotes an infinite loop, and is the preferred way of writing `while true`:
~~~~
-# use std::int;
+use std::int;
let mut x = 5;
loop {
x += x - 3;
patterns, as in this definition of `area`:
~~~~
-# use std::float;
+use std::float;
# struct Point {x: float, y: float}
# enum Shape { Circle(Point, float), Rectangle(Point, Point) }
fn area(sh: Shape) -> float {
Enum variants may also be structs. For example:
~~~~
-# use std::float;
+use std::float;
# struct Point { x: float, y: float }
# fn square(x: float) -> float { x * x }
enum Shape {
may be omitted from `do` expressions.
~~~~
-# use std::task::spawn;
+use std::task::spawn;
+
do spawn {
debug!("Kablam!");
}
To call such a method, just prefix it with the type name and a double colon:
~~~~
-# use std::float::consts::pi;
+use std::float::consts::pi;
struct Circle { radius: float }
impl Circle {
fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }
Generic `type`, `struct`, and `enum` declarations follow the same pattern:
~~~~
-# use std::hashmap::HashMap;
+use std::hashmap::HashMap;
type Set<T> = HashMap<T, ()>;
struct Stack<T> {
implementation to use.
~~~~
-# use std::float::consts::pi;
+use std::float::consts::pi;
trait Shape { fn new(area: float) -> Self; }
struct Circle { radius: float }
struct Square { length: float }
Now, we can implement `Circle` on a type only if we also implement `Shape`.
~~~~
-# use std::float::consts::pi;
+use std::float::consts::pi;
# trait Shape { fn area(&self) -> float; }
# trait Circle : Shape { fn radius(&self) -> float; }
# struct Point { x: float, y: float }
Likewise, supertrait methods may also be called on trait objects.
~~~ {.xfail-test}
-# use std::float::consts::pi;
+use std::float::consts::pi;
# trait Shape { fn area(&self) -> float; }
# trait Circle : Shape { fn radius(&self) -> float; }
# struct Point { x: float, y: float }
~/.emacs.d/elpa/).
* or using <kbd>M-x package-install rust-mode
+
+### Known bugs
+
+* Combining `global-whitespace-mode` and `rust-mode` is generally glitchy.
+ See [Issue #3994](https://github.com/mozilla/rust/issues/3994).
// the reverse direction.
use std::cast;
-use std::cmp;
use std::ptr;
use std::util;
use std::iterator::{FromIterator, InvertIterator};
}
}
+impl<T> Node<T> {
+ fn new(v: T) -> Node<T> {
+ Node{value: v, next: None, prev: Rawlink::none()}
+ }
+}
+
/// Set the .prev field on `next`, then return `Some(next)`
fn link_with_prev<T>(mut next: ~Node<T>, prev: Rawlink<Node<T>>) -> Link<T> {
next.prev = prev;
}
}
+// private methods
+impl<T> DList<T> {
+ /// Add a Node first in the list
+ #[inline]
+ fn push_front_node(&mut self, mut new_head: ~Node<T>) {
+ match self.list_head {
+ None => {
+ self.list_tail = Rawlink::some(new_head);
+ self.list_head = link_with_prev(new_head, Rawlink::none());
+ }
+ Some(ref mut head) => {
+ new_head.prev = Rawlink::none();
+ head.prev = Rawlink::some(new_head);
+ util::swap(head, &mut new_head);
+ head.next = Some(new_head);
+ }
+ }
+ self.length += 1;
+ }
+
+ /// Remove the first Node and return it, or None if the list is empty
+ #[inline]
+ fn pop_front_node(&mut self) -> Option<~Node<T>> {
+ do self.list_head.take().map_consume |mut front_node| {
+ self.length -= 1;
+ match front_node.next.take() {
+ Some(node) => self.list_head = link_with_prev(node, Rawlink::none()),
+ None => self.list_tail = Rawlink::none()
+ }
+ front_node
+ }
+ }
+
+ /// Add a Node last in the list
+ #[inline]
+ fn push_back_node(&mut self, mut new_tail: ~Node<T>) {
+ match self.list_tail.resolve() {
+ None => return self.push_front_node(new_tail),
+ Some(tail) => {
+ self.list_tail = Rawlink::some(new_tail);
+ tail.next = link_with_prev(new_tail, Rawlink::some(tail));
+ }
+ }
+ self.length += 1;
+ }
+
+ /// Remove the last Node and return it, or None if the list is empty
+ #[inline]
+ fn pop_back_node(&mut self) -> Option<~Node<T>> {
+ do self.list_tail.resolve().map_consume_default(None) |tail| {
+ self.length -= 1;
+ self.list_tail = tail.prev;
+ match tail.prev.resolve() {
+ None => self.list_head.take(),
+ Some(tail_prev) => tail_prev.next.take()
+ }
+ }
+ }
+}
+
impl<T> Deque<T> for DList<T> {
/// Provide a reference to the front element, or None if the list is empty
#[inline]
self.list_tail.resolve().map_mut(|tail| &mut tail.value)
}
- /// Add an element last in the list
+ /// Add an element first in the list
///
/// O(1)
- fn push_back(&mut self, elt: T) {
- match self.list_tail.resolve() {
- None => return self.push_front(elt),
- Some(tail) => {
- let mut new_tail = ~Node{value: elt, next: None, prev: self.list_tail};
- self.list_tail = Rawlink::some(new_tail);
- tail.next = Some(new_tail);
- }
- }
- self.length += 1;
+ fn push_front(&mut self, elt: T) {
+ self.push_front_node(~Node::new(elt))
}
- /// Remove the last element and return it, or None if the list is empty
+ /// Remove the first element and return it, or None if the list is empty
///
/// O(1)
- fn pop_back(&mut self) -> Option<T> {
- match self.list_tail.resolve() {
- None => None,
- Some(tail) => {
- self.length -= 1;
- let tail_own = match tail.prev.resolve() {
- None => {
- self.list_tail = Rawlink::none();
- self.list_head.take_unwrap()
- },
- Some(tail_prev) => {
- self.list_tail = tail.prev;
- tail_prev.next.take_unwrap()
- }
- };
- Some(tail_own.value)
- }
- }
+ fn pop_front(&mut self) -> Option<T> {
+ self.pop_front_node().map_consume(|~Node{value, _}| value)
}
- /// Add an element first in the list
+ /// Add an element last in the list
///
/// O(1)
- fn push_front(&mut self, elt: T) {
- let mut new_head = ~Node{value: elt, next: None, prev: Rawlink::none()};
- match self.list_head {
- None => {
- self.list_tail = Rawlink::some(new_head);
- self.list_head = Some(new_head);
- }
- Some(ref mut head) => {
- head.prev = Rawlink::some(new_head);
- util::swap(head, &mut new_head);
- head.next = Some(new_head);
- }
- }
- self.length += 1;
+ fn push_back(&mut self, elt: T) {
+ self.push_back_node(~Node::new(elt))
}
- /// Remove the first element and return it, or None if the list is empty
+ /// Remove the last element and return it, or None if the list is empty
///
/// O(1)
- fn pop_front(&mut self) -> Option<T> {
- match self.list_head.take() {
- None => None,
- Some(old_head) => {
- self.length -= 1;
- match *old_head {
- Node{value: value, next: Some(next), prev: _} => {
- self.list_head = link_with_prev(next, Rawlink::none());
- Some(value)
- }
- Node{value: value, next: None, prev: _} => {
- self.list_tail = Rawlink::none();
- Some(value)
- }
- }
- }
- }
+ fn pop_back(&mut self) -> Option<T> {
+ self.pop_back_node().map_consume(|~Node{value, _}| value)
}
}
DList{list_head: None, list_tail: Rawlink::none(), length: 0}
}
+ /// Move the last element to the front of the list.
+ ///
+ /// If the list is empty, do nothing.
+ #[inline]
+ pub fn rotate_forward(&mut self) {
+ do self.pop_back_node().map_consume |tail| {
+ self.push_front_node(tail)
+ };
+ }
+
+ /// Move the first element to the back of the list.
+ ///
+ /// If the list is empty, do nothing.
+ #[inline]
+ pub fn rotate_backward(&mut self) {
+ do self.pop_front_node().map_consume |head| {
+ self.push_back_node(head)
+ };
+ }
+
/// Add all elements from `other` to the end of the list
///
/// O(1)
None => *self = other,
Some(tail) => {
match other {
- DList{list_head: None, list_tail: _, length: _} => return,
+ DList{list_head: None, _} => return,
DList{list_head: Some(node), list_tail: o_tail, length: o_length} => {
tail.next = link_with_prev(node, self.list_tail);
self.list_tail = o_tail;
if take_a {
it.next();
} else {
- it.insert_next(other.pop_front().unwrap());
+ it.insert_next_node(other.pop_front_node().unwrap());
}
}
}
}
}
-impl<T: cmp::TotalOrd> DList<T> {
+impl<T: Ord> DList<T> {
/// Insert `elt` sorted in ascending order
///
/// O(N)
#[inline]
pub fn insert_ordered(&mut self, elt: T) {
- self.insert_when(elt, |a, b| a.cmp(b) != cmp::Less);
+ self.insert_when(elt, |a, b| a >= b)
}
}
if self.nelem == 0 {
return None;
}
- match *self.head {
- None => None,
- Some(ref head) => {
- self.nelem -= 1;
- self.head = &head.next;
- Some(&head.value)
- }
+ do self.head.map |head| {
+ self.nelem -= 1;
+ self.head = &head.next;
+ &head.value
}
}
if self.nelem == 0 {
return None;
}
- match self.tail.resolve() {
- None => None,
- Some(prev) => {
- self.nelem -= 1;
- self.tail = prev.prev;
- Some(&prev.value)
- }
+ do self.tail.resolve().map_consume |prev| {
+ self.nelem -= 1;
+ self.tail = prev.prev;
+ &prev.value
}
}
}
if self.nelem == 0 {
return None;
}
- match self.head.resolve() {
- None => None,
- Some(next) => {
- self.nelem -= 1;
- self.head = match next.next {
- Some(ref mut node) => Rawlink::some(&mut **node),
- None => Rawlink::none(),
- };
- Some(&mut next.value)
- }
+ do self.head.resolve().map_consume |next| {
+ self.nelem -= 1;
+ self.head = match next.next {
+ Some(ref mut node) => Rawlink::some(&mut **node),
+ None => Rawlink::none(),
+ };
+ &mut next.value
}
}
if self.nelem == 0 {
return None;
}
- match self.tail.resolve() {
- None => None,
- Some(prev) => {
- self.nelem -= 1;
- self.tail = prev.prev;
- Some(&mut prev.value)
- }
+ do self.tail.resolve().map_consume |prev| {
+ self.nelem -= 1;
+ self.tail = prev.prev;
+ &mut prev.value
}
}
}
/// Allow mutating the DList while iterating
pub trait ListInsertion<A> {
- /// Insert `elt` just after to the most recently yielded element
+ /// Insert `elt` just after to the element most recently returned by `.next()`
+ ///
+ /// The inserted element does not appear in the iteration.
fn insert_next(&mut self, elt: A);
/// Provide a reference to the next element, without changing the iterator
fn peek_next<'a>(&'a mut self) -> Option<&'a mut A>;
}
-impl<'self, A> ListInsertion<A> for MutDListIterator<'self, A> {
- fn insert_next(&mut self, elt: A) {
- // Insert an element before `self.head` so that it is between the
+// private methods for MutDListIterator
+impl<'self, A> MutDListIterator<'self, A> {
+ fn insert_next_node(&mut self, mut ins_node: ~Node<A>) {
+ // Insert before `self.head` so that it is between the
// previously yielded element and self.head.
+ //
+ // The inserted node will not appear in further iteration.
match self.head.resolve() {
- None => { self.list.push_back(elt); }
+ None => { self.list.push_back_node(ins_node); }
Some(node) => {
let prev_node = match node.prev.resolve() {
- None => return self.list.push_front(elt),
+ None => return self.list.push_front_node(ins_node),
Some(prev) => prev,
};
- let mut ins_node = ~Node{value: elt, next: None, prev: Rawlink::none()};
let node_own = prev_node.next.take_unwrap();
ins_node.next = link_with_prev(node_own, Rawlink::some(ins_node));
prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node));
}
}
}
+}
+
+impl<'self, A> ListInsertion<A> for MutDListIterator<'self, A> {
+ #[inline]
+ fn insert_next(&mut self, elt: A) {
+ self.insert_next_node(~Node::new(elt))
+ }
#[inline]
fn peek_next<'a>(&'a mut self) -> Option<&'a mut A> {
- match self.head.resolve() {
- None => None,
- Some(head) => Some(&mut head.value),
+ if self.nelem == 0 {
+ return None
}
+ self.head.resolve().map_consume(|head| &mut head.value)
}
}
}
}
+ #[test]
+ fn test_rotate() {
+ let mut n = DList::new::<int>();
+ n.rotate_backward(); check_links(&n);
+ assert_eq!(n.len(), 0);
+ n.rotate_forward(); check_links(&n);
+ assert_eq!(n.len(), 0);
+
+ let v = ~[1,2,3,4,5];
+ let mut m = list_from(v);
+ m.rotate_backward(); check_links(&m);
+ m.rotate_forward(); check_links(&m);
+ assert_eq!(v.iter().collect::<~[&int]>(), m.iter().collect());
+ m.rotate_forward(); check_links(&m);
+ m.rotate_forward(); check_links(&m);
+ m.pop_front(); check_links(&m);
+ m.rotate_forward(); check_links(&m);
+ m.rotate_backward(); check_links(&m);
+ m.push_front(9); check_links(&m);
+ m.rotate_forward(); check_links(&m);
+ assert_eq!(~[3,9,5,1,2], m.consume_iter().collect());
+ }
+
#[test]
fn test_iterator() {
let m = generate_test();
let _: DList<int> = v.iter().transform(|x| *x).collect();
}
}
- #[bench]
- fn bench_collect_into_vec(b: &mut test::BenchHarness) {
- let v = &[0, ..64];
- do b.iter {
- let _: ~[int] = v.iter().transform(|&x|x).collect();
- }
- }
#[bench]
fn bench_push_front(b: &mut test::BenchHarness) {
m.push_front(0);
}
}
+
#[bench]
- fn bench_push_front_vec_size10(b: &mut test::BenchHarness) {
- let mut m = ~[0, ..10];
+ fn bench_push_back(b: &mut test::BenchHarness) {
+ let mut m = DList::new::<int>();
do b.iter {
- m.unshift(0);
- m.pop(); // to keep it fair, dont' grow the vec
+ m.push_back(0);
}
}
#[bench]
- fn bench_push_back(b: &mut test::BenchHarness) {
+ fn bench_push_back_pop_back(b: &mut test::BenchHarness) {
let mut m = DList::new::<int>();
do b.iter {
m.push_back(0);
+ m.pop_back();
}
}
+
#[bench]
- fn bench_push_back_vec(b: &mut test::BenchHarness) {
- let mut m = ~[];
+ fn bench_push_front_pop_front(b: &mut test::BenchHarness) {
+ let mut m = DList::new::<int>();
do b.iter {
- m.push(0);
+ m.push_front(0);
+ m.pop_front();
}
}
#[bench]
- fn bench_push_back_pop_back(b: &mut test::BenchHarness) {
+ fn bench_rotate_forward(b: &mut test::BenchHarness) {
let mut m = DList::new::<int>();
+ m.push_front(0);
+ m.push_front(1);
do b.iter {
- m.push_back(0);
- m.pop_back();
+ m.rotate_forward();
}
}
+
#[bench]
- fn bench_push_back_pop_back_vec(b: &mut test::BenchHarness) {
- let mut m = ~[];
+ fn bench_rotate_backward(b: &mut test::BenchHarness) {
+ let mut m = DList::new::<int>();
+ m.push_front(0);
+ m.push_front(1);
do b.iter {
- m.push(0);
- m.pop();
+ m.rotate_backward();
}
}
assert!(m.mut_rev_iter().len_() == 128);
}
}
- #[bench]
- fn bench_iter_vec(b: &mut test::BenchHarness) {
- let v = &[0, ..128];
- do b.iter {
- for v.iter().advance |_| {}
- }
- }
}
}
pub type List = ~[Json];
-pub type Object = HashMap<~str, Json>;
+pub type Object = TreeMap<~str, Json>;
#[deriving(Eq)]
/// If an error occurs while parsing some JSON, this is the structure which is
self.bump();
self.parse_whitespace();
- let mut values = ~HashMap::new();
+ let mut values = ~TreeMap::new();
if self.ch == '}' {
self.bump();
let len = match self.stack.pop() {
Object(obj) => {
let len = obj.len();
- for obj.consume().advance |(key, value)| {
+ for obj.consume_iter().advance |(key, value)| {
self.stack.push(value);
self.stack.push(String(key));
}
fn to_json(&self) -> Json { List(self.map(|elt| elt.to_json())) }
}
-impl<A:ToJson> ToJson for HashMap<~str, A> {
+impl<A:ToJson> ToJson for TreeMap<~str, A> {
fn to_json(&self) -> Json {
- let mut d = HashMap::new();
+ let mut d = TreeMap::new();
for self.iter().advance |(key, value)| {
d.insert((*key).clone(), value.to_json());
}
}
}
-impl<A:ToJson> ToJson for TreeMap<~str, A> {
+impl<A:ToJson> ToJson for HashMap<~str, A> {
fn to_json(&self) -> Json {
- let mut d = HashMap::new();
+ let mut d = TreeMap::new();
for self.iter().advance |(key, value)| {
d.insert((*key).clone(), value.to_json());
}
use super::*;
- use std::hashmap::HashMap;
use std::io;
use std::result;
- use extra::serialize::Decodable;
+ use serialize::Decodable;
+ use treemap::TreeMap;
#[deriving(Eq, Encodable, Decodable)]
enum Animal {
}
fn mk_object(items: &[(~str, Json)]) -> Json {
- let mut d = ~HashMap::new();
+ let mut d = ~TreeMap::new();
for items.iter().advance |item| {
match *item {
fn test_decode_map() {
let s = ~"{\"a\": \"Dog\", \"b\": [\"Frog\", \"Henry\", 349]}";
let mut decoder = Decoder(from_str(s).unwrap());
- let mut map: HashMap<~str, Animal> = Decodable::decode(&mut decoder);
+ let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder);
assert_eq!(map.pop(&~"a"), Some(Dog));
assert_eq!(map.pop(&~"b"), Some(Frog(~"Henry", 349)));
}
}
+impl<
+ S: Encoder,
+ T: Encodable<S>
+> Encodable<S> for DList<T> {
+ fn encode(&self, s: &mut S) {
+ do s.emit_seq(self.len()) |s| {
+ for self.iter().enumerate().advance |(i, e)| {
+ s.emit_seq_elt(i, |s| e.encode(s));
+ }
+ }
+ }
+}
+
impl<D:Decoder,T:Decodable<D>> Decodable<D> for DList<T> {
fn decode(d: &mut D) -> DList<T> {
let mut list = DList::new();
#[allow(missing_doc)];
-
-use std::cmp;
use std::iterator::{Iterator, IteratorUtil, EnumerateIterator, FilterMapIterator, InvertIterator};
use std::uint;
use std::util::replace;
pub type SmallIntMapMutRevIterator<'self, T> = InvertIterator<(uint, &'self mut T),
SmallIntMapMutIterator<'self, T>>;
-
-/// A set implemented on top of the SmallIntMap type. This set is always a set
-/// of integers, and the space requirements are on the order of the highest
-/// valued integer in the set.
-pub struct SmallIntSet {
- priv map: SmallIntMap<()>
-}
-
-impl Container for SmallIntSet {
- /// Return the number of elements in the map
- fn len(&self) -> uint {
- self.map.len()
- }
-
- /// Return true if the map contains no elements
- fn is_empty(&self) -> bool { self.len() == 0 }
-}
-
-impl Mutable for SmallIntSet {
- /// Clear the map, removing all key-value pairs.
- fn clear(&mut self) { self.map.clear() }
-}
-
-impl Set<uint> for SmallIntSet {
- /// Return true if the set contains a value
- fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) }
-
- /// Return true if the set has no elements in common with `other`.
- /// This is equivalent to checking for an empty uintersection.
- fn is_disjoint(&self, other: &SmallIntSet) -> bool {
- for self.each |v| { if other.contains(v) { return false } }
- true
- }
-
- /// Return true if the set is a subset of another
- fn is_subset(&self, other: &SmallIntSet) -> bool {
- for self.each |v| { if !other.contains(v) { return false } }
- true
- }
-
- /// Return true if the set is a superset of another
- fn is_superset(&self, other: &SmallIntSet) -> bool {
- other.is_subset(self)
- }
-
- /// Visit the values representing the difference
- fn difference(&self, other: &SmallIntSet, f: &fn(&uint) -> bool) -> bool {
- self.each(|v| other.contains(v) || f(v))
- }
-
- /// Visit the values representing the symmetric difference
- fn symmetric_difference(&self,
- other: &SmallIntSet,
- f: &fn(&uint) -> bool) -> bool {
- let len = cmp::max(self.map.v.len() ,other.map.v.len());
-
- for uint::range(0, len) |i| {
- if self.contains(&i) ^ other.contains(&i) {
- if !f(&i) { return false; }
- }
- }
- return true;
- }
-
- /// Visit the values representing the uintersection
- fn intersection(&self, other: &SmallIntSet, f: &fn(&uint) -> bool) -> bool {
- self.each(|v| !other.contains(v) || f(v))
- }
-
- /// Visit the values representing the union
- fn union(&self, other: &SmallIntSet, f: &fn(&uint) -> bool) -> bool {
- let len = cmp::max(self.map.v.len() ,other.map.v.len());
-
- for uint::range(0, len) |i| {
- if self.contains(&i) || other.contains(&i) {
- if !f(&i) { return false; }
- }
- }
- return true;
- }
-}
-
-impl MutableSet<uint> for SmallIntSet {
- /// Add a value to the set. Return true if the value was not already
- /// present in the set.
- fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }
-
- /// Remove a value from the set. Return true if the value was
- /// present in the set.
- fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }
-}
-
-impl SmallIntSet {
- /// Create an empty SmallIntSet
- pub fn new() -> SmallIntSet { SmallIntSet{map: SmallIntMap::new()} }
-
- /// Visit all values in order
- pub fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) }
-
- /// An iterator visiting all set members in ascending order.
- /// Iterator element type is uint
- pub fn iter<'r>(&'r self) -> SmallIntSetIterator<'r> {
- SmallIntSetIterator {
- iter: self.map.iter()
- }
- }
-
- /// An iterator visiting all set members in descending order.
- /// Iterator element type is uint
- pub fn rev_iter<'r>(&'r mut self) -> SmallIntSetRevIterator<'r> {
- self.iter().invert()
- }
-
-}
-
-pub struct SmallIntSetIterator<'self> {
- priv iter: SmallIntMapIterator<'self, ()>
-}
-
-impl<'self> Iterator<uint> for SmallIntSetIterator<'self> {
- #[inline]
- fn next(&mut self) -> Option<uint> {
- let next_opt = self.iter.next();
- match next_opt {
- None => { None }
- Some((idx, _)) => { Some(idx) }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.iter.size_hint()
- }
-}
-
-impl<'self> DoubleEndedIterator<uint> for SmallIntSetIterator<'self> {
- #[inline]
- fn next_back(&mut self) -> Option<uint> {
- let next_opt = self.iter.next_back();
- match next_opt {
- None => { None }
- Some((idx, _)) => { Some(idx) }
- }
- }
-}
-
-pub type SmallIntSetRevIterator<'self> = InvertIterator<uint, SmallIntSetIterator<'self>>;
-
-
#[cfg(test)]
mod test_map {
find_seq_n(10_000, &mut m, bh);
}
}
-
-#[cfg(test)]
-mod test_set {
-
- use super::SmallIntSet;
-
- #[test]
- fn test_disjoint() {
- let mut xs = SmallIntSet::new();
- let mut ys = SmallIntSet::new();
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(5));
- assert!(ys.insert(11));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(7));
- assert!(xs.insert(19));
- assert!(xs.insert(4));
- assert!(ys.insert(2));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(ys.insert(7));
- assert!(!xs.is_disjoint(&ys));
- assert!(!ys.is_disjoint(&xs));
- }
-
- #[test]
- fn test_subset_and_superset() {
- let mut a = SmallIntSet::new();
- assert!(a.insert(0));
- assert!(a.insert(5));
- assert!(a.insert(11));
- assert!(a.insert(7));
-
- let mut b = SmallIntSet::new();
- assert!(b.insert(0));
- assert!(b.insert(7));
- assert!(b.insert(19));
- assert!(b.insert(250));
- assert!(b.insert(11));
- assert!(b.insert(200));
-
- assert!(!a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(!b.is_superset(&a));
-
- assert!(b.insert(5));
-
- assert!(a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(b.is_superset(&a));
- }
-
- #[test]
- fn test_intersection() {
- let mut a = SmallIntSet::new();
- let mut b = SmallIntSet::new();
-
- assert!(a.insert(11));
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(77));
- assert!(a.insert(103));
- assert!(a.insert(5));
-
- assert!(b.insert(2));
- assert!(b.insert(11));
- assert!(b.insert(77));
- assert!(b.insert(5));
- assert!(b.insert(3));
-
- let mut i = 0;
- let expected = [3, 5, 11, 77];
- for a.intersection(&b) |x| {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_difference() {
- let mut a = SmallIntSet::new();
- let mut b = SmallIntSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
-
- assert!(b.insert(3));
- assert!(b.insert(9));
-
- let mut i = 0;
- let expected = [1, 5, 11];
- for a.difference(&b) |x| {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_symmetric_difference() {
- let mut a = SmallIntSet::new();
- let mut b = SmallIntSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
-
- assert!(b.insert(3));
- assert!(b.insert(9));
- assert!(b.insert(14));
- assert!(b.insert(22));
-
- let mut i = 0;
- let expected = [1, 5, 11, 14, 22];
- for a.symmetric_difference(&b) |x| {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_union() {
- let mut a = SmallIntSet::new();
- let mut b = SmallIntSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
- assert!(a.insert(16));
- assert!(a.insert(19));
- assert!(a.insert(24));
-
- assert!(b.insert(1));
- assert!(b.insert(5));
- assert!(b.insert(9));
- assert!(b.insert(13));
- assert!(b.insert(19));
-
- let mut i = 0;
- let expected = [1, 3, 5, 9, 11, 13, 16, 19, 24];
- for a.union(&b) |x| {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_iterator() {
- let mut a = SmallIntSet::new();
-
- assert!(a.insert(0));
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(6));
- assert!(a.insert(10));
-
- let mut it = a.iter();
- assert_eq!(it.size_hint(), (0, Some(11)));
- assert_eq!(it.next().unwrap(), 0);
- assert_eq!(it.size_hint(), (0, Some(10)));
- assert_eq!(it.next().unwrap(), 1);
- assert_eq!(it.size_hint(), (0, Some(9)));
- assert_eq!(it.next().unwrap(), 3);
- assert_eq!(it.size_hint(), (0, Some(7)));
- assert_eq!(it.next().unwrap(), 6);
- assert_eq!(it.size_hint(), (0, Some(4)));
- assert_eq!(it.next().unwrap(), 10);
- assert_eq!(it.size_hint(), (0, Some(0)));
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_iterator_size_hints() {
- let mut a = SmallIntSet::new();
-
- assert!(a.insert(0));
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(6));
- assert!(a.insert(10));
-
- assert_eq!(a.iter().size_hint(), (0, Some(11)));
- assert_eq!(a.rev_iter().size_hint(), (0, Some(11)));
- }
-
- #[test]
- fn test_rev_iterator() {
- let mut a = SmallIntSet::new();
-
- assert!(a.insert(0));
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(6));
- assert!(a.insert(10));
-
- let mut it = a.rev_iter();
- assert_eq!(it.next().unwrap(), 10);
- assert_eq!(it.next().unwrap(), 6);
- assert_eq!(it.next().unwrap(), 3);
- assert_eq!(it.next().unwrap(), 1);
- assert_eq!(it.next().unwrap(), 0);
- assert!(it.next().is_none());
- }
-}
use std::to_str::ToStr;
use std::u64;
use std::f64;
-use std::hashmap::HashMap;
use std::os;
impl ToJson for Metric {
fn to_json(&self) -> json::Json {
- let mut map = ~HashMap::new();
+ let mut map = ~TreeMap::new();
map.insert(~"value", json::Number(self.value as float));
map.insert(~"noise", json::Number(self.noise as float));
json::Object(map)
pub fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> {
TreeMapIterator{stack: ~[], node: &self.root, remaining: self.length}
}
+
+ /// Get a lazy iterator that consumes the treemap.
+ pub fn consume_iter(self) -> TreeMapConsumeIterator<K, V> {
+ let TreeMap { root: root, length: length } = self;
+ let stk = match root {
+ None => ~[],
+ Some(~tn) => ~[tn]
+ };
+ TreeMapConsumeIterator {
+ stack: stk,
+ remaining: length
+ }
+ }
}
/// Lazy forward iterator over a map
}
}
+/// Lazy forward iterator over a map that consumes the map while iterating
+pub struct TreeMapConsumeIterator<K, V> {
+ priv stack: ~[TreeNode<K, V>],
+ priv remaining: uint
+}
+
+impl<K, V> Iterator<(K, V)> for TreeMapConsumeIterator<K,V> {
+ #[inline]
+ fn next(&mut self) -> Option<(K, V)> {
+ while !self.stack.is_empty() {
+ let TreeNode {
+ key: key,
+ value: value,
+ left: left,
+ right: right,
+ level: level
+ } = self.stack.pop();
+
+ match left {
+ Some(~left) => {
+ let n = TreeNode {
+ key: key,
+ value: value,
+ left: None,
+ right: right,
+ level: level
+ };
+ self.stack.push(n);
+ self.stack.push(left);
+ }
+ None => {
+ match right {
+ Some(~right) => self.stack.push(right),
+ None => ()
+ }
+ self.remaining -= 1;
+ return Some((key, value))
+ }
+ }
+ }
+ None
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (self.remaining, Some(self.remaining))
+ }
+
+}
+
impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> {
/// Advance the iterator to the next node (in order). If there are no more nodes, return `None`.
#[inline]
use json;
use sha1::Sha1;
use serialize::{Encoder, Encodable, Decoder, Decodable};
-use sort;
+use arc::{ARC,RWARC};
+use treemap::TreeMap;
use std::cell::Cell;
-use std::cmp;
use std::comm::{PortOne, oneshot, send_one, recv_one};
use std::either::{Either, Left, Right};
-use std::hashmap::HashMap;
use std::io;
use std::result;
use std::run;
use std::task;
-use std::to_bytes;
/**
*
*
*/
-#[deriving(Clone, Eq, Encodable, Decodable)]
+#[deriving(Clone, Eq, Encodable, Decodable, TotalOrd, TotalEq)]
struct WorkKey {
kind: ~str,
name: ~str
}
-impl to_bytes::IterBytes for WorkKey {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
- self.kind.iter_bytes(lsb0, |b| f(b)) && self.name.iter_bytes(lsb0, |b| f(b))
- }
-}
-
-impl cmp::Ord for WorkKey {
- fn lt(&self, other: &WorkKey) -> bool {
- self.kind < other.kind ||
- (self.kind == other.kind &&
- self.name < other.name)
- }
- fn le(&self, other: &WorkKey) -> bool {
- self.lt(other) || self.eq(other)
- }
- fn ge(&self, other: &WorkKey) -> bool {
- self.gt(other) || self.eq(other)
- }
- fn gt(&self, other: &WorkKey) -> bool {
- ! self.le(other)
- }
-}
-
impl WorkKey {
pub fn new(kind: &str, name: &str) -> WorkKey {
WorkKey {
}
}
-struct WorkMap(HashMap<WorkKey, ~str>);
-
-impl Clone for WorkMap {
- fn clone(&self) -> WorkMap {
- WorkMap((**self).clone())
- }
-}
+#[deriving(Clone, Eq, Encodable, Decodable)]
+struct WorkMap(TreeMap<WorkKey, ~str>);
impl WorkMap {
- fn new() -> WorkMap { WorkMap(HashMap::new()) }
-}
-
-impl<S:Encoder> Encodable<S> for WorkMap {
- fn encode(&self, s: &mut S) {
- let mut d = ~[];
- for self.iter().advance |(k, v)| {
- d.push(((*k).clone(), (*v).clone()))
- }
- sort::tim_sort(d);
- d.encode(s)
- }
-}
-
-impl<D:Decoder> Decodable<D> for WorkMap {
- fn decode(d: &mut D) -> WorkMap {
- let v : ~[(WorkKey,~str)] = Decodable::decode(d);
- let mut w = WorkMap::new();
- for v.iter().advance |pair| {
- w.insert(pair.first(), pair.second());
- }
- w
- }
+ fn new() -> WorkMap { WorkMap(TreeMap::new()) }
}
struct Database {
db_filename: Path,
- db_cache: HashMap<~str, ~str>,
+ db_cache: TreeMap<~str, ~str>,
db_dirty: bool
}
impl Database {
- pub fn prepare(&mut self,
+
+ pub fn new(p: Path) -> Database {
+ Database {
+ db_filename: p,
+ db_cache: TreeMap::new(),
+ db_dirty: false
+ }
+ }
+
+ pub fn prepare(&self,
fn_name: &str,
declared_inputs: &WorkMap)
-> Option<(WorkMap, WorkMap, ~str)> {
}
impl Logger {
+
+ pub fn new() -> Logger {
+ Logger { a: () }
+ }
+
pub fn info(&self, i: &str) {
io::println(~"workcache: " + i);
}
}
+#[deriving(Clone)]
struct Context {
- db: @mut Database,
- logger: @mut Logger,
- cfg: @json::Object,
- freshness: HashMap<~str,@fn(&str,&str)->bool>
+ db: RWARC<Database>,
+ logger: RWARC<Logger>,
+ cfg: ARC<json::Object>,
+ freshness: ARC<TreeMap<~str,extern fn(&str,&str)->bool>>
}
-#[deriving(Clone)]
-struct Prep {
- ctxt: @Context,
- fn_name: ~str,
+struct Prep<'self> {
+ ctxt: &'self Context,
+ fn_name: &'self str,
declared_inputs: WorkMap,
}
discovered_outputs: WorkMap
}
-struct Work<T> {
- prep: @mut Prep,
+struct Work<'self, T> {
+ prep: &'self Prep<'self>,
res: Option<Either<T,PortOne<(Exec,T)>>>
}
}
impl Context {
- pub fn new(db: @mut Database, lg: @mut Logger, cfg: @json::Object)
- -> Context {
+
+ pub fn new(db: RWARC<Database>,
+ lg: RWARC<Logger>,
+ cfg: ARC<json::Object>) -> Context {
Context {
db: db,
logger: lg,
cfg: cfg,
- freshness: HashMap::new()
+ freshness: ARC(TreeMap::new())
}
}
- pub fn prep<T:Send +
- Encodable<json::Encoder> +
- Decodable<json::Decoder>>(@self, // FIXME(#5121)
- fn_name:&str,
- blk: &fn(@mut Prep)->Work<T>)
- -> Work<T> {
- let p = @mut Prep {
- ctxt: self,
- fn_name: fn_name.to_owned(),
- declared_inputs: WorkMap::new()
- };
- blk(p)
+ pub fn prep<'a>(&'a self, fn_name: &'a str) -> Prep<'a> {
+ Prep::new(self, fn_name)
}
-}
+ pub fn with_prep<'a, T>(&'a self, fn_name: &'a str, blk: &fn(p: &mut Prep) -> T) -> T {
+ let mut p = self.prep(fn_name);
+ blk(&mut p)
+ }
-trait TPrep {
- fn declare_input(&mut self, kind:&str, name:&str, val:&str);
- fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool;
- fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool;
- fn exec<T:Send +
- Encodable<json::Encoder> +
- Decodable<json::Decoder>>( // FIXME(#5121)
- &self, blk: ~fn(&Exec) -> T) -> Work<T>;
}
-impl TPrep for Prep {
+impl<'self> Prep<'self> {
+ fn new(ctxt: &'self Context, fn_name: &'self str) -> Prep<'self> {
+ Prep {
+ ctxt: ctxt,
+ fn_name: fn_name,
+ declared_inputs: WorkMap::new()
+ }
+ }
+}
+
+impl<'self> Prep<'self> {
fn declare_input(&mut self, kind:&str, name:&str, val:&str) {
self.declared_inputs.insert(WorkKey::new(kind, name),
val.to_owned());
fn is_fresh(&self, cat: &str, kind: &str,
name: &str, val: &str) -> bool {
let k = kind.to_owned();
- let f = (*self.ctxt.freshness.get(&k))(name, val);
- let lg = self.ctxt.logger;
- if f {
+ let f = self.ctxt.freshness.get().find(&k);
+ let fresh = match f {
+ None => fail!("missing freshness-function for '%s'", kind),
+ Some(f) => (*f)(name, val)
+ };
+ do self.ctxt.logger.write |lg| {
+ if fresh {
lg.info(fmt!("%s %s:%s is fresh",
cat, kind, name));
} else {
lg.info(fmt!("%s %s:%s is not fresh",
cat, kind, name))
}
- f
+ };
+ fresh
}
fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
}
fn exec<T:Send +
- Encodable<json::Encoder> +
- Decodable<json::Decoder>>( // FIXME(#5121)
- &self, blk: ~fn(&Exec) -> T) -> Work<T> {
+ Encodable<json::Encoder> +
+ Decodable<json::Decoder>>(
+ &'self self, blk: ~fn(&Exec) -> T) -> T {
+ self.exec_work(blk).unwrap()
+ }
+
+ fn exec_work<T:Send +
+ Encodable<json::Encoder> +
+ Decodable<json::Decoder>>( // FIXME(#5121)
+ &'self self, blk: ~fn(&Exec) -> T) -> Work<'self, T> {
let mut bo = Some(blk);
- let cached = self.ctxt.db.prepare(self.fn_name, &self.declared_inputs);
+ let cached = do self.ctxt.db.read |db| {
+ db.prepare(self.fn_name, &self.declared_inputs)
+ };
- match cached {
+ let res = match cached {
Some((ref disc_in, ref disc_out, ref res))
- if self.all_fresh("declared input",
- &self.declared_inputs) &&
- self.all_fresh("discovered input", disc_in) &&
- self.all_fresh("discovered output", disc_out) => {
- Work::new(@mut (*self).clone(), Left(json_decode(*res)))
+ if self.all_fresh("declared input",&self.declared_inputs) &&
+ self.all_fresh("discovered input", disc_in) &&
+ self.all_fresh("discovered output", disc_out) => {
+ Left(json_decode(*res))
}
_ => {
let v = blk(&exe);
send_one(chan, (exe, v));
}
- Work::new(@mut (*self).clone(), Right(port))
+ Right(port)
}
- }
+ };
+ Work::new(self, res)
}
}
-impl<T:Send +
+impl<'self, T:Send +
Encodable<json::Encoder> +
- Decodable<json::Decoder>> Work<T> { // FIXME(#5121)
- pub fn new(p: @mut Prep, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
+ Decodable<json::Decoder>>
+ Work<'self, T> { // FIXME(#5121)
+
+ pub fn new(p: &'self Prep<'self>, e: Either<T,PortOne<(Exec,T)>>) -> Work<'self, T> {
Work { prep: p, res: Some(e) }
}
-}
-// FIXME (#3724): movable self. This should be in impl Work.
-fn unwrap<T:Send +
- Encodable<json::Encoder> +
- Decodable<json::Decoder>>( // FIXME(#5121)
- w: Work<T>) -> T {
- let mut ww = w;
- let s = ww.res.take();
-
- match s {
- None => fail!(),
- Some(Left(v)) => v,
- Some(Right(port)) => {
- let (exe, v) = recv_one(port);
-
- let s = json_encode(&v);
-
- let p = &*ww.prep;
- let db = p.ctxt.db;
- db.cache(p.fn_name,
- &p.declared_inputs,
- &exe.discovered_inputs,
- &exe.discovered_outputs,
- s);
- v
+ pub fn unwrap(self) -> T {
+ let Work { prep, res } = self;
+ match res {
+ None => fail!(),
+ Some(Left(v)) => v,
+ Some(Right(port)) => {
+ let (exe, v) = recv_one(port);
+ let s = json_encode(&v);
+ do prep.ctxt.db.write |db| {
+ db.cache(prep.fn_name,
+ &prep.declared_inputs,
+ &exe.discovered_inputs,
+ &exe.discovered_outputs,
+ s);
+ }
+ v
+ }
}
}
}
+
//#[test]
fn test() {
use std::io::WriterUtil;
- let db = @mut Database { db_filename: Path("db.json"),
- db_cache: HashMap::new(),
- db_dirty: false };
- let lg = @mut Logger { a: () };
- let cfg = @HashMap::new();
- let cx = @Context::new(db, lg, cfg);
- let w:Work<~str> = do cx.prep("test1") |prep| {
- let pth = Path("foo.c");
- {
- let file = io::file_writer(&pth, [io::Create]).unwrap();
- file.write_str("int main() { return 0; }");
- }
+ let pth = Path("foo.c");
+ {
+ let r = io::file_writer(&pth, [io::Create]);
+ r.get_ref().write_str("int main() { return 0; }");
+ }
+
+ let cx = Context::new(RWARC(Database::new(Path("db.json"))),
+ RWARC(Logger::new()),
+ ARC(TreeMap::new()));
+
+ let s = do cx.with_prep("test1") |prep| {
+
+ let subcx = cx.clone();
prep.declare_input("file", pth.to_str(), digest_file(&pth));
do prep.exec |_exe| {
let out = Path("foo.o");
run::process_status("gcc", [~"foo.c", ~"-o", out.to_str()]);
+
+ let _proof_of_concept = subcx.prep("subfn");
+ // Could run sub-rules inside here.
+
out.to_str()
}
};
- let s = unwrap(w);
io::println(s);
}
lower_bound(Result),
range_result(Result, Result),
}
-pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
+pub fn trans_opt(bcx: @mut Block, o: &Opt) -> opt_result {
let _icx = push_ctxt("match::trans_opt");
let ccx = bcx.ccx();
let bcx = bcx;
}
}
-pub fn variant_opt(bcx: block, pat_id: ast::node_id)
+pub fn variant_opt(bcx: @mut Block, pat_id: ast::node_id)
-> Opt {
let ccx = bcx.ccx();
match ccx.tcx.def_map.get_copy(&pat_id) {
#[deriving(Clone)]
pub struct ArmData<'self> {
- bodycx: block,
+ bodycx: @mut Block,
arm: &'self ast::arm,
bindings_map: @BindingsMap
}
data: ArmData<'self>
}
-pub fn match_to_str(bcx: block, m: &Match) -> ~str {
+pub fn match_to_str(bcx: @mut Block, m: &Match) -> ~str {
if bcx.sess().verbose() {
// for many programs, this just take too long to serialize
fmt!("%?", m.pats.map(|p| pat_to_str(*p, bcx.sess().intr())))
}
}
-pub fn matches_to_str(bcx: block, m: &[Match]) -> ~str {
+pub fn matches_to_str(bcx: @mut Block, m: &[Match]) -> ~str {
fmt!("%?", m.map(|n| match_to_str(bcx, n)))
}
return false;
}
-pub fn expand_nested_bindings<'r>(bcx: block,
+pub fn expand_nested_bindings<'r>(bcx: @mut Block,
m: &[Match<'r>],
col: uint,
val: ValueRef)
}
}
-pub fn assert_is_binding_or_wild(bcx: block, p: @ast::pat) {
+pub fn assert_is_binding_or_wild(bcx: @mut Block, p: @ast::pat) {
if !pat_is_binding_or_wild(bcx.tcx().def_map, p) {
bcx.sess().span_bug(
p.span,
pub type enter_pat<'self> = &'self fn(@ast::pat) -> Option<~[@ast::pat]>;
-pub fn enter_match<'r>(bcx: block,
+pub fn enter_match<'r>(bcx: @mut Block,
dm: DefMap,
m: &[Match<'r>],
col: uint,
return result;
}
-pub fn enter_default<'r>(bcx: block,
+pub fn enter_default<'r>(bcx: @mut Block,
dm: DefMap,
m: &[Match<'r>],
col: uint,
// <nmatsakis> so all patterns must either be records (resp. tuples) or
// wildcards
-pub fn enter_opt<'r>(bcx: block,
+pub fn enter_opt<'r>(bcx: @mut Block,
m: &[Match<'r>],
opt: &Opt,
col: uint,
}
}
-pub fn enter_rec_or_struct<'r>(bcx: block,
+pub fn enter_rec_or_struct<'r>(bcx: @mut Block,
dm: DefMap,
m: &[Match<'r>],
col: uint,
}
}
-pub fn enter_tup<'r>(bcx: block,
+pub fn enter_tup<'r>(bcx: @mut Block,
dm: DefMap,
m: &[Match<'r>],
col: uint,
}
}
-pub fn enter_tuple_struct<'r>(bcx: block,
+pub fn enter_tuple_struct<'r>(bcx: @mut Block,
dm: DefMap,
m: &[Match<'r>],
col: uint,
}
}
-pub fn enter_box<'r>(bcx: block,
+pub fn enter_box<'r>(bcx: @mut Block,
dm: DefMap,
m: &[Match<'r>],
col: uint,
}
}
-pub fn enter_uniq<'r>(bcx: block,
+pub fn enter_uniq<'r>(bcx: @mut Block,
dm: DefMap,
m: &[Match<'r>],
col: uint,
}
}
-pub fn enter_region<'r>(bcx: block,
+pub fn enter_region<'r>(bcx: @mut Block,
dm: DefMap,
m: &[Match<'r>],
col: uint,
// Returns the options in one column of matches. An option is something that
// needs to be conditionally matched at runtime; for example, the discriminant
// on a set of enum variants or a literal.
-pub fn get_options(bcx: block, m: &[Match], col: uint) -> ~[Opt] {
+pub fn get_options(bcx: @mut Block, m: &[Match], col: uint) -> ~[Opt] {
let ccx = bcx.ccx();
fn add_to_set(tcx: ty::ctxt, set: &mut ~[Opt], val: Opt) {
if set.iter().any(|l| opt_eq(tcx, l, &val)) {return;}
pub struct ExtractedBlock {
vals: ~[ValueRef],
- bcx: block
+ bcx: @mut Block
}
-pub fn extract_variant_args(bcx: block,
+pub fn extract_variant_args(bcx: @mut Block,
repr: &adt::Repr,
disr_val: int,
val: ValueRef)
ExtractedBlock { vals: args, bcx: bcx }
}
-fn match_datum(bcx: block, val: ValueRef, pat_id: ast::node_id) -> Datum {
+fn match_datum(bcx: @mut Block, val: ValueRef, pat_id: ast::node_id) -> Datum {
//! Helper for converting from the ValueRef that we pass around in
//! the match code, which is always by ref, into a Datum. Eventually
//! we should just pass around a Datum and be done with it.
}
-pub fn extract_vec_elems(bcx: block,
+pub fn extract_vec_elems(bcx: @mut Block,
pat_span: span,
pat_id: ast::node_id,
elem_count: uint,
}
// NB: This function does not collect fields from struct-like enum variants.
-pub fn collect_record_or_struct_fields(bcx: block,
+pub fn collect_record_or_struct_fields(bcx: @mut Block,
m: &[Match],
col: uint)
-> ~[ast::ident] {
}
}
-pub fn pats_require_rooting(bcx: block,
+pub fn pats_require_rooting(bcx: @mut Block,
m: &[Match],
col: uint)
-> bool {
}
}
-pub fn root_pats_as_necessary(mut bcx: block,
+pub fn root_pats_as_necessary(mut bcx: @mut Block,
m: &[Match],
col: uint,
val: ValueRef)
- -> block {
+ -> @mut Block {
for m.iter().advance |br| {
let pat_id = br.pats[col].id;
if pat_id != 0 {
any_pat!(m, ast::pat_tup(_))
}
-pub fn any_tuple_struct_pat(bcx: block, m: &[Match], col: uint) -> bool {
+pub fn any_tuple_struct_pat(bcx: @mut Block, m: &[Match], col: uint) -> bool {
do m.iter().any |br| {
let pat = br.pats[col];
match pat.node {
// Compiles a comparison between two things.
//
// NB: This must produce an i1, not a Rust bool (i8).
-pub fn compare_values(cx: block,
+pub fn compare_values(cx: @mut Block,
lhs: ValueRef,
rhs: ValueRef,
rhs_t: ty::t)
}
}
-fn store_non_ref_bindings(bcx: block,
+fn store_non_ref_bindings(bcx: @mut Block,
bindings_map: &BindingsMap,
mut opt_temp_cleanups: Option<&mut ~[ValueRef]>)
- -> block
+ -> @mut Block
{
/*!
*
return bcx;
}
-fn insert_lllocals(bcx: block,
+fn insert_lllocals(bcx: @mut Block,
bindings_map: &BindingsMap,
binding_mode: IrrefutablePatternBindingMode,
- add_cleans: bool) -> block {
+ add_cleans: bool) -> @mut Block {
/*!
* For each binding in `data.bindings_map`, adds an appropriate entry into
* the `fcx.lllocals` map. If add_cleans is true, then adds cleanups for
return bcx;
}
-pub fn compile_guard(bcx: block,
+pub fn compile_guard(bcx: @mut Block,
guard_expr: @ast::expr,
data: &ArmData,
m: &[Match],
vals: &[ValueRef],
chk: Option<mk_fail>)
- -> block {
+ -> @mut Block {
debug!("compile_guard(bcx=%s, guard_expr=%s, m=%s, vals=%?)",
bcx.to_str(),
bcx.expr_to_str(guard_expr),
bcx
};
- fn drop_bindings(bcx: block, data: &ArmData) -> block {
+ fn drop_bindings(bcx: @mut Block, data: &ArmData) -> @mut Block {
let mut bcx = bcx;
for data.bindings_map.each_value |&binding_info| {
match binding_info.trmode {
}
}
-pub fn compile_submatch(bcx: block,
+pub fn compile_submatch(bcx: @mut Block,
m: &[Match],
vals: &[ValueRef],
chk: Option<mk_fail>) {
}
}
-fn compile_submatch_continue(mut bcx: block,
+fn compile_submatch_continue(mut bcx: @mut Block,
m: &[Match],
vals: &[ValueRef],
chk: Option<mk_fail>,
}
}
-pub fn trans_match(bcx: block,
+pub fn trans_match(bcx: @mut Block,
match_expr: &ast::expr,
discr_expr: @ast::expr,
arms: &[ast::arm],
- dest: Dest) -> block {
+ dest: Dest) -> @mut Block {
let _icx = push_ctxt("match::trans_match");
do with_scope(bcx, match_expr.info(), "match") |bcx| {
trans_match_inner(bcx, discr_expr, arms, dest)
}
}
-fn create_bindings_map(bcx: block, pat: @ast::pat) -> BindingsMap {
+fn create_bindings_map(bcx: @mut Block, pat: @ast::pat) -> BindingsMap {
// Create the bindings map, which is a mapping from each binding name
// to an alloca() that will be the value for that local variable.
// Note that we use the names because each binding will have many ids
return bindings_map;
}
-pub fn trans_match_inner(scope_cx: block,
+pub fn trans_match_inner(scope_cx: @mut Block,
discr_expr: @ast::expr,
arms: &[ast::arm],
- dest: Dest) -> block {
+ dest: Dest) -> @mut Block {
let _icx = push_ctxt("match::trans_match_inner");
let mut bcx = scope_cx;
let tcx = bcx.tcx();
bcx = controlflow::join_blocks(scope_cx, arm_cxs);
return bcx;
- fn mk_fail(bcx: block, sp: span, msg: @str,
+ fn mk_fail(bcx: @mut Block, sp: span, msg: @str,
finished: @mut Option<BasicBlockRef>) -> BasicBlockRef {
match *finished { Some(bb) => return bb, _ => () }
let fail_cx = sub_block(bcx, "case_fallthrough");
BindArgument
}
-pub fn store_local(bcx: block,
+pub fn store_local(bcx: @mut Block,
pat: @ast::pat,
opt_init_expr: Option<@ast::expr>)
- -> block {
+ -> @mut Block {
/*!
* Generates code for a local variable declaration like
* `let <pat>;` or `let <pat> = <opt_init_expr>`.
}
};
- fn create_dummy_locals(mut bcx: block, pat: @ast::pat) -> block {
+ fn create_dummy_locals(mut bcx: @mut Block, pat: @ast::pat) -> @mut Block {
// create dummy memory for the variables if we have no
// value to store into them immediately
let tcx = bcx.tcx();
}
}
-pub fn store_arg(mut bcx: block,
+pub fn store_arg(mut bcx: @mut Block,
pat: @ast::pat,
llval: ValueRef)
- -> block {
+ -> @mut Block {
/*!
* Generates code for argument patterns like `fn foo(<pat>: T)`.
* Creates entries in the `llargs` map for each of the bindings
return bcx;
}
-fn mk_binding_alloca(mut bcx: block,
+fn mk_binding_alloca(mut bcx: @mut Block,
p_id: ast::node_id,
path: &ast::Path,
binding_mode: IrrefutablePatternBindingMode,
- populate: &fn(block, ty::t, ValueRef) -> block) -> block {
+ populate: &fn(@mut Block, ty::t, ValueRef) -> @mut Block) -> @mut Block {
let var_ty = node_id_type(bcx, p_id);
let ident = ast_util::path_to_ident(path);
let llval = alloc_ty(bcx, var_ty, bcx.ident(ident));
return bcx;
}
-fn bind_irrefutable_pat(bcx: block,
+fn bind_irrefutable_pat(bcx: @mut Block,
pat: @ast::pat,
val: ValueRef,
binding_mode: IrrefutablePatternBindingMode)
- -> block {
+ -> @mut Block {
/*!
* A simple version of the pattern matching code that only handles
* irrefutable patterns. This is used in let/argument patterns,
* these, for places in trans where the `ty::t` isn't directly
* available.
*/
-pub fn represent_node(bcx: block, node: ast::node_id) -> @Repr {
+pub fn represent_node(bcx: @mut Block, node: ast::node_id) -> @Repr {
represent_type(bcx.ccx(), node_id_type(bcx, node))
}
*
* This should ideally be less tightly tied to `_match`.
*/
-pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef)
+pub fn trans_switch(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
-> (_match::branch_kind, Option<ValueRef>) {
match *r {
CEnum(*) | General(*) => {
/// Obtain the actual discriminant of a value.
-pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef)
+pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
-> ValueRef {
match *r {
CEnum(min, max) => load_discr(bcx, scrutinee, min, max),
}
}
-fn nullable_bitdiscr(bcx: block, nonnull: &Struct, nndiscr: int, ptrfield: uint,
+fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: int, ptrfield: uint,
scrutinee: ValueRef) -> ValueRef {
let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield]));
}
/// Helper for cases where the discriminant is simply loaded.
-fn load_discr(bcx: block, scrutinee: ValueRef, min: int, max: int)
+fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: int, max: int)
-> ValueRef {
let ptr = GEPi(bcx, scrutinee, [0, 0]);
if max + 1 == min {
*
* This should ideally be less tightly tied to `_match`.
*/
-pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result {
+pub fn trans_case(bcx: @mut Block, r: &Repr, discr: int) -> _match::opt_result {
match *r {
CEnum(*) => {
_match::single_result(rslt(bcx, C_int(bcx.ccx(), discr)))
* representation. The fields, if any, should then be initialized via
* `trans_field_ptr`.
*/
-pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) {
+pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int) {
match *r {
CEnum(min, max) => {
assert!(min <= discr && discr <= max);
}
/// Access a field, at a point when the value's case is known.
-pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int,
+pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int,
ix: uint) -> ValueRef {
// Note: if this ever needs to generate conditionals (e.g., if we
// decide to do some kind of cdr-coding-like non-unique repr
}
}
-fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint,
+fn struct_field_ptr(bcx: @mut Block, st: &Struct, val: ValueRef, ix: uint,
needs_cast: bool) -> ValueRef {
let ccx = bcx.ccx();
}
/// Access the struct drop flag, if present.
-pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef {
+pub fn trans_drop_flag_ptr(bcx: @mut Block, r: &Repr, val: ValueRef) -> ValueRef {
match *r {
Univariant(ref st, true) => GEPi(bcx, val, [0, st.fields.len() - 1]),
_ => bcx.ccx().sess.bug("tried to get drop flag of non-droppable type")
use syntax::ast;
// Take an inline assembly expression and splat it out via LLVM
-pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
+pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
let mut bcx = bcx;
let mut constraints = ~[];
_InsnCtxt { _x: () }
}
-fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool {
+fn fcx_has_nonzero_span(fcx: &FunctionContext) -> bool {
match fcx.span {
None => true,
Some(span) => *span.lo != 0 || *span.hi != 0
return c;
}
}
-pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
+pub fn umax(cx: @mut Block, a: ValueRef, b: ValueRef) -> ValueRef {
let _icx = push_ctxt("umax");
let cond = ICmp(cx, lib::llvm::IntULT, a, b);
return Select(cx, cond, b, a);
}
-pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
+pub fn umin(cx: @mut Block, a: ValueRef, b: ValueRef) -> ValueRef {
let _icx = push_ctxt("umin");
let cond = ICmp(cx, lib::llvm::IntULT, a, b);
return Select(cx, cond, a, b);
// Given a pointer p, returns a pointer sz(p) (i.e., inc'd by sz bytes).
// The type of the returned pointer is always i8*. If you care about the
// return type, use bump_ptr().
-pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef {
+pub fn ptr_offs(bcx: @mut Block, base: ValueRef, sz: ValueRef) -> ValueRef {
let _icx = push_ctxt("ptr_offs");
let raw = PointerCast(bcx, base, Type::i8p());
InBoundsGEP(bcx, raw, [sz])
// Increment a pointer by a given amount and then cast it to be a pointer
// to a given type.
-pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) ->
+pub fn bump_ptr(bcx: @mut Block, t: ty::t, base: ValueRef, sz: ValueRef) ->
ValueRef {
let _icx = push_ctxt("bump_ptr");
let ccx = bcx.ccx();
// known.
//
// The runtime equivalent is box_body() in "rust_internal.h".
-pub fn opaque_box_body(bcx: block,
+pub fn opaque_box_body(bcx: @mut Block,
body_t: ty::t,
boxptr: ValueRef) -> ValueRef {
let _icx = push_ctxt("opaque_box_body");
// malloc_raw_dyn: allocates a box to contain a given type, but with a
// potentially dynamic size.
-pub fn malloc_raw_dyn(bcx: block,
+pub fn malloc_raw_dyn(bcx: @mut Block,
t: ty::t,
heap: heap,
size: ValueRef) -> Result {
let _icx = push_ctxt("malloc_raw");
let ccx = bcx.ccx();
- fn require_alloc_fn(bcx: block, t: ty::t, it: LangItem) -> ast::def_id {
+ fn require_alloc_fn(bcx: @mut Block, t: ty::t, it: LangItem) -> ast::def_id {
let li = &bcx.tcx().lang_items;
match li.require(it) {
Ok(id) => id,
// malloc_raw: expects an unboxed type and returns a pointer to
// enough space for a box of that type. This includes a rust_opaque_box
// header.
-pub fn malloc_raw(bcx: block, t: ty::t, heap: heap) -> Result {
+pub fn malloc_raw(bcx: @mut Block, t: ty::t, heap: heap) -> Result {
let ty = type_of(bcx.ccx(), t);
let size = llsize_of(bcx.ccx(), ty);
malloc_raw_dyn(bcx, t, heap, size)
}
pub struct MallocResult {
- bcx: block,
+ bcx: @mut Block,
box: ValueRef,
body: ValueRef
}
// malloc_general_dyn: usefully wraps malloc_raw_dyn; allocates a box,
// and pulls out the body
-pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef)
+pub fn malloc_general_dyn(bcx: @mut Block, t: ty::t, heap: heap, size: ValueRef)
-> MallocResult {
assert!(heap != heap_exchange);
let _icx = push_ctxt("malloc_general");
MallocResult { bcx: bcx, box: llbox, body: body }
}
-pub fn malloc_general(bcx: block, t: ty::t, heap: heap) -> MallocResult {
+pub fn malloc_general(bcx: @mut Block, t: ty::t, heap: heap) -> MallocResult {
let ty = type_of(bcx.ccx(), t);
assert!(heap != heap_exchange);
malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty))
}
-pub fn malloc_boxed(bcx: block, t: ty::t)
+pub fn malloc_boxed(bcx: @mut Block, t: ty::t)
-> MallocResult {
malloc_general(bcx, t, heap_managed)
}
-pub fn heap_for_unique(bcx: block, t: ty::t) -> heap {
+pub fn heap_for_unique(bcx: @mut Block, t: ty::t) -> heap {
if ty::type_contents(bcx.tcx(), t).contains_managed() {
heap_managed_unique
} else {
}
}
-pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) {
+pub fn maybe_set_managed_unique_rc(bcx: @mut Block, bx: ValueRef, heap: heap) {
assert!(heap != heap_exchange);
if heap == heap_managed_unique {
// In cases where we are looking at a unique-typed allocation in the
pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, }
// NB: This produces an i1, not a Rust bool (i8).
-pub fn compare_scalar_types(cx: block,
+pub fn compare_scalar_types(cx: @mut Block,
lhs: ValueRef,
rhs: ValueRef,
t: ty::t,
// A helper function to do the actual comparison of scalar values.
-pub fn compare_scalar_values(cx: block,
+pub fn compare_scalar_values(cx: @mut Block,
lhs: ValueRef,
rhs: ValueRef,
nt: scalar_type,
op: ast::binop)
-> ValueRef {
let _icx = push_ctxt("compare_scalar_values");
- fn die(cx: block) -> ! {
+ fn die(cx: @mut Block) -> ! {
cx.tcx().sess.bug("compare_scalar_values: must be a\
comparison operator");
}
}
}
-pub type val_and_ty_fn<'self> = &'self fn(block, ValueRef, ty::t) -> block;
+pub type val_and_ty_fn<'self> = &'self fn(@mut Block, ValueRef, ty::t) -> @mut Block;
-pub fn load_inbounds(cx: block, p: ValueRef, idxs: &[uint]) -> ValueRef {
+pub fn load_inbounds(cx: @mut Block, p: ValueRef, idxs: &[uint]) -> ValueRef {
return Load(cx, GEPi(cx, p, idxs));
}
-pub fn store_inbounds(cx: block, v: ValueRef, p: ValueRef, idxs: &[uint]) {
+pub fn store_inbounds(cx: @mut Block, v: ValueRef, p: ValueRef, idxs: &[uint]) {
Store(cx, v, GEPi(cx, p, idxs));
}
// Iterates through the elements of a structural type.
-pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
- f: val_and_ty_fn) -> block {
+pub fn iter_structural_ty(cx: @mut Block, av: ValueRef, t: ty::t,
+ f: val_and_ty_fn) -> @mut Block {
let _icx = push_ctxt("iter_structural_ty");
- fn iter_variant(cx: block, repr: &adt::Repr, av: ValueRef,
+ fn iter_variant(cx: @mut Block, repr: &adt::Repr, av: ValueRef,
variant: @ty::VariantInfo,
- tps: &[ty::t], f: val_and_ty_fn) -> block {
+ tps: &[ty::t], f: val_and_ty_fn) -> @mut Block {
let _icx = push_ctxt("iter_variant");
let tcx = cx.tcx();
let mut cx = cx;
return cx;
}
-pub fn cast_shift_expr_rhs(cx: block, op: ast::binop,
+pub fn cast_shift_expr_rhs(cx: @mut Block, op: ast::binop,
lhs: ValueRef, rhs: ValueRef) -> ValueRef {
cast_shift_rhs(op, lhs, rhs,
|a,b| Trunc(cx, a, b),
}
}
-pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop,
- rhs: ValueRef, rhs_t: ty::t) -> block {
+pub fn fail_if_zero(cx: @mut Block, span: span, divrem: ast::binop,
+ rhs: ValueRef, rhs_t: ty::t) -> @mut Block {
let text = if divrem == ast::div {
@"attempted to divide by zero"
} else {
}
}
-pub fn null_env_ptr(bcx: block) -> ValueRef {
+pub fn null_env_ptr(bcx: @mut Block) -> ValueRef {
C_null(Type::opaque_box(bcx.ccx()).ptr_to())
}
};
}
-pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef])
- -> (ValueRef, block) {
+pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef])
+ -> (ValueRef, @mut Block) {
let _icx = push_ctxt("invoke_");
if bcx.unreachable {
return (C_null(Type::i8()), bcx);
}
}
-pub fn need_invoke(bcx: block) -> bool {
+pub fn need_invoke(bcx: @mut Block) -> bool {
if (bcx.ccx().sess.opts.debugging_opts & session::no_landing_pads != 0) {
return false;
}
}
}
-pub fn have_cached_lpad(bcx: block) -> bool {
+pub fn have_cached_lpad(bcx: @mut Block) -> bool {
let mut res = false;
do in_lpad_scope_cx(bcx) |inf| {
match inf.landing_pad {
return res;
}
-pub fn in_lpad_scope_cx(bcx: block, f: &fn(si: &mut scope_info)) {
+pub fn in_lpad_scope_cx(bcx: @mut Block, f: &fn(si: &mut ScopeInfo)) {
let mut bcx = bcx;
let mut cur_scope = bcx.scope;
loop {
}
}
-pub fn get_landing_pad(bcx: block) -> BasicBlockRef {
+pub fn get_landing_pad(bcx: @mut Block) -> BasicBlockRef {
let _icx = push_ctxt("get_landing_pad");
let mut cached = None;
return pad_bcx.llbb;
}
-pub fn find_bcx_for_scope(bcx: block, scope_id: ast::node_id) -> block {
+pub fn find_bcx_for_scope(bcx: @mut Block, scope_id: ast::node_id) -> @mut Block {
let mut bcx_sid = bcx;
let mut cur_scope = bcx_sid.scope;
loop {
}
-pub fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef {
+pub fn do_spill(bcx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
if ty::type_is_bot(t) {
return C_null(Type::i8p());
}
// Since this function does *not* root, it is the caller's responsibility to
// ensure that the referent is pointed to by a root.
-pub fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef {
+pub fn do_spill_noroot(cx: @mut Block, v: ValueRef) -> ValueRef {
let llptr = alloca(cx, val_ty(v), "");
Store(cx, v, llptr);
return llptr;
}
-pub fn spill_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef {
+pub fn spill_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
let _icx = push_ctxt("spill_if_immediate");
if ty::type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); }
return v;
}
-pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef {
+pub fn load_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
let _icx = push_ctxt("load_if_immediate");
if ty::type_is_immediate(cx.tcx(), t) { return Load(cx, v); }
return v;
}
-pub fn trans_trace(bcx: block, sp_opt: Option<span>, trace_str: @str) {
+pub fn trans_trace(bcx: @mut Block, sp_opt: Option<span>, trace_str: @str) {
if !bcx.sess().trace() { return; }
let _icx = push_ctxt("trans_trace");
add_comment(bcx, trace_str);
Call(bcx, ccx.upcalls.trace, args);
}
-pub fn ignore_lhs(_bcx: block, local: &ast::Local) -> bool {
+pub fn ignore_lhs(_bcx: @mut Block, local: &ast::Local) -> bool {
match local.pat.node {
ast::pat_wild => true, _ => false
}
}
-pub fn init_local(bcx: block, local: &ast::Local) -> block {
+pub fn init_local(bcx: @mut Block, local: &ast::Local) -> @mut Block {
debug!("init_local(bcx=%s, local.id=%?)",
bcx.to_str(), local.id);
_match::store_local(bcx, local.pat, local.init)
}
-pub fn trans_stmt(cx: block, s: &ast::stmt) -> block {
+pub fn trans_stmt(cx: @mut Block, s: &ast::stmt) -> @mut Block {
let _icx = push_ctxt("trans_stmt");
debug!("trans_stmt(%s)", stmt_to_str(s, cx.tcx().sess.intr()));
// You probably don't want to use this one. See the
// next three functions instead.
-pub fn new_block(cx: fn_ctxt, parent: Option<block>, scope: Option<@mut scope_info>,
- is_lpad: bool, name: &str, opt_node_info: Option<NodeInfo>)
- -> block {
-
+pub fn new_block(cx: @mut FunctionContext,
+ parent: Option<@mut Block>,
+ scope: Option<@mut ScopeInfo>,
+ is_lpad: bool,
+ name: &str,
+ opt_node_info: Option<NodeInfo>)
+ -> @mut Block {
unsafe {
let llbb = do name.as_c_str |buf| {
llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf)
};
- let bcx = mk_block(llbb,
- parent,
- is_lpad,
- opt_node_info,
- cx);
+ let bcx = @mut Block::new(llbb,
+ parent,
+ is_lpad,
+ opt_node_info,
+ cx);
bcx.scope = scope;
for parent.iter().advance |cx| {
if cx.unreachable {
}
}
-pub fn simple_block_scope(parent: Option<@mut scope_info>,
- node_info: Option<NodeInfo>) -> @mut scope_info {
- @mut scope_info {
+pub fn simple_block_scope(parent: Option<@mut ScopeInfo>,
+ node_info: Option<NodeInfo>) -> @mut ScopeInfo {
+ @mut ScopeInfo {
parent: parent,
loop_break: None,
loop_label: None,
}
// Use this when you're at the top block of a function or the like.
-pub fn top_scope_block(fcx: fn_ctxt, opt_node_info: Option<NodeInfo>)
- -> block {
+pub fn top_scope_block(fcx: @mut FunctionContext, opt_node_info: Option<NodeInfo>)
+ -> @mut Block {
return new_block(fcx, None, Some(simple_block_scope(None, opt_node_info)), false,
"function top level", opt_node_info);
}
-pub fn scope_block(bcx: block,
+pub fn scope_block(bcx: @mut Block,
opt_node_info: Option<NodeInfo>,
- n: &str) -> block {
+ n: &str) -> @mut Block {
return new_block(bcx.fcx, Some(bcx), Some(simple_block_scope(None, opt_node_info)), bcx.is_lpad,
n, opt_node_info);
}
-pub fn loop_scope_block(bcx: block,
- loop_break: block,
+pub fn loop_scope_block(bcx: @mut Block,
+ loop_break: @mut Block,
loop_label: Option<ident>,
n: &str,
- opt_node_info: Option<NodeInfo>) -> block {
- return new_block(bcx.fcx, Some(bcx), Some(@mut scope_info {
+ opt_node_info: Option<NodeInfo>) -> @mut Block {
+ return new_block(bcx.fcx, Some(bcx), Some(@mut ScopeInfo {
parent: None,
loop_break: Some(loop_break),
loop_label: loop_label,
}
// Use this when creating a block for the inside of a landing pad.
-pub fn lpad_block(bcx: block, n: &str) -> block {
+pub fn lpad_block(bcx: @mut Block, n: &str) -> @mut Block {
new_block(bcx.fcx, Some(bcx), None, true, n, None)
}
// Use this when you're making a general CFG BB within a scope.
-pub fn sub_block(bcx: block, n: &str) -> block {
+pub fn sub_block(bcx: @mut Block, n: &str) -> @mut Block {
new_block(bcx.fcx, Some(bcx), None, bcx.is_lpad, n, None)
}
-pub fn raw_block(fcx: fn_ctxt, is_lpad: bool, llbb: BasicBlockRef) -> block {
- mk_block(llbb, None, is_lpad, None, fcx)
+pub fn raw_block(fcx: @mut FunctionContext, is_lpad: bool, llbb: BasicBlockRef) -> @mut Block {
+ @mut Block::new(llbb, None, is_lpad, None, fcx)
}
// need to make sure those variables go out of scope when the block ends. We
// do that by running a 'cleanup' function for each variable.
// trans_block_cleanups runs all the cleanup functions for the block.
-pub fn trans_block_cleanups(bcx: block, cleanups: ~[cleanup]) -> block {
+pub fn trans_block_cleanups(bcx: @mut Block, cleanups: ~[cleanup]) -> @mut Block {
trans_block_cleanups_(bcx, cleanups, false)
}
-pub fn trans_block_cleanups_(bcx: block,
+pub fn trans_block_cleanups_(bcx: @mut Block,
cleanups: &[cleanup],
/* cleanup_cx: block, */
- is_lpad: bool) -> block {
+ is_lpad: bool) -> @mut Block {
let _icx = push_ctxt("trans_block_cleanups");
// NB: Don't short-circuit even if this block is unreachable because
// GC-based cleanup needs to the see that the roots are live.
// In the last argument, Some(block) mean jump to this block, and none means
// this is a landing pad and leaving should be accomplished with a resume
// instruction.
-pub fn cleanup_and_leave(bcx: block,
+pub fn cleanup_and_leave(bcx: @mut Block,
upto: Option<BasicBlockRef>,
leave: Option<BasicBlockRef>) {
let _icx = push_ctxt("cleanup_and_leave");
}
}
-pub fn cleanup_block(bcx: block, upto: Option<BasicBlockRef>) -> block{
+pub fn cleanup_block(bcx: @mut Block, upto: Option<BasicBlockRef>) -> @mut Block{
let _icx = push_ctxt("cleanup_block");
let mut cur = bcx;
let mut bcx = bcx;
bcx
}
-pub fn cleanup_and_Br(bcx: block, upto: block, target: BasicBlockRef) {
+pub fn cleanup_and_Br(bcx: @mut Block, upto: @mut Block, target: BasicBlockRef) {
let _icx = push_ctxt("cleanup_and_Br");
cleanup_and_leave(bcx, Some(upto.llbb), Some(target));
}
-pub fn leave_block(bcx: block, out_of: block) -> block {
+pub fn leave_block(bcx: @mut Block, out_of: @mut Block) -> @mut Block {
let _icx = push_ctxt("leave_block");
let next_cx = sub_block(block_parent(out_of), "next");
if bcx.unreachable { Unreachable(next_cx); }
next_cx
}
-pub fn with_scope(bcx: block,
+pub fn with_scope(bcx: @mut Block,
opt_node_info: Option<NodeInfo>,
name: &str,
- f: &fn(block) -> block) -> block {
+ f: &fn(@mut Block) -> @mut Block) -> @mut Block {
let _icx = push_ctxt("with_scope");
debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)",
ret
}
-pub fn with_scope_result(bcx: block,
+pub fn with_scope_result(bcx: @mut Block,
opt_node_info: Option<NodeInfo>,
_name: &str,
- f: &fn(block) -> Result) -> Result {
+ f: &fn(@mut Block) -> Result) -> Result {
let _icx = push_ctxt("with_scope_result");
let scope = simple_block_scope(bcx.scope, opt_node_info);
rslt(out_bcx, val)
}
-pub fn with_scope_datumblock(bcx: block, opt_node_info: Option<NodeInfo>,
- name: &str, f: &fn(block) -> datum::DatumBlock)
+pub fn with_scope_datumblock(bcx: @mut Block, opt_node_info: Option<NodeInfo>,
+ name: &str, f: &fn(@mut Block) -> datum::DatumBlock)
-> datum::DatumBlock {
use middle::trans::datum::DatumBlock;
}
}
-pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block {
+pub fn with_cond(bcx: @mut Block, val: ValueRef, f: &fn(@mut Block) -> @mut Block) -> @mut Block {
let _icx = push_ctxt("with_cond");
let next_cx = base::sub_block(bcx, "next");
let cond_cx = base::sub_block(bcx, "cond");
next_cx
}
-pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
+pub fn call_memcpy(cx: @mut Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
let _icx = push_ctxt("call_memcpy");
let ccx = cx.ccx();
let key = match ccx.sess.targ_cfg.arch {
Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile]);
}
-pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
+pub fn memcpy_ty(bcx: @mut Block, dst: ValueRef, src: ValueRef, t: ty::t) {
let _icx = push_ctxt("memcpy_ty");
let ccx = bcx.ccx();
if ty::type_is_structural(t) {
}
}
-pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) {
+pub fn zero_mem(cx: @mut Block, llptr: ValueRef, t: ty::t) {
if cx.unreachable { return; }
let _icx = push_ctxt("zero_mem");
let bcx = cx;
b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
}
-pub fn alloc_ty(bcx: block, t: ty::t, name: &str) -> ValueRef {
+pub fn alloc_ty(bcx: @mut Block, t: ty::t, name: &str) -> ValueRef {
let _icx = push_ctxt("alloc_ty");
let ccx = bcx.ccx();
let ty = type_of::type_of(ccx, t);
return val;
}
-pub fn alloca(cx: block, ty: Type, name: &str) -> ValueRef {
+pub fn alloca(cx: @mut Block, ty: Type, name: &str) -> ValueRef {
alloca_maybe_zeroed(cx, ty, name, false)
}
-pub fn alloca_maybe_zeroed(cx: block, ty: Type, name: &str, zero: bool) -> ValueRef {
+pub fn alloca_maybe_zeroed(cx: @mut Block, ty: Type, name: &str, zero: bool) -> ValueRef {
let _icx = push_ctxt("alloca");
if cx.unreachable {
unsafe {
p
}
-pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
+pub fn arrayalloca(cx: @mut Block, ty: Type, v: ValueRef) -> ValueRef {
let _icx = push_ctxt("arrayalloca");
if cx.unreachable {
unsafe {
// Creates and returns space for, or returns the argument representing, the
// slot where the return value of the function must go.
-pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
+pub fn make_return_pointer(fcx: @mut FunctionContext, output_type: ty::t) -> ValueRef {
unsafe {
if !ty::type_is_immediate(fcx.ccx.tcx, output_type) {
llvm::LLVMGetParam(fcx.llfn, 0)
param_substs: Option<@param_substs>,
opt_node_info: Option<NodeInfo>,
sp: Option<span>)
- -> fn_ctxt {
+ -> @mut FunctionContext {
for param_substs.iter().advance |p| { p.validate(); }
debug!("new_fn_ctxt_w_id(path=%s, id=%?, \
}
};
let is_immediate = ty::type_is_immediate(ccx.tcx, substd_output_type);
- let fcx = @mut fn_ctxt_ {
+ let fcx = @mut FunctionContext {
llfn: llfndecl,
llenv: unsafe {
llvm::LLVMGetUndef(Type::i8p().to_ref())
llfndecl: ValueRef,
output_type: ty::t,
sp: Option<span>)
- -> fn_ctxt {
+ -> @mut FunctionContext {
new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, None, sp)
}
// spaces that have been created for them (by code in the llallocas field of
// the function's fn_ctxt). create_llargs_for_fn_args populates the llargs
// field of the fn_ctxt with
-pub fn create_llargs_for_fn_args(cx: fn_ctxt,
+pub fn create_llargs_for_fn_args(cx: @mut FunctionContext,
self_arg: self_arg,
args: &[ast::arg])
-> ~[ValueRef] {
})
}
-pub fn copy_args_to_allocas(fcx: fn_ctxt,
- bcx: block,
+pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
+ bcx: @mut Block,
args: &[ast::arg],
raw_llargs: &[ValueRef],
- arg_tys: &[ty::t]) -> block {
+ arg_tys: &[ty::t]) -> @mut Block {
let _icx = push_ctxt("copy_args_to_allocas");
let mut bcx = bcx;
// Ties up the llstaticallocas -> llloadenv -> lltop edges,
// and builds the return block.
-pub fn finish_fn(fcx: fn_ctxt, last_bcx: block) {
+pub fn finish_fn(fcx: @mut FunctionContext, last_bcx: @mut Block) {
let _icx = push_ctxt("finish_fn");
let ret_cx = match fcx.llreturn {
}
// Builds the return block for a function.
-pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) {
+pub fn build_return_block(fcx: &FunctionContext, ret_cx: @mut Block) {
// Return the value if this function immediate; otherwise, return void.
if fcx.llretptr.is_some() && fcx.has_immediate_return_value {
Ret(ret_cx, Load(ret_cx, fcx.llretptr.get()))
id: ast::node_id,
attributes: &[ast::Attribute],
output_type: ty::t,
- maybe_load_env: &fn(fn_ctxt),
- finish: &fn(block)) {
+ maybe_load_env: &fn(@mut FunctionContext),
+ finish: &fn(@mut Block)) {
ccx.stats.n_closures += 1;
let _icx = push_ctxt("trans_closure");
set_uwtable(llfndecl);
|_bcx| { });
}
-fn insert_synthetic_type_entries(bcx: block,
+fn insert_synthetic_type_entries(bcx: @mut Block,
fn_args: &[ast::arg],
arg_tys: &[ty::t])
{
}
}
-pub fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef,
+pub fn fill_fn_pair(bcx: @mut Block, pair: ValueRef, llfn: ValueRef,
llenvptr: ValueRef) {
let ccx = bcx.ccx();
let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]);
let val = match item {
ast_map::node_item(i, pth) => {
let my_path = vec::append((*pth).clone(), [path_name(i.ident)]);
- match i.node {
+ let v = match i.node {
ast::item_static(_, m, expr) => {
let typ = ty::node_id_to_type(ccx.tcx, i.id);
let s = mangle_exported_name(ccx, my_path, typ);
llfn
}
_ => fail!("get_item_val: weird result in table")
+ };
+ match (attr::first_attr_value_str_by_name(i.attrs, "link_section")) {
+ Some(sect) => unsafe {
+ do sect.as_c_str |buf| {
+ llvm::LLVMSetSection(v, buf);
+ }
+ },
+ None => ()
}
+ v
}
ast_map::node_trait_method(trait_method, _, pth) => {
debug!("get_item_val(): processing a node_trait_method");
})));
}
-pub fn vp2i(cx: block, v: ValueRef) -> ValueRef {
+pub fn vp2i(cx: @mut Block, v: ValueRef) -> ValueRef {
let ccx = cx.ccx();
return PtrToInt(cx, v, ccx.int_type);
}
ifn!("llvm.dbg.value", [Type::metadata(), Type::i64(), Type::metadata()], Type::void());
}
-pub fn trap(bcx: block) {
+pub fn trap(bcx: @mut Block) {
match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") {
Some(&x) => { Call(bcx, x, []); },
_ => bcx.sess().bug("unbound llvm.trap in trap")
use std::cast;
use std::libc::{c_uint, c_ulonglong, c_char};
-pub fn terminate(cx: block, _: &str) {
+pub fn terminate(cx: @mut Block, _: &str) {
cx.terminated = true;
}
-pub fn check_not_terminated(cx: block) {
+pub fn check_not_terminated(cx: @mut Block) {
if cx.terminated {
fail!("already terminated!");
}
}
-pub fn B(cx: block) -> Builder {
+pub fn B(cx: @mut Block) -> Builder {
let b = cx.fcx.ccx.builder();
b.position_at_end(cx.llbb);
b
// for (fail/break/return statements, call to diverging functions, etc), and
// further instructions to the block should simply be ignored.
-pub fn RetVoid(cx: block) {
+pub fn RetVoid(cx: @mut Block) {
if cx.unreachable { return; }
check_not_terminated(cx);
terminate(cx, "RetVoid");
B(cx).ret_void();
}
-pub fn Ret(cx: block, V: ValueRef) {
+pub fn Ret(cx: @mut Block, V: ValueRef) {
if cx.unreachable { return; }
check_not_terminated(cx);
terminate(cx, "Ret");
B(cx).ret(V);
}
-pub fn AggregateRet(cx: block, RetVals: &[ValueRef]) {
+pub fn AggregateRet(cx: @mut Block, RetVals: &[ValueRef]) {
if cx.unreachable { return; }
check_not_terminated(cx);
terminate(cx, "AggregateRet");
B(cx).aggregate_ret(RetVals);
}
-pub fn Br(cx: block, Dest: BasicBlockRef) {
+pub fn Br(cx: @mut Block, Dest: BasicBlockRef) {
if cx.unreachable { return; }
check_not_terminated(cx);
terminate(cx, "Br");
B(cx).br(Dest);
}
-pub fn CondBr(cx: block, If: ValueRef, Then: BasicBlockRef,
+pub fn CondBr(cx: @mut Block, If: ValueRef, Then: BasicBlockRef,
Else: BasicBlockRef) {
if cx.unreachable { return; }
check_not_terminated(cx);
B(cx).cond_br(If, Then, Else);
}
-pub fn Switch(cx: block, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
+pub fn Switch(cx: @mut Block, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
-> ValueRef {
if cx.unreachable { return _Undef(V); }
check_not_terminated(cx);
}
}
-pub fn IndirectBr(cx: block, Addr: ValueRef, NumDests: uint) {
+pub fn IndirectBr(cx: @mut Block, Addr: ValueRef, NumDests: uint) {
if cx.unreachable { return; }
check_not_terminated(cx);
terminate(cx, "IndirectBr");
B(cx).indirect_br(Addr, NumDests);
}
-pub fn Invoke(cx: block,
+pub fn Invoke(cx: @mut Block,
Fn: ValueRef,
Args: &[ValueRef],
Then: BasicBlockRef,
B(cx).invoke(Fn, Args, Then, Catch)
}
-pub fn FastInvoke(cx: block, Fn: ValueRef, Args: &[ValueRef],
+pub fn FastInvoke(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef],
Then: BasicBlockRef, Catch: BasicBlockRef) {
if cx.unreachable { return; }
check_not_terminated(cx);
B(cx).fast_invoke(Fn, Args, Then, Catch);
}
-pub fn Unreachable(cx: block) {
+pub fn Unreachable(cx: @mut Block) {
if cx.unreachable { return; }
cx.unreachable = true;
if !cx.terminated {
}
/* Arithmetic */
-pub fn Add(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn Add(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).add(LHS, RHS)
}
-pub fn NSWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn NSWAdd(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).nswadd(LHS, RHS)
}
-pub fn NUWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn NUWAdd(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).nuwadd(LHS, RHS)
}
-pub fn FAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn FAdd(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).fadd(LHS, RHS)
}
-pub fn Sub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn Sub(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).sub(LHS, RHS)
}
-pub fn NSWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn NSWSub(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).nswsub(LHS, RHS)
}
-pub fn NUWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn NUWSub(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).nuwsub(LHS, RHS)
}
-pub fn FSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn FSub(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).fsub(LHS, RHS)
}
-pub fn Mul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn Mul(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).mul(LHS, RHS)
}
-pub fn NSWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn NSWMul(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).nswmul(LHS, RHS)
}
-pub fn NUWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn NUWMul(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).nuwmul(LHS, RHS)
}
-pub fn FMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn FMul(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).fmul(LHS, RHS)
}
-pub fn UDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn UDiv(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).udiv(LHS, RHS)
}
-pub fn SDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn SDiv(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).sdiv(LHS, RHS)
}
-pub fn ExactSDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn ExactSDiv(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).exactsdiv(LHS, RHS)
}
-pub fn FDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn FDiv(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).fdiv(LHS, RHS)
}
-pub fn URem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn URem(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).urem(LHS, RHS)
}
-pub fn SRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn SRem(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).srem(LHS, RHS)
}
-pub fn FRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn FRem(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).frem(LHS, RHS)
}
-pub fn Shl(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn Shl(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).shl(LHS, RHS)
}
-pub fn LShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn LShr(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).lshr(LHS, RHS)
}
-pub fn AShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn AShr(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).ashr(LHS, RHS)
}
-pub fn And(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn And(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).and(LHS, RHS)
}
-pub fn Or(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn Or(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).or(LHS, RHS)
}
-pub fn Xor(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn Xor(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).xor(LHS, RHS)
}
-pub fn BinOp(cx: block, Op: Opcode, LHS: ValueRef, RHS: ValueRef)
+pub fn BinOp(cx: @mut Block, Op: Opcode, LHS: ValueRef, RHS: ValueRef)
-> ValueRef {
if cx.unreachable { return _Undef(LHS); }
B(cx).binop(Op, LHS, RHS)
}
-pub fn Neg(cx: block, V: ValueRef) -> ValueRef {
+pub fn Neg(cx: @mut Block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
B(cx).neg(V)
}
-pub fn NSWNeg(cx: block, V: ValueRef) -> ValueRef {
+pub fn NSWNeg(cx: @mut Block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
B(cx).nswneg(V)
}
-pub fn NUWNeg(cx: block, V: ValueRef) -> ValueRef {
+pub fn NUWNeg(cx: @mut Block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
B(cx).nuwneg(V)
}
-pub fn FNeg(cx: block, V: ValueRef) -> ValueRef {
+pub fn FNeg(cx: @mut Block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
B(cx).fneg(V)
}
-pub fn Not(cx: block, V: ValueRef) -> ValueRef {
+pub fn Not(cx: @mut Block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
B(cx).not(V)
}
/* Memory */
-pub fn Malloc(cx: block, Ty: Type) -> ValueRef {
+pub fn Malloc(cx: @mut Block, Ty: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
B(cx).malloc(Ty)
}
}
-pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef {
+pub fn ArrayMalloc(cx: @mut Block, Ty: Type, Val: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
B(cx).array_malloc(Ty, Val)
}
}
-pub fn Alloca(cx: block, Ty: Type, name: &str) -> ValueRef {
+pub fn Alloca(cx: @mut Block, Ty: Type, name: &str) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
let b = cx.fcx.ccx.builder();
}
}
-pub fn ArrayAlloca(cx: block, Ty: Type, Val: ValueRef) -> ValueRef {
+pub fn ArrayAlloca(cx: @mut Block, Ty: Type, Val: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
let b = cx.fcx.ccx.builder();
}
}
-pub fn Free(cx: block, PointerVal: ValueRef) {
+pub fn Free(cx: @mut Block, PointerVal: ValueRef) {
if cx.unreachable { return; }
B(cx).free(PointerVal)
}
-pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
+pub fn Load(cx: @mut Block, PointerVal: ValueRef) -> ValueRef {
unsafe {
let ccx = cx.fcx.ccx;
if cx.unreachable {
}
}
-pub fn AtomicLoad(cx: block, PointerVal: ValueRef, order: AtomicOrdering) -> ValueRef {
+pub fn AtomicLoad(cx: @mut Block, PointerVal: ValueRef, order: AtomicOrdering) -> ValueRef {
unsafe {
let ccx = cx.fcx.ccx;
if cx.unreachable {
}
-pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong,
+pub fn LoadRangeAssert(cx: @mut Block, PointerVal: ValueRef, lo: c_ulonglong,
hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
if cx.unreachable {
let ccx = cx.fcx.ccx;
}
}
-pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
+pub fn Store(cx: @mut Block, Val: ValueRef, Ptr: ValueRef) {
if cx.unreachable { return; }
B(cx).store(Val, Ptr)
}
-pub fn AtomicStore(cx: block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrdering) {
+pub fn AtomicStore(cx: @mut Block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrdering) {
if cx.unreachable { return; }
B(cx).atomic_store(Val, Ptr, order)
}
-pub fn GEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef {
+pub fn GEP(cx: @mut Block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); }
B(cx).gep(Pointer, Indices)
// Simple wrapper around GEP that takes an array of ints and wraps them
// in C_i32()
#[inline]
-pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef {
+pub fn GEPi(cx: @mut Block, base: ValueRef, ixs: &[uint]) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); }
B(cx).gepi(base, ixs)
}
}
-pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef {
+pub fn InBoundsGEP(cx: @mut Block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); }
B(cx).inbounds_gep(Pointer, Indices)
}
}
-pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef {
+pub fn StructGEP(cx: @mut Block, Pointer: ValueRef, Idx: uint) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); }
B(cx).struct_gep(Pointer, Idx)
}
}
-pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef {
+pub fn GlobalString(cx: @mut Block, _Str: *c_char) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
B(cx).global_string(_Str)
}
}
-pub fn GlobalStringPtr(cx: block, _Str: *c_char) -> ValueRef {
+pub fn GlobalStringPtr(cx: @mut Block, _Str: *c_char) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); }
B(cx).global_string_ptr(_Str)
}
/* Casts */
-pub fn Trunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn Trunc(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).trunc(Val, DestTy)
}
}
-pub fn ZExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn ZExt(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).zext(Val, DestTy)
}
}
-pub fn SExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn SExt(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).sext(Val, DestTy)
}
}
-pub fn FPToUI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn FPToUI(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).fptoui(Val, DestTy)
}
}
-pub fn FPToSI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn FPToSI(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).fptosi(Val, DestTy)
}
}
-pub fn UIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn UIToFP(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).uitofp(Val, DestTy)
}
}
-pub fn SIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn SIToFP(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).sitofp(Val, DestTy)
}
}
-pub fn FPTrunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn FPTrunc(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).fptrunc(Val, DestTy)
}
}
-pub fn FPExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn FPExt(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).fpext(Val, DestTy)
}
}
-pub fn PtrToInt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn PtrToInt(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).ptrtoint(Val, DestTy)
}
}
-pub fn IntToPtr(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn IntToPtr(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).inttoptr(Val, DestTy)
}
}
-pub fn BitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn BitCast(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).bitcast(Val, DestTy)
}
}
-pub fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn ZExtOrBitCast(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).zext_or_bitcast(Val, DestTy)
}
}
-pub fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn SExtOrBitCast(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).sext_or_bitcast(Val, DestTy)
}
}
-pub fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn TruncOrBitCast(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).trunc_or_bitcast(Val, DestTy)
}
}
-pub fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: Type, _: *u8)
+pub fn Cast(cx: @mut Block, Op: Opcode, Val: ValueRef, DestTy: Type, _: *u8)
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
}
}
-pub fn PointerCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn PointerCast(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).pointercast(Val, DestTy)
}
}
-pub fn IntCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn IntCast(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).intcast(Val, DestTy)
}
}
-pub fn FPCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef {
+pub fn FPCast(cx: @mut Block, Val: ValueRef, DestTy: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); }
B(cx).fpcast(Val, DestTy)
/* Comparisons */
-pub fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef)
+pub fn ICmp(cx: @mut Block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef)
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); }
}
}
-pub fn FCmp(cx: block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef)
+pub fn FCmp(cx: @mut Block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef)
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); }
}
/* Miscellaneous instructions */
-pub fn EmptyPhi(cx: block, Ty: Type) -> ValueRef {
+pub fn EmptyPhi(cx: @mut Block, Ty: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); }
B(cx).empty_phi(Ty)
}
}
-pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef {
+pub fn Phi(cx: @mut Block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); }
B(cx).phi(Ty, vals, bbs)
}
}
-pub fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef {
+pub fn _UndefReturn(cx: @mut Block, Fn: ValueRef) -> ValueRef {
unsafe {
let ccx = cx.fcx.ccx;
let ty = val_ty(Fn);
}
}
-pub fn add_span_comment(cx: block, sp: span, text: &str) {
+pub fn add_span_comment(cx: @mut Block, sp: span, text: &str) {
B(cx).add_span_comment(sp, text)
}
-pub fn add_comment(cx: block, text: &str) {
+pub fn add_comment(cx: @mut Block, text: &str) {
B(cx).add_comment(text)
}
-pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
+pub fn InlineAsmCall(cx: @mut Block, asm: *c_char, cons: *c_char,
inputs: &[ValueRef], output: Type,
volatile: bool, alignstack: bool,
dia: AsmDialect) -> ValueRef {
B(cx).inline_asm_call(asm, cons, inputs, output, volatile, alignstack, dia)
}
-pub fn Call(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
+pub fn Call(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
if cx.unreachable { return _UndefReturn(cx, Fn); }
B(cx).call(Fn, Args)
}
-pub fn FastCall(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
+pub fn FastCall(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
if cx.unreachable { return _UndefReturn(cx, Fn); }
B(cx).call(Fn, Args)
}
-pub fn CallWithConv(cx: block, Fn: ValueRef, Args: &[ValueRef],
+pub fn CallWithConv(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef],
Conv: CallConv) -> ValueRef {
if cx.unreachable { return _UndefReturn(cx, Fn); }
B(cx).call_with_conv(Fn, Args, Conv)
}
-pub fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) -> ValueRef {
+pub fn Select(cx: @mut Block, If: ValueRef, Then: ValueRef, Else: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(Then); }
B(cx).select(If, Then, Else)
}
-pub fn VAArg(cx: block, list: ValueRef, Ty: Type) -> ValueRef {
+pub fn VAArg(cx: @mut Block, list: ValueRef, Ty: Type) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); }
B(cx).va_arg(list, Ty)
}
}
-pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> ValueRef {
+pub fn ExtractElement(cx: @mut Block, VecVal: ValueRef, Index: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
B(cx).extract_element(VecVal, Index)
}
}
-pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef,
+pub fn InsertElement(cx: @mut Block, VecVal: ValueRef, EltVal: ValueRef,
Index: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
}
}
-pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
+pub fn ShuffleVector(cx: @mut Block, V1: ValueRef, V2: ValueRef,
Mask: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
}
}
-pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef {
+pub fn VectorSplat(cx: @mut Block, NumElts: uint, EltVal: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
B(cx).vector_splat(NumElts, EltVal)
}
}
-pub fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef {
+pub fn ExtractValue(cx: @mut Block, AggVal: ValueRef, Index: uint) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); }
B(cx).extract_value(AggVal, Index)
}
}
-pub fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef, Index: uint) {
+pub fn InsertValue(cx: @mut Block, AggVal: ValueRef, EltVal: ValueRef, Index: uint) {
if cx.unreachable { return; }
B(cx).insert_value(AggVal, EltVal, Index)
}
-pub fn IsNull(cx: block, Val: ValueRef) -> ValueRef {
+pub fn IsNull(cx: @mut Block, Val: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); }
B(cx).is_null(Val)
}
}
-pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef {
+pub fn IsNotNull(cx: @mut Block, Val: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); }
B(cx).is_not_null(Val)
}
}
-pub fn PtrDiff(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+pub fn PtrDiff(cx: @mut Block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
unsafe {
let ccx = cx.fcx.ccx;
if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type.to_ref()); }
}
}
-pub fn Trap(cx: block) {
+pub fn Trap(cx: @mut Block) {
if cx.unreachable { return; }
B(cx).trap();
}
-pub fn LandingPad(cx: block, Ty: Type, PersFn: ValueRef,
+pub fn LandingPad(cx: @mut Block, Ty: Type, PersFn: ValueRef,
NumClauses: uint) -> ValueRef {
check_not_terminated(cx);
assert!(!cx.unreachable);
B(cx).landing_pad(Ty, PersFn, NumClauses)
}
-pub fn SetCleanup(cx: block, LandingPad: ValueRef) {
+pub fn SetCleanup(cx: @mut Block, LandingPad: ValueRef) {
B(cx).set_cleanup(LandingPad)
}
-pub fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
+pub fn Resume(cx: @mut Block, Exn: ValueRef) -> ValueRef {
check_not_terminated(cx);
terminate(cx, "Resume");
B(cx).resume(Exn)
}
// Atomic Operations
-pub fn AtomicCmpXchg(cx: block, dst: ValueRef,
+pub fn AtomicCmpXchg(cx: @mut Block, dst: ValueRef,
cmp: ValueRef, src: ValueRef,
order: AtomicOrdering) -> ValueRef {
B(cx).atomic_cmpxchg(dst, cmp, src, order)
}
-pub fn AtomicRMW(cx: block, op: AtomicBinOp,
+pub fn AtomicRMW(cx: @mut Block, op: AtomicBinOp,
dst: ValueRef, src: ValueRef,
order: AtomicOrdering) -> ValueRef {
B(cx).atomic_rmw(op, dst, src, order)
return llfn;
}
- pub fn build_shim_args(&self, bcx: block, arg_tys: &[Type], llargbundle: ValueRef)
+ pub fn build_shim_args(&self, bcx: @mut Block, arg_tys: &[Type], llargbundle: ValueRef)
-> ~[ValueRef] {
let mut atys: &[LLVMType] = self.arg_tys;
let mut attrs: &[option::Option<Attribute>] = self.attrs;
return llargvals;
}
- pub fn build_shim_ret(&self, bcx: block, arg_tys: &[Type], ret_def: bool,
+ pub fn build_shim_ret(&self, bcx: @mut Block, arg_tys: &[Type], ret_def: bool,
llargbundle: ValueRef, llretval: ValueRef) {
for self.attrs.iter().enumerate().advance |(i, a)| {
match *a {
};
}
- pub fn build_wrap_args(&self, bcx: block, ret_ty: Type,
+ pub fn build_wrap_args(&self, bcx: @mut Block, ret_ty: Type,
llwrapfn: ValueRef, llargbundle: ValueRef) {
let mut atys: &[LLVMType] = self.arg_tys;
let mut attrs: &[option::Option<Attribute>] = self.attrs;
store_inbounds(bcx, llretptr, llargbundle, [0u, n]);
}
- pub fn build_wrap_ret(&self, bcx: block, arg_tys: &[Type], llargbundle: ValueRef) {
+ pub fn build_wrap_ret(&self, bcx: @mut Block, arg_tys: &[Type], llargbundle: ValueRef) {
if self.ret_ty.ty.kind() == Void {
return;
}
}
pub struct Callee {
- bcx: block,
+ bcx: @mut Block,
data: CalleeData
}
-pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
+pub fn trans(bcx: @mut Block, expr: @ast::expr) -> Callee {
let _icx = push_ctxt("trans_callee");
debug!("callee::trans(expr=%s)", expr.repr(bcx.tcx()));
// any other expressions are closures:
return datum_callee(bcx, expr);
- fn datum_callee(bcx: block, expr: @ast::expr) -> Callee {
+ fn datum_callee(bcx: @mut Block, expr: @ast::expr) -> Callee {
let DatumBlock {bcx, datum} = expr::trans_to_datum(bcx, expr);
match ty::get(datum.ty).sty {
ty::ty_bare_fn(*) => {
}
}
- fn fn_callee(bcx: block, fd: FnData) -> Callee {
+ fn fn_callee(bcx: @mut Block, fd: FnData) -> Callee {
return Callee {bcx: bcx, data: Fn(fd)};
}
- fn trans_def(bcx: block, def: ast::def, ref_expr: @ast::expr) -> Callee {
+ fn trans_def(bcx: @mut Block, def: ast::def, ref_expr: @ast::expr) -> Callee {
match def {
ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id))
}
}
-pub fn trans_fn_ref_to_callee(bcx: block,
+pub fn trans_fn_ref_to_callee(bcx: @mut Block,
def_id: ast::def_id,
ref_id: ast::node_id) -> Callee {
Callee {bcx: bcx,
data: Fn(trans_fn_ref(bcx, def_id, ref_id))}
}
-pub fn trans_fn_ref(bcx: block,
+pub fn trans_fn_ref(bcx: @mut Block,
def_id: ast::def_id,
ref_id: ast::node_id) -> FnData {
/*!
}
pub fn trans_fn_ref_with_vtables_to_callee(
- bcx: block,
+ bcx: @mut Block,
def_id: ast::def_id,
ref_id: ast::node_id,
type_params: &[ty::t],
type_params, vtables))}
}
-fn get_impl_resolutions(bcx: block,
+fn get_impl_resolutions(bcx: @mut Block,
impl_id: ast::def_id)
-> typeck::vtable_res {
if impl_id.crate == ast::local_crate {
}
}
-fn resolve_default_method_vtables(bcx: block,
+fn resolve_default_method_vtables(bcx: @mut Block,
impl_id: ast::def_id,
method: &ty::Method,
substs: &ty::substs,
pub fn trans_fn_ref_with_vtables(
- bcx: block, //
+ bcx: @mut Block, //
def_id: ast::def_id, // def id of fn
ref_id: ast::node_id, // node id of use of fn; may be zero if N/A
type_params: &[ty::t], // values for fn's ty params
// ______________________________________________________________________
// Translating calls
-pub fn trans_call(in_cx: block,
+pub fn trans_call(in_cx: @mut Block,
call_ex: @ast::expr,
f: @ast::expr,
args: CallArgs,
id: ast::node_id,
dest: expr::Dest)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("trans_call");
trans_call_inner(in_cx,
call_ex.info(),
DontAutorefArg).bcx
}
-pub fn trans_method_call(in_cx: block,
+pub fn trans_method_call(in_cx: @mut Block,
call_ex: @ast::expr,
callee_id: ast::node_id,
rcvr: @ast::expr,
args: CallArgs,
dest: expr::Dest)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("trans_method_call");
debug!("trans_method_call(call_ex=%s, rcvr=%s)",
call_ex.repr(in_cx.tcx()),
DontAutorefArg).bcx
}
-pub fn trans_lang_call(bcx: block,
+pub fn trans_lang_call(bcx: @mut Block,
did: ast::def_id,
args: &[ValueRef],
dest: Option<expr::Dest>)
DontAutorefArg)
}
-pub fn trans_lang_call_with_type_params(bcx: block,
+pub fn trans_lang_call_with_type_params(bcx: @mut Block,
did: ast::def_id,
args: &[ValueRef],
type_params: &[ty::t],
dest: expr::Dest)
- -> block {
+ -> @mut Block {
let fty;
if did.crate == ast::local_crate {
fty = ty::node_id_to_type(bcx.tcx(), did.node);
}
// See [Note-arg-mode]
-pub fn trans_call_inner(in_cx: block,
+pub fn trans_call_inner(in_cx: @mut Block,
call_info: Option<NodeInfo>,
fn_expr_ty: ty::t,
ret_ty: ty::t,
- get_callee: &fn(block) -> Callee,
+ get_callee: &fn(@mut Block) -> Callee,
args: CallArgs,
dest: Option<expr::Dest>,
autoref_arg: AutorefArg)
ArgVals(&'self [ValueRef])
}
-pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: Option<expr::Dest>)
+pub fn trans_ret_slot(bcx: @mut Block, fn_ty: ty::t, dest: Option<expr::Dest>)
-> ValueRef {
let retty = ty::ty_fn_ret(fn_ty);
}
}
-pub fn trans_args(cx: block,
+pub fn trans_args(cx: @mut Block,
args: CallArgs,
fn_ty: ty::t,
ret_flag: Option<ValueRef>,
autoref_arg: AutorefArg,
- llargs: &mut ~[ValueRef]) -> block
+ llargs: &mut ~[ValueRef]) -> @mut Block
{
let _icx = push_ctxt("trans_args");
let mut temp_cleanups = ~[];
// temp_cleanups: cleanups that should run only if failure occurs before the
// call takes place:
-pub fn trans_arg_expr(bcx: block,
+pub fn trans_arg_expr(bcx: @mut Block,
formal_arg_ty: ty::t,
self_mode: ty::SelfMode,
arg_expr: @ast::expr,
return cdata_ty;
}
-fn heap_for_unique_closure(bcx: block, t: ty::t) -> heap {
+fn heap_for_unique_closure(bcx: @mut Block, t: ty::t) -> heap {
if ty::type_contents(bcx.tcx(), t).contains_managed() {
heap_managed_unique
} else {
}
}
-pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t)
+pub fn allocate_cbox(bcx: @mut Block, sigil: ast::Sigil, cdata_ty: ty::t)
-> Result {
let _icx = push_ctxt("closure::allocate_cbox");
let ccx = bcx.ccx();
pub struct ClosureResult {
llbox: ValueRef, // llvalue of ptr to closure
cdata_ty: ty::t, // type of the closure data
- bcx: block // final bcx
+ bcx: @mut Block // final bcx
}
// Given a block context and a list of tydescs and values to bind
// construct a closure out of them. If copying is true, it is a
// heap allocated closure that copies the upvars into environment.
// Otherwise, it is stack allocated and copies pointers to the upvars.
-pub fn store_environment(bcx: block,
+pub fn store_environment(bcx: @mut Block,
bound_values: ~[EnvValue],
sigil: ast::Sigil) -> ClosureResult {
let _icx = push_ctxt("closure::store_environment");
// Given a context and a list of upvars, build a closure. This just
// collects the upvars and packages them up for store_environment.
-pub fn build_closure(bcx0: block,
+pub fn build_closure(bcx0: @mut Block,
cap_vars: &[moves::CaptureVar],
sigil: ast::Sigil,
include_ret_handle: Option<ValueRef>) -> ClosureResult {
// Given an enclosing block context, a new function context, a closure type,
// and a list of upvars, generate code to load and populate the environment
// with the upvars and type descriptors.
-pub fn load_environment(fcx: fn_ctxt,
+pub fn load_environment(fcx: @mut FunctionContext,
cdata_ty: ty::t,
cap_vars: &[moves::CaptureVar],
load_ret_handle: bool,
}
}
-pub fn trans_expr_fn(bcx: block,
+pub fn trans_expr_fn(bcx: @mut Block,
sigil: ast::Sigil,
decl: &ast::fn_decl,
body: &ast::Block,
outer_id: ast::node_id,
user_id: ast::node_id,
is_loop_body: Option<Option<ValueRef>>,
- dest: expr::Dest) -> block {
+ dest: expr::Dest) -> @mut Block {
/*!
*
* Translates the body of a closure expression.
}
pub fn make_closure_glue(
- cx: block,
+ cx: @mut Block,
v: ValueRef,
t: ty::t,
- glue_fn: &fn(block, v: ValueRef, t: ty::t) -> block) -> block {
+ glue_fn: &fn(@mut Block, v: ValueRef, t: ty::t) -> @mut Block) -> @mut Block {
let _icx = push_ctxt("closure::make_closure_glue");
let bcx = cx;
let tcx = cx.tcx();
}
pub fn make_opaque_cbox_take_glue(
- bcx: block,
+ bcx: @mut Block,
sigil: ast::Sigil,
cboxptr: ValueRef) // ptr to ptr to the opaque closure
- -> block {
+ -> @mut Block {
// Easy cases:
let _icx = push_ctxt("closure::make_opaque_cbox_take_glue");
match sigil {
}
pub fn make_opaque_cbox_drop_glue(
- bcx: block,
+ bcx: @mut Block,
sigil: ast::Sigil,
cboxptr: ValueRef) // ptr to the opaque closure
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue");
match sigil {
ast::BorrowedSigil => bcx,
}
pub fn make_opaque_cbox_free_glue(
- bcx: block,
+ bcx: @mut Block,
sigil: ast::Sigil,
cbox: ValueRef) // ptr to ptr to the opaque closure
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("closure::make_opaque_cbox_free_glue");
match sigil {
ast::BorrowedSigil => {
// Function context. Every LLVM function we create will have one of
// these.
-pub struct fn_ctxt_ {
+pub struct FunctionContext {
// The ValueRef returned from a call to llvm::LLVMAddFunction; the
// address of the first instruction in the sequence of
// instructions for this function that will go in the .text
// always be Some.
llretptr: Option<ValueRef>,
- entry_bcx: Option<block>,
+ entry_bcx: Option<@mut Block>,
// These elements: "hoisted basic blocks" containing
// administrative activities that have to happen in only one place in
ccx: @mut CrateContext
}
-impl fn_ctxt_ {
+impl FunctionContext {
pub fn arg_pos(&self, arg: uint) -> uint {
if self.has_immediate_return_value {
arg + 1u
}
}
-pub type fn_ctxt = @mut fn_ctxt_;
-
pub fn warn_not_to_commit(ccx: &mut CrateContext, msg: &str) {
if !ccx.do_not_commit_warning_issued {
ccx.do_not_commit_warning_issued = true;
}
pub enum cleanup {
- clean(@fn(block) -> block, cleantype),
- clean_temp(ValueRef, @fn(block) -> block, cleantype),
+ clean(@fn(@mut Block) -> @mut Block, cleantype),
+ clean_temp(ValueRef, @fn(@mut Block) -> @mut Block, cleantype),
}
// Can't use deriving(Clone) because of the managed closure.
dest: BasicBlockRef
}
-pub fn shrink_scope_clean(scope_info: &mut scope_info, size: uint) {
+pub fn shrink_scope_clean(scope_info: &mut ScopeInfo, size: uint) {
scope_info.landing_pad = None;
scope_info.cleanup_paths = scope_info.cleanup_paths.iter()
.take_while(|&cu| cu.size <= size).transform(|&x|x).collect();
}
-pub fn grow_scope_clean(scope_info: &mut scope_info) {
+pub fn grow_scope_clean(scope_info: &mut ScopeInfo) {
scope_info.landing_pad = None;
}
}
}
-pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) {
+pub fn add_clean(bcx: @mut Block, val: ValueRef, t: ty::t) {
if !ty::type_needs_drop(bcx.tcx(), t) { return; }
debug!("add_clean(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx()));
}
}
-pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) {
+pub fn add_clean_temp_immediate(cx: @mut Block, val: ValueRef, ty: ty::t) {
if !ty::type_needs_drop(cx.tcx(), ty) { return; }
debug!("add_clean_temp_immediate(%s, %s, %s)",
cx.to_str(), cx.val_to_str(val),
}
}
-pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) {
+pub fn add_clean_temp_mem(bcx: @mut Block, val: ValueRef, t: ty::t) {
add_clean_temp_mem_in_scope_(bcx, None, val, t);
}
-pub fn add_clean_temp_mem_in_scope(bcx: block, scope_id: ast::node_id, val: ValueRef, t: ty::t) {
+pub fn add_clean_temp_mem_in_scope(bcx: @mut Block,
+ scope_id: ast::node_id,
+ val: ValueRef,
+ t: ty::t) {
add_clean_temp_mem_in_scope_(bcx, Some(scope_id), val, t);
}
-pub fn add_clean_temp_mem_in_scope_(bcx: block, scope_id: Option<ast::node_id>,
+pub fn add_clean_temp_mem_in_scope_(bcx: @mut Block, scope_id: Option<ast::node_id>,
val: ValueRef, t: ty::t) {
if !ty::type_needs_drop(bcx.tcx(), t) { return; }
debug!("add_clean_temp_mem(%s, %s, %s)",
grow_scope_clean(scope_info);
}
}
-pub fn add_clean_return_to_mut(bcx: block,
+pub fn add_clean_return_to_mut(bcx: @mut Block,
scope_id: ast::node_id,
root_key: root_map_key,
frozen_val_ref: ValueRef,
grow_scope_clean(scope_info);
}
}
-pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) {
+pub fn add_clean_free(cx: @mut Block, ptr: ValueRef, heap: heap) {
let free_fn = match heap {
heap_managed | heap_managed_unique => {
- let f: @fn(block) -> block = |a| glue::trans_free(a, ptr);
+ let f: @fn(@mut Block) -> @mut Block = |a| glue::trans_free(a, ptr);
f
}
heap_exchange | heap_exchange_closure => {
- let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr);
+ let f: @fn(@mut Block) -> @mut Block = |a| glue::trans_exchange_free(a, ptr);
f
}
};
// to a system where we can also cancel the cleanup on local variables, but
// this will be more involved. For now, we simply zero out the local, and the
// drop glue checks whether it is zero.
-pub fn revoke_clean(cx: block, val: ValueRef) {
+pub fn revoke_clean(cx: @mut Block, val: ValueRef) {
do in_scope_cx(cx, None) |scope_info| {
let cleanup_pos = scope_info.cleanups.iter().position(
|cu| match *cu {
}
}
-pub fn block_cleanups(bcx: block) -> ~[cleanup] {
+pub fn block_cleanups(bcx: @mut Block) -> ~[cleanup] {
match bcx.scope {
None => ~[],
Some(inf) => inf.cleanups.clone(),
}
}
-pub struct scope_info {
- parent: Option<@mut scope_info>,
- loop_break: Option<block>,
+pub struct ScopeInfo {
+ parent: Option<@mut ScopeInfo>,
+ loop_break: Option<@mut Block>,
loop_label: Option<ident>,
// A list of functions that must be run at when leaving this
// block, cleaning up any variables that were introduced in the
node_info: Option<NodeInfo>,
}
-impl scope_info {
+impl ScopeInfo {
pub fn empty_cleanups(&mut self) -> bool {
self.cleanups.is_empty()
}
// code. Each basic block we generate is attached to a function, typically
// with many basic blocks per function. All the basic blocks attached to a
// function are organized as a directed graph.
-pub struct block_ {
+pub struct Block {
// The BasicBlockRef returned from a call to
// llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
// block to the function pointed to by llfn. We insert
llbb: BasicBlockRef,
terminated: bool,
unreachable: bool,
- parent: Option<block>,
+ parent: Option<@mut Block>,
// The current scope within this basic block
- scope: Option<@mut scope_info>,
+ scope: Option<@mut ScopeInfo>,
// Is this block part of a landing pad?
is_lpad: bool,
// info about the AST node this block originated from, if any
node_info: Option<NodeInfo>,
// The function context for the function to which this block is
// attached.
- fcx: fn_ctxt
-}
+ fcx: @mut FunctionContext
+}
+
+impl Block {
+
+ pub fn new(llbb: BasicBlockRef,
+ parent: Option<@mut Block>,
+ is_lpad: bool,
+ node_info: Option<NodeInfo>,
+ fcx: @mut FunctionContext)
+ -> Block {
+ Block {
+ llbb: llbb,
+ terminated: false,
+ unreachable: false,
+ parent: parent,
+ scope: None,
+ is_lpad: is_lpad,
+ node_info: node_info,
+ fcx: fcx
+ }
+ }
+
+ pub fn ccx(&self) -> @mut CrateContext { self.fcx.ccx }
+ pub fn tcx(&self) -> ty::ctxt { self.fcx.ccx.tcx }
+ pub fn sess(&self) -> Session { self.fcx.ccx.sess }
-pub fn block_(llbb: BasicBlockRef, parent: Option<block>,
- is_lpad: bool, node_info: Option<NodeInfo>, fcx: fn_ctxt)
- -> block_ {
+ pub fn ident(&self, ident: ident) -> @str {
+ token::ident_to_str(&ident)
+ }
- block_ {
- llbb: llbb,
- terminated: false,
- unreachable: false,
- parent: parent,
- scope: None,
- is_lpad: is_lpad,
- node_info: node_info,
- fcx: fcx
+ pub fn node_id_to_str(&self, id: ast::node_id) -> ~str {
+ ast_map::node_id_to_str(self.tcx().items, id, self.sess().intr())
+ }
+
+ pub fn expr_to_str(&self, e: @ast::expr) -> ~str {
+ e.repr(self.tcx())
+ }
+
+ pub fn expr_is_lval(&self, e: &ast::expr) -> bool {
+ ty::expr_is_lval(self.tcx(), self.ccx().maps.method_map, e)
+ }
+
+ pub fn expr_kind(&self, e: &ast::expr) -> ty::ExprKind {
+ ty::expr_kind(self.tcx(), self.ccx().maps.method_map, e)
+ }
+
+ pub fn def(&self, nid: ast::node_id) -> ast::def {
+ match self.tcx().def_map.find(&nid) {
+ Some(&v) => v,
+ None => {
+ self.tcx().sess.bug(fmt!(
+ "No def associated with node id %?", nid));
+ }
+ }
+ }
+
+ pub fn val_to_str(&self, val: ValueRef) -> ~str {
+ self.ccx().tn.val_to_str(val)
+ }
+
+ pub fn llty_str(&self, ty: Type) -> ~str {
+ self.ccx().tn.type_to_str(ty)
}
-}
-pub type block = @mut block_;
+ pub fn ty_to_str(&self, t: ty::t) -> ~str {
+ t.repr(self.tcx())
+ }
-pub fn mk_block(llbb: BasicBlockRef, parent: Option<block>,
- is_lpad: bool, node_info: Option<NodeInfo>, fcx: fn_ctxt)
- -> block {
- @mut block_(llbb, parent, is_lpad, node_info, fcx)
+ pub fn to_str(&self) -> ~str {
+ unsafe {
+ match self.node_info {
+ Some(node_info) => fmt!("[block %d]", node_info.id),
+ None => fmt!("[block %x]", transmute(&*self)),
+ }
+ }
+ }
}
pub struct Result {
- bcx: block,
+ bcx: @mut Block,
val: ValueRef
}
-pub fn rslt(bcx: block, val: ValueRef) -> Result {
+pub fn rslt(bcx: @mut Block, val: ValueRef) -> Result {
Result {bcx: bcx, val: val}
}
impl Result {
- pub fn unpack(&self, bcx: &mut block) -> ValueRef {
+ pub fn unpack(&self, bcx: &mut @mut Block) -> ValueRef {
*bcx = self.bcx;
return self.val;
}
}
}
-pub fn in_scope_cx(cx: block, scope_id: Option<ast::node_id>, f: &fn(si: &mut scope_info)) {
+pub fn in_scope_cx(cx: @mut Block, scope_id: Option<ast::node_id>, f: &fn(si: &mut ScopeInfo)) {
let mut cur = cx;
let mut cur_scope = cur.scope;
loop {
}
}
-pub fn block_parent(cx: block) -> block {
+pub fn block_parent(cx: @mut Block) -> @mut Block {
match cx.parent {
Some(b) => b,
None => cx.sess().bug(fmt!("block_parent called on root block %?",
}
}
-// Accessors
-
-impl block_ {
- pub fn ccx(&self) -> @mut CrateContext { self.fcx.ccx }
- pub fn tcx(&self) -> ty::ctxt { self.fcx.ccx.tcx }
- pub fn sess(&self) -> Session { self.fcx.ccx.sess }
-
- pub fn ident(&self, ident: ident) -> @str {
- token::ident_to_str(&ident)
- }
-
- pub fn node_id_to_str(&self, id: ast::node_id) -> ~str {
- ast_map::node_id_to_str(self.tcx().items, id, self.sess().intr())
- }
-
- pub fn expr_to_str(&self, e: @ast::expr) -> ~str {
- e.repr(self.tcx())
- }
-
- pub fn expr_is_lval(&self, e: &ast::expr) -> bool {
- ty::expr_is_lval(self.tcx(), self.ccx().maps.method_map, e)
- }
-
- pub fn expr_kind(&self, e: &ast::expr) -> ty::ExprKind {
- ty::expr_kind(self.tcx(), self.ccx().maps.method_map, e)
- }
-
- pub fn def(&self, nid: ast::node_id) -> ast::def {
- match self.tcx().def_map.find(&nid) {
- Some(&v) => v,
- None => {
- self.tcx().sess.bug(fmt!(
- "No def associated with node id %?", nid));
- }
- }
- }
-
- pub fn val_to_str(&self, val: ValueRef) -> ~str {
- self.ccx().tn.val_to_str(val)
- }
-
- pub fn llty_str(&self, ty: Type) -> ~str {
- self.ccx().tn.type_to_str(ty)
- }
-
- pub fn ty_to_str(&self, t: ty::t) -> ~str {
- t.repr(self.tcx())
- }
-
- pub fn to_str(&self) -> ~str {
- unsafe {
- match self.node_info {
- Some(node_info) => fmt!("[block %d]", node_info.id),
- None => fmt!("[block %x]", transmute(&*self)),
- }
- }
- }
-}
// Let T be the content of a box @T. tuplify_box_ty(t) returns the
// representation of @T as a tuple (i.e., the ty::t version of what T_box()
pub type mono_id = @mono_id_;
-pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
+pub fn umax(cx: @mut Block, a: ValueRef, b: ValueRef) -> ValueRef {
let cond = build::ICmp(cx, lib::llvm::IntULT, a, b);
return build::Select(cx, cond, b, a);
}
-pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
+pub fn umin(cx: @mut Block, a: ValueRef, b: ValueRef) -> ValueRef {
let cond = build::ICmp(cx, lib::llvm::IntULT, a, b);
return build::Select(cx, cond, a, b);
}
-pub fn align_to(cx: block, off: ValueRef, align: ValueRef) -> ValueRef {
+pub fn align_to(cx: @mut Block, off: ValueRef, align: ValueRef) -> ValueRef {
let mask = build::Sub(cx, align, C_int(cx.ccx(), 1));
let bumped = build::Add(cx, off, mask);
return build::And(cx, bumped, build::Not(cx, mask));
r
}
-pub fn monomorphize_type(bcx: block, t: ty::t) -> ty::t {
+pub fn monomorphize_type(bcx: @mut Block, t: ty::t) -> ty::t {
match bcx.fcx.param_substs {
Some(substs) => {
ty::subst_tps(bcx.tcx(), substs.tys, substs.self_ty, t)
}
}
-pub fn node_id_type(bcx: block, id: ast::node_id) -> ty::t {
+pub fn node_id_type(bcx: @mut Block, id: ast::node_id) -> ty::t {
let tcx = bcx.tcx();
let t = ty::node_id_to_type(tcx, id);
monomorphize_type(bcx, t)
}
-pub fn expr_ty(bcx: block, ex: &ast::expr) -> ty::t {
+pub fn expr_ty(bcx: @mut Block, ex: &ast::expr) -> ty::t {
node_id_type(bcx, ex.id)
}
-pub fn expr_ty_adjusted(bcx: block, ex: &ast::expr) -> ty::t {
+pub fn expr_ty_adjusted(bcx: @mut Block, ex: &ast::expr) -> ty::t {
let tcx = bcx.tcx();
let t = ty::expr_ty_adjusted(tcx, ex);
monomorphize_type(bcx, t)
}
-pub fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] {
+pub fn node_id_type_params(bcx: @mut Block, id: ast::node_id) -> ~[ty::t] {
let tcx = bcx.tcx();
let params = ty::node_id_to_type_params(tcx, id);
}
}
-pub fn node_vtables(bcx: block, id: ast::node_id)
+pub fn node_vtables(bcx: @mut Block, id: ast::node_id)
-> Option<typeck::vtable_res> {
let raw_vtables = bcx.ccx().maps.vtable_map.find(&id);
raw_vtables.map(
|&vts| resolve_vtables_in_fn_ctxt(bcx.fcx, *vts))
}
-pub fn resolve_vtables_in_fn_ctxt(fcx: fn_ctxt, vts: typeck::vtable_res)
+pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext, vts: typeck::vtable_res)
-> typeck::vtable_res {
resolve_vtables_under_param_substs(fcx.ccx.tcx,
fcx.param_substs,
}
-// Apply the typaram substitutions in the fn_ctxt to a vtable. This should
+// Apply the typaram substitutions in the FunctionContext to a vtable. This should
// eliminate any vtable_params.
-pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: &typeck::vtable_origin)
+pub fn resolve_vtable_in_fn_ctxt(fcx: &FunctionContext, vt: &typeck::vtable_origin)
-> typeck::vtable_origin {
resolve_vtable_under_param_substs(fcx.ccx.tcx,
fcx.param_substs,
}
}
-pub fn filename_and_line_num_from_span(bcx: block,
+pub fn filename_and_line_num_from_span(bcx: @mut Block,
span: span) -> (ValueRef, ValueRef) {
let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo);
let filename_cstr = C_cstr(bcx.ccx(), loc.file.name);
}
// Casts a Rust bool value to an i1.
-pub fn bool_to_i1(bcx: block, llval: ValueRef) -> ValueRef {
+pub fn bool_to_i1(bcx: @mut Block, llval: ValueRef) -> ValueRef {
build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(false))
}
-pub fn langcall(bcx: block, span: Option<span>, msg: &str,
+pub fn langcall(bcx: @mut Block, span: Option<span>, msg: &str,
li: LangItem) -> ast::def_id {
match bcx.tcx().lang_items.require(li) {
Ok(id) => id,
use syntax::ast_util;
use syntax::codemap::span;
-pub fn trans_block(bcx: block, b: &ast::Block, dest: expr::Dest) -> block {
+pub fn trans_block(bcx: @mut Block, b: &ast::Block, dest: expr::Dest) -> @mut Block {
let _icx = push_ctxt("trans_block");
let mut bcx = bcx;
for b.stmts.iter().advance |s| {
return bcx;
}
-pub fn trans_if(bcx: block,
+pub fn trans_if(bcx: @mut Block,
cond: @ast::expr,
thn: &ast::Block,
els: Option<@ast::expr>,
dest: expr::Dest)
- -> block {
+ -> @mut Block {
debug!("trans_if(bcx=%s, cond=%s, thn=%?, dest=%s)",
bcx.to_str(), bcx.expr_to_str(cond), thn.id,
dest.to_str(bcx.ccx()));
return next_bcx;
// trans `else [ if { .. } ... | { .. } ]`
- fn trans_if_else(bcx: block, elexpr: @ast::expr,
- dest: expr::Dest, scope_name: &str) -> (block, block) {
+ fn trans_if_else(bcx: @mut Block, elexpr: @ast::expr,
+ dest: expr::Dest, scope_name: &str) -> (@mut Block, @mut Block) {
let else_bcx_in = scope_block(bcx, elexpr.info(), scope_name);
let else_bcx_out = match elexpr.node {
ast::expr_if(_, _, _) => {
}
}
-pub fn join_blocks(parent_bcx: block, in_cxs: &[block]) -> block {
+pub fn join_blocks(parent_bcx: @mut Block, in_cxs: &[@mut Block]) -> @mut Block {
let out = sub_block(parent_bcx, "join");
let mut reachable = false;
for in_cxs.iter().advance |bcx| {
return out;
}
-pub fn trans_while(bcx: block, cond: @ast::expr, body: &ast::Block) -> block {
+pub fn trans_while(bcx: @mut Block, cond: @ast::expr, body: &ast::Block) -> @mut Block {
let _icx = push_ctxt("trans_while");
let next_bcx = sub_block(bcx, "while next");
return next_bcx;
}
-pub fn trans_loop(bcx:block,
+pub fn trans_loop(bcx:@mut Block,
body: &ast::Block,
opt_label: Option<ident>)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("trans_loop");
let next_bcx = sub_block(bcx, "next");
let body_bcx_in = loop_scope_block(bcx, next_bcx, opt_label, "`loop`",
pub fn trans_log(log_ex: &ast::expr,
lvl: @ast::expr,
- bcx: block,
- e: @ast::expr) -> block {
+ bcx: @mut Block,
+ e: @ast::expr) -> @mut Block {
let _icx = push_ctxt("trans_log");
let ccx = bcx.ccx();
let mut bcx = bcx;
}
}
-pub fn trans_break_cont(bcx: block,
+pub fn trans_break_cont(bcx: @mut Block,
opt_label: Option<ident>,
to_end: bool)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("trans_break_cont");
// Locate closest loop block, outputting cleanup as we go.
let mut unwind = bcx;
let mut target;
loop {
cur_scope = match cur_scope {
- Some(@scope_info {
+ Some(@ScopeInfo {
loop_break: Some(brk),
loop_label: l,
parent,
return bcx;
}
-pub fn trans_break(bcx: block, label_opt: Option<ident>) -> block {
+pub fn trans_break(bcx: @mut Block, label_opt: Option<ident>) -> @mut Block {
return trans_break_cont(bcx, label_opt, true);
}
-pub fn trans_cont(bcx: block, label_opt: Option<ident>) -> block {
+pub fn trans_cont(bcx: @mut Block, label_opt: Option<ident>) -> @mut Block {
return trans_break_cont(bcx, label_opt, false);
}
-pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block {
+pub fn trans_ret(bcx: @mut Block, e: Option<@ast::expr>) -> @mut Block {
let _icx = push_ctxt("trans_ret");
let mut bcx = bcx;
let dest = match bcx.fcx.loop_ret {
return bcx;
}
-pub fn trans_fail_expr(bcx: block,
+pub fn trans_fail_expr(bcx: @mut Block,
sp_opt: Option<span>,
fail_expr: Option<@ast::expr>)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("trans_fail_expr");
let mut bcx = bcx;
match fail_expr {
}
}
-pub fn trans_fail(bcx: block,
+pub fn trans_fail(bcx: @mut Block,
sp_opt: Option<span>,
fail_str: @str)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("trans_fail");
let V_fail_str = C_cstr(bcx.ccx(), fail_str);
return trans_fail_value(bcx, sp_opt, V_fail_str);
}
-fn trans_fail_value(bcx: block,
+fn trans_fail_value(bcx: @mut Block,
sp_opt: Option<span>,
V_fail_str: ValueRef)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("trans_fail_value");
let ccx = bcx.ccx();
let (V_filename, V_line) = match sp_opt {
return bcx;
}
-pub fn trans_fail_bounds_check(bcx: block, sp: span,
- index: ValueRef, len: ValueRef) -> block {
+pub fn trans_fail_bounds_check(bcx: @mut Block, sp: span,
+ index: ValueRef, len: ValueRef) -> @mut Block {
let _icx = push_ctxt("trans_fail_bounds_check");
let (filename, line) = filename_and_line_num_from_span(bcx, sp);
let args = ~[filename, line, index, len];
}
pub struct DatumBlock {
- bcx: block,
+ bcx: @mut Block,
datum: Datum,
}
return Datum {val: val, ty: ty, mode: ByValue};
}
-pub fn immediate_rvalue_bcx(bcx: block,
+pub fn immediate_rvalue_bcx(bcx: @mut Block,
val: ValueRef,
ty: ty::t)
-> DatumBlock {
return DatumBlock {bcx: bcx, datum: immediate_rvalue(val, ty)};
}
-pub fn scratch_datum(bcx: block, ty: ty::t, name: &str, zero: bool) -> Datum {
+pub fn scratch_datum(bcx: @mut Block, ty: ty::t, name: &str, zero: bool) -> Datum {
/*!
* Allocates temporary space on the stack using alloca() and
* returns a by-ref Datum pointing to it. If `zero` is true, the
impl Datum {
pub fn store_to(&self,
- bcx: block,
+ bcx: @mut Block,
action: CopyAction,
dst: ValueRef)
- -> block {
+ -> @mut Block {
/*!
*
* Stores this value into its final home. This moves if
}
pub fn store_to_dest(&self,
- bcx: block,
+ bcx: @mut Block,
dest: expr::Dest)
- -> block {
+ -> @mut Block {
match dest {
expr::Ignore => {
return bcx;
}
pub fn store_to_datum(&self,
- bcx: block,
+ bcx: @mut Block,
action: CopyAction,
datum: Datum)
- -> block {
+ -> @mut Block {
debug!("store_to_datum(self=%s, action=%?, datum=%s)",
self.to_str(bcx.ccx()), action, datum.to_str(bcx.ccx()));
assert!(datum.mode.is_by_ref());
self.store_to(bcx, action, datum.val)
}
- pub fn move_to_datum(&self, bcx: block, action: CopyAction, datum: Datum)
- -> block {
+ pub fn move_to_datum(&self, bcx: @mut Block, action: CopyAction, datum: Datum)
+ -> @mut Block {
assert!(datum.mode.is_by_ref());
self.move_to(bcx, action, datum.val)
}
- pub fn copy_to_datum(&self, bcx: block, action: CopyAction, datum: Datum)
- -> block {
+ pub fn copy_to_datum(&self, bcx: @mut Block, action: CopyAction, datum: Datum)
+ -> @mut Block {
assert!(datum.mode.is_by_ref());
self.copy_to(bcx, action, datum.val)
}
- pub fn copy_to(&self, bcx: block, action: CopyAction, dst: ValueRef)
- -> block {
+ pub fn copy_to(&self, bcx: @mut Block, action: CopyAction, dst: ValueRef)
+ -> @mut Block {
/*!
*
* Copies the value into `dst`, which should be a pointer to a
}
pub fn copy_to_no_check(&self,
- bcx: block,
+ bcx: @mut Block,
action: CopyAction,
dst: ValueRef)
- -> block {
+ -> @mut Block {
/*!
*
* A helper for `copy_to()` which does not check to see if we
// This works like copy_val, except that it deinitializes the source.
// Since it needs to zero out the source, src also needs to be an lval.
//
- pub fn move_to(&self, bcx: block, action: CopyAction, dst: ValueRef)
- -> block {
+ pub fn move_to(&self, bcx: @mut Block, action: CopyAction, dst: ValueRef)
+ -> @mut Block {
let _icx = push_ctxt("move_to");
let mut bcx = bcx;
return bcx;
}
- pub fn add_clean(&self, bcx: block) {
+ pub fn add_clean(&self, bcx: @mut Block) {
/*!
* Schedules this datum for cleanup in `bcx`. The datum
* must be an rvalue.
}
}
- pub fn cancel_clean(&self, bcx: block) {
+ pub fn cancel_clean(&self, bcx: @mut Block) {
if ty::type_needs_drop(bcx.tcx(), self.ty) {
match self.mode {
ByValue |
self.mode)
}
- pub fn to_value_datum(&self, bcx: block) -> Datum {
+ pub fn to_value_datum(&self, bcx: @mut Block) -> Datum {
/*!
*
* Yields a by-value form of this datum. This may involve
}
}
- pub fn to_value_llval(&self, bcx: block) -> ValueRef {
+ pub fn to_value_llval(&self, bcx: @mut Block) -> ValueRef {
/*!
*
* Yields the value itself. */
}
}
- pub fn to_ref_datum(&self, bcx: block) -> Datum {
+ pub fn to_ref_datum(&self, bcx: @mut Block) -> Datum {
/*!
* Yields a by-ref form of this datum. This may involve
* creation of a temporary stack slot. The value returned by
}
}
- pub fn to_ref_llval(&self, bcx: block) -> ValueRef {
+ pub fn to_ref_llval(&self, bcx: @mut Block) -> ValueRef {
match self.mode {
ByRef(_) => self.val,
ByValue => {
}
}
- pub fn to_zeroable_ref_llval(&self, bcx: block) -> ValueRef {
+ pub fn to_zeroable_ref_llval(&self, bcx: @mut Block) -> ValueRef {
/*!
* Returns a by-ref llvalue that can be zeroed in order to
* cancel cleanup. This is a kind of hokey bridge used
appropriate_mode(tcx, self.ty)
}
- pub fn to_appropriate_llval(&self, bcx: block) -> ValueRef {
+ pub fn to_appropriate_llval(&self, bcx: @mut Block) -> ValueRef {
/*!
*
* Yields an llvalue with the `appropriate_mode()`. */
}
}
- pub fn to_appropriate_datum(&self, bcx: block) -> Datum {
+ pub fn to_appropriate_datum(&self, bcx: @mut Block) -> Datum {
/*!
*
* Yields a datum with the `appropriate_mode()`. */
}
pub fn get_element(&self,
- bcx: block,
+ bcx: @mut Block,
ty: ty::t,
source: DatumCleanup,
gep: &fn(ValueRef) -> ValueRef)
}
}
- pub fn drop_val(&self, bcx: block) -> block {
+ pub fn drop_val(&self, bcx: @mut Block) -> @mut Block {
if !ty::type_needs_drop(bcx.tcx(), self.ty) {
return bcx;
}
};
}
- pub fn box_body(&self, bcx: block) -> Datum {
+ pub fn box_body(&self, bcx: @mut Block) -> Datum {
/*!
*
* This datum must represent an @T or ~T box. Returns a new
}
}
- pub fn to_rptr(&self, bcx: block) -> Datum {
+ pub fn to_rptr(&self, bcx: @mut Block) -> Datum {
//! Returns a new datum of region-pointer type containing the
//! the same ptr as this datum (after converting to by-ref
//! using `to_ref_llval()`).
/// derefs: Number of times deref'd already.
/// is_auto: If true, only deref if auto-derefable.
pub fn try_deref(&self,
- bcx: block,
+ bcx: @mut Block,
span: span,
expr_id: ast::node_id,
derefs: uint,
is_auto: bool)
- -> (Option<Datum>, block) {
+ -> (Option<Datum>, @mut Block) {
let ccx = bcx.ccx();
debug!("try_deref(expr_id=%?, derefs=%?, is_auto=%b, self=%?)",
}
}
- fn deref_ptr(bcx: block, lv: &Datum, ty: ty::t) -> Datum {
+ fn deref_ptr(bcx: @mut Block, lv: &Datum, ty: ty::t) -> Datum {
Datum {
val: lv.to_value_llval(bcx),
ty: ty,
}
/// expr: The deref expression.
- pub fn deref(&self, bcx: block, expr: &ast::expr, derefs: uint)
+ pub fn deref(&self, bcx: @mut Block, expr: &ast::expr, derefs: uint)
-> DatumBlock {
match self.try_deref(bcx, expr.span, expr.id, derefs, false) {
(Some(lvres), bcx) => DatumBlock { bcx: bcx, datum: lvres },
}
pub fn autoderef(&self,
- bcx: block,
+ bcx: @mut Block,
span: span,
expr_id: ast::node_id,
max: uint)
}
pub fn get_vec_base_and_len(&self,
- mut bcx: block,
+ mut bcx: @mut Block,
span: span,
expr_id: ast::node_id,
derefs: uint)
- -> (block, ValueRef, ValueRef) {
+ -> (@mut Block, ValueRef, ValueRef) {
//! Converts a vector into the slice pair. Performs rooting
//! and write guards checks.
(bcx, base, len)
}
- pub fn get_vec_base_and_len_no_root(&self, bcx: block)
+ pub fn get_vec_base_and_len_no_root(&self, bcx: @mut Block)
-> (ValueRef, ValueRef) {
//! Converts a vector into the slice pair. Des not root
//! nor perform write guard checks.
}
pub fn root_and_write_guard(&self,
- bcx: block,
+ bcx: @mut Block,
span: span,
expr_id: ast::node_id,
derefs: uint)
- -> block {
+ -> @mut Block {
write_guard::root_and_write_guard(self, bcx, span, expr_id, derefs)
}
- pub fn to_result(&self, bcx: block) -> common::Result {
+ pub fn to_result(&self, bcx: @mut Block) -> common::Result {
rslt(bcx, self.to_appropriate_llval(bcx))
}
}
impl DatumBlock {
- pub fn unpack(&self, bcx: &mut block) -> Datum {
+ pub fn unpack(&self, bcx: &mut @mut Block) -> Datum {
*bcx = self.bcx;
return self.datum;
}
*self
}
- pub fn drop_val(&self) -> block {
+ pub fn drop_val(&self) -> @mut Block {
self.datum.drop_val(self.bcx)
}
pub fn store_to(&self,
action: CopyAction,
dst: ValueRef)
- -> block {
+ -> @mut Block {
self.datum.store_to(self.bcx, action, dst)
}
- pub fn copy_to(&self, action: CopyAction, dst: ValueRef) -> block {
+ pub fn copy_to(&self, action: CopyAction, dst: ValueRef) -> @mut Block {
self.datum.copy_to(self.bcx, action, dst)
}
- pub fn move_to(&self, action: CopyAction, dst: ValueRef) -> block {
+ pub fn move_to(&self, action: CopyAction, dst: ValueRef) -> @mut Block {
self.datum.move_to(self.bcx, action, dst)
}
///
/// Adds the created metadata nodes directly to the crate's IR.
/// The return value should be ignored if called from outside of the debuginfo module.
-pub fn create_local_var_metadata(bcx: block, local: @ast::Local) -> DIVariable {
+pub fn create_local_var_metadata(bcx: @mut Block, local: @ast::Local) -> DIVariable {
let cx = bcx.ccx();
let ident = match local.pat.node {
///
/// Adds the created metadata nodes directly to the crate's IR.
/// The return value should be ignored if called from outside of the debuginfo module.
-pub fn create_argument_metadata(bcx: block, arg: &ast::arg, span: span) -> Option<DIVariable> {
+pub fn create_argument_metadata(bcx: @mut Block, arg: &ast::arg, span: span) -> Option<DIVariable> {
debug!("create_argument_metadata");
if true {
// XXX create_argument_metadata disabled for now because "node_id_type(bcx, arg.id)" below
/// Sets the current debug location at the beginning of the span
///
/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...)
-pub fn update_source_pos(bcx: block, span: span) {
+pub fn update_source_pos(bcx: @mut Block, span: span) {
if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) {
return;
}
///
/// Adds the created metadata nodes directly to the crate's IR.
/// The return value should be ignored if called from outside of the debuginfo module.
-pub fn create_function_metadata(fcx: fn_ctxt) -> DISubprogram {
+pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
let cx = fcx.ccx;
- let fcx = &mut *fcx;
let span = fcx.span.get();
let fnitem = cx.tcx.items.get_copy(&fcx.id);
}
/// Get or create the lexical block metadata node for the given LLVM basic block.
-fn lexical_block_metadata(bcx: block) -> DILexicalBlock {
+fn lexical_block_metadata(bcx: @mut Block) -> DILexicalBlock {
let cx = bcx.ccx();
let mut bcx = bcx;
}
}
-fn drop_and_cancel_clean(bcx: block, dat: Datum) -> block {
+fn drop_and_cancel_clean(bcx: @mut Block, dat: Datum) -> @mut Block {
let bcx = dat.drop_val(bcx);
dat.cancel_clean(bcx);
return bcx;
}
-pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
+pub fn trans_to_datum(bcx: @mut Block, expr: @ast::expr) -> DatumBlock {
debug!("trans_to_datum(expr=%s)", bcx.expr_to_str(expr));
let mut bcx = bcx;
debug!("after adjustments, datum=%s", datum.to_str(bcx.ccx()));
return DatumBlock {bcx: bcx, datum: datum};
- fn auto_ref(bcx: block, datum: Datum) -> DatumBlock {
+ fn auto_ref(bcx: @mut Block, datum: Datum) -> DatumBlock {
DatumBlock {bcx: bcx, datum: datum.to_rptr(bcx)}
}
- fn auto_borrow_fn(bcx: block,
+ fn auto_borrow_fn(bcx: @mut Block,
adjusted_ty: ty::t,
datum: Datum) -> DatumBlock {
// Currently, all closure types are represented precisely the
mode: datum.mode}}
}
- fn auto_slice(bcx: block,
+ fn auto_slice(bcx: @mut Block,
autoderefs: uint,
expr: &ast::expr,
datum: Datum) -> DatumBlock {
DatumBlock {bcx: bcx, datum: scratch}
}
- fn add_env(bcx: block, expr: &ast::expr, datum: Datum) -> DatumBlock {
+ fn add_env(bcx: @mut Block, expr: &ast::expr, datum: Datum) -> DatumBlock {
// This is not the most efficient thing possible; since closures
// are two words it'd be better if this were compiled in
// 'dest' mode, but I can't find a nice way to structure the
DatumBlock {bcx: bcx, datum: scratch}
}
- fn auto_slice_and_ref(bcx: block,
+ fn auto_slice_and_ref(bcx: @mut Block,
autoderefs: uint,
expr: &ast::expr,
datum: Datum) -> DatumBlock {
}
}
-pub fn trans_into(bcx: block, expr: @ast::expr, dest: Dest) -> block {
+pub fn trans_into(bcx: @mut Block, expr: @ast::expr, dest: Dest) -> @mut Block {
if bcx.tcx().adjustments.contains_key(&expr.id) {
// use trans_to_datum, which is mildly less efficient but
// which will perform the adjustments:
};
}
-fn trans_lvalue(bcx: block, expr: @ast::expr) -> DatumBlock {
+fn trans_lvalue(bcx: @mut Block, expr: @ast::expr) -> DatumBlock {
/*!
*
* Translates an lvalue expression, always yielding a by-ref
};
}
-fn trans_to_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
+fn trans_to_datum_unadjusted(bcx: @mut Block, expr: @ast::expr) -> DatumBlock {
/*!
* Translates an expression into a datum. If this expression
* is an rvalue, this will result in a temporary value being
}
}
- fn nil(bcx: block, ty: ty::t) -> DatumBlock {
+ fn nil(bcx: @mut Block, ty: ty::t) -> DatumBlock {
let datum = immediate_rvalue(C_nil(), ty);
DatumBlock {bcx: bcx, datum: datum}
}
}
-fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
+fn trans_rvalue_datum_unadjusted(bcx: @mut Block, expr: @ast::expr) -> DatumBlock {
let _icx = push_ctxt("trans_rvalue_datum_unadjusted");
trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
}
}
-fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
+fn trans_rvalue_stmt_unadjusted(bcx: @mut Block, expr: @ast::expr) -> @mut Block {
let mut bcx = bcx;
let _icx = push_ctxt("trans_rvalue_stmt");
};
}
-fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
- dest: Dest) -> block {
+fn trans_rvalue_dps_unadjusted(bcx: @mut Block, expr: @ast::expr,
+ dest: Dest) -> @mut Block {
let _icx = push_ctxt("trans_rvalue_dps_unadjusted");
let tcx = bcx.tcx();
}
}
-fn trans_def_dps_unadjusted(bcx: block, ref_expr: &ast::expr,
- def: ast::def, dest: Dest) -> block {
+fn trans_def_dps_unadjusted(bcx: @mut Block, ref_expr: &ast::expr,
+ def: ast::def, dest: Dest) -> @mut Block {
let _icx = push_ctxt("trans_def_dps_unadjusted");
let ccx = bcx.ccx();
}
}
-fn trans_def_datum_unadjusted(bcx: block,
+fn trans_def_datum_unadjusted(bcx: @mut Block,
ref_expr: &ast::expr,
def: ast::def) -> DatumBlock
{
}
}
- fn fn_data_to_datum(bcx: block,
+ fn fn_data_to_datum(bcx: @mut Block,
ref_expr: &ast::expr,
def_id: ast::def_id,
fn_data: callee::FnData) -> DatumBlock {
}
}
-fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
+fn trans_lvalue_unadjusted(bcx: @mut Block, expr: @ast::expr) -> DatumBlock {
/*!
*
* Translates an lvalue expression, always yielding a by-ref
}
};
- fn trans_rec_field(bcx: block,
+ fn trans_rec_field(bcx: @mut Block,
base: @ast::expr,
field: ast::ident) -> DatumBlock {
//! Translates `base.field`.
}
}
- fn trans_index(bcx: block,
+ fn trans_index(bcx: @mut Block,
index_expr: &ast::expr,
base: @ast::expr,
idx: @ast::expr) -> DatumBlock {
};
}
- fn trans_def_lvalue(bcx: block,
+ fn trans_def_lvalue(bcx: @mut Block,
ref_expr: &ast::expr,
def: ast::def)
-> DatumBlock
}
}
- fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t)
+ fn get_val(bcx: @mut Block, did: ast::def_id, const_ty: ty::t)
-> ValueRef {
// For external constants, we don't inline.
if did.crate == ast::local_crate {
}
}
-pub fn trans_local_var(bcx: block, def: ast::def) -> Datum {
+pub fn trans_local_var(bcx: @mut Block, def: ast::def) -> Datum {
let _icx = push_ctxt("trans_local_var");
return match def {
}
};
- fn take_local(bcx: block,
+ fn take_local(bcx: @mut Block,
table: &HashMap<ast::node_id, ValueRef>,
nid: ast::node_id) -> Datum {
let v = match table.find(&nid) {
}
}
-fn trans_rec_or_struct(bcx: block,
+fn trans_rec_or_struct(bcx: @mut Block,
fields: &[ast::Field],
base: Option<@ast::expr>,
expr_span: codemap::span,
id: ast::node_id,
- dest: Dest) -> block
+ dest: Dest) -> @mut Block
{
let _icx = push_ctxt("trans_rec");
let bcx = bcx;
* - `optbase` contains information on the base struct (if any) from
* which remaining fields are copied; see comments on `StructBaseInfo`.
*/
-fn trans_adt(bcx: block, repr: &adt::Repr, discr: int,
+fn trans_adt(bcx: @mut Block, repr: &adt::Repr, discr: int,
fields: &[(uint, @ast::expr)],
optbase: Option<StructBaseInfo>,
- dest: Dest) -> block {
+ dest: Dest) -> @mut Block {
let _icx = push_ctxt("trans_adt");
let mut bcx = bcx;
let addr = match dest {
}
-fn trans_immediate_lit(bcx: block, expr: @ast::expr,
+fn trans_immediate_lit(bcx: @mut Block, expr: @ast::expr,
lit: ast::lit) -> DatumBlock {
// must not be a string constant, that is a RvalueDpsExpr
let _icx = push_ctxt("trans_immediate_lit");
immediate_rvalue_bcx(bcx, consts::const_lit(bcx.ccx(), expr, lit), ty)
}
-fn trans_unary_datum(bcx: block,
+fn trans_unary_datum(bcx: @mut Block,
un_expr: &ast::expr,
op: ast::unop,
sub_expr: @ast::expr) -> DatumBlock {
}
};
- fn trans_boxed_expr(bcx: block,
+ fn trans_boxed_expr(bcx: @mut Block,
box_ty: ty::t,
contents: @ast::expr,
contents_ty: ty::t,
}
}
-fn trans_addr_of(bcx: block, expr: &ast::expr,
+fn trans_addr_of(bcx: @mut Block, expr: &ast::expr,
subexpr: @ast::expr) -> DatumBlock {
let _icx = push_ctxt("trans_addr_of");
let mut bcx = bcx;
// Important to get types for both lhs and rhs, because one might be _|_
// and the other not.
-fn trans_eager_binop(bcx: block,
+fn trans_eager_binop(bcx: @mut Block,
binop_expr: &ast::expr,
binop_ty: ty::t,
op: ast::binop,
// refinement types would obviate the need for this
enum lazy_binop_ty { lazy_and, lazy_or }
-fn trans_lazy_binop(bcx: block,
+fn trans_lazy_binop(bcx: @mut Block,
binop_expr: &ast::expr,
op: lazy_binop_ty,
a: @ast::expr,
return immediate_rvalue_bcx(join, phi, binop_ty);
}
-fn trans_binary(bcx: block,
+fn trans_binary(bcx: @mut Block,
binop_expr: &ast::expr,
op: ast::binop,
lhs: @ast::expr,
}
}
-fn trans_overloaded_op(bcx: block,
+fn trans_overloaded_op(bcx: @mut Block,
expr: &ast::expr,
callee_id: ast::node_id,
rcvr: @ast::expr,
args: ~[@ast::expr],
ret_ty: ty::t,
dest: Dest)
- -> block {
+ -> @mut Block {
let origin = bcx.ccx().maps.method_map.get_copy(&expr.id);
let fty = node_id_type(bcx, callee_id);
callee::trans_call_inner(bcx,
DoAutorefArg).bcx
}
-fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type,
+fn int_cast(bcx: @mut Block, lldsttype: Type, llsrctype: Type,
llsrc: ValueRef, signed: bool) -> ValueRef {
let _icx = push_ctxt("int_cast");
unsafe {
}
}
-fn float_cast(bcx: block, lldsttype: Type, llsrctype: Type,
+fn float_cast(bcx: @mut Block, lldsttype: Type, llsrctype: Type,
llsrc: ValueRef) -> ValueRef {
let _icx = push_ctxt("float_cast");
let srcsz = llsrctype.float_width();
}
}
-fn trans_imm_cast(bcx: block, expr: @ast::expr,
+fn trans_imm_cast(bcx: @mut Block, expr: @ast::expr,
id: ast::node_id) -> DatumBlock {
let _icx = push_ctxt("trans_cast");
let ccx = bcx.ccx();
return immediate_rvalue_bcx(bcx, newval, t_out);
}
-fn trans_assign_op(bcx: block,
+fn trans_assign_op(bcx: @mut Block,
expr: @ast::expr,
callee_id: ast::node_id,
op: ast::binop,
dst: @ast::expr,
- src: @ast::expr) -> block
+ src: @ast::expr) -> @mut Block
{
let _icx = push_ctxt("trans_assign_op");
let mut bcx = bcx;
}
type shim_arg_builder<'self> =
- &'self fn(bcx: block, tys: &ShimTypes,
+ &'self fn(bcx: @mut Block, tys: &ShimTypes,
llargbundle: ValueRef) -> ~[ValueRef];
type shim_ret_builder<'self> =
- &'self fn(bcx: block, tys: &ShimTypes,
+ &'self fn(bcx: @mut Block, tys: &ShimTypes,
llargbundle: ValueRef,
llretval: ValueRef);
return llshimfn;
}
-type wrap_arg_builder<'self> = &'self fn(bcx: block,
+type wrap_arg_builder<'self> = &'self fn(bcx: @mut Block,
tys: &ShimTypes,
llwrapfn: ValueRef,
llargbundle: ValueRef);
-type wrap_ret_builder<'self> = &'self fn(bcx: block,
+type wrap_ret_builder<'self> = &'self fn(bcx: @mut Block,
tys: &ShimTypes,
llargbundle: ValueRef);
let _icx = push_ctxt("foreign::build_shim_fn");
- fn build_args(bcx: block, tys: &ShimTypes, llargbundle: ValueRef)
+ fn build_args(bcx: @mut Block, tys: &ShimTypes, llargbundle: ValueRef)
-> ~[ValueRef] {
let _icx = push_ctxt("foreign::shim::build_args");
tys.fn_ty.build_shim_args(bcx, tys.llsig.llarg_tys, llargbundle)
}
- fn build_ret(bcx: block,
+ fn build_ret(bcx: @mut Block,
tys: &ShimTypes,
llargbundle: ValueRef,
llretval: ValueRef) {
build_args,
build_ret);
- fn build_args(bcx: block,
+ fn build_args(bcx: @mut Block,
tys: &ShimTypes,
llwrapfn: ValueRef,
llargbundle: ValueRef) {
}
}
- fn build_ret(bcx: block,
+ fn build_ret(bcx: @mut Block,
shim_types: &ShimTypes,
llargbundle: ValueRef) {
let _icx = push_ctxt("foreign::wrap::build_ret");
ref_id: Option<ast::node_id>) {
debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident));
- fn simple_llvm_intrinsic(bcx: block, name: &'static str, num_args: uint) {
+ fn simple_llvm_intrinsic(bcx: @mut Block, name: &'static str, num_args: uint) {
assert!(num_args <= 4);
let mut args = [0 as ValueRef, ..4];
let first_real_arg = bcx.fcx.arg_pos(0u);
Ret(bcx, Call(bcx, llfn, args.slice(0, num_args)));
}
- fn memcpy_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
+ fn memcpy_intrinsic(bcx: @mut Block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
let ccx = bcx.ccx();
let lltp_ty = type_of::type_of(ccx, tp_ty);
let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
RetVoid(bcx);
}
- fn memset_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
+ fn memset_intrinsic(bcx: @mut Block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
let ccx = bcx.ccx();
let lltp_ty = type_of::type_of(ccx, tp_ty);
let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
RetVoid(bcx);
}
- fn count_zeros_intrinsic(bcx: block, name: &'static str) {
+ fn count_zeros_intrinsic(bcx: @mut Block, name: &'static str) {
let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
let y = C_i1(false);
let llfn = bcx.ccx().intrinsics.get_copy(&name);
let _icx = push_ctxt("foreign::foreign::build_shim_fn");
- fn build_args(bcx: block, tys: &ShimTypes, llargbundle: ValueRef)
+ fn build_args(bcx: @mut Block, tys: &ShimTypes, llargbundle: ValueRef)
-> ~[ValueRef] {
let _icx = push_ctxt("foreign::extern::shim::build_args");
let ccx = bcx.ccx();
return llargvals;
}
- fn build_ret(bcx: block,
+ fn build_ret(bcx: @mut Block,
shim_types: &ShimTypes,
llargbundle: ValueRef,
llretval: ValueRef) {
build_args,
build_ret);
- fn build_args(bcx: block,
+ fn build_args(bcx: @mut Block,
tys: &ShimTypes,
llwrapfn: ValueRef,
llargbundle: ValueRef) {
llargbundle);
}
- fn build_ret(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) {
+ fn build_ret(bcx: @mut Block, tys: &ShimTypes, llargbundle: ValueRef) {
let _icx = push_ctxt("foreign::foreign::wrap::build_ret");
tys.fn_ty.build_wrap_ret(bcx, tys.llsig.llarg_tys, llargbundle);
}
use std::str;
use syntax::ast;
-pub fn trans_free(cx: block, v: ValueRef) -> block {
+pub fn trans_free(cx: @mut Block, v: ValueRef) -> @mut Block {
let _icx = push_ctxt("trans_free");
callee::trans_lang_call(cx,
langcall(cx, None, "", FreeFnLangItem),
Some(expr::Ignore)).bcx
}
-pub fn trans_exchange_free(cx: block, v: ValueRef) -> block {
+pub fn trans_exchange_free(cx: @mut Block, v: ValueRef) -> @mut Block {
let _icx = push_ctxt("trans_exchange_free");
callee::trans_lang_call(cx,
langcall(cx, None, "", ExchangeFreeFnLangItem),
Some(expr::Ignore)).bcx
}
-pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block {
+pub fn take_ty(cx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
// NB: v is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("take_ty");
if ty::type_needs_drop(cx.tcx(), t) {
return cx;
}
-pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block {
+pub fn drop_ty(cx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
// NB: v is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("drop_ty");
if ty::type_needs_drop(cx.tcx(), t) {
return cx;
}
-pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
+pub fn drop_ty_immediate(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
let _icx = push_ctxt("drop_ty_immediate");
match ty::get(t).sty {
ty::ty_uniq(_)
}
}
-pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block {
+pub fn free_ty(cx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
// NB: v is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("free_ty");
if ty::type_needs_drop(cx.tcx(), t) {
return cx;
}
-pub fn free_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
+pub fn free_ty_immediate(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
let _icx = push_ctxt("free_ty_immediate");
match ty::get(t).sty {
ty::ty_uniq(_) |
}
// See [Note-arg-mode]
-pub fn call_tydesc_glue_full(bcx: block,
+pub fn call_tydesc_glue_full(bcx: @mut Block,
v: ValueRef,
tydesc: ValueRef,
field: uint,
}
// See [Note-arg-mode]
-pub fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: uint)
- -> block {
+pub fn call_tydesc_glue(cx: @mut Block, v: ValueRef, t: ty::t, field: uint)
+ -> @mut Block {
let _icx = push_ctxt("call_tydesc_glue");
let ti = get_tydesc(cx.ccx(), t);
call_tydesc_glue_full(cx, v, ti.tydesc, field, Some(ti));
return cx;
}
-pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) -> block {
+pub fn make_visit_glue(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
let _icx = push_ctxt("make_visit_glue");
do with_scope(bcx, None, "visitor cleanup") |bcx| {
let mut bcx = bcx;
}
}
-pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) -> block {
+pub fn make_free_glue(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
// NB: v0 is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("make_free_glue");
match ty::get(t).sty {
}
}
-pub fn trans_struct_drop_flag(bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast::def_id,
- class_did: ast::def_id, substs: &ty::substs) -> block {
+pub fn trans_struct_drop_flag(bcx: @mut Block, t: ty::t, v0: ValueRef, dtor_did: ast::def_id,
+ class_did: ast::def_id, substs: &ty::substs) -> @mut Block {
let repr = adt::represent_type(bcx.ccx(), t);
let drop_flag = adt::trans_drop_flag_ptr(bcx, repr, v0);
do with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) |cx| {
}
}
-pub fn trans_struct_drop(mut bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast::def_id,
- class_did: ast::def_id, substs: &ty::substs) -> block {
+pub fn trans_struct_drop(mut bcx: @mut Block, t: ty::t, v0: ValueRef, dtor_did: ast::def_id,
+ class_did: ast::def_id, substs: &ty::substs) -> @mut Block {
let repr = adt::represent_type(bcx.ccx(), t);
// Find and call the actual destructor
bcx
}
-pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) -> block {
+pub fn make_drop_glue(bcx: @mut Block, v0: ValueRef, t: ty::t) -> @mut Block {
// NB: v0 is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("make_drop_glue");
let ccx = bcx.ccx();
}
// box_ptr_ptr is optional, it is constructed if not supplied.
-pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef,
+pub fn decr_refcnt_maybe_free(bcx: @mut Block, box_ptr: ValueRef,
box_ptr_ptr: Option<ValueRef>,
t: ty::t)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("decr_refcnt_maybe_free");
let ccx = bcx.ccx();
}
-pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) -> block {
+pub fn make_take_glue(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
let _icx = push_ctxt("make_take_glue");
// NB: v is a *pointer* to type t here, not a direct value.
match ty::get(t).sty {
}
}
-pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) {
+pub fn incr_refcnt_of_boxed(cx: @mut Block, box_ptr: ValueRef) {
let _icx = push_ctxt("incr_refcnt_of_boxed");
let ccx = cx.ccx();
let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]);
return inf;
}
-pub type glue_helper<'self> = &'self fn(block, ValueRef, ty::t) -> block;
+pub type glue_helper<'self> = &'self fn(@mut Block, ValueRef, ty::t) -> @mut Block;
pub fn declare_generic_glue(ccx: &mut CrateContext, t: ty::t, llfnty: Type,
name: &str) -> ValueRef {
[]);
}
-pub fn trans_self_arg(bcx: block,
+pub fn trans_self_arg(bcx: @mut Block,
base: @ast::expr,
temp_cleanups: &mut ~[ValueRef],
mentry: typeck::method_map_entry) -> Result {
DontAutorefArg)
}
-pub fn trans_method_callee(bcx: block,
+pub fn trans_method_callee(bcx: @mut Block,
callee_id: ast::node_id,
this: @ast::expr,
mentry: typeck::method_map_entry)
}
}
-pub fn trans_static_method_callee(bcx: block,
+pub fn trans_static_method_callee(bcx: @mut Block,
method_id: ast::def_id,
trait_id: ast::def_id,
callee_id: ast::node_id)
meth.def_id
}
-pub fn trans_monomorphized_callee(bcx: block,
+pub fn trans_monomorphized_callee(bcx: @mut Block,
callee_id: ast::node_id,
base: @ast::expr,
mentry: typeck::method_map_entry,
}
-pub fn combine_impl_and_methods_tps(bcx: block,
+pub fn combine_impl_and_methods_tps(bcx: @mut Block,
mth_did: ast::def_id,
callee_id: ast::node_id,
rcvr_substs: &[ty::t],
}
-pub fn trans_trait_callee(bcx: block,
+pub fn trans_trait_callee(bcx: @mut Block,
callee_id: ast::node_id,
n_method: uint,
self_expr: @ast::expr,
explicit_self)
}
-pub fn trans_trait_callee_from_llval(bcx: block,
+pub fn trans_trait_callee_from_llval(bcx: @mut Block,
callee_ty: ty::t,
n_method: uint,
llpair: ValueRef,
/// Creates a returns a dynamic vtable for the given type and vtable origin.
/// This is used only for objects.
-pub fn get_vtable(bcx: block,
+pub fn get_vtable(bcx: @mut Block,
self_ty: ty::t,
origin: typeck::vtable_origin)
-> ValueRef {
}
/// Generates a dynamic vtable for objects.
-pub fn make_impl_vtable(bcx: block,
+pub fn make_impl_vtable(bcx: @mut Block,
impl_id: ast::def_id,
self_ty: ty::t,
substs: &[ty::t],
make_vtable(ccx, tydesc, methods)
}
-pub fn trans_trait_cast(bcx: block,
+pub fn trans_trait_cast(bcx: @mut Block,
val: @ast::expr,
id: ast::node_id,
dest: expr::Dest,
_store: ty::TraitStore)
- -> block {
+ -> @mut Block {
let mut bcx = bcx;
let _icx = push_ctxt("impl::trans_cast");
pub struct Reflector {
visitor_val: ValueRef,
visitor_methods: @~[@ty::Method],
- final_bcx: block,
+ final_bcx: @mut Block,
tydesc_ty: Type,
- bcx: block
+ bcx: @mut Block
}
impl Reflector {
}
// Emit a sequence of calls to visit_ty::visit_foo
-pub fn emit_calls_to_trait_visit_ty(bcx: block,
+pub fn emit_calls_to_trait_visit_ty(bcx: @mut Block,
t: ty::t,
visitor_val: ValueRef,
visitor_trait_id: def_id)
- -> block {
+ -> @mut Block {
let final = sub_block(bcx, "final");
let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx).unwrap();
let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
}
}
-pub fn get_fill(bcx: block, vptr: ValueRef) -> ValueRef {
+pub fn get_fill(bcx: @mut Block, vptr: ValueRef) -> ValueRef {
let _icx = push_ctxt("tvec::get_fill");
Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill]))
}
-pub fn set_fill(bcx: block, vptr: ValueRef, fill: ValueRef) {
+pub fn set_fill(bcx: @mut Block, vptr: ValueRef, fill: ValueRef) {
Store(bcx, fill, GEPi(bcx, vptr, [0u, abi::vec_elt_fill]));
}
-pub fn get_alloc(bcx: block, vptr: ValueRef) -> ValueRef {
+pub fn get_alloc(bcx: @mut Block, vptr: ValueRef) -> ValueRef {
Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_alloc]))
}
-pub fn get_bodyptr(bcx: block, vptr: ValueRef, t: ty::t) -> ValueRef {
+pub fn get_bodyptr(bcx: @mut Block, vptr: ValueRef, t: ty::t) -> ValueRef {
if ty::type_contents(bcx.tcx(), t).contains_managed() {
GEPi(bcx, vptr, [0u, abi::box_field_body])
} else {
}
}
-pub fn get_dataptr(bcx: block, vptr: ValueRef) -> ValueRef {
+pub fn get_dataptr(bcx: @mut Block, vptr: ValueRef) -> ValueRef {
let _icx = push_ctxt("tvec::get_dataptr");
GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u])
}
-pub fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
+pub fn pointer_add(bcx: @mut Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
let _icx = push_ctxt("tvec::pointer_add");
let old_ty = val_ty(ptr);
let bptr = PointerCast(bcx, ptr, Type::i8p());
return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
}
-pub fn alloc_raw(bcx: block, unit_ty: ty::t,
+pub fn alloc_raw(bcx: @mut Block, unit_ty: ty::t,
fill: ValueRef, alloc: ValueRef, heap: heap) -> Result {
let _icx = push_ctxt("tvec::alloc_uniq");
let ccx = bcx.ccx();
}
}
-pub fn alloc_uniq_raw(bcx: block, unit_ty: ty::t,
+pub fn alloc_uniq_raw(bcx: @mut Block, unit_ty: ty::t,
fill: ValueRef, alloc: ValueRef) -> Result {
alloc_raw(bcx, unit_ty, fill, alloc, base::heap_for_unique(bcx, unit_ty))
}
-pub fn alloc_vec(bcx: block,
+pub fn alloc_vec(bcx: @mut Block,
unit_ty: ty::t,
elts: uint,
heap: heap)
return rslt(bcx, vptr);
}
-pub fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) ->
- block {
+pub fn make_drop_glue_unboxed(bcx: @mut Block, vptr: ValueRef, vec_ty: ty::t) ->
+ @mut Block {
let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
let tcx = bcx.tcx();
let unit_ty = ty::sequence_element_type(tcx, vec_ty);
}
}
-pub fn trans_fixed_vstore(bcx: block,
+pub fn trans_fixed_vstore(bcx: @mut Block,
vstore_expr: @ast::expr,
content_expr: &ast::expr,
dest: expr::Dest)
- -> block {
+ -> @mut Block {
//!
//
// [...] allocates a fixed-size array and moves it around "by value".
};
}
-pub fn trans_slice_vstore(bcx: block,
+pub fn trans_slice_vstore(bcx: @mut Block,
vstore_expr: @ast::expr,
content_expr: @ast::expr,
dest: expr::Dest)
- -> block {
+ -> @mut Block {
//!
//
// &[...] allocates memory on the stack and writes the values into it,
return bcx;
}
-pub fn trans_lit_str(bcx: block,
+pub fn trans_lit_str(bcx: @mut Block,
lit_expr: @ast::expr,
str_lit: @str,
dest: Dest)
- -> block {
+ -> @mut Block {
//!
//
// Literal strings translate to slices into static memory. This is
}
-pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::expr,
+pub fn trans_uniq_or_managed_vstore(bcx: @mut Block, heap: heap, vstore_expr: @ast::expr,
content_expr: &ast::expr) -> DatumBlock {
//!
//
return immediate_rvalue_bcx(bcx, val, vt.vec_ty);
}
-pub fn write_content(bcx: block,
+pub fn write_content(bcx: @mut Block,
vt: &VecTypes,
vstore_expr: @ast::expr,
content_expr: &ast::expr,
dest: Dest)
- -> block {
+ -> @mut Block {
let _icx = push_ctxt("tvec::write_content");
let mut bcx = bcx;
}
}
-pub fn vec_types_from_expr(bcx: block, vec_expr: &ast::expr) -> VecTypes {
+pub fn vec_types_from_expr(bcx: @mut Block, vec_expr: &ast::expr) -> VecTypes {
let vec_ty = node_id_type(bcx, vec_expr.id);
vec_types(bcx, vec_ty)
}
-pub fn vec_types(bcx: block, vec_ty: ty::t) -> VecTypes {
+pub fn vec_types(bcx: @mut Block, vec_ty: ty::t) -> VecTypes {
let ccx = bcx.ccx();
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
let llunit_ty = type_of::type_of(ccx, unit_ty);
llunit_size: llunit_size}
}
-pub fn elements_required(bcx: block, content_expr: &ast::expr) -> uint {
+pub fn elements_required(bcx: @mut Block, content_expr: &ast::expr) -> uint {
//! Figure out the number of elements we need to store this content
match content_expr.node {
}
}
-pub fn get_base_and_len(bcx: block,
+pub fn get_base_and_len(bcx: @mut Block,
llval: ValueRef,
vec_ty: ty::t) -> (ValueRef, ValueRef) {
//!
}
}
-pub type iter_vec_block<'self> = &'self fn(block, ValueRef, ty::t) -> block;
+pub type iter_vec_block<'self> = &'self fn(@mut Block, ValueRef, ty::t) -> @mut Block;
-pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t,
- fill: ValueRef, f: iter_vec_block) -> block {
+pub fn iter_vec_raw(bcx: @mut Block, data_ptr: ValueRef, vec_ty: ty::t,
+ fill: ValueRef, f: iter_vec_block) -> @mut Block {
let _icx = push_ctxt("tvec::iter_vec_raw");
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
}
-pub fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t,
- fill: ValueRef, f: iter_vec_block) -> block {
+pub fn iter_vec_uniq(bcx: @mut Block, vptr: ValueRef, vec_ty: ty::t,
+ fill: ValueRef, f: iter_vec_block) -> @mut Block {
let _icx = push_ctxt("tvec::iter_vec_uniq");
let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr, vec_ty));
iter_vec_raw(bcx, data_ptr, vec_ty, fill, f)
}
-pub fn iter_vec_unboxed(bcx: block, body_ptr: ValueRef, vec_ty: ty::t,
- f: iter_vec_block) -> block {
+pub fn iter_vec_unboxed(bcx: @mut Block, body_ptr: ValueRef, vec_ty: ty::t,
+ f: iter_vec_block) -> @mut Block {
let _icx = push_ctxt("tvec::iter_vec_unboxed");
let fill = get_fill(bcx, body_ptr);
let dataptr = get_dataptr(bcx, body_ptr);
use middle::trans::glue;
use middle::ty;
-pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t)
- -> block {
+pub fn make_free_glue(bcx: @mut Block, vptrptr: ValueRef, box_ty: ty::t)
+ -> @mut Block {
let _icx = push_ctxt("uniq::make_free_glue");
let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty);
use middle::trans::type_::Type;
pub fn root_and_write_guard(datum: &Datum,
- mut bcx: block,
+ mut bcx: @mut Block,
span: span,
expr_id: ast::node_id,
- derefs: uint) -> block {
+ derefs: uint) -> @mut Block {
let key = root_map_key { id: expr_id, derefs: derefs };
debug!("write_guard::root_and_write_guard(key=%?)", key);
}
}
-pub fn return_to_mut(mut bcx: block,
+pub fn return_to_mut(mut bcx: @mut Block,
root_key: root_map_key,
frozen_val_ref: ValueRef,
bits_val_ref: ValueRef,
filename_val: ValueRef,
- line_val: ValueRef) -> block {
+ line_val: ValueRef) -> @mut Block {
debug!("write_guard::return_to_mut(root_key=%?, %s, %s, %s)",
root_key,
bcx.to_str(),
}
fn root(datum: &Datum,
- mut bcx: block,
+ mut bcx: @mut Block,
span: span,
root_key: root_map_key,
- root_info: RootInfo) -> block {
+ root_info: RootInfo) -> @mut Block {
//! In some cases, borrowck will decide that an @T/@[]/@str
//! value must be rooted for the program to be safe. In that
//! case, we will call this function, which will stash a copy
}
fn perform_write_guard(datum: &Datum,
- bcx: block,
- span: span) -> block {
+ bcx: @mut Block,
+ span: span) -> @mut Block {
debug!("perform_write_guard");
let llval = datum.to_value_llval(bcx);
let len_buckets = self.buckets.len();
let bucket = self.buckets[idx].take();
- let value = match bucket {
- None => None,
- Some(Bucket{value, _}) => {
- Some(value)
- },
+ let value = do bucket.map_consume |bucket| {
+ bucket.value
};
/* re-inserting buckets may cause changes in size, so remember
// `consume_rev_iter` is more efficient than `consume_iter` for vectors
HashMapConsumeIterator {iter: self.buckets.consume_rev_iter()}
}
-
}
impl<K: Hash + Eq, V: Clone> HashMap<K, V> {
fn eq(&self, other: &HashMap<K, V>) -> bool {
if self.len() != other.len() { return false; }
- for self.iter().advance |(key, value)| {
+ do self.iter().all |(key, value)| {
match other.find(key) {
- None => return false,
- Some(v) => if value != v { return false },
+ None => false,
+ Some(v) => value == v
}
}
-
- true
}
fn ne(&self, other: &HashMap<K, V>) -> bool { !self.eq(other) }
assert_eq!(n, None);
}
}
+
+#[cfg(test)]
+mod bench {
+ use extra::test::BenchHarness;
+ use rand::{XorShiftRng,RngUtil};
+ use uint;
+ use float;
+
+ #[bench]
+ fn uint_to_str_rand(bh: &mut BenchHarness) {
+ let mut rng = XorShiftRng::new();
+ do bh.iter {
+ uint::to_str(rng.gen());
+ }
+ }
+
+ #[bench]
+ fn float_to_str_rand(bh: &mut BenchHarness) {
+ let mut rng = XorShiftRng::new();
+ do bh.iter {
+ float::to_str(rng.gen());
+ }
+ }
+}
\ No newline at end of file
pub trait Index<Index,Result> {
fn index(&self, index: &Index) -> Result;
}
+
+#[cfg(test)]
+mod bench {
+
+ use extra::test::BenchHarness;
+ use ops::Drop;
+
+ // Overhead of dtors
+
+ struct HasDtor {
+ x: int
+ }
+
+ impl Drop for HasDtor {
+ fn drop(&self) {
+ }
+ }
+
+ #[bench]
+ fn alloc_obj_with_dtor(bh: &mut BenchHarness) {
+ do bh.iter {
+ HasDtor { x : 10 };
+ }
+ }
+}
\ No newline at end of file
}
#[cfg(test)]
-mod tests {
+mod test {
use option::{Option, Some};
use super::*;
}
}
}
+
+#[cfg(test)]
+mod bench {
+ use extra::test::BenchHarness;
+ use rand::*;
+ use sys::size_of;
+
+ #[bench]
+ fn rand_xorshift(bh: &mut BenchHarness) {
+ let mut rng = XorShiftRng::new();
+ do bh.iter {
+ rng.gen::<uint>();
+ }
+ bh.bytes = size_of::<uint>() as u64;
+ }
+
+ #[bench]
+ fn rand_isaac(bh: &mut BenchHarness) {
+ let mut rng = IsaacRng::new();
+ do bh.iter {
+ rng.gen::<uint>();
+ }
+ bh.bytes = size_of::<uint>() as u64;
+ }
+
+ #[bench]
+ fn rand_shuffle_100(bh: &mut BenchHarness) {
+ let mut rng = XorShiftRng::new();
+ let x : &mut[uint] = [1,..100];
+ do bh.iter {
+ rng.shuffle_mut(x);
+ }
+ }
+}
\ No newline at end of file
pub unsafe fn exchange_free(ptr: *c_char) {
free(ptr as *c_void);
}
+
+#[cfg(test)]
+mod bench {
+ use extra::test::BenchHarness;
+
+ #[bench]
+ fn alloc_owned_small(bh: &mut BenchHarness) {
+ do bh.iter {
+ ~10;
+ }
+ }
+
+ #[bench]
+ fn alloc_owned_big(bh: &mut BenchHarness) {
+ do bh.iter {
+ ~[10, ..1000];
+ }
+ }
+}
fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox);
fn rust_current_boxed_region() -> *BoxedRegion;
}
+
+#[cfg(test)]
+mod bench {
+ use extra::test::BenchHarness;
+
+ #[bench]
+ fn alloc_managed_small(bh: &mut BenchHarness) {
+ do bh.iter {
+ @10;
+ }
+ }
+
+ #[bench]
+ fn alloc_managed_big(bh: &mut BenchHarness) {
+ do bh.iter {
+ @[10, ..1000];
+ }
+ }
+}
#[deny(non_camel_case_types)];
#[deny(missing_doc)];
+// Make extra accessible for benchmarking
+#[cfg(test)] extern mod extra(vers="0.8-pre");
+
// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern mod realstd(name = "std");
#[cfg(test)] pub use kinds = realstd::kinds;
assert_eq!(5, sum_len([s.as_slice()]));
}
}
+
+#[cfg(test)]
+mod bench {
+ use extra::test::BenchHarness;
+ use str;
+
+ #[bench]
+ fn is_utf8_100_ascii(bh: &mut BenchHarness) {
+
+ let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
+ Lorem ipsum dolor sit amet, consectetur. ");
+
+ assert_eq!(100, s.len());
+ do bh.iter {
+ str::is_utf8(s);
+ }
+ }
+
+ #[bench]
+ fn is_utf8_100_multibyte(bh: &mut BenchHarness) {
+ let s = bytes!("ππππππΰΈΰΈ£Ψ―ΩΩΨ© Ψ§ΩΩΩΩΨͺΰΈΰΈ¨ΰΉΰΈΰΈ’δΈεπ
πΏπ»ππΉπ»π°");
+ assert_eq!(100, s.len());
+ do bh.iter {
+ str::is_utf8(s);
+ }
+ }
+
+ #[bench]
+ fn map_chars_100_ascii(bh: &mut BenchHarness) {
+ let s = "HelloHelloHelloHelloHelloHelloHelloHelloHelloHello\
+ HelloHelloHelloHelloHelloHelloHelloHelloHelloHello";
+ do bh.iter {
+ s.map_chars(|c| ((c as uint) + 1) as char);
+ }
+ }
+
+ #[bench]
+ fn map_chars_100_multibytes(bh: &mut BenchHarness) {
+ let s = "πππππππππππππππππππππππππ\
+ πππππππππππππππππππππππππ\
+ πππππππππππππππππππππππππ\
+ πππππππππππππππππππππππππ";
+ do bh.iter {
+ s.map_chars(|c| ((c as uint) + 1) as char);
+ }
+ }
+}
unsafe { assert_eq!(did_run, true); }
}
}
+
+/// Completely miscellaneous language-construct benchmarks.
+#[cfg(test)]
+mod bench {
+
+ use extra::test::BenchHarness;
+ use option::{Some,None};
+
+ // Static/dynamic method dispatch
+
+ struct Struct {
+ field: int
+ }
+
+ trait Trait {
+ fn method(&self) -> int;
+ }
+
+ impl Trait for Struct {
+ fn method(&self) -> int {
+ self.field
+ }
+ }
+
+ #[bench]
+ fn trait_vtable_method_call(bh: &mut BenchHarness) {
+ let s = Struct { field: 10 };
+ let t = &s as &Trait;
+ do bh.iter {
+ t.method();
+ }
+ }
+
+ #[bench]
+ fn trait_static_method_call(bh: &mut BenchHarness) {
+ let s = Struct { field: 10 };
+ do bh.iter {
+ s.method();
+ }
+ }
+
+ // Overhead of various match forms
+
+ #[bench]
+ fn match_option_some(bh: &mut BenchHarness) {
+ let x = Some(10);
+ do bh.iter {
+ let _q = match x {
+ Some(y) => y,
+ None => 11
+ };
+ }
+ }
+
+ #[bench]
+ fn match_vec_pattern(bh: &mut BenchHarness) {
+ let x = [1,2,3,4,5,6];
+ do bh.iter {
+ let _q = match x {
+ [1,2,3,.._] => 10,
+ _ => 11
+ };
+ }
+ }
+}
return &reinterpret_cast<const cratemap_v0 *>(this)->
m_children[0];
case 1:
- return &m_children[1];
+ return &m_children[0];
default: assert(false && "Unknown crate map version!");
return NULL; // Appease -Werror=return-type
}
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::libc;
+
+extern "C" {
+ pub fn rand() -> libc::c_int;
+}
+
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//aux-build:issue_5844_aux.rs
+
+extern mod issue_5844_aux;
+
+fn main () {
+ issue_5844_aux::rand(); //~ ERROR: requires unsafe
+}
+
--- /dev/null
+#[cfg(not(target_os = "macos"))]
+#[link_section=".moretext"]
+fn i_live_in_more_text() -> &'static str {
+ "knock knock"
+}
+
+#[cfg(not(target_os = "macos"))]
+#[link_section=".imm"]
+static magic: uint = 42;
+
+#[cfg(not(target_os = "macos"))]
+#[link_section=".mut"]
+static mut frobulator: uint = 0xdeadbeef;
+
+#[cfg(target_os = "macos")]
+#[link_section="__TEXT,__moretext"]
+fn i_live_in_more_text() -> &'static str {
+ "knock knock"
+}
+
+#[cfg(target_os = "macos")]
+#[link_section="__RODATA,__imm"]
+static magic: uint = 42;
+
+#[cfg(target_os = "macos")]
+#[link_section="__DATA,__mut"]
+static mut frobulator: uint = 0xdeadbeef;
+
+fn main() {
+ unsafe {
+ frobulator = 0xcafebabe;
+ printfln!("%? %? %?", i_live_in_more_text(), magic, frobulator);
+ }
+}