Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby in your phone. Interpreters. Ruby. iOS

Ruby in your phone. Interpreters. Ruby. iOS

Short story of interpreters, Scheme, Ruby. Described how to build ruby for iOS, including extensions & standard library

C4edd51fe88b9820a046db724d53fd91?s=128

Denis Lebedev

July 31, 2013
Tweet

More Decks by Denis Lebedev

Other Decks in Technology

Transcript

  1. Ruby in your phone Interpreters. Ruby. iOS Denis Lebedev linkedin.com/in/dlebedev

    среда, 31 июля 13 г.
  2. Interpreters среда, 31 июля 13 г.

  3. Program execution - execute code directly (Lisp) - translate code

    to IR and execute (Python, Ruby) - execute stored precompiled code среда, 31 июля 13 г.
  4. Ruby 1.8 slow single-pass interpreter MRI 1.9 yet another Ruby

    VM - YARV среда, 31 июля 13 г.
  5. Scheme среда, 31 июля 13 г.

  6. So simple (+ 3 4 5) среда, 31 июля 13

    г.
  7. NOT so simple (begin (define fact (lambda (n) (if (<=

    n 1) 1 (* n (fact (- n 1)))))) среда, 31 июля 13 г.
  8. How it works? Program Parser Execution representation output среда, 31

    июля 13 г.
  9. Rispy http://stuff.thedeemon.com/rispy/ 60 LOC scheme-interpreter среда, 31 июля 13 г.

  10. Parsing [ :begin, [ :define, :fact, [ :lambda, [ :n],

    [ :if, [ :<=, :n, 1], 1, [ :*, :n, [ :fact, [ :-, :n, 1]]]]]] среда, 31 июля 13 г.
  11. Evaluating - define nested ENVIRONMENT for each lexical scope -

    recursive call of eval(x, env) with a large switch-case среда, 31 июля 13 г.
  12. Ruby среда, 31 июля 13 г.

  13. Ripper require ‘ripper’ Ripper.sexp (‘p “hello world”’) среда, 31 июля

    13 г.
  14. Ripper output [:program, [[:command, [:@ident, "p", [1, 0]], [:args_add_block, [[:string_literal,

    [:string_content, [:@tstring_content, "Hello World", [1, 3]]]]], false]]]] среда, 31 июля 13 г.
  15. parse.y Ruby parser ~11,500 LOC среда, 31 июля 13 г.

  16. iOS среда, 31 июля 13 г.

  17. Building Ruby for armvX. Fail story - download source, build

    using make[x] - build native with Clang installed on iDevice [x] - create Xcode project, add sources, build [x] среда, 31 июля 13 г.
  18. Building Ruby for armvX. Success story 1. A lot of

    TIME spent configuring make 2. Building fails 2’. Some sources won’t compile -> edit/delete 3. Google some new flags -> add 4. Repeat step 1. среда, 31 июля 13 г.
  19. Building Ruby for armvX. Success story 1. A lot of

    TIME spent configuring make 2. Building fails 2’. Some sources won’t compile -> edit/delete 3. Google some new flags -> add 4. Repeat step 1. libruby-static.a we’ve got ya!!! среда, 31 июля 13 г.
  20. Building Ruby extensions 1. --with-static-linked-ext flag 2. Modify content of

    /ext source files 3. Compile to *.a Dynamic libraries are disabled in iOS. среда, 31 июля 13 г.
  21. Run extensions 1. Manually link each extension to libruby-static.a 2.

    Call “Init_xxx methods” in ObjC-code 3. Don’t forget to link encoding packages from /enc среда, 31 июля 13 г.
  22. Standard library /lib - some extensions work out of the

    box - sometimes code editing required - modificaton of PATH variables is required Network, dates, math, etc. is working and tested. среда, 31 июля 13 г.
  23. Usage in Obj-C [[RubyEvaluator sharedInstance] evaluate:@”3.times { puts 1}”] Produces:

    1 1 1 среда, 31 июля 13 г.
  24. Implementation details - Uses rb_eval_string_protect from “ruby.h” - Omits all

    intermediate output :( - Does not allow to interrupt input :( :( :( среда, 31 июля 13 г.
  25. Do yo want some C? - Ruby allows to write

    ‘native’ extensions - We use some tricks to create Ruby<>Obj-C bridge среда, 31 июля 13 г.
  26. Captureoutput.rb class CaptureOutput < IO def initialize super(2) end def

    write(text) captured_write(text) end def gets captured_read end end def gets captured_read end buf = CaptureOutput.new $stderr = buf $stdout = buf $stdin = buf среда, 31 июля 13 г.
  27. Captureoutput.c void init_captureoutput(void (*write_callback)(VALUE str), VALUE (*stdin_read_callback)(void)) { stdout_write_callback =

    write_callback; rb_define_method(rb_cObject, "captured_write", object_captured_write, 1); b_define_method(rb_cObject, "captured_read", object_captured_read, 0); rb_require("captureoutput"); } среда, 31 июля 13 г.
  28. RubyEvaluator.m static void write_function(VALUE str) { ! evaluatorOutputBlock(convert(str)); } static

    VALUE read_function(void) { ! NSString *input; ! do { ! ! sleep(0.1); ! ! input = evaluatorInputBlock(); ! } while (!input); ! ! return str_to_VALUE(input); } среда, 31 июля 13 г.
  29. benchmark.rb ios-ruby ~0.6 sec irb ~0.08 sec factorial(10000): среда, 31

    июля 13 г.
  30. https://github.com/garnett/iOSRuby среда, 31 июля 13 г.

  31. Thanks! среда, 31 июля 13 г.