mbed I/F binding for mruby

Dependents:   mruby_mbed_web mirb_mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers opcode.h Source File

opcode.h

00001 /*
00002 ** mruby/opcode.h - RiteVM operation codes
00003 **
00004 ** See Copyright Notice in mruby.h
00005 */
00006 
00007 #ifndef MRUBY_OPCODE_H
00008 #define MRUBY_OPCODE_H
00009 
00010 #define MAXARG_Bx        (0xffff)
00011 #define MAXARG_sBx       (MAXARG_Bx>>1)         /* `sBx' is signed */
00012 
00013 /* instructions: packed 32 bit      */
00014 /* -------------------------------  */
00015 /*     A:B:C:OP = 9: 9: 7: 7        */
00016 /*      A:Bx:OP =    9:16: 7        */
00017 /*        Ax:OP =      25: 7        */
00018 /*   A:Bz:Cz:OP = 9:14: 2: 7        */
00019 
00020 #define GET_OPCODE(i)            ((int)(((mrb_code)(i)) & 0x7f))
00021 #define GETARG_A(i)              ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
00022 #define GETARG_B(i)              ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
00023 #define GETARG_C(i)              ((int)((((mrb_code)(i)) >>  7) & 0x7f))
00024 #define GETARG_Bx(i)             ((int)((((mrb_code)(i)) >>  7) & 0xffff))
00025 #define GETARG_sBx(i)            ((int)(GETARG_Bx(i)-MAXARG_sBx))
00026 #define GETARG_Ax(i)             ((int32_t)((((mrb_code)(i)) >>  7) & 0x1ffffff))
00027 #define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1))))
00028 #define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1))))
00029 #define GETARG_b(i)              GETARG_UNPACK_b(i,14,2)
00030 #define GETARG_c(i)              GETARG_UNPACK_c(i,14,2)
00031 
00032 #define MKOPCODE(op)          ((op) & 0x7f)
00033 #define MKARG_A(c)            ((mrb_code)((c) & 0x1ff) << 23)
00034 #define MKARG_B(c)            ((mrb_code)((c) & 0x1ff) << 14)
00035 #define MKARG_C(c)            (((c) & 0x7f) <<  7)
00036 #define MKARG_Bx(v)           ((mrb_code)((v) & 0xffff) << 7)
00037 #define MKARG_sBx(v)          MKARG_Bx((v)+MAXARG_sBx)
00038 #define MKARG_Ax(v)           ((mrb_code)((v) & 0x1ffffff) << 7)
00039 #define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7))
00040 #define MKARG_bc(b,c)         MKARG_PACK(b,14,c,2)
00041 
00042 #define MKOP_A(op,a)        (MKOPCODE(op)|MKARG_A(a))
00043 #define MKOP_AB(op,a,b)     (MKOP_A(op,a)|MKARG_B(b))
00044 #define MKOP_ABC(op,a,b,c)  (MKOP_AB(op,a,b)|MKARG_C(c))
00045 #define MKOP_ABx(op,a,bx)   (MKOP_A(op,a)|MKARG_Bx(bx))
00046 #define MKOP_Bx(op,bx)      (MKOPCODE(op)|MKARG_Bx(bx))
00047 #define MKOP_sBx(op,sbx)    (MKOPCODE(op)|MKARG_sBx(sbx))
00048 #define MKOP_AsBx(op,a,sbx) (MKOP_A(op,a)|MKARG_sBx(sbx))
00049 #define MKOP_Ax(op,ax)      (MKOPCODE(op)|MKARG_Ax(ax))
00050 #define MKOP_Abc(op,a,b,c)  (MKOP_A(op,a)|MKARG_bc(b,c))
00051 
00052 enum {
00053   /*-----------------------------------------------------------------------
00054   operation code  operand description
00055   ------------------------------------------------------------------------*/
00056   OP_NOP=0,/*                                                             */
00057   OP_MOVE,/*      A B     R(A) := R(B)                                    */
00058   OP_LOADL,/*     A Bx    R(A) := Pool(Bx)                                */
00059   OP_LOADI,/*     A sBx   R(A) := sBx                                     */
00060   OP_LOADSYM,/*   A Bx    R(A) := Syms(Bx)                                */
00061   OP_LOADNIL,/*   A       R(A) := nil                                     */
00062   OP_LOADSELF,/*  A       R(A) := self                                    */
00063   OP_LOADT,/*     A       R(A) := true                                    */
00064   OP_LOADF,/*     A       R(A) := false                                   */
00065 
00066   OP_GETGLOBAL,/* A Bx    R(A) := getglobal(Syms(Bx))                     */
00067   OP_SETGLOBAL,/* A Bx    setglobal(Syms(Bx), R(A))                       */
00068   OP_GETSPECIAL,/*A Bx    R(A) := Special[Bx]                             */
00069   OP_SETSPECIAL,/*A Bx    Special[Bx] := R(A)                             */
00070   OP_GETIV,/*     A Bx    R(A) := ivget(Syms(Bx))                         */
00071   OP_SETIV,/*     A Bx    ivset(Syms(Bx),R(A))                            */
00072   OP_GETCV,/*     A Bx    R(A) := cvget(Syms(Bx))                         */
00073   OP_SETCV,/*     A Bx    cvset(Syms(Bx),R(A))                            */
00074   OP_GETCONST,/*  A Bx    R(A) := constget(Syms(Bx))                      */
00075   OP_SETCONST,/*  A Bx    constset(Syms(Bx),R(A))                         */
00076   OP_GETMCNST,/*  A Bx    R(A) := R(A)::Syms(Bx)                          */
00077   OP_SETMCNST,/*  A Bx    R(A+1)::Syms(Bx) := R(A)                        */
00078   OP_GETUPVAR,/*  A B C   R(A) := uvget(B,C)                              */
00079   OP_SETUPVAR,/*  A B C   uvset(B,C,R(A))                                 */
00080 
00081   OP_JMP,/*       sBx     pc+=sBx                                         */
00082   OP_JMPIF,/*     A sBx   if R(A) pc+=sBx                                 */
00083   OP_JMPNOT,/*    A sBx   if !R(A) pc+=sBx                                */
00084   OP_ONERR,/*     sBx     rescue_push(pc+sBx)                             */
00085   OP_RESCUE,/*    A       clear(exc); R(A) := exception (ignore when A=0) */
00086   OP_POPERR,/*    A       A.times{rescue_pop()}                           */
00087   OP_RAISE,/*     A       raise(R(A))                                     */
00088   OP_EPUSH,/*     Bx      ensure_push(SEQ[Bx])                            */
00089   OP_EPOP,/*      A       A.times{ensure_pop().call}                      */
00090 
00091   OP_SEND,/*      A B C   R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C))    */
00092   OP_SENDB,/*     A B C   R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/
00093   OP_FSEND,/*     A B C   R(A) := fcall(R(A),Syms(B),R(A+1),...,R(A+C-1)) */
00094   OP_CALL,/*      A       R(A) := self.call(frame.argc, frame.argv)       */
00095   OP_SUPER,/*     A C     R(A) := super(R(A+1),... ,R(A+C+1))             */
00096   OP_ARGARY,/*    A Bx    R(A) := argument array (16=6:1:5:4)             */
00097   OP_ENTER,/*     Ax      arg setup according to flags (23=5:5:1:5:5:1:1) */
00098   OP_KARG,/*      A B C   R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B))  */
00099   OP_KDICT,/*     A C     R(A) := kdict                                   */
00100 
00101   OP_RETURN,/*    A B     return R(A) (B=normal,in-block return/break)    */
00102   OP_TAILCALL,/*  A B C   return call(R(A),Syms(B),*R(C))                 */
00103   OP_BLKPUSH,/*   A Bx    R(A) := block (16=6:1:5:4)                      */
00104 
00105   OP_ADD,/*       A B C   R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)            */
00106   OP_ADDI,/*      A B C   R(A) := R(A)+C (Syms[B]=:+)                     */
00107   OP_SUB,/*       A B C   R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)            */
00108   OP_SUBI,/*      A B C   R(A) := R(A)-C (Syms[B]=:-)                     */
00109   OP_MUL,/*       A B C   R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)            */
00110   OP_DIV,/*       A B C   R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)            */
00111   OP_EQ,/*        A B C   R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)          */
00112   OP_LT,/*        A B C   R(A) := R(A)<R(A+1)  (Syms[B]=:<,C=1)           */
00113   OP_LE,/*        A B C   R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)          */
00114   OP_GT,/*        A B C   R(A) := R(A)>R(A+1)  (Syms[B]=:>,C=1)           */
00115   OP_GE,/*        A B C   R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)          */
00116 
00117   OP_ARRAY,/*     A B C   R(A) := ary_new(R(B),R(B+1)..R(B+C))            */
00118   OP_ARYCAT,/*    A B     ary_cat(R(A),R(B))                              */
00119   OP_ARYPUSH,/*   A B     ary_push(R(A),R(B))                             */
00120   OP_AREF,/*      A B C   R(A) := R(B)[C]                                 */
00121   OP_ASET,/*      A B C   R(B)[C] := R(A)                                 */
00122   OP_APOST,/*     A B C   *R(A),R(A+1)..R(A+C) := R(A)                    */
00123 
00124   OP_STRING,/*    A Bx    R(A) := str_dup(Lit(Bx))                        */
00125   OP_STRCAT,/*    A B     str_cat(R(A),R(B))                              */
00126 
00127   OP_HASH,/*      A B C   R(A) := hash_new(R(B),R(B+1)..R(B+C))           */
00128   OP_LAMBDA,/*    A Bz Cz R(A) := lambda(SEQ[Bz],Cz)                      */
00129   OP_RANGE,/*     A B C   R(A) := range_new(R(B),R(B+1),C)                */
00130 
00131   OP_OCLASS,/*    A       R(A) := ::Object                                */
00132   OP_CLASS,/*     A B     R(A) := newclass(R(A),Syms(B),R(A+1))           */
00133   OP_MODULE,/*    A B     R(A) := newmodule(R(A),Syms(B))                 */
00134   OP_EXEC,/*      A Bx    R(A) := blockexec(R(A),SEQ[Bx])                 */
00135   OP_METHOD,/*    A B     R(A).newmethod(Syms(B),R(A+1))                  */
00136   OP_SCLASS,/*    A B     R(A) := R(B).singleton_class                    */
00137   OP_TCLASS,/*    A       R(A) := target_class                            */
00138 
00139   OP_DEBUG,/*     A B C   print R(A),R(B),R(C)                            */
00140   OP_STOP,/*              stop VM                                         */
00141   OP_ERR,/*       Bx      raise RuntimeError with message Lit(Bx)         */
00142 
00143   OP_RSVD1,/*             reserved instruction #1                         */
00144   OP_RSVD2,/*             reserved instruction #2                         */
00145   OP_RSVD3,/*             reserved instruction #3                         */
00146   OP_RSVD4,/*             reserved instruction #4                         */
00147   OP_RSVD5,/*             reserved instruction #5                         */
00148 };
00149 
00150 #define OP_L_STRICT  1
00151 #define OP_L_CAPTURE 2
00152 #define OP_L_METHOD  OP_L_STRICT
00153 #define OP_L_LAMBDA  (OP_L_STRICT|OP_L_CAPTURE)
00154 #define OP_L_BLOCK   OP_L_CAPTURE
00155 
00156 #define OP_R_NORMAL 0
00157 #define OP_R_BREAK  1
00158 #define OP_R_RETURN 2
00159 
00160 #endif  /* MRUBY_OPCODE_H */
00161