$30 off During Our Annual Pro Sale. View Details »

MRuby as Development Platform for Payments

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.

Scalone

September 19, 2014
Tweet

More Decks by Scalone

Other Decks in Programming

Transcript

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

    for its application” Elecia White Making Embedded System
  2. !

  3. .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
  4. 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.
  5. EMULATOR • POSXML compiler in the browser • POSXML runtime

    as it is in POS now • MRUBY compiler • MRUBY runtime as it is in POS
  6. 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
  7. 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
  8. In practice... class Adapter def self.start(file) $f = Fiber.new do

    # The contents as before... end $f.resume end end
  9. 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 }
  10. 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
  11. _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],
  12. JS strings as array buffers are uneasy to handle Use

    hex strings or Arrays Sometimes string arrays
  13. # 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
  14. Oh, I see you need W O R K E

    R S it would be a shame if they BREAK