Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

132 lines (99 sloc) 3.259 kB
#ifndef RBX_INSTRUCTIONS_UTIL_HPP
#define RBX_INSTRUCTIONS_UTIL_HPP
#define SPECIFIC (static_cast<SubClass*>(this))
namespace rubinius {
template <class SubClass>
class VisitInstructions {
protected:
opcode* stream_;
int size_;
int next_ip_;
public:
void set_stream(opcode* stream, int size) {
stream_ = stream;
size_ = size;
}
void set_stream(VMMethod* vmm) {
set_stream(vmm->opcodes, vmm->total);
}
void visit(opcode code, opcode arg1, opcode arg2) { }
#define HANDLE_INST0(code, name) \
void visit_ ## name() { SPECIFIC->visit(code, -1, -1); }
#define HANDLE_INST1(code, name) \
void visit_ ## name(opcode arg1) { SPECIFIC->visit(code, arg1, -1); }
#define HANDLE_INST2(code, name) \
void visit_ ## name(opcode arg1, opcode arg2) { SPECIFIC->visit(code, arg1, arg2); }
#include "vm/gen/instruction_visitors.hpp"
#undef HANDLE_INST0
#undef HANDLE_INST1
#undef HANDLE_INST2
void at_ip(int ip) { }
bool before(opcode op, opcode arg1 = 0, opcode arg2 = 0) { return true; }
int dispatch(int ip) {
SPECIFIC->at_ip(ip);
switch(stream_[ip]) {
#define HANDLE_INST0(code, name) \
case code: \
next_ip_ = ip + 1; \
if(SPECIFIC->before(stream_[ip])) { \
SPECIFIC->visit_ ## name(); } return next_ip_;
#define HANDLE_INST1(code, name) \
case code: \
next_ip_ = ip + 2; \
if(SPECIFIC->before(stream_[ip], stream_[ip + 1])) { \
SPECIFIC->visit_ ## name(stream_[ip + 1]); } return next_ip_;
#define HANDLE_INST2(code, name) \
case code: \
next_ip_ = ip + 3; \
if(SPECIFIC->before(stream_[ip], stream_[ip + 1], stream_[ip + 2])) { \
SPECIFIC->visit_ ## name(stream_[ip + 1], stream_[ip + 2]); } return next_ip_;
#include "vm/gen/instruction_visitors.hpp"
#undef HANDLE_INST0
#undef HANDLE_INST1
#undef HANDLE_INST2
default:
abort();
return -1;
}
}
opcode next_op() {
if(next_ip_ >= size_) return 0;
return stream_[next_ip_];
}
opcode next_op_operand(size_t which) {
if(next_ip_ >= size_) return 0;
return stream_[next_ip_ + 1 + which];
}
static int opcode_size(opcode op) {
#undef HANDLE_INST0
#undef HANDLE_INST1
#undef HANDLE_INST2
switch(op) {
#define HANDLE_INST0(code, name) case code: return 1;
#define HANDLE_INST1(code, name) case code: return 2;
#define HANDLE_INST2(code, name) case code: return 3;
#include "vm/gen/instruction_visitors.hpp"
#undef HANDLE_INST0
#undef HANDLE_INST1
#undef HANDLE_INST2
}
return -1;
}
void skip_next_op() {
if(next_ip_ >= size_) return;
opcode op = stream_[next_ip_];
next_ip_ += opcode_size(op);
}
void drive(opcode* stream, int size, int start = 0) {
set_stream(stream, size);
int ip = start;
while(ip < size) {
ip = dispatch(ip);
}
}
void drive(VMMethod* vmm) {
drive(vmm->opcodes, vmm->total);
}
};
}
#endif
Jump to Line
Something went wrong with that request. Please try again.