Save 37% off PRO during our Black Friday Sale! »

Rust: low-level programming without the segfaults

Rust: low-level programming without the segfaults

Presented at OSCON 2013.

2e36436c692b2e5fbc172e9fb7563171?s=128

dherman

July 25, 2013
Tweet

Transcript

  1. None
  2. None
  3. None
  4. The price of performance shouldn’t have to be crashes and

    exploits.
  5. • Safe unions and pointers • Explicit memory layout &

    stack allocation • Optional garbage collection • Mutability control & race-free concurrency Rust: perf + safety
  6. ALGEBRAIC DATA TYPES

  7. enum Color { Red, Green, Blue }

  8. enum Tree { Empty, Leaf(int), Node(~Tree, ~Tree) }

  9. tag tag int tag ~Tree ~Tree Empty Leaf(int) Node(~Tree, ~Tree)

  10. struct Tree { enum TreeTag tag; union { int leaf;

    Pair node; } data; }; enum TreeTag { Empty, Leaf, Node }; struct Pair { Tree *left, *right; };
  11. PATTERN MATCHING

  12. match tree { Empty => 0, Leaf(_) => 1, Node(~ref

    left, ~ref right) => f(left) + f(right) }
  13. enum Option<T> { None, Some(T) }

  14. None
  15. fn double(p: ~int) -> int { *p * 2 }

  16. fn double(p: Option<~int>) -> int { match p { None

    => 0, Some(~n) => n * 2 } }
  17. OWNERSHIP

  18. void *realloc(void *, ...); void free(void *); Owned pointers

  19. void *realloc(void *, ...); void free(void *); template<class K, class

    V> class Hashtable { vector<Bucket<K,V>> buckets; ... }; Owned pointers
  20. memcpy(void *dest, const void *src, uintptr_t count); Temporary pointers

  21. memcpy(void *dest, const void *src, uintptr_t count); template<class K, class

    V> class Hashtable { ... V& find(K& key); }; Temporary pointers
  22. the right to free memory What is ownership?

  23. struct Hashtable<K,V> { buckets: ~[Option<Bucket<K,V>>] } struct Bucket<K,V> { key:

    K, value: V }
  24. { let b = ~[]; let table = Hashtable {

    buckets: b }; ... }
  25. { let b = ~[]; let table = Hashtable {

    buckets: b }; ... } heap allocate
  26. { let b = ~[]; let table = Hashtable {

    buckets: b }; ... } heap allocate stack allocate
  27. { let b = ~[]; let table = Hashtable {

    buckets: b }; ... } heap allocate stack allocate move
  28. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); }
  29. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); } heap allocate
  30. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); } heap allocate move
  31. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); } heap allocate free p move
  32. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); } heap allocate free p move printfln!(“%d”, *x); // error
  33. BORROWING

  34. fn f() { let x: ~int = ~22; borrow(x); printfln!(“%d”,

    *x); } fn borrow(x: &int) { printfln!(“borrowing: %d”, *x); }
  35. fn f() { let x: int = 22; borrow(&x); printfln!(“%d”,

    *x); } fn borrow(x: &int) { printfln!(“borrowing: %d”, *x); }
  36. let w = ~22; { let x = &w; let

    y = &*x; } ‘a ‘b ‘c ‘d Lifetimes
  37. fn find<‘a,K,V>(tbl: &’a Hashtable<K,V>, key: &K) -> Option<&’a V> {

    ... }
  38. fn find<‘a,K,V>(tbl: &’a Hashtable<K,V>, key: &K) -> Option<&’a V> {

    ... } pointer with lifetime ‘a to table
  39. fn find<‘a,K,V>(tbl: &’a Hashtable<K,V>, key: &K) -> Option<&’a V> {

    ... } pointer with lifetime ‘a to table pointer with lifetime ‘a to value
  40. template<class K, class V> class Hashtable<K,V> V& Hashtable<K,V>::find(K& key); unsafe!

  41. CONCURRENCY

  42. Heap

  43. Heap

  44. let (port, chan) = stream(); do spawn { let p

    = ~Point { x: 1.0, y: 2.0 }; chan.send(p); } let p = port.recv(); printfln!(p.to_str());
  45. • Pluggable I/O • Optional scheduler • Data race-free shared

    data structures • Potential for race-free fork-join parallelism • Working on SIMD and GPU libs There’s more
  46. UNSAFE

  47. unsafe { transmute::<&str,&[u8]>(“L”) == &[76, 0] } unsafe fn f(...)

    { ... }
  48. unsafe { transmute::<&str,&[u8]>(“L”) == &[76, 0] } unsafe fn f(...)

    { ... } ☢
  49. 1. Don’t use unsafe code. 2. If you absolutely must

    break Rule 1, • get out of unsafe code ASAP, and • always provide a safe interface at the boundaries. The rules
  50. Low-level programming… without the segfaults.

  51. Thank you.

  52. Image credits Sean Martell http://blog.seanmartell.com Ben Clinch http://www.flickr.com/photos/benclinch/3048906022/ juicyrai http://www.flickr.com/photos/wink/180979062/

    Rama, Wikimedia Commons http://en.wikipedia.org/wiki/File:Sir_Tony_Hoare_IMG_5125.jpg Jared Zimmerman http://www.flickr.com/photos/spoinknet/7932382540/ CCAC North Library http://www.flickr.com/photos/ccacnorthlib/3553821699/ Mike Hayes http://www.flickr.com/photos/rotties/449650275/