#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 original; TypeInfo* type; std::vector 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 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