QV4::Lookup *runtimeLookups;
QV4::Value *runtimeRegularExpressions;
QV4::InternalClass **runtimeClasses;
+ QList<QV4::Function *> runtimeFunctions;
QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine) = 0;
};
-struct MothCompilationUnit : public CompilationUnit
-{
- virtual ~MothCompilationUnit() {
- // free all bytecode
- }
-
- // vector of bytecode
-
-};
-
}
}
locals[i] = getStringId(*irFunction->locals.at(i));
// write line number mappings
- quint32 *mappingsToWrite = (quint32*)(f + function->lineNumberMappingOffset);
- memcpy(mappingsToWrite, lineNumberMapping->constData(), 2 * function->nLineNumberMappingEntries * sizeof(quint32));
+ if (function->nLineNumberMappingEntries) {
+ quint32 *mappingsToWrite = (quint32*)(f + function->lineNumberMappingOffset);
+ memcpy(mappingsToWrite, lineNumberMapping->constData(), 2 * function->nLineNumberMappingEntries * sizeof(quint32));
+ }
// write inner functions
quint32 *innerFunctions = (quint32 *)(f + function->innerFunctionsOffset);
// Coderef + execution engine
- QList<QV4::Function *> runtimeFunctions;
QVector<JSC::MacroAssemblerCodeRef> codeRefs;
};
#include <private/qv4debugging_p.h>
#include <private/qv4function_p.h>
#include <private/qv4regexpobject_p.h>
+#include <private/qv4compileddata_p.h>
#undef USE_TYPE_INFO
, _stackSlotAllocator(0)
, _currentStatement(0)
{
+ compilationUnit = new CompilationUnit;
}
InstructionSelection::~InstructionSelection()
// TODO: patch stack size (the push instruction)
patchJumpAddresses();
- _vmFunction->code = VME::exec;
- _vmFunction->codeData = squeezeCode();
+ codeRefs.insert(_function, squeezeCode());
if (QV4::Debugging::Debugger *debugger = engine()->debugger)
debugger->setPendingBreakpoints(_vmFunction);
delete[] codeStart;
}
+QV4::CompiledData::CompilationUnit *InstructionSelection::backendCompileStep()
+{
+ compilationUnit->data = jsUnitGenerator.generateUnit();
+ compilationUnit->runtimeFunctions.reserve(jsUnitGenerator.irModule->functions.size());
+ compilationUnit->codeRefs.resize(jsUnitGenerator.irModule->functions.size());
+ int i = 0;
+ foreach (V4IR::Function *irFunction, jsUnitGenerator.irModule->functions) {
+ compilationUnit->runtimeFunctions << _irToVM[irFunction];
+ compilationUnit->codeRefs[i++] = codeRefs[irFunction];
+ }
+ return compilationUnit;
+}
+
void InstructionSelection::callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result)
{
Instruction::CallValue call;
_addrs.clear();
}
-uchar *InstructionSelection::squeezeCode() const
+QByteArray InstructionSelection::squeezeCode() const
{
int codeSize = _codeNext - _codeStart;
- uchar *squeezed = new uchar[codeSize];
- ::memcpy(squeezed, _codeStart, codeSize);
+ QByteArray squeezed;
+ squeezed.resize(codeSize);
+ ::memcpy(squeezed.data(), _codeStart, codeSize);
return squeezed;
}
return Param();
}
}
+
+
+QV4::Function *CompilationUnit::linkBackendToEngine(QV4::ExecutionEngine *engine)
+{
+ QV4::Function *rootRuntimeFunction = 0;
+
+ const QV4::CompiledData::Function *compiledRootFunction = data->functionAt(data->indexOfRootFunction);
+
+ for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
+ QV4::Function *runtimeFunction = runtimeFunctions.at(i);
+ const QV4::CompiledData::Function *compiledFunction = data->functionAt(i);
+
+ runtimeFunction->init(this, compiledFunction,
+ &VME::exec, /*size - doesn't matter for moth*/0);
+
+ runtimeFunction->codeData = reinterpret_cast<const uchar *>(codeRefs.at(i).constData());
+
+ if (compiledFunction == compiledRootFunction) {
+ assert(!rootRuntimeFunction);
+ rootRuntimeFunction = runtimeFunction;
+ }
+ }
+
+ return rootRuntimeFunction;
+}
class StackSlotAllocator;
+struct CompilationUnit : public QV4::CompiledData::CompilationUnit
+{
+ virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine);
+
+ QVector<QByteArray> codeRefs;
+
+};
+
+
class Q_QML_EXPORT InstructionSelection:
public V4IR::IRDecoder,
public EvalInstructionSelection
virtual void run(QV4::Function *vmFunction, V4IR::Function *function);
protected:
+ virtual QV4::CompiledData::CompilationUnit *backendCompileStep();
+
virtual void visitJump(V4IR::Jump *);
virtual void visitCJump(V4IR::CJump *);
virtual void visitRet(V4IR::Ret *);
inline ptrdiff_t addInstruction(const InstrData<Instr> &data);
ptrdiff_t addInstructionHelper(Instr::Type type, Instr &instr);
void patchJumpAddresses();
- uchar *squeezeCode() const;
+ QByteArray squeezeCode() const;
QV4::String *identifier(const QString &s);
StackSlotAllocator *_stackSlotAllocator;
V4IR::Stmt *_currentStatement;
+
+ CompilationUnit *compilationUnit;
+ QHash<V4IR::Function *, QByteArray> codeRefs;
};
class Q_QML_EXPORT ISelFactory: public EvalISelFactory
QV4::Function *createFunctionMapping(QV4::Function *outer, V4IR::Function *irFunction);
QV4::ExecutionEngine *engine() const { return _engine; }
virtual void run(QV4::Function *vmFunction, V4IR::Function *function) = 0;
- virtual QV4::CompiledData::CompilationUnit *backendCompileStep() { return 0; }
+ virtual QV4::CompiledData::CompilationUnit *backendCompileStep() = 0;
private:
QV4::ExecutionEngine *_engine;
UnwindHelper::deregisterFunction(this); // ### move to masm compilation unit
Q_ASSERT(!refCount);
- delete[] codeData;
foreach (Function *f, nestedFunctions)
f->deref();
if (compilationUnit)