public
Description: Rubinius, the Ruby VM
Homepage: http://rubini.us
Clone URL: git://github.com/evanphx/rubinius.git
rubinius / vm / vmmethod.hpp
100644 129 lines (100 sloc) 2.553 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#ifndef RBX_VMMETHOD_HPP
#define RBX_VMMETHOD_HPP
 
#include "vmexecutable.hpp"
#include "primitives.hpp"
#include "gc_root.hpp"
 
namespace rubinius {
  typedef void* instlocation;
  typedef uint32_t opcode;
 
  class Opcode;
  class CompiledMethod;
  class MethodContext;
 
  class VMMethod : public VMExecutable {
  public:
    static instlocation* instructions;
 
    opcode* opcodes;
    size_t total;
    TypedRoot<CompiledMethod*> original;
    TypeInfo* type;
    std::vector<VMMethod*> blocks;
 
    VMMethod(STATE, CompiledMethod* meth);
    ~VMMethod();
 
    virtual void specialize(TypeInfo* ti);
    virtual void compile(STATE);
    static bool executor(STATE, VMExecutable* meth, Task* task, Message& msg);
    virtual void resume(Task* task, MethodContext* ctx);
 
    std::vector<Opcode*> create_opcodes();
 
    /*
* Helper class for iterating over an Opcode array. Used to convert a
* VMMethod to an LLVM method.
*/
    class Iterator {
    public:
      VMMethod* vmm;
      size_t position;
 
      Iterator(VMMethod* vmm) :
        vmm(vmm), position(0) { }
 
      void inc() {
        position += width();
      }
 
      opcode op() {
        return vmm->opcodes[position];
      }
 
      int operand1() {
        return vmm->opcodes[position + 1];
      }
 
      int operand2() {
        return vmm->opcodes[position + 2];
      }
 
      size_t next_pos() {
        return position + width();
      }
 
      opcode next() {
        return vmm->opcodes[next_pos()];
      }
 
      size_t width() {
        opcode op = this->op();
#include "gen/iseq_instruction_size.gen"
        return width;
      }
 
      size_t args() {
        return width() - 1;
      }
 
      bool end() {
        return position >= vmm->total;
      }
    };
 
  };
 
  class Opcode {
  public:
    opcode op;
    int args;
    int arg1;
    int arg2;
    bool start_block;
    size_t block;
 
    Opcode(opcode op, int o1 = -1, int o2 = -1) :
      op(op), args(0), arg1(o1), arg2(o2), start_block(false), block(0) {
        if(o1 >= 0) args++;
        if(o2 >= 0) args++;
      }
 
    Opcode(VMMethod::Iterator& iter) : start_block(false), block(0) {
      op = iter.op();
      args = iter.args();
 
      switch(args) {
      case 2:
        arg2 = iter.operand2();
      case 1:
        arg1 = iter.operand1();
      }
 
    }
 
    bool is_goto();
    bool is_terminator();
    bool is_send();
  };
 
  class VMPrimitiveMethod : public VMMethod {
  public:
    VMPrimitiveMethod(STATE, CompiledMethod* meth, rubinius::executor func);
  };
};
 
#endif