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

MRuby as Development Platform for Payments

E822acb0564c5632aae69fef35f85b3d?s=47 Scalone
September 19, 2014

MRuby as Development Platform for Payments

We have been working on payment market with embedded applications for 3 years, providing a development platform for machines of Point Of Sale, it was develop only for some devices with our own Virtual Machine. After made so many mistakes in our own Virtual Machine We found MRuby as new Virtual Machine and We had a big jump in quality.
Improving tests, time to support new devices, code beauty, user development experience and including expand the platform for mobiles.
This presentation is focused on the testimony of this path. Let's talk about others technologies We leave to get MRuby. The difficulties, solutions and how We managed to link MRuby with many devices.



September 19, 2014


  1. Hi, hi! this is the team CloudWalk www.cloudwalk.io

  2. NOT Crowdworks

  3. Hi, hi! this is the team CloudWalk www.cloudwalk.io

  4. Thiago Scalone @scalone

  5. Thiago Scalone @scalone

  6. Daniel Rodríguez @sadasant

  7. @sadasant is definitely not related to Sasada-san *<:•)

  8. MRuby as a Development Platform for Payments.

  9. payments

  10. payments involve POS terminals

  11. What is an EMBEDDED SYSTEM?

  12. “An embedded system is a computerized system that is purpose-built

    for its application” Elecia White Making Embedded System
  13. NO OS Limited Syscalls No POSIX Crazy API No ANSI

  14. SCENARIO 1000 POS terminals Bug in production…

  15. None
  16. Update manually? Network issues? Energy issues? Customers waiting? Transactions interrupted?

  17. None
  18. !

  19. solves this

  20. Easy way to Develop and deploy Cross Platform Payments Applications

  21. None
  22. IDE Install (only windows) WEBSITE .exe Download Cloud walking CloudWalk

    Servers OLD TIMES POS
  23. None
  24. Web IDE (all major browsers) WEBSITE CloudWalk Servers NOW POS

  25. CloudWalk.io has been using <POSXML/> for 10 years

  26. Structured XML Static memory

  27. Enough We need to move forward

  28. Enough We need to go Mobile

  29. Enough We need to be Developer Friendly

  30. Why not Ruby?

  31. Beautiful Hacker friendly Semantic Productive Small

  32. I feel Happy

  33. WE WANT RUBY EVERYWHERE starting with POS terminals mmmmmmmmmm

  34. DoItYourself FAIL


  36. No JRuby core-team 40 seconds to boot No community



  39. Smaller Ruby

  40. None
  41. MRuby Resource saving High Portability RiteVM bytecode Static Gems ANSI

    C Size
  42. None
  43. None
  44. None
  45. None
  46. None
  47. .set noreorder .global pipe .type pipe,@function pipe: lui $gp, %hi(_gp_disp)

    addiu $gp, %lo(_gp_disp) addu $gp, $gp, $25 li $2, 4042 syscall beq $7, $0, 1f nop lw $25, %call16(__syscall_ret)($gp) jr $25 subu $4, $0, $2 1: sw $2, 0($4) sw $3, 4($4) move $2, $0 jr $ra nop
  48. BSD libc μClibc Newlib klibc EGLIBC Musl …

  49. MRuby App da_funk interface MRuby Core mruby-pax-network mruby-pax-io PAXSDK MUSL

    PAX OS
  50. MRuby App da_funk interface MRuby Core mrubygem mrubygem Platform SDK

    Libc Platform OS
  51. da_funk

  52. CloudWalk Mruby Framework Hardware Agnostic Modular Simple

  53. CloudWalk Mruby Framework ON THE WEB

  54. None
  55. xxuejie, if you’re watching this, we love you

  56. webruby = new win.WEBRUBY(); // Custom compile function webruby.compile_to_file(source_code, file_name);

    // Emscripten’s FS.readFile wrapper var bytecode = io.readFile(file_name); DEPLOY 1. 2. 3. 4.
  57. EMULATOR • POSXML compiler in the browser • POSXML runtime

    as it is in POS now • MRUBY compiler • MRUBY runtime as it is in POS
  58. Let’s compile and run class Program < Device def self.call

    Display.puts "Hey Thiago!" Display.puts "How are you?", 1 message = IO.getc # press CANCEL to quit exit if message == IO::CANCEL Display.clear 1 Display.puts "You said: " + message, 1 IO.getc end end
  59. Theoretical Adapter.start class Adapter def self.start(file) load "./da_funk.mrb" load "./platform.mrb"

    load file app = Device::Support.path_to_class file[2..-1] loop do app.call end end end
  60. In practice... class Adapter def self.start(file) $f = Fiber.new do

    # The contents as before... end $f.resume end end
  61. We call JavaScript functions and wait for callbacks $device =

    MrubyJs.window.device def self.read_key key = "" $device.read do |input| key = input $f.resume end Fiber.yield key end // Example var device = window.device = {}; device.read = function(callback) { setTimeout(function() { callback(42); }, 60000); // One minute }
  62. xxuejie, if you’re watching this, we love you

  63. 01001010101010101001001 10110110101010101010010 11010101001000010101111 1011010010101001 11010100101001010101010 01010101010010010101011 01101010111010101101000 00101000100101101001011 01111101010100101001110 0101010100

    11111111110101001010101 00011111111111111111111 11010110000100100100000 00110010101010100101001 0010100101011 EMSCRIPTEN generated programs sometimes LEAK we're not mad at you Kripken, you're awesome
  64. Keep it clean

  65. _getaddrinfo function _mrb_addrinfo_getaddrinfo(a,b,c){var d=0,e=0,f=STACKTOP;STACKTOP=0|STACKTOP+440,0|assert(!(3&STACKTOP)),0|assert((0|STACK_MAX)> (0|STACKTOP));var g=c;for(c=STACKTOP,STACKTOP=0|STACKTOP+12,0|assert((0|STACK_MAX)>(0|STACKTOP)),HEAP32[c>>2]=HEAP32[g>>2],HEAP32 [c+4>>2]=HEAP32[g+4>>2],HEAP32[c+8>>2]=HEAP32[g+8>>2],d=1;;)switch(d){case 1:var h,k,x,y,z,A,i=f,j=f+32,l=f+36,m=f+148,n=f+160,o=f+172, p=f+184,q=f+196,r=f+208,s=f+220,t=f+232,u=f+244,v=f+256,w=f+268,B=f+272,C=f+284,D=f+296,E=f+308,F=f+320,G=f+332,H=f+344,I=f+356,J=f+368,

    K=f+380,L=f+392,M=f+404,N=f+416,O=f+428;h=b,z=0,A=0;var P=h;_mrb_ary_new(B,P);var Q=n,R=B;assert(!0),HEAP32[Q>>2]=HEAP32[R>>2],HEAP32 [Q+4>>2]=HEAP32[R+4>>2],HEAP32[Q+8>>2]=HEAP32[R+8>>2];var S=h,T=_mrb_gc_arena_save(S);x=T;var U=h,V=l;_mrb_str_new(C,U,V,110);var W=s, X=C;assert(!0),HEAP32[W>>2]=HEAP32[X>>2],HEAP32[W+4>>2]=HEAP32[X+4>>2],HEAP32[W+8>>2]=HEAP32[X+8>>2],_mrb_nil_value1732(D);var Y=r,Z=D; assert(!0),HEAP32[Y>>2]=HEAP32[Z>>2],HEAP32[Y+4>>2]=HEAP32[Z+4>>2],HEAP32[Y+8>>2]=HEAP32[Z+8>>2];var $=v,_=r;assert(!0),HEAP32[$>>2] =HEAP32[_>>2],HEAP32[$+4>>2]=HEAP32[_+4>>2],HEAP32[$+8>>2]=HEAP32[_+8>>2];var ab=o,bb=v;assert(!0),HEAP32[ab>>2]=HEAP32[bb>>2],HEAP32 [ab+4>>2]=HEAP32[bb+4>>2],HEAP32[ab+8>>2]=HEAP32[bb+8>>2],HEAP32[w>>2]=0;var cb=h;_mrb_get_args(cb,193640,(e=STACKTOP, STACKTOP=0|STACKTOP+24,0|assert((0|STACK_MAX)>(0|STACKTOP)),HEAP32[e>>2]=q,HEAP32[e+4>>2]=u,HEAP32[e+8>>2]=o,HEAP32[e+12>>2]=v,HEAP32 [e+16>>2]=r,HEAP32[e+20>>2]=w,e)),STACKTOP=e;var eb=0|q+8,fb=HEAP32[eb>>2],gb=16==(0|fb);if(gb){d=2;break}d=3;break;case 2:var hb=h, ib=_mrb_str_to_cstr(hb,q);z=ib,d=8;break;case 3:var jb=0|q+8,kb=HEAP32[jb>>2],lb=0==(0|kb);if(lb){d=4;break}d=6;break;case 4:var mb=0|q, nb=mb,ob=HEAP32[nb>>2],pb=0!=(0|ob);if(pb){d=6;break}d=5;break;case 5:z=0,d=7;break;case 6:var qb=h,rb=h,sb=_mrb_class_get(rb,193604); _mrb_raise(qb,sb,193540),d=7;break;case 7:d=8;break;case 8:var tb=0|u+8,ub=HEAP32[tb>>2],vb=16==(0|ub);if(vb){d=9;break}d=10;break;case 9:var wb=h,xb=_mrb_str_to_cstr(wb,u);A=xb,d=18;break;case 10:var yb=0|u+8,zb=HEAP32[yb>>2],Ab=3==(0|zb);if(Ab){d=11;break}d=12;break; case 11:var Bb=h,Cb=h;_mrb_funcall(E,Cb,u,193488,0,(e=STACKTOP,STACKTOP=0|STACKTOP+1,STACKTOP=-4&STACKTOP+3,0|assert((0|STACK_MAX)> (0|STACKTOP)),HEAP32[e>>2]=0,e)),STACKTOP=e;var Db=_mrb_str_to_cstr(Bb,E);A=Db,d=17;break;case 12:var Eb=0|u+8,Fb=HEAP32[Eb>>2],Gb=0== (0|Fb);if(Gb){d=13;break}d=15;break;case 13:var Hb=0|u,Ib=Hb,Jb=HEAP32[Ib>>2],Kb=0!=(0|Jb);if(Kb){d=15;break}d=14;break;case 14:A=0, d=16;break;case 15:var Lb=h,Mb=h,Nb=_mrb_class_get(Mb,193604);_mrb_raise(Lb,Nb,193388),d=16;break;case 16:d=17;break;case 17:d=18;break; case 18:var Ob=i;_memset(Ob,0,32);var Pb=HEAP32[w>>2],Qb=0|i;HEAP32[Qb>>2]=Pb;var Rb=0|o+8,Sb=HEAP32[Rb>>2],Tb=3==(0|Sb);if(Tb){d=19; break}d=20;break;case 19:var Ub=0|o,Vb=Ub,Wb=HEAP32[Vb>>2],Xb=0|i+4;HEAP32[Xb>>2]=Wb,d=20;break;case 20:var Yb=0|v+8,Zb=HEAP32 [Yb>>2],$b=3==(0|Zb);if($b){d=21;break}d=22;break;case 21:var _b=0|v,ac=_b,bc=HEAP32[ac>>2],cc=0|i+8;HEAP32[cc>>2]=bc,d=22;break;case 22:var dc=h,ec=h,fc=_mrb_intern_cstr(ec,198640);_mrb_cv_get(F,dc,c,fc);var gc=p,hc=F;assert(!0),HEAP32[gc>>2]=HEAP32[hc>>2],HEAP32 [gc+4>>2]=HEAP32[hc+4>>2],HEAP32[gc+8>>2]=HEAP32[hc+8>>2];var ic=0|p+8,jc=HEAP32[ic>>2],kc=7==(0|jc);if(kc){d=23;break}d=24;break;case 23:var lc=0|p,mc=lc,nc=HEAP32[mc>>2],oc=nc;_freeaddrinfo(oc);var pc=h,qc=h,rc=_mrb_intern_cstr(qc,198640);_mrb_nil_value1732(G), _mrb_cv_set(pc,c,rc,G),d=24;break;case 24:var sc=z,tc=A,uc=_getaddrinfo(sc,tc,i,j);y=uc;var vc=y,wc=0!=(0|vc);if(wc){d=25;break}d=26; break;case 25:var xc=h,yc=h,zc=_mrb_class_get(yc,193944),Ac=h,Bc=y,Cc=_gai_strerror(Bc);_mrb_str_new_cstr(H,Ac,Cc),_mrb_raisef(xc,zc, 193312,(e=STACKTOP,STACKTOP=0|STACKTOP+12,0|assert((0|STACK_MAX)>(0|STACKTOP)),HEAP32[e>>2]=HEAP32[H>>2],HEAP32[e+4>>2]=HEAP32[H+4>>2],
  66. JS strings as array buffers are uneasy to handle Use

    hex strings or Arrays Sometimes string arrays
  67. Override default Ruby Classes use Emscripten’s API directly

  68. # Something like this, don’t do this at home class

    TCPSocket @socket = "" def initialize(host, port) @socket = MrubyJs.window.socket(host, port) end def write(data) @socket.write(data) end def read(length) @socket.read(length) end def close; @socket.close() end end
  69. Oh, I see you need W O R K E

    R S it would be a shame if they BREAK
  70. None
  71. let’s stop talking about nightmares time to ▶PLAY with the

  72. Mruby PAX 200


  74. Verifone, Ingenico

  75. Continuous Delivery

  76. NFC We have it working with POSXML on Verifone and

  77. ありがとうございました! by @scalone and @sadasant