Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant
++
++ #include "qv4instr_moth_p.h"
++ #include <private/qv4compileddata_p.h>
++ #include <private/qv4calldata_p.h>
++
++ #include <QtCore/qdebug.h>
++
++ using namespace QV4;
++ using namespace QV4::Moth;
++
++ int InstrInfo::size(Instr::Type type)
++ {
++ #define MOTH_RETURN_INSTR_SIZE(I) case Instr::Type::I: case Instr::Type::I##_Wide: return InstrMeta<int(Instr::Type::I)>::Size;
++ switch (type) {
++ FOR_EACH_MOTH_INSTR_ALL(MOTH_RETURN_INSTR_SIZE)
++ }
++ #undef MOTH_RETURN_INSTR_SIZE
++ Q_UNREACHABLE();
++ }
++
++ static QByteArray alignedNumber(int n) {
++ QByteArray number = QByteArray::number(n);
++ return number.prepend(8 - number.size(), ' ');
++ }
++
++ static QByteArray alignedLineNumber(int line) {
++ if (line > 0)
++ return alignedNumber(static_cast<int>(line));
++ return QByteArray(" ");
++ }
++
++ static QByteArray rawBytes(const char *data, int n)
++ {
++ QByteArray ba;
++ while (n) {
++ uint num = *reinterpret_cast<const uchar *>(data);
++ if (num < 16)
++ ba += '0';
++ ba += QByteArray::number(num, 16) + " ";
++ ++data;
++ --n;
++ }
++ while (ba.size() < 25)
++ ba += ' ';
++ return ba;
++ }
++
++ #define ABSOLUTE_OFFSET() \
++ (code + beginOffset - start + offset)
++
++ #define MOTH_BEGIN_INSTR(instr) \
++ { \
++ INSTR_##instr(MOTH_DECODE_WITH_BASE) \
++ if (static_cast<int>(Instr::Type::instr) >= 0x100) \
++ --base_ptr; \
++ s << alignedLineNumber(line) << alignedNumber(beginOffset + codeOffset).constData() << ": " \
++ << rawBytes(base_ptr, int(code - base_ptr)) << #instr << " ";
++
++ #define MOTH_END_INSTR(instr) \
++ s << "\n"; \
++ continue; \
++ }
++
++ QT_BEGIN_NAMESPACE
++ namespace QV4 {
++ namespace Moth {
++
++ const int InstrInfo::argumentCount[] = {
++ FOR_EACH_MOTH_INSTR_ALL(MOTH_COLLECT_NARGS)
++ };
++
++ QString dumpRegister(int reg, int nFormals)
++ {
++ Q_STATIC_ASSERT(offsetof(CallData, function) == 0);
++ Q_STATIC_ASSERT(offsetof(CallData, context) == sizeof(StaticValue));
++ Q_STATIC_ASSERT(offsetof(CallData, accumulator) == 2*sizeof(StaticValue));
++ Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 3*sizeof(StaticValue));
++ if (reg == CallData::Function)
++ return QStringLiteral("(function)");
++ else if (reg == CallData::Context)
++ return QStringLiteral("(context)");
++ else if (reg == CallData::Accumulator)
++ return QStringLiteral("(accumulator)");
++ else if (reg == CallData::NewTarget)
++ return QStringLiteral("(new.target)");
++ else if (reg == CallData::This)
++ return QStringLiteral("(this)");
++ else if (reg == CallData::Argc)
++ return QStringLiteral("(argc)");
++ reg -= CallData::HeaderSize();
++ if (reg < nFormals)
++ return QStringLiteral("a%1").arg(reg);
++ reg -= nFormals;
++ return QStringLiteral("r%1").arg(reg);
++
++ }
++
++ QString dumpArguments(int argc, int argv, int nFormals)
++ {
++ if (!argc)
++ return QStringLiteral("()");
++ return QStringLiteral("(") + dumpRegister(argv, nFormals) + QStringLiteral(", ") + QString::number(argc) + QStringLiteral(")");
++ }
++
++ QString dumpBytecode(
++ const char *code, int len, int nLocals, int nFormals, int /*startLine*/,
++ const QList<CompiledData::CodeOffsetToLineAndStatement> &lineAndStatementNumberMapping)
++ {
++ return dumpBytecode(code, len, nLocals, nFormals, 0, len - 1, lineAndStatementNumberMapping);
++ }
++
++ QT_WARNING_PUSH
++ QT_WARNING_DISABLE_LARGE_STACK_FRAME // unclear how this can be shrunk...
++ QString dumpBytecode(
++ const char *code, int len, int nLocals, int nFormals, int beginOffset, int endOffset,
++ const QList<CompiledData::CodeOffsetToLineAndStatement> &lineAndStatementNumberMapping)
++ {
++ Q_ASSERT(beginOffset <= endOffset && 0 <= beginOffset && endOffset <= len);
++
++ MOTH_JUMP_TABLE;
++
++ auto findLine = [](const CompiledData::CodeOffsetToLineAndStatement &entry, uint offset) {
++ return entry.codeOffset < offset;
++ };
++
++ QString output;
++ QTextStream s{ &output };
++
++ int lastLine = -1;
++ code += beginOffset;
++ const char *start = code;
++ const char *end = code + (endOffset - beginOffset) + 1;
++ while (code < end) {
++ const auto codeToLine = std::lower_bound(
++ lineAndStatementNumberMapping.constBegin(),
++ lineAndStatementNumberMapping.constEnd(),
++ static_cast<uint>(code - start + beginOffset) + 1, findLine) - 1;
++ int line = int(codeToLine->line);
++ if (line != lastLine)
++ lastLine = line;
++ else
++ line = -1;
++
++ int codeOffset = int(code - start);
++
++ MOTH_DISPATCH()
++
++ MOTH_BEGIN_INSTR(LoadReg)
++ s << dumpRegister(reg, nFormals);
++ MOTH_END_INSTR(LoadReg)
++
++ MOTH_BEGIN_INSTR(StoreReg)
++ s << dumpRegister(reg, nFormals);
++ MOTH_END_INSTR(StoreReg)
++
++ MOTH_BEGIN_INSTR(MoveReg)
++ s << dumpRegister(srcReg, nFormals) << ", " << dumpRegister(destReg, nFormals);
++ MOTH_END_INSTR(MoveReg)
++
++ MOTH_BEGIN_INSTR(LoadImport)
++ s << "i" << index;
++ MOTH_END_INSTR(LoadImport)
++
++ MOTH_BEGIN_INSTR(LoadConst)
++ s << "C" << index;
++ MOTH_END_INSTR(LoadConst)
++
++ MOTH_BEGIN_INSTR(LoadNull)
++ MOTH_END_INSTR(LoadNull)
++
++ MOTH_BEGIN_INSTR(LoadZero)
++ MOTH_END_INSTR(LoadZero)
++
++ MOTH_BEGIN_INSTR(LoadTrue)
++ MOTH_END_INSTR(LoadTrue)
++
++ MOTH_BEGIN_INSTR(LoadFalse)
++ MOTH_END_INSTR(LoadFalse)
++
++ MOTH_BEGIN_INSTR(LoadUndefined)
++ MOTH_END_INSTR(LoadUndefined)
++
++ MOTH_BEGIN_INSTR(LoadInt)
++ s << value;
++ MOTH_END_INSTR(LoadInt)
++
++ MOTH_BEGIN_INSTR(MoveConst)
++ s << "C" << constIndex << ", " << dumpRegister(destTemp, nFormals);
++ MOTH_END_INSTR(MoveConst)
++
++ MOTH_BEGIN_INSTR(LoadLocal)
++ if (index < nLocals)
++ s << "l" << index;
++ else
++ s << "a" << (index - nLocals);
++ MOTH_END_INSTR(LoadLocal)
++
++ MOTH_BEGIN_INSTR(StoreLocal)
++ if (index < nLocals)
++ s << "l" << index;
++ else
++ s << "a" << (index - nLocals);
++ MOTH_END_INSTR(StoreLocal)
++
++ MOTH_BEGIN_INSTR(LoadScopedLocal)
++ if (index < nLocals)
++ s << "l" << index << "@" << scope;
++ else
++ s << "a" << (index - nLocals) << "@" << scope;
++ MOTH_END_INSTR(LoadScopedLocal)
++
++ MOTH_BEGIN_INSTR(StoreScopedLocal)
++ if (index < nLocals)
++ s << ", " << "l" << index << "@" << scope;
++ else
++ s << ", " << "a" << (index - nLocals) << "@" << scope;
++ MOTH_END_INSTR(StoreScopedLocal)
++
++ MOTH_BEGIN_INSTR(LoadRuntimeString)
++ s << stringId;
++ MOTH_END_INSTR(LoadRuntimeString)
++
++ MOTH_BEGIN_INSTR(MoveRegExp)
++ s << regExpId << ", " << dumpRegister(destReg, nFormals);
++ MOTH_END_INSTR(MoveRegExp)
++
++ MOTH_BEGIN_INSTR(LoadClosure)
++ s << value;
++ MOTH_END_INSTR(LoadClosure)
++
++ MOTH_BEGIN_INSTR(LoadName)
++ s << name;
++ MOTH_END_INSTR(LoadName)
++
++ MOTH_BEGIN_INSTR(LoadGlobalLookup)
++ s << index;
++ MOTH_END_INSTR(LoadGlobalLookup)
++
++ MOTH_BEGIN_INSTR(LoadQmlContextPropertyLookup)
++ s << index;
++ MOTH_END_INSTR(LoadQmlContextPropertyLookup)
++
++ MOTH_BEGIN_INSTR(StoreNameSloppy)
++ s << name;
++ MOTH_END_INSTR(StoreNameSloppy)
++
++ MOTH_BEGIN_INSTR(StoreNameStrict)
++ s << name;
++ MOTH_END_INSTR(StoreNameStrict)
++
++ MOTH_BEGIN_INSTR(LoadElement)
++ s << dumpRegister(base, nFormals) << "[acc]";
++ MOTH_END_INSTR(LoadElement)
++
++ MOTH_BEGIN_INSTR(StoreElement)
++ s << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]";
++ MOTH_END_INSTR(StoreElement)
++
++ MOTH_BEGIN_INSTR(LoadProperty)
++ s << "acc[" << name << "]";
++ MOTH_END_INSTR(LoadProperty)
++
++ MOTH_BEGIN_INSTR(LoadOptionalProperty)
++ s << "acc[" << name << "], jump(" << ABSOLUTE_OFFSET() << ")";
++ MOTH_END_INSTR(LoadOptionalProperty)
++
++ MOTH_BEGIN_INSTR(GetLookup)
++ s << "acc(" << index << ")";
++ MOTH_END_INSTR(GetLookup)
++
++ MOTH_BEGIN_INSTR(GetOptionalLookup)
++ s << "acc(" << index << "), jump(" << ABSOLUTE_OFFSET() << ")";
++ MOTH_END_INSTR(GetOptionalLookup)
++
++ MOTH_BEGIN_INSTR(StoreProperty)
++ s << dumpRegister(base, nFormals) << "[" << name<< "]";
++ MOTH_END_INSTR(StoreProperty)
++
++ MOTH_BEGIN_INSTR(SetLookup)
++ s << dumpRegister(base, nFormals) << "(" << index << ")";
++ MOTH_END_INSTR(SetLookup)
++
++ MOTH_BEGIN_INSTR(LoadSuperProperty)
++ s << dumpRegister(property, nFormals);
++ MOTH_END_INSTR(LoadSuperProperty)
++
++ MOTH_BEGIN_INSTR(StoreSuperProperty)
++ s << dumpRegister(property, nFormals);
++ MOTH_END_INSTR(StoreSuperProperty)
++
++ MOTH_BEGIN_INSTR(Yield)
++ MOTH_END_INSTR(Yield)
++
++ MOTH_BEGIN_INSTR(YieldStar)
++ MOTH_END_INSTR(YieldStar)
++
++ MOTH_BEGIN_INSTR(Resume)
++ s << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(Resume)
++
++ MOTH_BEGIN_INSTR(CallValue)
++ s << dumpRegister(name, nFormals) << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(CallValue)
++
++ MOTH_BEGIN_INSTR(CallWithReceiver)
++ s << dumpRegister(name, nFormals) << dumpRegister(thisObject, nFormals)
++ << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(CallWithReceiver)
++
++ MOTH_BEGIN_INSTR(CallProperty)
++ s << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals)
++ ;
++ MOTH_END_INSTR(CallProperty)
++
++ MOTH_BEGIN_INSTR(CallPropertyLookup)
++ s << dumpRegister(base, nFormals) << "." << lookupIndex
++ << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(CallPropertyLookup)
++
++ MOTH_BEGIN_INSTR(CallName)
++ s << name << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(CallName)
++
++ MOTH_BEGIN_INSTR(CallPossiblyDirectEval)
++ s << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(CallPossiblyDirectEval)
++
++ MOTH_BEGIN_INSTR(CallGlobalLookup)
++ s << index << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(CallGlobalLookup)
++
++ MOTH_BEGIN_INSTR(CallQmlContextPropertyLookup)
++ s << index << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(CallQmlContextPropertyLookup)
++
++ MOTH_BEGIN_INSTR(CallWithSpread)
++ s << "new " << dumpRegister(func, nFormals) << dumpRegister(thisObject, nFormals)
++ << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(CallWithSpread)
++
++ MOTH_BEGIN_INSTR(Construct)
++ s << "new " << dumpRegister(func, nFormals) << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(Construct)
++
++ MOTH_BEGIN_INSTR(ConstructWithSpread)
++ s << "new " << dumpRegister(func, nFormals) << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(ConstructWithSpread)
++
++ MOTH_BEGIN_INSTR(SetUnwindHandler)
++ if (offset)
++ s << ABSOLUTE_OFFSET();
++ else
++ s << "<null>";
++ MOTH_END_INSTR(SetUnwindHandler)
++
++ MOTH_BEGIN_INSTR(UnwindDispatch)
++ MOTH_END_INSTR(UnwindDispatch)
++
++ MOTH_BEGIN_INSTR(UnwindToLabel)
++ s << "(" << level << ") " << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(UnwindToLabel)
++
++ MOTH_BEGIN_INSTR(DeadTemporalZoneCheck)
++ s << name;
++ MOTH_END_INSTR(DeadTemporalZoneCheck)
++
++ MOTH_BEGIN_INSTR(ThrowException)
++ MOTH_END_INSTR(ThrowException)
++
++ MOTH_BEGIN_INSTR(GetException)
++ MOTH_END_INSTR(HasException)
++
++ MOTH_BEGIN_INSTR(SetException)
++ MOTH_END_INSTR(SetExceptionFlag)
++
++ MOTH_BEGIN_INSTR(CreateCallContext)
++ MOTH_END_INSTR(CreateCallContext)
++
++ MOTH_BEGIN_INSTR(PushCatchContext)
++ s << index << ", " << name;
++ MOTH_END_INSTR(PushCatchContext)
++
++ MOTH_BEGIN_INSTR(PushWithContext)
++ MOTH_END_INSTR(PushWithContext)
++
++ MOTH_BEGIN_INSTR(PushBlockContext)
++ s << index;
++ MOTH_END_INSTR(PushBlockContext)
++
++ MOTH_BEGIN_INSTR(CloneBlockContext)
++ MOTH_END_INSTR(CloneBlockContext)
++
++ MOTH_BEGIN_INSTR(PushScriptContext)
++ s << index;
++ MOTH_END_INSTR(PushScriptContext)
++
++ MOTH_BEGIN_INSTR(PopScriptContext)
++ MOTH_END_INSTR(PopScriptContext)
++
++ MOTH_BEGIN_INSTR(PopContext)
++ MOTH_END_INSTR(PopContext)
++
++ MOTH_BEGIN_INSTR(GetIterator)
++ s << iterator;
++ MOTH_END_INSTR(GetIterator)
++
++ MOTH_BEGIN_INSTR(IteratorNext)
++ s << dumpRegister(value, nFormals) << ", " << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(IteratorNext)
++
++ MOTH_BEGIN_INSTR(IteratorNextForYieldStar)
++ s << dumpRegister(iterator, nFormals) << ", " << dumpRegister(object, nFormals)
++ << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(IteratorNextForYieldStar)
++
++ MOTH_BEGIN_INSTR(IteratorClose)
++ MOTH_END_INSTR(IteratorClose)
++
++ MOTH_BEGIN_INSTR(DestructureRestElement)
++ MOTH_END_INSTR(DestructureRestElement)
++
++ MOTH_BEGIN_INSTR(DeleteProperty)
++ s << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]";
++ MOTH_END_INSTR(DeleteProperty)
++
++ MOTH_BEGIN_INSTR(DeleteName)
++ s << name;
++ MOTH_END_INSTR(DeleteName)
++
++ MOTH_BEGIN_INSTR(TypeofName)
++ s << name;
++ MOTH_END_INSTR(TypeofName)
++
++ MOTH_BEGIN_INSTR(TypeofValue)
++ MOTH_END_INSTR(TypeofValue)
++
++ MOTH_BEGIN_INSTR(DeclareVar)
++ s << isDeletable << ", " << varName;
++ MOTH_END_INSTR(DeclareVar)
++
++ MOTH_BEGIN_INSTR(DefineArray)
++ s << dumpRegister(args, nFormals) << ", " << argc;
++ MOTH_END_INSTR(DefineArray)
++
++ MOTH_BEGIN_INSTR(DefineObjectLiteral)
++ s << internalClassId
++ << ", " << argc
++ << ", " << dumpRegister(args, nFormals);
++ MOTH_END_INSTR(DefineObjectLiteral)
++
++ MOTH_BEGIN_INSTR(CreateClass)
++ s << classIndex
++ << ", " << dumpRegister(heritage, nFormals)
++ << ", " << dumpRegister(computedNames, nFormals);
++ MOTH_END_INSTR(CreateClass)
++
++ MOTH_BEGIN_INSTR(CreateMappedArgumentsObject)
++ MOTH_END_INSTR(CreateMappedArgumentsObject)
++
++ MOTH_BEGIN_INSTR(CreateUnmappedArgumentsObject)
++ MOTH_END_INSTR(CreateUnmappedArgumentsObject)
++
++ MOTH_BEGIN_INSTR(CreateRestParameter)
++ s << argIndex;
++ MOTH_END_INSTR(CreateRestParameter)
++
++ MOTH_BEGIN_INSTR(ConvertThisToObject)
++ MOTH_END_INSTR(ConvertThisToObject)
++
++ MOTH_BEGIN_INSTR(LoadSuperConstructor)
++ MOTH_END_INSTR(LoadSuperConstructor)
++
++ MOTH_BEGIN_INSTR(ToObject)
++ MOTH_END_INSTR(ToObject)
++
++ MOTH_BEGIN_INSTR(Jump)
++ s << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(Jump)
++
++ MOTH_BEGIN_INSTR(JumpTrue)
++ s << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(JumpTrue)
++
++ MOTH_BEGIN_INSTR(JumpFalse)
++ s << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(JumpFalse)
++
++ MOTH_BEGIN_INSTR(JumpNotUndefined)
++ s << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(JumpNotUndefined)
++
++ MOTH_BEGIN_INSTR(JumpNoException)
++ s << ABSOLUTE_OFFSET();
++ MOTH_END_INSTR(JumpNoException)
++
++ MOTH_BEGIN_INSTR(CheckException)
++ MOTH_END_INSTR(CheckException)
++
++ MOTH_BEGIN_INSTR(CmpEqNull)
++ MOTH_END_INSTR(CmpEqNull)
++
++ MOTH_BEGIN_INSTR(CmpNeNull)
++ MOTH_END_INSTR(CmpNeNull)
++
++ MOTH_BEGIN_INSTR(CmpEqInt)
++ s << lhs;
++ MOTH_END_INSTR(CmpEq)
++
++ MOTH_BEGIN_INSTR(CmpNeInt)
++ s << lhs;
++ MOTH_END_INSTR(CmpNeInt)
++
++ MOTH_BEGIN_INSTR(CmpEq)
++ s << dumpRegister(lhs, nFormals);
++ MOTH_END_INSTR(CmpEq)
++
++ MOTH_BEGIN_INSTR(CmpNe)
++ s << dumpRegister(lhs, nFormals);
++ MOTH_END_INSTR(CmpNe)
++
++ MOTH_BEGIN_INSTR(CmpGt)
++ s << dumpRegister(lhs, nFormals);
++ MOTH_END_INSTR(CmpGt)
++
++ MOTH_BEGIN_INSTR(CmpGe)
++ s << dumpRegister(lhs, nFormals);
++ MOTH_END_INSTR(CmpGe)
++
++ MOTH_BEGIN_INSTR(CmpLt)
++ s << dumpRegister(lhs, nFormals);
++ MOTH_END_INSTR(CmpLt)
++
++ MOTH_BEGIN_INSTR(CmpLe)
++ s << dumpRegister(lhs, nFormals);
++ MOTH_END_INSTR(CmpLe)
++
++ MOTH_BEGIN_INSTR(CmpStrictEqual)
++ s << dumpRegister(lhs, nFormals);
++ MOTH_END_INSTR(CmpStrictEqual)
++
++ MOTH_BEGIN_INSTR(CmpStrictNotEqual)
++ s << dumpRegister(lhs, nFormals);
++ MOTH_END_INSTR(CmpStrictNotEqual)
++
++ MOTH_BEGIN_INSTR(UNot)
++ MOTH_END_INSTR(UNot)
++
++ MOTH_BEGIN_INSTR(UPlus)
++ MOTH_END_INSTR(UPlus)
++
++ MOTH_BEGIN_INSTR(UMinus)
++ MOTH_END_INSTR(UMinus)
++
++ MOTH_BEGIN_INSTR(UCompl)
++ MOTH_END_INSTR(UCompl)
++
++ MOTH_BEGIN_INSTR(Increment)
++ MOTH_END_INSTR(Increment)
++
++ MOTH_BEGIN_INSTR(Decrement)
++ MOTH_END_INSTR(Decrement)
++
++ MOTH_BEGIN_INSTR(Add)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Add)
++
++ MOTH_BEGIN_INSTR(BitAnd)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(BitAnd)
++
++ MOTH_BEGIN_INSTR(BitOr)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(BitOr)
++
++ MOTH_BEGIN_INSTR(BitXor)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(BitXor)
++
++ MOTH_BEGIN_INSTR(UShr)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(UShr)
++
++ MOTH_BEGIN_INSTR(Shr)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Shr)
++
++ MOTH_BEGIN_INSTR(Shl)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Shl)
++
++ MOTH_BEGIN_INSTR(BitAndConst)
++ s << "acc, " << rhs;
++ MOTH_END_INSTR(BitAndConst)
++
++ MOTH_BEGIN_INSTR(BitOrConst)
++ s << "acc, " << rhs;
++ MOTH_END_INSTR(BitOr)
++
++ MOTH_BEGIN_INSTR(BitXorConst)
++ s << "acc, " << rhs;
++ MOTH_END_INSTR(BitXor)
++
++ MOTH_BEGIN_INSTR(UShrConst)
++ s << "acc, " << rhs;
++ MOTH_END_INSTR(UShrConst)
++
++ MOTH_BEGIN_INSTR(ShrConst)
++ s << "acc, " << rhs;
++ MOTH_END_INSTR(ShrConst)
++
++ MOTH_BEGIN_INSTR(ShlConst)
++ s << "acc, " << rhs;
++ MOTH_END_INSTR(ShlConst)
++
++ MOTH_BEGIN_INSTR(Exp)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Exp)
++
++ MOTH_BEGIN_INSTR(Mul)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Mul)
++
++ MOTH_BEGIN_INSTR(Div)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Div)
++
++ MOTH_BEGIN_INSTR(Mod)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Mod)
++
++ MOTH_BEGIN_INSTR(Sub)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Sub)
++
++ MOTH_BEGIN_INSTR(As)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(Sub)
++
++ MOTH_BEGIN_INSTR(CmpIn)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(CmpIn)
++
++ MOTH_BEGIN_INSTR(CmpInstanceOf)
++ s << dumpRegister(lhs, nFormals) << ", acc";
++ MOTH_END_INSTR(CmpInstanceOf)
++
++ MOTH_BEGIN_INSTR(Ret)
++ MOTH_END_INSTR(Ret)
++
++ MOTH_BEGIN_INSTR(Debug)
++ MOTH_END_INSTR(Debug)
++
++ MOTH_BEGIN_INSTR(InitializeBlockDeadTemporalZone)
++ s << dumpRegister(firstReg, nFormals) << ", " << count;
++ MOTH_END_INSTR(InitializeBlockDeadTemporalZone)
++
++ MOTH_BEGIN_INSTR(ThrowOnNullOrUndefined)
++ MOTH_END_INSTR(ThrowOnNullOrUndefined)
++
++ MOTH_BEGIN_INSTR(GetTemplateObject)
++ s << index;
++ MOTH_END_INSTR(GetTemplateObject)
++
++ MOTH_BEGIN_INSTR(TailCall)
++ s << dumpRegister(func, nFormals) << dumpRegister(thisObject, nFormals) << dumpArguments(argc, argv, nFormals);
++ MOTH_END_INSTR(TailCall)
++ }
++ return output;
++ }
++ QT_WARNING_POP // DISABLE_LARGE_STACK_FRAME
++
++ }
++ }
++ QT_END_NAMESPACE