Module Ruva::VM::Opcodes
In: lib/ruva/opcodes.rb

Provides the standard opcode implementations. The VM will use the standard opcodes by default. If you want to pass custom opcodes, you can base your modifications off the hash in Opcodes::OPCODES

Methods

__any_add   __any_aload   __any_astore   __any_cmpg   __any_div   __any_load   __any_mul   __any_neg   __any_rem   __any_return   __any_store   __any_sub   check_byte   check_char   check_double   check_float   check_int   check_long   check_short   long_jump   long_operands   not_yet   op0   op1   op10   op100   op101   op102   op103   op104   op105   op106   op107   op108   op109   op11   op110   op111   op112   op113   op114   op115   op116   op117   op118   op119   op12   op120   op121   op122   op123   op124   op125   op126   op127   op128   op129   op13   op130   op131   op132   op133   op134   op135   op136   op137   op138   op139   op14   op140   op141   op142   op143   op144   op145   op146   op147   op148   op149   op15   op150   op151   op152   op153   op154   op155   op156   op157   op158   op159   op16   op160   op161   op162   op163   op164   op165   op166   op167   op168   op169   op17   op170   op171   op172   op173   op174   op175   op177   op178   op179   op18   op180   op181   op182   op183   op184   op185   op186   op187   op188   op189   op19   op190   op191   op192   op193   op194   op195   op196   op197   op198   op199   op2   op200   op201   op202   op254   op255   op26   op27   op28   op29   op3   op30   op31   op32   op33   op34   op35   op36   op37   op38   op39   op4   op40   op41   op42   op43   op44   op45   op5   op54   op55   op56   op57   op59   op6   op60   op61   op62   op63   op64   op65   op66   op67   op68   op69   op7   op70   op71   op72   op73   op74   op75   op76   op77   op78   op79   op8   op80   op81   op82   op84   op85   op86   op87   op88   op89   op9   op90   op91   op92   op93   op94   op95   op96   op97   op98   op99   operands_long   operands_short   short_jump   short_operands   signed_byte   signed_long   signed_short  

External Aliases

__any_cmpg -> __any_cmpl
  NaN treated the same right now
__any_aload -> op50
  AALOAD (0x32) () …, arrayref, idx => …, value
__any_astore -> op83
  AASTORE (0x53) () …, arrayref, idx, value => …
__any_load -> op25
  ALOAD (0x19) (idx) …, => …, objectref
__any_return -> op176
  ARETURN (0xB0) () …, value => (^) objectref
__any_store -> op58
 
 ASTORE (0x3A)
(idx)
 ..., objectref =>  ...
__any_aload -> op51
  BALOAD (0x33) () …, arrayref, idx => …, value
__any_aload -> op52
  CALOAD (0x34) () …, arrayref, idx => …, value
__any_aload -> op49
  DALOAD (0x31) () …, arrayref, idx => …, value
__any_load -> op24
  DLOAD (0x18) (idx) …, => …, value
__any_aload -> op48
  FALOAD (0x30) () …, arrayref, idx => …, value
__any_load -> op23
  FLOAD (0x17) (idx) …, => …, value
__any_aload -> op46
  IALOAD (0x2E) () …, arrayref, idx => …, value
__any_load -> op21
  ILOAD (0x15) (idx) …, => …, value
__any_aload -> op47
  LALOAD (0x2f) () …, arrayref, idx => …, value
op19 -> op20
  LDC2W (0x14) (idx1, idx2) … => …, value
__any_load -> op22
  LLOAD (0x16) (idx) …, => …, value
__any_aload -> op53
  SALOAD (0x35) () …, arrayref, idx => …, value

Public Class methods

[Source]

     # File lib/ruva/opcodes.rb, line 150
150:         def __any_add(vm)
151:           v2 = vm.stack.pop
152:           v1 = vm.stack.pop
153:           vm.stack.push(v1 + v2)
154:         end

IMPLEMENTATION OPCODES () …, arrayref, idx => …, value

[Source]

     # File lib/ruva/opcodes.rb, line 127
127:         def __any_aload(vm)
128:           idx = vm.stack.pop
129:           arr = vm.stack.pop
130:           vm.stack.push(arr[idx])           
131:         end

() …, arrayref, idx, value => …

[Source]

     # File lib/ruva/opcodes.rb, line 135
135:         def __any_astore(vm)
136:           value = vm.stack.pop
137:           idx = vm.stack.pop
138:           arr = vm.stack.pop         
139:           arr[idx] = value
140:         end

[Source]

     # File lib/ruva/opcodes.rb, line 156
156:         def __any_cmpg(vm)
157:           v2 = vm.stack.pop
158:           v1 = vm.stack.pop
159:           vm.stack.push(v1 <=> v2)
160:         end

[Source]

     # File lib/ruva/opcodes.rb, line 165
165:         def __any_div(vm)
166:           v2 = vm.stack.pop
167:           v1 = vm.stack.pop
168:           vm.stack.push(v1 / v2)
169:         end

[Source]

     # File lib/ruva/opcodes.rb, line 142
142:         def __any_load(vm, idx)
143:           vm.stack.push(vm.locals[idx])
144:         end

[Source]

     # File lib/ruva/opcodes.rb, line 171
171:         def __any_mul(vm)
172:           v2 = vm.stack.pop
173:           v1 = vm.stack.pop
174:           vm.stack.push(v1 * v2)
175:         end

[Source]

     # File lib/ruva/opcodes.rb, line 183
183:         def __any_neg(vm)
184:           vm.stack.push(-vm.stack.pop)      
185:         end

[Source]

     # File lib/ruva/opcodes.rb, line 187
187:         def __any_rem(vm)
188:           v2 = vm.stack.pop
189:           v1 = vm.stack.pop
190:           vm.stack.push(v1 % v2)      
191:         end

[Source]

     # File lib/ruva/opcodes.rb, line 193
193:         def __any_return(vm)
194:           r = vm.stack.pop
195:           vm.pop_frame
196:           vm.stack.push(r)
197:         end

[Source]

     # File lib/ruva/opcodes.rb, line 146
146:         def __any_store(vm, idx)
147:           vm.locals[idx] = vm.stack.pop
148:         end

[Source]

     # File lib/ruva/opcodes.rb, line 177
177:         def __any_sub(vm)
178:           v2 = vm.stack.pop
179:           v1 = vm.stack.pop
180:           vm.stack.push(v1 - v2)
181:         end

Check a ruby Integer is in byte range. Do this before pushing it.

[Source]

    # File lib/ruva/opcodes.rb, line 20
20:         def check_byte(b)
21:           raise IllegalArgumentError, "Invalid byte #{b.inspect}" unless b && b.is_a?(Integer) && (-128..127).member?(b)          
22:           b.is_a?(VM::Types::Cat2Value) ? b.__value : b
23:         end

Check a ruby Integer is in char range. Do this before pushing it.

[Source]

    # File lib/ruva/opcodes.rb, line 26
26:         def check_char(c)
27:           raise IllegalArgumentError, "Invalid char #{c.inspect}" unless c && c.is_a?(Integer) && (0..65535).member?(c)          
28:           c.is_a?(VM::Types::Cat2Value) ? c.__value : c
29:         end

Check a ruby Float as a double and wrap it in a VM::Types::Cat2Value Do this before pushing it.

[Source]

    # File lib/ruva/opcodes.rb, line 52
52:         def check_double(d)
53:           raise IllegalArgumentError, "Invalid double #{d.inspect}" unless d && d.is_a?(Float)          
54:           d.is_a?(VM::Types::Cat2Value) ? d : VM::Types::Cat2Value.new(d)  
55:         end

Check a ruby Float as a float. Do this before pushing it.

[Source]

    # File lib/ruva/opcodes.rb, line 58
58:         def check_float(f)
59:           raise IllegalArgumentError, "Invalid float #{f.inspect}" unless f && f.is_a?(Float)          
60:           f.is_a?(VM::Types::Cat2Value) ? f.__value : f
61:         end

Check a ruby Integer is in int range. Do this before pushing it.

[Source]

    # File lib/ruva/opcodes.rb, line 38
38:         def check_int(i)
39:           raise IllegalArgumentError, "Invalid int #{i.inspect}" unless i.is_a?(Integer)         
40:           i.is_a?(VM::Types::Cat2Value) ? i.__value : i  
41:         end

Check a ruby Integer is in long range and wrap it in a VM::Types::Cat2Value. Do this before pushing it.

[Source]

    # File lib/ruva/opcodes.rb, line 45
45:         def check_long(i)
46:           raise IllegalArgumentError, "Invalid long #{i.inspect}" unless i.is_a?(Integer)         
47:           i.is_a?(VM::Types::Cat2Value) ? i : VM::Types::Cat2Value.new(i)  
48:         end

Check a ruby Integer is in short range. Do this before pushing it.

[Source]

    # File lib/ruva/opcodes.rb, line 32
32:         def check_short(s)
33:           raise IllegalArgumentError, "Invalid short #{s.inspect}" unless s && s.is_a?(Integer) && (-32768..32767).member?(s)          
34:           s.is_a?(VM::Types::Cat2Value) ? s.__value : s
35:         end

Encode the supplied (char-range) operands as a long (32-bit) jump target instruction offset. This is calculated as the operands value as a short, minus five (to account for the fact that pc will already point to the next instruction).

[Source]

     # File lib/ruva/opcodes.rb, line 118
118:         def long_jump(b1, b2, b3, b4)
119:           signed_long(operands_long(b1, b2, b3, b4)) - 5
120:         end

Decode the supplied long (32-bit) operands to a quad of char-range operands.

[Source]

    # File lib/ruva/opcodes.rb, line 81
81:         def long_operands(long)
82:           # TODO reverse for little-endian plaf? 
83:           # How does JVM behave?
84:           [(long & 0xFF000000) >> 24, 
85:            (long & 0x00FF0000) >> 16, 
86:            (long & 0x0000FF00) >> 8, 
87:             long & 0x000000FF]
88:         end

[Source]

    # File lib/ruva/opcodes.rb, line 15
15:         def not_yet
16:           raise Ruva::VM::VMError, "Unimplemented Opcode (defined: #{caller[-1]})"
17:         end

NOP (0x00) () …

[Source]

      # File lib/ruva/opcodes.rb, line 1908
1908:         def op0(vm, *operands)
1909:           # nop
1910:         end

ACONSTNULL (0x01) () …, => …, null

[Source]

     # File lib/ruva/opcodes.rb, line 217
217:         def op1(vm)  
218:           vm.stack.push nil     
219:         end

LCONST_1 (0x0a) () … => …, const

[Source]

      # File lib/ruva/opcodes.rb, line 1660
1660:         def op10(vm)
1661:           vm.stack.push(check_long(1))                
1662:         end

ISUB (0x64) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1552
1552:         def op100(vm)
1553:           b, a = vm.stack.pop, vm.stack.pop
1554:           check_int(a) and check_int(b)
1555:           vm.stack.push(a) and vm.stack.push(b)        
1556:           __any_sub(vm)
1557:         end

LSUB (0x65) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1838
1838:         def op101(vm)
1839:           b, a = vm.stack.pop, vm.stack.pop
1840:           vm.stack.push(check_long(a - b))
1841:         end

FSUB (0x66) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 815
815:         def op102(vm)
816:           b, a = vm.stack.pop, vm.stack.pop
817:           check_float(a) and check_float(b)
818:           vm.stack.push(a) and vm.stack.push(b)        
819:           __any_sub(vm)
820:         end

DSUB (0x67) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 544
544:         def op103(vm)
545:           b, a = vm.stack.pop, vm.stack.pop
546:           vm.stack.push(check_double(a - b))
547:         end

IMUL (0x68) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1226
1226:         def op104(vm)
1227:           b, a = vm.stack.pop, vm.stack.pop
1228:           check_int(a) and check_int(b)
1229:           vm.stack.push(a) and vm.stack.push(b)        
1230:           __any_mul(vm)
1231:         end

LMUL (0x69) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1737
1737:         def op105(vm)
1738:           b, a = vm.stack.pop, vm.stack.pop
1739:           vm.stack.push(check_long(a * b))
1740:         end

FMUL (0x6A) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 743
743:         def op106(vm)
744:           b, a = vm.stack.pop, vm.stack.pop
745:           check_float(a) and check_float(b)
746:           vm.stack.push(a) and vm.stack.push(b)        
747:           __any_mul(vm)
748:         end

DMUL (0x6B) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 476
476:         def op107(vm)
477:           b, a = vm.stack.pop, vm.stack.pop
478:           vm.stack.push(check_double(a * b))
479:         end

IDIV (0x6C) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1045
1045:         def op108(vm)
1046:           b, a = vm.stack.pop, vm.stack.pop
1047:           check_int(a) and check_int(b)
1048:           vm.stack.push(a) and vm.stack.push(b)        
1049:           __any_div(vm)
1050:         end

LDIV (0x6d) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1696
1696:         def op109(vm)
1697:           b, a = vm.stack.pop, vm.stack.pop
1698:           vm.stack.push(check_long(a / b))
1699:         end

FCONST_0 (0x0B) () … => …, const

[Source]

     # File lib/ruva/opcodes.rb, line 679
679:         def op11(vm)        
680:           vm.stack.push(0.0)
681:         end

FDIV (0x6E) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 700
700:         def op110(vm)
701:           b, a = vm.stack.pop, vm.stack.pop
702:           check_float(a) and check_float(b)
703:           vm.stack.push(a) and vm.stack.push(b)        
704:           __any_div(vm)
705:         end

DDIV (0x6F) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 435
435:         def op111(vm)
436:           b, a = vm.stack.pop, vm.stack.pop
437:           vm.stack.push(check_double(a / b))
438:         end

IREM (0x70) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1480
1480:         def op112(vm)
1481:           b, a = vm.stack.pop, vm.stack.pop
1482:           check_int(a) and check_int(b)
1483:           vm.stack.push(a) and vm.stack.push(b)        
1484:          __any_rem(vm)
1485:         end

LREM (0x71) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1767
1767:         def op113(vm)
1768:           b, a = vm.stack.pop, vm.stack.pop
1769:           vm.stack.push(check_long(a % b))
1770:         end

FREM (0x72) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 761
761:         def op114(vm)
762:           b, a = vm.stack.pop, vm.stack.pop
763:           check_float(a) and check_float(b)
764:           vm.stack.push(a) and vm.stack.push(b)        
765:           __any_rem(vm)
766:         end

DREM (0x73) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 492
492:         def op115(vm)
493:           b, a = vm.stack.pop, vm.stack.pop
494:           vm.stack.push(check_double(a % b))
495:         end

INEG (0x74) () …, value => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1236
1236:         def op116(vm)
1237:           vm.stack.push(check_int(vm.stack.pop))
1238:           __any_neg(vm)
1239:         end

LNEG (0x75) () …, value => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1745
1745:         def op117(vm)
1746:           vm.stack.push(check_long(-vm.stack.pop))
1747:         end

FNEG (0x76) () …, value => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 753
753:         def op118(vm)
754:           vm.stack.push(check_float(vm.stack.pop))
755:           __any_neg(vm)
756:         end

DNEG (0x77) () …, value => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 484
484:         def op119(vm)
485:           a = vm.stack.pop
486:           vm.stack.push(check_double(-a))
487:         end

FCONST_1 (0x0C) () … => …, const

[Source]

     # File lib/ruva/opcodes.rb, line 686
686:         def op12(vm)        
687:           vm.stack.push(1.0)
688:         end

ISHL (0x78) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1498
1498:         def op120(vm)
1499:           b, a = check_int(vm.stack.pop), check_int(vm.stack.pop)        
1500:           vm.stack.push(a << b)
1501:         end

LSHL (0x79) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1784
1784:         def op121(vm)
1785:           v2 = vm.stack.pop
1786:           v1 = vm.stack.pop
1787:           vm.stack.push(check_long(v1 << v2))
1788:         end

ISHR (0x7A) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1506
1506:         def op122(vm)
1507:           v2 = vm.stack.pop
1508:           v1 = vm.stack.pop
1509:           check_int(v1) and check_int(v2)
1510:           vm.stack.push(v1 >> v2)
1511:         end

LSHR (0x7B) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1793
1793:         def op123(vm)
1794:           v2 = vm.stack.pop
1795:           v1 = vm.stack.pop
1796:           vm.stack.push(check_long(v1 >> v2))
1797:         end

IUSHR (0x7C) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1562
1562:         def op124(vm)
1563:           b, a = check_int(vm.stack.pop), check_int(vm.stack.pop)        
1564:           vm.stack.push([a].pack('l').unpack('L').first >> b)
1565:         end

LUSHR (0x7D) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1846
1846:         def op125(vm)
1847:           not_yet
1848:         end

IAND (0x7E) () …, value1, value2 => …, result

[Source]

     # File lib/ruva/opcodes.rb, line 980
980:         def op126(vm)
981:           b, a = check_int(vm.stack.pop), check_int(vm.stack.pop)        
982:           vm.stack.push(a & b)
983:         end

LAND (0x7f) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1630
1630:         def op127(vm)
1631:           b,a = vm.stack.pop, vm.stack.pop
1632:           vm.stack.push(check_long(a & b))
1633:         end
               INT ##################

IOR (0x80) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1471
1471:         def op128(vm)
1472:           v2 = vm.stack.pop
1473:           v1 = vm.stack.pop
1474:           vm.stack.push(v1 | v2)
1475:         end

LOR (0x81) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1759
1759:         def op129(vm)
1760:           b,a = vm.stack.pop, vm.stack.pop
1761:           vm.stack.push(check_long(b | a))
1762:         end

FCONST_2 (0x0D) () … => …, const

[Source]

     # File lib/ruva/opcodes.rb, line 693
693:         def op13(vm)        
694:           vm.stack.push(2.0)
695:         end

IXOR (0x82) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1570
1570:         def op130(vm)
1571:           v2 = vm.stack.pop
1572:           v1 = vm.stack.pop
1573:           vm.stack.push(v1 ^ v2)
1574:         end

LXOR (0x83) () …, value1, value2 => …, result

[Source]

      # File lib/ruva/opcodes.rb, line 1853
1853:         def op131(vm)          
1854:           b,a = vm.stack.pop, vm.stack.pop
1855:           vm.stack.push(check_long(b ^ a))
1856:         end

IINC (0x84) (idx, const) …, => …

[Source]

      # File lib/ruva/opcodes.rb, line 1185
1185:         def op132(vm, idx, const)
1186:           locals = vm.locals     
1187:           locals[idx] = check_int(locals[idx]) + check_byte(signed_byte(const))
1188:         end

I2L (0x85) () …, value => …, long

[Source]

     # File lib/ruva/opcodes.rb, line 951
951:         def op133(vm)
952:           vm.stack.push(check_long(Integer(vm.stack.pop)))
953:         end

I2F (0x86) () …, value => …, float

[Source]

     # File lib/ruva/opcodes.rb, line 944
944:         def op134(vm)
945:           vm.stack.push(check_float(Float(vm.stack.pop)))
946:         end

I2D (0x87) …, value => …, double

[Source]

     # File lib/ruva/opcodes.rb, line 937
937:         def op135(vm)
938:           vm.stack.push(check_double(Float(vm.stack.pop)))
939:         end

L2I (0x88) () …, value => …, int

[Source]

      # File lib/ruva/opcodes.rb, line 1610
1610:         def op136(vm)
1611:           vm.stack.push(check_int([vm.stack.pop & 0xFFFFFFFF].pack('Q').unpack('q').first))
1612:         end

L2F (0x89) () …, value => …, long

[Source]

      # File lib/ruva/opcodes.rb, line 1603
1603:         def op137(vm)
1604:           vm.stack.push(check_float(Float(vm.stack.pop.__value)))
1605:         end
             LONG ################

L2D (0x8a) () …, value => …, double

[Source]

      # File lib/ruva/opcodes.rb, line 1596
1596:         def op138(vm)
1597:           vm.stack.push(check_double(Float(vm.stack.pop.__value)))
1598:         end

F2I (0x8B) () …, value => …, int

[Source]

     # File lib/ruva/opcodes.rb, line 622
622:         def op139(vm)
623:           vm.stack.push(Integer(vm.stack.pop))
624:         end

DCONST_0 (0x0E) () … => …, const

[Source]

     # File lib/ruva/opcodes.rb, line 421
421:         def op14(vm)
422:           vm.stack.push(check_double(0.0))
423:         end

F2L (0x8C) () …, value => …, long

[Source]

     # File lib/ruva/opcodes.rb, line 629
629:         def op140(vm)
630:           vm.stack.push(check_long(Integer(vm.stack.pop)))
631:         end
             FLOAT ######################

F2D (0x8D) () …, value => …, double

[Source]

     # File lib/ruva/opcodes.rb, line 615
615:         def op141(