#ifndef QV4ISEL_MOTH_P_H #define QV4ISEL_MOTH_P_H #include "qv4isel_p.h" #include "qv4ir_p.h" #include "qmljs_objects.h" #include "qv4instr_moth_p.h" namespace QQmlJS { namespace Moth { class InstructionSelection : public IR::StmtVisitor, public EvalInstructionSelection { public: InstructionSelection(VM::ExecutionEngine *engine, IR::Module *module); ~InstructionSelection(); virtual void run(VM::Function *vmFunction, IR::Function *function); protected: virtual void visitExp(IR::Exp *); virtual void visitEnter(IR::Enter *); virtual void visitLeave(IR::Leave *); virtual void visitMove(IR::Move *); virtual void visitJump(IR::Jump *); virtual void visitCJump(IR::CJump *); virtual void visitRet(IR::Ret *); private: struct Instruction { #define MOTH_INSTR_DATA_TYPEDEF(I, FMT) typedef InstrData I; FOR_EACH_MOTH_INSTR(MOTH_INSTR_DATA_TYPEDEF) #undef MOTH_INSTR_DATA_TYPEDEF private: Instruction(); }; void simpleMove(IR::Move *); void callActivationProperty(IR::Call *c, int targetTempIndex); void callValue(IR::Call *c, int targetTempIndex); void callProperty(IR::Call *c, int targetTempIndex); void construct(IR::New *ctor, int targetTempIndex); void prepareCallArgs(IR::ExprList *, quint32 &, quint32 &); int outgoingArgumentTempStart() const { return _function->tempCount; } int scratchTempIndex() const { return outgoingArgumentTempStart() + _function->maxNumberOfArguments; } int frameSize() const { return scratchTempIndex() + 1 - _function->locals.size(); } template inline ptrdiff_t addInstruction(const InstrData &data); ptrdiff_t addInstructionHelper(Instr::Type type, Instr &instr); IR::Function *_function; IR::BasicBlock *_block; QHash > _patches; QHash _addrs; uchar *_code; uchar *_ccode; }; class ISelFactory: public EvalISelFactory { public: virtual ~ISelFactory() {} virtual EvalInstructionSelection *create(VM::ExecutionEngine *engine, IR::Module *module) { return new InstructionSelection(engine, module); } }; template ptrdiff_t InstructionSelection::addInstruction(const InstrData &data) { Instr genericInstr; InstrMeta::setData(genericInstr, data); return addInstructionHelper(static_cast(InstrT), genericInstr); } } // namespace Moth } // namespace QQmlJS #endif // QV4ISEL_MOTH_P_H