7#include <private/qv4compileddata_p.h>
8#include <private/qv4staticvalue_p.h>
9#include <private/qv4alloca_p.h>
10#include <private/qqmljslexer_p.h>
11#include <private/qqmljsast_p.h>
12#include <private/qml_compile_hash_p.h>
13#include <private/qqmlirbuilder_p.h>
14#include <QCryptographicHash>
24 const size_t remainderMask =
divisor - 1;
25 return (
x + remainderMask) & ~remainderMask;
39 if (
it != stringToId.
cend())
49 Q_ASSERT(stringToId.contains(
string));
50 return stringToId.value(
string);
72 char *dataStart =
reinterpret_cast<char *
>(unit);
74 char *
stringData =
reinterpret_cast<char *
>(stringTable)
76 for (
int i = backingUnitTableSize ;
i <
strings.size(); ++
i) {
77 const int index =
i - backingUnitTableSize;
84 s->size = qstr.
size();
86 ushort *uc =
reinterpret_cast<ushort *
>(
reinterpret_cast<char *
>(
s) +
sizeof(*
s));
87 qToLittleEndian<ushort>(qstr.
constData(),
s->size, uc);
96#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
99 const int checksummableDataOffset
102 const char *dataPtr =
reinterpret_cast<const char *
>(unit) + checksummableDataOffset;
122 return registerGetterLookup(registerString(
name),
mode);
136 return lookups.size() - 1;
141 return registerSetterLookup(registerString(
name));
149 return lookups.size() - 1;
156 return lookups.size() - 1;
165 return lookups.size() - 1;
183 return regexps.size() - 1;
188 int idx = constants.indexOf(
v);
192 return constants.size() - 1;
197 return constants.at(idx);
209 jsClassOffsets.append(jsClassData.size());
210 const int oldSize = jsClassData.size();
211 jsClassData.resize(jsClassData.size() +
size);
212 memset(jsClassData.data() + oldSize, 0,
size);
220 member->
set(registerString(
name),
false);
224 return jsClassOffsets.size() - 1;
231 jsClassData.data() + jsClassOffsets[jsClassId]);
238 jsClassData.data() + jsClassOffsets[jsClassId]);
243 return stringForIndex(
members[member].nameOffset());
248 translations.append(translation);
249 return translations.size() - 1;
258 if (
type->typeArgument) {
259 registerString(
type->typeArgument->toString());
260 registerString(
type->typeId->toString());
262 registerString(
type->toString());
265 registerString(module->fileName);
266 registerString(module->finalUrl);
267 for (
Context *
f : std::as_const(module->functions)) {
268 registerString(
f->name);
269 registerTypeStrings(
f->returnType);
270 for (
int i = 0;
i <
f->arguments.size(); ++
i) {
271 registerString(
f->arguments.at(
i).id);
273 =
f->arguments.at(
i).typeAnnotation.data()) {
274 registerTypeStrings(annotation->type);
277 for (
int i = 0;
i <
f->locals.size(); ++
i)
278 registerString(
f->locals.at(
i));
280 for (
Context *
c : std::as_const(module->blocks)) {
281 for (
int i = 0;
i <
c->locals.size(); ++
i)
282 registerString(
c->locals.at(
i));
286 registerString(
entry.exportName);
287 registerString(
entry.moduleRequest);
288 registerString(
entry.importName);
289 registerString(
entry.localName);
291 std::for_each(module->localExportEntries.constBegin(), module->localExportEntries.constEnd(), registerExportEntry);
292 std::for_each(module->indirectExportEntries.constBegin(), module->indirectExportEntries.constEnd(), registerExportEntry);
293 std::for_each(module->starExportEntries.constBegin(), module->starExportEntries.constEnd(), registerExportEntry);
296 for (
const auto &
entry: module->importEntries) {
297 registerString(
entry.moduleRequest);
298 registerString(
entry.importName);
299 registerString(
entry.localName);
306 Q_ALLOCA_VAR(
quint32_le, blockClassAndFunctionOffsets, (module->functions.size() + module->classes.size() + module->templateObjects.size() + module->blocks.size()) *
sizeof(
quint32_le));
307 uint jsClassDataOffset = 0;
313 dataPtr =
reinterpret_cast<char *
>(malloc(tempHeader.
unitSize));
314 memset(dataPtr, 0, tempHeader.
unitSize);
316 memcpy(unit, &tempHeader,
sizeof(tempHeader));
324 for (
int i = 0;
i < module->functions.size(); ++
i) {
326 if (
function == module->rootContext)
329 writeFunction(dataPtr + blockClassAndFunctionOffsets[
i],
function);
332 for (
int i = 0;
i < module->classes.size(); ++
i) {
333 const Class &
c = module->classes.at(
i);
335 writeClass(dataPtr + blockClassAndFunctionOffsets[
i + module->functions.size()],
c);
338 for (
int i = 0;
i < module->templateObjects.size(); ++
i) {
341 writeTemplateObject(dataPtr + blockClassAndFunctionOffsets[
i + module->functions.size() + module->classes.size()],
t);
344 for (
int i = 0;
i < module->blocks.size(); ++
i) {
345 Context *block = module->blocks.at(
i);
347 writeBlock(dataPtr + blockClassAndFunctionOffsets[
i + module->classes.size() + module->templateObjects.size() + module->functions.size()], block);
352 *lookupsToWrite++ = l;
356 memcpy(regexpTable, regexps.constData(), regexps.size() *
sizeof(*regexpTable));
358#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
360 if (constants.size())
361 memcpy(constantTable, constants.constData(), constants.size() *
sizeof(
ReturnedValue));
364 for (
int i = 0;
i < constants.count(); ++
i)
365 constantTable[
i] = constants.at(
i);
369 if (jsClassData.size())
370 memcpy(dataPtr + jsClassDataOffset, jsClassData.constData(), jsClassData.size());
374 for (
int i = 0;
i < jsClassOffsets.size(); ++
i)
375 jsClassOffsetTable[
i] = jsClassDataOffset + jsClassOffsets.at(
i);
378 if (translations.size()) {
412 for (
const QString &moduleRequest: module->moduleRequests) {
413 *moduleRequestEntryToWrite = getStringId(moduleRequest);
414 moduleRequestEntryToWrite++;
419 if (
option == GenerateWithStringTable)
420 stringTable.serialize(unit);
422 generateUnitChecksum(unit);
449 function->nestedFunctionIndex = std::numeric_limits<uint32_t>::max();
458 function->formalsOffset = currentOffset;
461 const auto idGenerator = [
this](
const QString &
str) {
return getStringId(
str); };
470 function->localsOffset = currentOffset;
476 currentOffset +=
function->nLineAndStatementNumbers
489 function->codeOffset = currentOffset;
495 auto *formal = &formals[
i];
503 for (
int i = 0;
i < irFunction->
locals.size(); ++
i)
504 locals[
i] = getStringId(irFunction->
locals.at(
i));
507 memcpy(
f +
function->lineAndStatementNumberOffset(),
513 for (
unsigned u : irFunction->
labelInfo) {
532 allMethods +=
c.methods;
542 for (
int i = 0;
i < allMethods.
size(); ++
i) {
543 method->name = allMethods.
at(
i).nameIndex;
545 method->function = allMethods.
at(
i).functionIndex;
551 qDebug() <<
"=== Class" << stringForIndex(cls->
nameIndex) <<
"static methods"
557 if (i < cls->nStaticMethods)
577 tmpl->
size =
t.strings.size();
584 for (
int i = 0;
i <
t.strings.size(); ++
i)
588 for (
int i = 0;
i <
t.rawStrings.size(); ++
i)
593 qDebug() <<
"=== TemplateObject size" << tmpl->
size;
615 for (
int i = 0;
i < irBlock->
locals.size(); ++
i)
616 locals[
i] = getStringId(irBlock->
locals.at(
i));
621 for (
int i = 0;
i < irBlock->
locals.size(); ++
i)
622 qDebug() <<
" " <<
i <<
":" << locals[
i];
630 memset(&unit, 0,
sizeof(unit));
633 unit.
flags |= module->unitFlags;
677 *jsClassDataOffset = nextOffset;
678 nextOffset += jsClassData.size();
689 *tableSizePtr =
count;
690 *offsetPtr = nextOffset;
710 for (
int i = 0;
i < module->functions.size(); ++
i) {
711 Context *
f = module->functions.at(
i);
712 blockAndFunctionOffsets[
i] = nextOffset;
715 f->arguments.size(),
f->locals.size(),
f->lineAndStatementNumberMapping.size(),
716 f->nestedContexts.size(),
int(
f->labelInfo.size()),
f->code.size());
717 functionSize +=
size -
f->code.size();
721 blockAndFunctionOffsets += module->functions.size();
723 for (
int i = 0;
i < module->classes.size(); ++
i) {
724 const Class &
c = module->classes.at(
i);
725 blockAndFunctionOffsets[
i] = nextOffset;
729 blockAndFunctionOffsets += module->classes.size();
731 for (
int i = 0;
i < module->templateObjects.size(); ++
i) {
732 const TemplateObject &
t = module->templateObjects.at(
i);
733 blockAndFunctionOffsets[
i] = nextOffset;
737 blockAndFunctionOffsets += module->templateObjects.size();
739 for (
int i = 0;
i < module->blocks.size(); ++
i) {
740 Context *
c = module->blocks.at(
i);
741 blockAndFunctionOffsets[
i] = nextOffset;
746 if (
option == GenerateWithStringTable) {
750 nextOffset += stringTable.sizeOfTableAndData();
758 unit.
sourceTimeStamp = module->sourceTimeStamp.isValid() ? module->sourceTimeStamp.toMSecsSinceEpoch() : 0;
765 qDebug() <<
"Generated JS unit that is" << unit.
unitSize <<
"bytes contains:";
766 qDebug() <<
" " << functionSize <<
"bytes for non-code function data for" << unit.
functionTableSize <<
"functions";
767 qDebug() <<
" " << translations.size() *
sizeof(CompiledData::TranslationData) <<
"bytes for" << translations.size() <<
"translations";
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
qsizetype size() const noexcept
Returns the size of this array.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
const_iterator cend() const noexcept
const_iterator constFind(const T &value) const
iterator insert(const T &value)
QString toString() const
Returns a deep copy of this string view's data as a QString.
\macro QT_RESTRICTED_CAST_FROM_ASCII
const QChar * constData() const
Returns a pointer to the data stored in the QString.
qsizetype size() const
Returns the number of characters in this string.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
QHash< int, QWidget * > hash
[35multi]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
static const char magic_str[]
static size_t roundUpToMultipleOf(size_t divisor, size_t x)
Q_CORE_EXPORT char * qstrcpy(char *dst, const char *src)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
static quint32 checksum(const QByteArray &table)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei const GLchar ** strings
[1]
GLenum GLenum GLsizei count
GLenum GLuint GLintptr offset
GLenum GLenum GLsizei void * table
QCborArray members(const QCborMap *classDef, QLatin1StringView key, QTypeRevision maxMajorVersion, Postprocess &&process)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
#define Q_ALLOCA_VAR(type, name, size)
#define QV4_DATA_STRUCTURE_VERSION
static constexpr qsizetype jsClassMembersOffset
static QV4::CompiledData::Lookup::Mode lookupMode(QV4::Compiler::JSUnitGenerator::LookupMode mode)
QT_BEGIN_NAMESPACE typedef uchar * output
QNetworkRequest request(url)
quint16_le sizeOfLocalTemporalDeadZone
static int calculateSize(int nLocals)
static int calculateSize(int nStaticMethods, int nMethods)
quint32_le methodTableOffset
const Method * methodTable() const
quint32_le nStaticMethods
quint32_le constructorFunction
static int calculateSize(int nFormals, int nLocals, int nLinesAndStatements, int nInnerfunctions, int labelInfoSize, int codeSize)
void set(quint32 nameOffset, bool isAccessor)
static int calculateSize(int nMembers)
@ Type_QmlContextPropertyGetter
static int calculateSize(const QString &str)
static int calculateSize(int size)
uint stringIndexAt(uint i) const
uint rawStringIndexAt(uint i) const
quint32_le offsetToLookupTable
quint32_le offsetToIndirectExportEntryTable
quint32_le offsetToJSClassTable
quint32_le jsClassTableSize
quint32_le offsetToTemplateObjectTable
quint32_le functionTableSize
quint32_le offsetToRegexpTable
quint32_le importEntryTableSize
quint32_le starExportEntryTableSize
quint32_le lookupTableSize
qint32_le indexOfRootFunction
QString stringAtInternal(uint idx) const
quint32_le offsetToLocalExportEntryTable
quint32_le offsetToClassTable
quint32_le classTableSize
quint32_le offsetToStringTable
quint32_le offsetToQmlUnit
quint32_le offsetToFunctionTable
quint32_le offsetToStarExportEntryTable
quint32_le offsetToModuleRequestTable
quint32_le translationTableSize
quint32_le sourceFileIndex
quint32_le moduleRequestTableSize
quint32_le offsetToTranslationTable
char libraryVersionHash[QmlCompileHashSpace]
quint32_le blockTableSize
quint32_le templateObjectTableSize
quint32_le localExportEntryTableSize
quint32_le regexpTableSize
quint32_le offsetToImportEntryTable
quint32_le stringTableSize
quint32_le constantTableSize
qint64_le sourceTimeStamp
char dependencyMD5Checksum[16]
quint32_le offsetToConstantTable
quint32_le offsetToBlockTable
quint32_le indirectExportEntryTableSize
QQmlJS::AST::FormalParameterList * formals
bool innerFunctionAccessesThis
QQmlJS::AST::BoundNames arguments
QVector< Context * > nestedContexts
bool innerFunctionAccessesNewTarget
int firstTemporalDeadZoneRegister
QQmlJS::AST::Type * returnType
int sizeOfRegisterTemporalDeadZone
int registerCountInFunction
QVector< CompiledData::CodeOffsetToLineAndStatement > lineAndStatementNumberMapping
int sizeOfLocalTemporalDeadZone
std::vector< unsigned > labelInfo
int registerJSClass(const QStringList &members)
QString jsClassMember(int jsClassId, int member) const
int registerGlobalGetterLookup(int nameIndex, LookupMode mode)
void writeTemplateObject(char *f, const TemplateObject &o)
static void generateUnitChecksum(CompiledData::Unit *unit)
ReturnedValue constant(int idx) const
JSUnitGenerator(Module *module)
int registerTranslation(const CompiledData::TranslationData &translation)
void writeBlock(char *f, Context *irBlock) const
void writeClass(char *f, const Class &c)
int registerRegExp(QQmlJS::AST::RegExpLiteral *regexp)
QV4::CompiledData::Unit * generateUnit(GeneratorOption option=GenerateWithStringTable)
int registerSetterLookup(const QString &name)
int registerQmlContextPropertyGetterLookup(int nameIndex, LookupMode mode)
void writeFunction(char *f, Context *irFunction) const
int jsClassSize(int jsClassId) const
int registerConstant(ReturnedValue v)
int registerGetterLookup(const QString &name, LookupMode mode)
int registerString(const QString &str)
int getStringId(const QString &string) const
int registerString(const QString &str)
void serialize(CompiledData::Unit *unit)
void initializeFromBackingUnit(const CompiledData::Unit *unit)
static bool initType(QV4::CompiledData::ParameterType *type, const IdGenerator &idGenerator, const QQmlJS::AST::Type *annotation)