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

Denis Lebedev

July 31, 2013
Tweet

More Decks by Denis Lebedev

Other Decks in Technology

Transcript

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

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

    VM - YARV среда, 31 июля 13 г.
  3. NOT so simple (begin (define fact (lambda (n) (if (<=

    n 1) 1 (* n (fact (- n 1)))))) среда, 31 июля 13 г.
  4. Parsing [ :begin, [ :define, :fact, [ :lambda, [ :n],

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

    recursive call of eval(x, env) with a large switch-case среда, 31 июля 13 г.
  6. Ripper output [:program, [[:command, [:@ident, "p", [1, 0]], [:args_add_block, [[:string_literal,

    [:string_content, [:@tstring_content, "Hello World", [1, 3]]]]], false]]]] среда, 31 июля 13 г.
  7. 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 г.
  8. 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 г.
  9. 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 г.
  10. 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 г.
  11. 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 г.
  12. 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 г.
  13. Implementation details - Uses rb_eval_string_protect from “ruby.h” - Omits all

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

    ‘native’ extensions - We use some tricks to create Ruby<>Obj-C bridge среда, 31 июля 13 г.
  15. 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 г.
  16. 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 г.
  17. 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 г.