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
|
#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<Instr::I> 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 <int Instr>
inline ptrdiff_t addInstruction(const InstrData<Instr> &data);
ptrdiff_t addInstructionHelper(Instr::Type type, Instr &instr);
IR::Function *_function;
IR::BasicBlock *_block;
QHash<IR::BasicBlock *, QVector<ptrdiff_t> > _patches;
QHash<IR::BasicBlock *, ptrdiff_t> _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<int InstrT>
ptrdiff_t InstructionSelection::addInstruction(const InstrData<InstrT> &data)
{
Instr genericInstr;
InstrMeta<InstrT>::setData(genericInstr, data);
return addInstructionHelper(static_cast<Instr::Type>(InstrT), genericInstr);
}
} // namespace Moth
} // namespace QQmlJS
#endif // QV4ISEL_MOTH_P_H
|