Slide 1

Slide 1 text

Compiling Ruby

Slide 2

Slide 2 text

Kevin Deisz @kddeisz

Slide 3

Slide 3 text

# example.rb a = 5 puts a + 5

Slide 4

Slide 4 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $

Slide 5

Slide 5 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby example.rb 10 ~/compiling-ruby $

Slide 6

Slide 6 text

Ruby execution process

Slide 7

Slide 7 text

#require

Slide 8

Slide 8 text

Read source #require

Slide 9

Slide 9 text

Tokenize Read source #require

Slide 10

Slide 10 text

Tokenize Build AST Read source #require

Slide 11

Slide 11 text

Tokenize Build AST Read source #require Interpret AST

Slide 12

Slide 12 text

Tokenize Build AST Read source Interpret AST #require

Slide 13

Slide 13 text

Tokenize Build AST Build ISeq Read source Interpret AST #require

Slide 14

Slide 14 text

Execute ISeq Tokenize Build AST Build ISeq Read source Interpret AST #require

Slide 15

Slide 15 text

Tokenizing the input Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 16

Slide 16 text

# example.rb a = 5 puts a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 17

Slide 17 text

[comment="# example.rb\n"] a = 5 puts a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 18

Slide 18 text

[comment="# example.rb\n"] [ignored_nl] a = 5 puts a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 19

Slide 19 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] = 5 puts a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 20

Slide 20 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] 5 puts a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 21

Slide 21 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] puts a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 22

Slide 22 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5][nl] puts a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 23

Slide 23 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5][nl] [ident=puts] a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 24

Slide 24 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5][nl] [ident=puts] [ident=a] + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 25

Slide 25 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5][nl] [ident=puts] [ident=a] [op+] 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 26

Slide 26 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5][nl] [ident=puts] [ident=a] [op+] [int=5] Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 27

Slide 27 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5][nl] [ident=puts] [ident=a] [op+] [int=5][nl] Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 28

Slide 28 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] [nl] [ident=puts] [ident=a] [op+] [int=5] [nl] Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 29

Slide 29 text

Building the AST Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 30

Slide 30 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] [nl] [ident=puts] [ident=a] [op+] [int=5] [nl] Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 31

Slide 31 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] [nl] [ident=puts] [ident=a] [op+] [int=5] [nl] begin Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 32

Slide 32 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] [nl] [ident=puts] [ident=a] [op+] [int=5] [nl] begin Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 33

Slide 33 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] [nl] [ident=puts] [ident=a] [op+] [int=5] [nl] begin lvasgn :a int 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 34

Slide 34 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] [nl] [ident=puts] [ident=a] [op+] [int=5] [nl] begin lvasgn :a int 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 35

Slide 35 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] [nl] [ident=puts] [ident=a] [op+] [int=5] [nl] begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 36

Slide 36 text

[comment="# example.rb\n"] [ignored_nl] [ident=a] [op=] [int=5] [nl] [ident=puts] [ident=a] [op+] [int=5] [nl] begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 37

Slide 37 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 38

Slide 38 text

Interpreting the AST (≤ Ruby 1.8) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 39

Slide 39 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 40

Slide 40 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 41

Slide 41 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts local = {} instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 42

Slide 42 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts local = {} instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 43

Slide 43 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts local = {} instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $

Slide 44

Slide 44 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts local = {} instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 45

Slide 45 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts local = {} instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 46

Slide 46 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 5 local = {} instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 47

Slide 47 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts set :a
 5 local = {} instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 48

Slide 48 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 49

Slide 49 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 5 local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 50

Slide 50 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts get :a 5 local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 51

Slide 51 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 5 5 local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 52

Slide 52 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts send :+ 5 5 local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 53

Slide 53 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 10 local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 54

Slide 54 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts self
 10 local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 55

Slide 55 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts send :puts
 self
 10 local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb

Slide 56

Slide 56 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb 10

Slide 57

Slide 57 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts local = { a: 5 } instance = {} global = {} Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq ~/compiling-ruby $ ruby example.rb 10 ~/compiling-ruby $

Slide 58

Slide 58 text

Building YARV instruction sequences Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 59

Slide 59 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 60

Slide 60 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 61

Slide 61 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 62

Slide 62 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 63

Slide 63 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 64

Slide 64 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 65

Slide 65 text

0000 trace 1 0002 putobject 5 begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 66

Slide 66 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 67

Slide 67 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 68

Slide 68 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 69

Slide 69 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 70

Slide 70 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 71

Slide 71 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 72

Slide 72 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 73

Slide 73 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 74

Slide 74 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 75

Slide 75 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 76

Slide 76 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 77

Slide 77 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block ,

Slide 78

Slide 78 text

begin lvasgn :a int 5 lvar :a int 5 send :+ send :puts 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 79

Slide 79 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 80

Slide 80 text

Executing YARV instruction sequences Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 81

Slide 81 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 82

Slide 82 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 83

Slide 83 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq local = {} instance = {} global = {} ~/compiling-ruby $ 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 84

Slide 84 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq local = {} instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 85

Slide 85 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq local = {} instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 86

Slide 86 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 5 local = {} instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 87

Slide 87 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 
 5 local = {} instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 88

Slide 88 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 89

Slide 89 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 90

Slide 90 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq self local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 91

Slide 91 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq self local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 92

Slide 92 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 5
 self local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 93

Slide 93 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 5 self local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 94

Slide 94 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 5 5 self local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 95

Slide 95 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 5 5 self local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 96

Slide 96 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 10 self local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 97

Slide 97 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq 10 self local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 98

Slide 98 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 10 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 99

Slide 99 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq local = { 3: 5 } instance = {} global = {} ~/compiling-ruby $ ruby example.rb 10 ~/compiling-ruby $ 0000 trace 1 0002 putobject 5 0004 setlocal 3 0006 trace 1 0008 putself 0009 getlocal 3 0011 putobject 5 0013 opt_plus !mid:+, argc:1, ARGS_SIMPLE>, 0016 opt_send_without_block , 0019 leave

Slide 100

Slide 100 text

Reading/writing YARV instruction sequences (≥ Ruby 2.3) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq

Slide 101

Slide 101 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 102

Slide 102 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 103

Slide 103 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 104

Slide 104 text

# example.rb a = 5 puts a + 5 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 105

Slide 105 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 106

Slide 106 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 107

Slide 107 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 108

Slide 108 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 109

Slide 109 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 110

Slide 110 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 111

Slide 111 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ ls -l total 16 -rw-r--r-- 1 kddeisz staff 32 Aug 28 15:11 example.rb -rw-r--r-- 1 kddeisz staff 777 Aug 29 11:17 example.yarb ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 112

Slide 112 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ ls -l total 16 -rw-r--r-- 1 kddeisz staff 32 Aug 28 15:11 example.rb -rw-r--r-- 1 kddeisz staff 777 Aug 29 11:17 example.yarb ~/compiling-ruby $ ruby -e "content = File.read('example.yarb'); RubyVM::InstructionSequence.load_from_binary(content).eval" 10 ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 113

Slide 113 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ ls -l total 16 -rw-r--r-- 1 kddeisz staff 32 Aug 28 15:11 example.rb -rw-r--r-- 1 kddeisz staff 777 Aug 29 11:17 example.yarb ~/compiling-ruby $ ruby -e "content = File.read('example.yarb'); RubyVM::InstructionSequence.load_from_binary(content).eval" 10 ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 114

Slide 114 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ ls -l total 16 -rw-r--r-- 1 kddeisz staff 32 Aug 28 15:11 example.rb -rw-r--r-- 1 kddeisz staff 777 Aug 29 11:17 example.yarb ~/compiling-ruby $ ruby -e "content = File.read('example.yarb'); RubyVM::InstructionSequence.load_from_binary(content).eval" 10 ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 115

Slide 115 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ ls -l total 16 -rw-r--r-- 1 kddeisz staff 32 Aug 28 15:11 example.rb -rw-r--r-- 1 kddeisz staff 777 Aug 29 11:17 example.yarb ~/compiling-ruby $ ruby -e "content = File.read('example.yarb'); RubyVM::InstructionSequence.load_from_binary(content).eval" 10 ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 116

Slide 116 text

# example.rb a = 5 puts a + 5 ~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ ls -l total 16 -rw-r--r-- 1 kddeisz staff 32 Aug 28 15:11 example.rb -rw-r--r-- 1 kddeisz staff 777 Aug 29 11:17 example.yarb ~/compiling-ruby $ ruby -e "content = File.read('example.yarb'); RubyVM::InstructionSequence.load_from_binary(content).eval" 10 ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 117

Slide 117 text

Programmatically loading YARV instruction sequences (≥ Ruby 2.3) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 118

Slide 118 text

Execute ISeq Tokenize Build AST Build ISeq Read source Interpret AST #require Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 119

Slide 119 text

Tokenize Build AST Build ISeq Read source Interpret AST #require Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq Execute ISeq Write ISeq Read ISeq

Slide 120

Slide 120 text

/* ruby/load.c */ static int rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap) { ... if ((iseq = rb_iseq_load_iseq(fname)) != NULL) { /* OK */ } else { VALUE parser = rb_parser_new(); rb_parser_set_context(parser, NULL, FALSE); node = (NODE *)rb_parser_load_file(parser, fname); iseq = rb_iseq_new_top(node, rb_fstring_cstr(""), fname, rb_realpath_internal(Qnil, fname, 1), NULL); } rb_iseq_eval(iseq); ... } Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 121

Slide 121 text

/* ruby/load.c */ static int rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap) { ... if ((iseq = rb_iseq_load_iseq(fname)) != NULL) { /* OK */ } else { VALUE parser = rb_parser_new(); rb_parser_set_context(parser, NULL, FALSE); node = (NODE *)rb_parser_load_file(parser, fname); iseq = rb_iseq_new_top(node, rb_fstring_cstr(""), fname, rb_realpath_internal(Qnil, fname, 1), NULL); } rb_iseq_eval(iseq); ... } Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 122

Slide 122 text

/* ruby/iseq.c */ const rb_iseq_t * rb_iseq_load_iseq(VALUE fname) { VALUE iseqv = rb_check_funcall(rb_cISeq, rb_intern("load_iseq"), 1, &fname); if (!SPECIAL_CONST_P(iseqv) && RBASIC_CLASS(iseqv) == rb_cISeq) { return iseqw_check(iseqv); } return NULL; } Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 123

Slide 123 text

/* ruby/iseq.c */ const rb_iseq_t * rb_iseq_load_iseq(VALUE fname) { VALUE iseqv = rb_check_funcall(rb_cISeq, rb_intern("load_iseq"), 1, &fname); if (!SPECIAL_CONST_P(iseqv) && RBASIC_CLASS(iseqv) == rb_cISeq) { return iseqw_check(iseqv); } return NULL; } Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 124

Slide 124 text

/* ruby/iseq.c */ const rb_iseq_t * rb_iseq_load_iseq(VALUE fname) { VALUE iseqv = rb_check_funcall(rb_cISeq, rb_intern("load_iseq"), 1, &fname); if (!SPECIAL_CONST_P(iseqv) && RBASIC_CLASS(iseqv) == rb_cISeq) { return iseqw_check(iseqv); } return NULL; } Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 125

Slide 125 text

/* ruby/iseq.c */ const rb_iseq_t * rb_iseq_load_iseq(VALUE fname) { VALUE iseqv = rb_check_funcall(rb_cISeq, rb_intern("load_iseq"), 1, &fname); if (!SPECIAL_CONST_P(iseqv) && RBASIC_CLASS(iseqv) == rb_cISeq) { return iseqw_check(iseqv); } return NULL; } Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 126

Slide 126 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 127

Slide 127 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 128

Slide 128 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 129

Slide 129 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 130

Slide 130 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 131

Slide 131 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 132

Slide 132 text

Examples Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 133

Slide 133 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq /* bootsnap/lib/bootsnap/compile_cache/iseq.rb */ module InstructionSequenceMixin def load_iseq(path) # Having coverage enabled prevents iseq dumping/loading. return nil if defined?(Coverage) && Bootsnap::CompileCache::Native.coverage_running? Bootsnap::CompileCache::Native.fetch( Bootsnap::CompileCache::ISeq.cache_dir, path.to_s, Bootsnap::CompileCache::ISeq ) rescue RuntimeError => e if e.message =~ /unmatched platform/ puts "unmatched platform for file #{path}" end raise end ... end

Slide 134

Slide 134 text

/* yomikomu/lib/yomikomu.rb */ class RubyVM::InstructionSequence if ENV['YOMIKOMU_YOMIKOMANAI'] != 'true' def self.load_iseq fname ::Yomikomu::STORAGE.load_iseq(fname) end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 135

Slide 135 text

Now for the fun part Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq

Slide 136

Slide 136 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 137

Slide 137 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end begin content = File.read(source_path) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 138

Slide 138 text

content = File.read(source_path) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 139

Slide 139 text

content = File.read(source_path) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq THIS IS THE FUN PART Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 140

Slide 140 text

content = File.read(source_path) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 141

Slide 141 text

content = File.read(source_path) content.gsub!(/~n\(([\d\s+-\/*\(\)]+?)\)/) do |match| eval(match[3..-2]) end iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 142

Slide 142 text

content = File.read(source_path) content.gsub!(/~n\(([\d\s+-\/*\(\)]+?)\)/) do |match| eval(match[3..-2]) end iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.days_to_seconds(days) days * 24 * 60 * 60 end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 143

Slide 143 text

content = File.read(source_path) content.gsub!(/~n\(([\d\s+-\/*\(\)]+?)\)/) do |match| eval(match[3..-2]) end iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.days_to_seconds(days) days * ~n(24 * 60 * 60) end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 144

Slide 144 text

content = File.read(source_path) content.gsub!(/~n\(([\d\s+-\/*\(\)]+?)\)/) do |match| eval(match[3..-2]) end iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part module Utils def self.days_to_seconds(days) days * ~n(24 * 60 * 60) end end

Slide 145

Slide 145 text

content = File.read(source_path) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 146

Slide 146 text

content = File.read(source_path) serial_format = '%FT%T%:z' content.gsub!(/~d\((.+?)\)/) do |match| date = Date.parse(match[3..-2]) "Date.strptime('#{date.strftime(serial_format)}', " \ "'#{serial_format}')" end iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 147

Slide 147 text

content = File.read(source_path) serial_format = '%FT%T%:z' content.gsub!(/~d\((.+?)\)/) do |match| date = Date.parse(match[3..-2]) "Date.strptime('#{date.strftime(serial_format)}', " \ "'#{serial_format}')" end iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part module Utils def self.days_since_start(date) date - Date.parse('January 1st, 2017') end end

Slide 148

Slide 148 text

content = File.read(source_path) serial_format = '%FT%T%:z' content.gsub!(/~d\((.+?)\)/) do |match| date = Date.parse(match[3..-2]) "Date.strptime('#{date.strftime(serial_format)}', " \ "'#{serial_format}')" end iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.days_since_start(date) date - ~d(January 1st, 2017) end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 149

Slide 149 text

content = File.read(source_path) serial_format = '%FT%T%:z' content.gsub!(/~d\((.+?)\)/) do |match| date = Date.parse(match[3..-2]) "Date.strptime('#{date.strftime(serial_format)}', " \ "'#{serial_format}')" end iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part module Utils def self.days_since_start(date) date - ~d(January 1st, 2017) end end

Slide 150

Slide 150 text

It works! Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 151

Slide 151 text

It works! https://github.com/kddeisz/vernacular/blob/ master/lib/vernacular/regex_modifier.rb Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 152

Slide 152 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 153

Slide 153 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 154

Slide 154 text

Tokenize Build AST Build ISeq Read source Interpret AST #require Execute ISeq Write ISeq Read ISeq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 155

Slide 155 text

Tokenize Build AST Build ISeq Read source Interpret AST #require Execute ISeq Write ISeq Read ISeq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part Modify source

Slide 156

Slide 156 text

Let’s go further Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 157

Slide 157 text

content = File.read(source_path) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 158

Slide 158 text

content = File.read(source_path) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq THIS IS THE FUN PART Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 159

Slide 159 text

content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 160

Slide 160 text

content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.add(left, right) left + right end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 161

Slide 161 text

content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.add(left : Integer, right : Integer) left + right end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 162

Slide 162 text

content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part module Utils def self.add(left, right) unless left.is_a?(Integer) raise ArgumentError, "Invalid type, " \ "expected Integer, got #{left.class.name}" end unless right.is_a?(Integer) raise ArgumentError, "Invalid type, " \ "expected Integer, got #{right.class.name}" end left + right end end

Slide 163

Slide 163 text

content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.add(left : Integer, right : Integer) left + right end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 164

Slide 164 text

content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.add(left, right) left + right end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 165

Slide 165 text

content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.add(left, right) = Integer left + right end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 166

Slide 166 text

module Utils def self.add(left, right) result = begin left + right end unless result.is_a?(Integer) raise "Invalid return value, expected " \ "Integer got #{result.class.name}" end result end end content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 167

Slide 167 text

content = File.read(source_path) require 'parser/current' # class CustomBuilder < Parser::Builders::Default builder = CustomBuilder.new # class CustomParser < Parser::CurrentRuby parser = CustomParser.new(builder) # class CustomRewriter < Parser::Rewriter rewriter = CustomRewriter.new rewriter.instance_variable_set(:@parser, parser) buffer = Parser::Base.send(:setup_source_buffer, '(string)', 1, content, parser.default_encoding) ast = parser.parse(content) content = rewriter.rewrite(buffer, ast) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq module Utils def self.add(left, right) = Integer left + right end end Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 168

Slide 168 text

It works! Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 169

Slide 169 text

It works! https://github.com/kddeisz/vernacular/blob/ master/lib/vernacular/ast_modifier.rb Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 170

Slide 170 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 171

Slide 171 text

Tokenize Build AST Build ISeq Read source Interpret AST #require Execute ISeq Write ISeq Read ISeq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part Modify source

Slide 172

Slide 172 text

Tokenize Build AST Build ISeq Read source Interpret AST #require Execute ISeq Write ISeq Read ISeq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part Modify source Modify AST

Slide 173

Slide 173 text

Let’s go even further Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 174

Slide 174 text

~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 175

Slide 175 text

~/compiling-ruby $ ruby -e "File.write('example.yarb', RubyVM::InstructionSequence.compile_file('example.rb').to_binary)" ~/compiling-ruby $ hexdump example.yarb ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 176

Slide 176 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 177

Slide 177 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 struct ibf_header { char magic[4]; /* YARB */ unsigned int major_version; unsigned int minor_version; unsigned int size; unsigned int extra_size; unsigned int iseq_list_size; unsigned int id_list_size; unsigned int object_list_size; ibf_offset_t iseq_list_offset; ibf_offset_t id_list_offset; ibf_offset_t object_list_offset; }; Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 178

Slide 178 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 179

Slide 179 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 180

Slide 180 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 %w[59 41 52 42].map do |ord| ord.to_i(16).chr end.join # YARB Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 181

Slide 181 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 %w[59 41 52 42].map do |ord| ord.to_i(16).chr end.join # YARB %w{78 38 36 5f 36 34 2d 64 61 72 77 69 6e 31 35}.map do |ord| ord.to_i(16).chr end.join # x86_64-darwin15 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 182

Slide 182 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 183

Slide 183 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 header Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 184

Slide 184 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 header RUBY_VERSION Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 185

Slide 185 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 header RUBY_VERSION iseq offset list Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 186

Slide 186 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 header RUBY_VERSION iseq offset list id offset list Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 187

Slide 187 text

0000000 59 41 52 42 02 00 00 00 03 00 00 00 09 03 00 00 0000010 00 00 00 00 01 00 00 00 04 00 00 00 08 00 00 00 0000020 dc 01 00 00 e0 01 00 00 e9 02 00 00 78 38 36 5f 0000030 36 34 2d 64 61 72 77 69 6e 31 35 00 2a 00 00 00 0000040 00 00 00 00 01 00 00 00 00 00 00 00 0f 00 00 00 0000050 00 00 00 00 04 00 00 00 00 00 00 00 59 00 00 00 0000060 00 00 00 00 03 00 00 00 00 00 00 00 2a 00 00 00 0000070 00 00 00 00 01 00 00 00 00 00 00 00 0e 00 00 00 0000080 00 00 00 00 57 00 00 00 00 00 00 00 03 00 00 00 0000090 00 00 00 00 0f 00 00 00 00 00 00 00 04 00 00 00 00000a0 00 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 00000e0 03 00 00 00 06 00 00 00 04 00 00 00 01 00 00 00 00000f0 00 00 00 00 02 00 00 00 00 00 00 00 10 00 00 00 0000100 01 00 00 00 03 00 00 00 00 00 00 00 14 00 00 00 0000110 01 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000150 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 0000160 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 0000170 00 00 00 00 03 00 00 00 00 00 00 00 dc 00 00 00 0000180 00 00 00 00 ec 00 00 00 00 00 00 00 00 00 00 00 0000190 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 f4 00 00 00 00001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c0 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00001d0 00 00 00 00 02 00 00 00 03 00 00 00 14 01 00 00 00001e0 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00001f0 06 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 0000200 f1 00 00 00 08 00 00 00 00 00 00 00 45 00 00 00 0000210 01 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0000220 65 78 61 6d 70 6c 65 2e 72 62 45 00 00 00 01 00 0000230 00 00 00 00 00 00 43 00 00 00 00 00 00 00 2f 55 0000240 73 65 72 73 2f 6b 64 64 65 69 73 7a 2f 44 6f 63 0000250 75 6d 65 6e 74 73 2f 70 72 6f 6a 65 63 74 73 2f 0000260 73 61 6e 64 62 6f 78 2f 63 6f 6d 70 69 6c 69 6e 0000270 67 2d 72 75 62 79 2f 65 78 61 6d 70 6c 65 2e 72 0000280 62 45 00 00 00 02 00 00 00 00 00 00 00 06 00 00 0000290 00 00 00 00 00 3c 6d 61 69 6e 3e f5 00 00 00 0b 00002a0 00 00 00 00 00 00 00 45 00 00 00 02 00 00 00 00 00002b0 00 00 00 01 00 00 00 00 00 00 00 61 45 00 00 00 00002c0 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00002d0 2b 45 00 00 00 02 00 00 00 00 00 00 00 04 00 00 00002e0 00 00 00 00 00 70 75 74 73 00 02 00 00 0c 02 00 00002f0 00 2a 02 00 00 81 02 00 00 9b 02 00 00 a7 02 00 0000300 00 bc 02 00 00 d1 02 00 00 0000309 header RUBY_VERSION iseq offset list id offset list object offset list Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 188

Slide 188 text

~/compiling-ruby $ ruby -e "RubyVM::InstructionSequence.compile_file('example.rb').to_binary" [ 0 - 3] magic = YARB [ 4 - 7] major_version = 2 [ 8 - 11] minor_version = 3 [12 - 15] size = 801 [16 - 19] extra_size = 0 [20 - 23] iseq_list_size = 1 [24 - 27] id_list_size = 4 [28 - 31] object_list_size = 9 [32 - 35] iseq_list_offset = 468 [36 - 39] id_list_offset = 472 [40 - 43] object_list_offset = 765 [44 - 60] RUBY_PLATFORM = x86_64-darwin15 [468 - 471] iseq 0 = 276 [472 - 479] id 0 = a [480 - 487] id 1 = + [488 - 495] id 2 = puts iseqs = [{ location.pathobj = ["example.rb", true] location.base_label = "" location.label = "" iseq_encoded = param.opt_table = NULL param.keyword = NULL line_info_table = [{ position: 0, line_no: 3 }, { position: 6, line_no: 4 }] local_table = [36945] catch_table = NULL parent_iseq = -1 local_iseq = is_entries = NULL ci_entries = [{ mid: 43, flag: 16, orig_argc: 1 }, { mid: 15617, flag: 20, orig_argc: 1 }] cc_entries = NULL mark_ary = 0 body size = 20 }] ~/compiling-ruby $ Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 189

Slide 189 text

#load_iseq allows us to provide our own bytecode. Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 190

Slide 190 text

#load_iseq allows us to provide our own bytecode. We can inject debugging code into Ruby to learn the binary structure of a YARV bytecode dump. Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 191

Slide 191 text

#load_iseq allows us to provide our own bytecode. We can inject debugging code into Ruby to learn the binary structure of a YARV bytecode dump. So, we can write our own code that compiles down to YARV bytecode. Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 192

Slide 192 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end iseq_path = File.join( File.expand_path(__dir__, '.iseq'), source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }.gsub('.rb', '.yarb')) if File.exist?(iseq_path) && (File.mtime(source_path) <= File.mtime(iseq_path)) return RubyVM::InstructionSequence .load_from_binary(File.binread(iseq_path)) end

Slide 193

Slide 193 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part begin iseq = RubyVM::InstructionSequence .compile(File.read(source_path)) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end ...

Slide 194

Slide 194 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part begin content = File.read(source_path) iseq = RubyVM::InstructionSequence.compile(content) File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end ...

Slide 195

Slide 195 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part begin content = File.read(source_path) iseq = if File.basename(source_path).end_with?('.tb.rb') Tuby.compile(content) else RubyVM::InstructionSequence.compile(content) end File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end ...

Slide 196

Slide 196 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part begin content = File.read(source_path) iseq = if File.basename(source_path).end_with?('.tb.rb') Tuby.compile(content) else RubyVM::InstructionSequence.compile(content) end File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end ...

Slide 197

Slide 197 text

class RubyVM::InstructionSequence def self.load_iseq(source_path) Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part begin content = File.read(source_path) iseq = if File.basename(source_path).end_with?('.tb.rb') Tuby.compile(content) else RubyVM::InstructionSequence.compile(content) end File.binwrite(iseq_path, iseq.to_binary) iseq rescue SyntaxError, RuntimeError nil end end end ... Contract = String → #to_binary Tuby::compile RubyVM::InstructionSequence::compile

Slide 198

Slide 198 text

Tokenize Build AST Build ISeq Read source Interpret AST #require Execute ISeq Write ISeq Read ISeq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part Modify source Modify AST

Slide 199

Slide 199 text

Tokenize Build AST Build ISeq Read source Interpret AST #require Execute ISeq Write ISeq Read ISeq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part Modify source Modify AST Build Tuby

Slide 200

Slide 200 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part Because we’re writing YARV bytecode, we maintain interoperability with Ruby.

Slide 201

Slide 201 text

Because we’re writing YARV bytecode, we maintain interoperability with Ruby. We can get the benefits of a compiler and instruction elimination without having to write a native extension. Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 202

Slide 202 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part /* formulae.tb.rb */ impl Formulae::sphere_volume(radius) { (4 / 3) * 3.14159 * (radius ** 3) }

Slide 203

Slide 203 text

Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part /* formulae.tb.rb */ impl Formulae::sphere_volume(radius) { (4 / 3) * 3.14159 * (radius ** 3) } /* formulae.rb */ Formulae.sphere_volume(5) # 392.68987500000003

Slide 204

Slide 204 text

Does it work? Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 205

Slide 205 text

Does it work? Kind of… Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 206

Slide 206 text

Does it work? Kind of… https://github.com/kddeisz/tuby Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 207

Slide 207 text

Tokenize Build AST Build ISeq Read source Interpret AST #require Execute ISeq Write ISeq Read ISeq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part Modify source Modify AST Build Tuby

Slide 208

Slide 208 text

#require Execute ISeq Read ISeq Tokenize • Build AST • (Interpret AST) • Build ISeq • Execute ISeq • Read/write ISeq • The fun part

Slide 209

Slide 209 text

Why would you ever do this?

Slide 210

Slide 210 text

Programming is using human language to represent computer lexicon.

Slide 211

Slide 211 text

Programming is using human language to represent computer lexicon. Code gets read many more times than it gets written.

Slide 212

Slide 212 text

Programming is using human language to represent computer lexicon. Code gets read many more times than it gets written. Optimize for reading code.

Slide 213

Slide 213 text

What’s next?

Slide 214

Slide 214 text

#require Execute ISeq Read ISeq

Slide 215

Slide 215 text

#require Execute ISeq Read ISeq JIT Compile ISeq

Slide 216

Slide 216 text

No content

Slide 217

Slide 217 text

#require Execute ISeq Read ISeq

Slide 218

Slide 218 text

#require Execute ISeq Read ISeq Queue ISeq

Slide 219

Slide 219 text

#require Execute ISeq Read ISeq Queue ISeq Start worker

Slide 220

Slide 220 text

#require Execute ISeq Read ISeq Queue ISeq Start worker Dequeue ISeq

Slide 221

Slide 221 text

#require Execute ISeq Read ISeq Queue ISeq Start worker Generate C Dequeue ISeq

Slide 222

Slide 222 text

#require Execute ISeq Read ISeq Queue ISeq Start worker Generate C Dequeue ISeq Compile native

Slide 223

Slide 223 text

#require Execute ISeq Read ISeq Queue ISeq Start worker Generate C Dequeue ISeq Compile native Call native

Slide 224

Slide 224 text

No content

Slide 225

Slide 225 text

https://github.com/ruby/ruby/pull/1782

Slide 226

Slide 226 text

What’s next?

Slide 227

Slide 227 text

Compiling Ruby github.com/kddeisz/compiling-ruby Kevin Deisz @kddeisz