aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2019-01-03 15:44:34 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2019-03-20 09:16:52 +0000
commit5cfccf30898aed5ca96c0f8779b0f8a1117118b7 (patch)
tree361b7847136122d42b1647b4debdafa184baebb5 /src/qml
parentc9e6251cc8dfcf002f64b07e48dd68b7edd3f630 (diff)
Remove dead compile time QML context/scope property and id object code
After enabling lookups in QML files, we can remove all the code that tries to deal with (type) compile time detection of access to id objects and properties of the scope/context object. This also allows removing quite a bit of run-time code paths and even byte code instructions. Task-number: QTBUG-69898 Change-Id: I7b26d7983393594a3ef56466d3e633f1822b76f4 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp410
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h34
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp33
-rw-r--r--src/qml/compiler/qv4bytecodehandler.cpp27
-rw-r--r--src/qml/compiler/qv4codegen.cpp71
-rw-r--r--src/qml/compiler/qv4codegen_p.h58
-rw-r--r--src/qml/compiler/qv4compileddata_p.h27
-rw-r--r--src/qml/compiler/qv4compiler.cpp45
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h5
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp36
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h16
-rw-r--r--src/qml/jit/qv4baselinejit.cpp103
-rw-r--r--src/qml/jit/qv4baselinejit_p.h13
-rw-r--r--src/qml/jsruntime/qv4function.cpp1
-rw-r--r--src/qml/jsruntime/qv4function_p.h1
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp28
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h3
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp86
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h14
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp51
-rw-r--r--src/qml/qml/qqmlbinding.cpp32
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp82
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h21
-rw-r--r--src/qml/types/qqmllistmodel.cpp3
24 files changed, 41 insertions, 1159 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 4b4d3c27e8..ab43ea350b 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -974,7 +974,6 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node)
foe->node = funDecl;
foe->parentNode = funDecl;
foe->nameIndex = registerString(funDecl->name.toString());
- foe->disableAcceleratedLookups = false;
const int index = _object->functionsAndExpressions->append(foe);
Function *f = New<Function>();
@@ -1095,7 +1094,6 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST
expr->parentNode = parentNode;
expr->nameIndex = registerString(QLatin1String("expression for ")
+ stringAt(binding->propertyNameIndex));
- expr->disableAcceleratedLookups = false;
const int index = bindingsTarget()->functionsAndExpressions->append(expr);
binding->value.compiledScriptIndex = index;
// We don't need to store the binding script as string, except for script strings
@@ -1822,19 +1820,13 @@ char *QmlUnitGenerator::writeBindings(char *bindingPtr, const Object *o, Binding
JSCodeGen::JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator,
QV4::Compiler::Module *jsModule, QQmlJS::Engine *jsEngine,
- QQmlJS::AST::UiProgram *qmlRoot, QQmlTypeNameCache *imports,
+ QQmlJS::AST::UiProgram *qmlRoot,
const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames)
: QV4::Compiler::Codegen(jsUnitGenerator, /*strict mode*/false)
, sourceCode(sourceCode)
, jsEngine(jsEngine)
, qmlRoot(qmlRoot)
- , imports(imports)
, stringPool(stringPool)
- , _disableAcceleratedLookups(false)
- , _contextObject(nullptr)
- , _scopeObject(nullptr)
- , _qmlContextSlot(-1)
- , _importedScriptsSlot(-1)
{
m_globalNames = globalNames;
@@ -1842,18 +1834,6 @@ JSCodeGen::JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *
_fileNameIsUrl = true;
}
-void JSCodeGen::beginContextScope(const JSCodeGen::ObjectIdMapping &objectIds, QQmlPropertyCache *contextObject)
-{
- _idObjects = objectIds;
- _contextObject = contextObject;
- _scopeObject = nullptr;
-}
-
-void JSCodeGen::beginObjectScope(QQmlPropertyCache *scopeObject)
-{
- _scopeObject = scopeObject;
-}
-
QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<CompiledFunctionOrExpression> &functions)
{
auto qmlName = [&](const CompiledFunctionOrExpression &c) {
@@ -1918,7 +1898,6 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
body = body->finish();
}
- _disableAcceleratedLookups = qmlFunction.disableAcceleratedLookups;
int idx = defineFunction(name, function ? function : qmlFunction.parentNode,
function ? function->formals : nullptr,
body);
@@ -1928,392 +1907,6 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
return runtimeFunctionIndices;
}
-int JSCodeGen::defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, AST::StatementList *body)
-{
- int qmlContextTemp = -1;
- int importedScriptsTemp = -1;
- qSwap(_qmlContextSlot, qmlContextTemp);
- qSwap(_importedScriptsSlot, importedScriptsTemp);
-
- int result = Codegen::defineFunction(name, ast, formals, body);
-
- qSwap(_importedScriptsSlot, importedScriptsTemp);
- qSwap(_qmlContextSlot, qmlContextTemp);
-
- return result;
-}
-
-#ifndef V4_BOOTSTRAP
-QQmlPropertyData *JSCodeGen::lookupQmlCompliantProperty(QQmlPropertyCache *cache, const QString &name)
-{
- QQmlPropertyData *pd = cache->property(name, /*object*/nullptr, /*context*/nullptr);
-
- if (pd && !cache->isAllowedInRevision(pd))
- return nullptr;
-
- return pd;
-}
-
-enum MetaObjectResolverFlags {
- AllPropertiesAreFinal = 0x1,
- LookupsIncludeEnums = 0x2,
- LookupsExcludeProperties = 0x4,
- ResolveTypeInformationOnly = 0x8
-};
-
-#if 0
-static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlPropertyCache *metaObject);
-
-static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, const QQmlType &qmlType, int index);
-
-static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
- const QV4::IR::MemberExpressionResolver *resolver,
- QV4::IR::Member *member)
-{
- QV4::IR::Type result = QV4::IR::VarType;
-
- QQmlType type = resolver->qmlType;
-
- if (member->name->constData()->isUpper()) {
- bool ok = false;
- int value = type.enumValue(qmlEngine, *member->name, &ok);
- if (ok) {
- member->setEnumValue(value);
- return QV4::IR::SInt32Type;
- } else {
- int index = type.scopedEnumIndex(qmlEngine, *member->name, &ok);
- if (ok) {
- auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
- newResolver->owner = resolver->owner;
- initScopedEnumResolver(newResolver, type, index);
- return QV4::IR::DiscoveredType(newResolver);
- }
- }
- }
-
- if (type.isCompositeSingleton()) {
- QQmlRefPointer<QQmlTypeData> tdata = qmlEngine->typeLoader.getType(type.singletonInstanceInfo()->url);
- Q_ASSERT(tdata);
- tdata->release(); // Decrease the reference count added from QQmlTypeLoader::getType()
- // When a singleton tries to reference itself, it may not be complete yet.
- if (tdata->isComplete()) {
- auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
- newResolver->owner = resolver->owner;
- initMetaObjectResolver(newResolver, qmlEngine->propertyCacheForType(tdata->compilationUnit()->metaTypeId));
- newResolver->flags |= AllPropertiesAreFinal;
- return newResolver->resolveMember(qmlEngine, newResolver, member);
- }
- } else if (type.isSingleton()) {
- const QMetaObject *singletonMeta = type.singletonInstanceInfo()->instanceMetaObject;
- if (singletonMeta) { // QJSValue-based singletons cannot be accelerated
- auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
- newResolver->owner = resolver->owner;
- initMetaObjectResolver(newResolver, qmlEngine->cache(singletonMeta));
- member->kind = QV4::IR::Member::MemberOfSingletonObject;
- return newResolver->resolveMember(qmlEngine, newResolver, member);
- }
- }
-#if 0
- else if (const QMetaObject *attachedMeta = type->attachedPropertiesType(qmlEngine)) {
- // Right now the attached property IDs are not stable and cannot be embedded in the
- // code that is cached on disk.
- QQmlPropertyCache *cache = qmlEngine->cache(attachedMeta);
- auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
- newResolver->owner = resolver->owner;
- initMetaObjectResolver(newResolver, cache);
- member->setAttachedPropertiesId(type->attachedPropertiesId(qmlEngine));
- return newResolver->resolveMember(qmlEngine, newResolver, member);
- }
-#endif
-
- return result;
-}
-
-static void initQmlTypeResolver(QV4::IR::MemberExpressionResolver *resolver, const QQmlType &qmlType)
-{
- Q_ASSERT(resolver);
-
- resolver->resolveMember = &resolveQmlType;
- resolver->qmlType = qmlType;
- resolver->typenameCache = 0;
- resolver->flags = 0;
-}
-
-static QV4::IR::DiscoveredType resolveImportNamespace(
- QQmlEnginePrivate *, const QV4::IR::MemberExpressionResolver *resolver,
- QV4::IR::Member *member)
-{
- QV4::IR::Type result = QV4::IR::VarType;
- QQmlTypeNameCache *typeNamespace = resolver->typenameCache;
- const QQmlImportRef *importNamespace = resolver->import;
-
- QQmlTypeNameCache::Result r = typeNamespace->query(*member->name, importNamespace);
- if (r.isValid()) {
- member->freeOfSideEffects = true;
- if (r.scriptIndex != -1) {
- // TODO: remember the index and replace with subscript later.
- result = QV4::IR::VarType;
- } else if (r.type.isValid()) {
- // TODO: Propagate singleton information, so that it is loaded
- // through the singleton getter in the run-time. Until then we
- // can't accelerate access :(
- if (!r.type.isSingleton()) {
- auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
- newResolver->owner = resolver->owner;
- initQmlTypeResolver(newResolver, r.type);
- return QV4::IR::DiscoveredType(newResolver);
- }
- } else {
- Q_ASSERT(false); // How can this happen?
- }
- }
-
- return result;
-}
-
-static void initImportNamespaceResolver(QV4::IR::MemberExpressionResolver *resolver,
- QQmlTypeNameCache *imports, const QQmlImportRef *importNamespace)
-{
- resolver->resolveMember = &resolveImportNamespace;
- resolver->import = importNamespace;
- resolver->typenameCache = imports;
- resolver->flags = 0;
-}
-
-static QV4::IR::DiscoveredType resolveMetaObjectProperty(
- QQmlEnginePrivate *qmlEngine, const QV4::IR::MemberExpressionResolver *resolver,
- QV4::IR::Member *member)
-{
- QV4::IR::Type result = QV4::IR::VarType;
- QQmlPropertyCache *metaObject = resolver->propertyCache;
-
- if (member->name->constData()->isUpper() && (resolver->flags & LookupsIncludeEnums)) {
- const QMetaObject *mo = metaObject->createMetaObject();
- QByteArray enumName = member->name->toUtf8();
- for (int ii = mo->enumeratorCount() - 1; ii >= 0; --ii) {
- QMetaEnum metaEnum = mo->enumerator(ii);
- bool ok;
- int value = metaEnum.keyToValue(enumName.constData(), &ok);
- if (ok) {
- member->setEnumValue(value);
- return QV4::IR::SInt32Type;
- }
- }
- }
-
- if (member->kind != QV4::IR::Member::MemberOfIdObjectsArray && member->kind != QV4::IR::Member::MemberOfSingletonObject &&
- qmlEngine && !(resolver->flags & LookupsExcludeProperties)) {
- QQmlPropertyData *property = member->property;
- if (!property && metaObject) {
- if (QQmlPropertyData *candidate = metaObject->property(*member->name, /*object*/0, /*context*/0)) {
- const bool isFinalProperty = (candidate->isFinal() || (resolver->flags & AllPropertiesAreFinal))
- && !candidate->isFunction();
-
- if (lookupHints()
- && !(resolver->flags & AllPropertiesAreFinal)
- && !candidate->isFinal()
- && !candidate->isFunction()
- && candidate->isDirect()) {
- qWarning() << "Hint: Access to property" << *member->name << "of" << metaObject->className() << "could be accelerated if it was marked as FINAL";
- }
-
- if (isFinalProperty && metaObject->isAllowedInRevision(candidate)) {
- property = candidate;
- member->inhibitTypeConversionOnWrite = true;
- if (!(resolver->flags & ResolveTypeInformationOnly))
- member->property = candidate; // Cache for next iteration and isel needs it.
- }
- }
- }
-
- if (property) {
- // Enums cannot be mapped to IR types, they need to go through the run-time handling
- // of accepting strings that will then be converted to the right values.
- if (property->isEnum())
- return QV4::IR::VarType;
-
- switch (property->propType()) {
- case QMetaType::Bool: result = QV4::IR::BoolType; break;
- case QMetaType::Int: result = QV4::IR::SInt32Type; break;
- case QMetaType::Double: result = QV4::IR::DoubleType; break;
- case QMetaType::QString: result = QV4::IR::StringType; break;
- default:
- if (property->isQObject()) {
- if (QQmlPropertyCache *cache = qmlEngine->propertyCacheForType(property->propType())) {
- auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
- newResolver->owner = resolver->owner;
- initMetaObjectResolver(newResolver, cache);
- return QV4::IR::DiscoveredType(newResolver);
- }
- } else if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType())) {
- if (QQmlPropertyCache *cache = qmlEngine->cache(valueTypeMetaObject)) {
- auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
- newResolver->owner = resolver->owner;
- initMetaObjectResolver(newResolver, cache);
- newResolver->flags |= ResolveTypeInformationOnly;
- return QV4::IR::DiscoveredType(newResolver);
- }
- }
- break;
- }
- }
- }
-
- return result;
-}
-
-static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlPropertyCache *metaObject)
-{
- Q_ASSERT(resolver);
-
- resolver->resolveMember = &resolveMetaObjectProperty;
- resolver->propertyCache = metaObject;
- resolver->flags = 0;
-}
-
-static QV4::IR::DiscoveredType resolveScopedEnum(QQmlEnginePrivate *qmlEngine,
- const QV4::IR::MemberExpressionResolver *resolver,
- QV4::IR::Member *member)
-{
- if (!member->name->constData()->isUpper())
- return QV4::IR::VarType;
-
- QQmlType type = resolver->qmlType;
- int index = resolver->flags;
-
- bool ok = false;
- int value = type.scopedEnumValue(qmlEngine, index, *member->name, &ok);
- if (!ok)
- return QV4::IR::VarType;
- member->setEnumValue(value);
- return QV4::IR::SInt32Type;
-}
-
-static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, const QQmlType &qmlType, int index)
-{
- Q_ASSERT(resolver);
-
- resolver->resolveMember = &resolveScopedEnum;
- resolver->qmlType = qmlType;
- resolver->flags = index;
-}
-#endif
-
-#endif // V4_BOOTSTRAP
-
-void JSCodeGen::beginFunctionBodyHook()
-{
- _qmlContextSlot = bytecodeGenerator->newRegister();
- _importedScriptsSlot = bytecodeGenerator->newRegister();
-
-#ifndef V4_BOOTSTRAP
- Instruction::LoadQmlContext load;
- load.result = Reference::fromStackSlot(this, _qmlContextSlot).stackSlot();
- bytecodeGenerator->addInstruction(load);
-
-#if 0
- temp->type = QV4::IR::QObjectType;
- temp->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
- initMetaObjectResolver(temp->memberResolver, _scopeObject);
- auto name = _block->NAME(QV4::IR::Name::builtin_qml_context, 0, 0);
- name->type = temp->type;
-#endif
-
- Instruction::LoadQmlImportedScripts loadScripts;
- loadScripts.result = Reference::fromStackSlot(this, _importedScriptsSlot).stackSlot();
- bytecodeGenerator->addInstruction(loadScripts);
-#endif
-}
-
-QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &name)
-{
-#ifndef V4_BOOTSTRAP
- // FIXME: Remove this function.
- if (_disableAcceleratedLookups || true)
- return Reference();
-
- // Implement QML lookup semantics in the current file context.
- //
- // Note: We do not check if properties of the qml scope object or context object
- // are final. That's because QML tries to get as close as possible to lexical scoping,
- // which means in terms of properties that only those visible at compile time are chosen.
- // I.e. access to a "foo" property declared within the same QML component as "property int foo"
- // will always access that instance and as integer. If a sub-type implements its own property string foo,
- // then that one is not chosen for accesses from within this file, because it wasn't visible at compile
- // time. This corresponds to the logic in QQmlPropertyCache::findProperty to find the property associated
- // with the correct QML context.
-
- // Look for IDs first.
- for (const IdMapping &mapping : qAsConst(_idObjects)) {
- if (name == mapping.name) {
- if (_context->contextType == QV4::Compiler::ContextType::Binding)
- _context->idObjectDependencies.insert(mapping.idIndex);
-
- Instruction::LoadIdObject load;
- load.base = Reference::fromStackSlot(this, _qmlContextSlot).stackSlot();
- load.index = mapping.idIndex;
-
- Reference result = Reference::fromAccumulator(this);
- bytecodeGenerator->addInstruction(load);
- result.isReadonly = true;
- return result;
- }
- }
-
- if (name.at(0).isUpper()) {
- QQmlTypeNameCache::Result r = imports->query(name);
- if (r.isValid()) {
- if (r.scriptIndex != -1) {
- Reference imports = Reference::fromStackSlot(this, _importedScriptsSlot);
- return Reference::fromSubscript(imports, Reference::fromConst(this, QV4::Encode(r.scriptIndex)));
- } else if (r.type.isValid()) {
- return Reference::fromName(this, name);
- } else {
- Q_ASSERT(r.importNamespace);
- return Reference::fromName(this, name);
- }
- }
- }
-
- if (_scopeObject) {
- QQmlPropertyData *data = lookupQmlCompliantProperty(_scopeObject, name);
- if (data) {
- // Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
- if (data->isFunction())
- return Reference::fromName(this, name);
-
- Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
- Reference::PropertyCapturePolicy capturePolicy;
- if (!data->isConstant() && !data->isQmlBinding())
- capturePolicy = Reference::CaptureAtRuntime;
- else
- capturePolicy = data->isConstant() ? Reference::DontCapture : Reference::CaptureAheadOfTime;
- return Reference::fromQmlScopeObject(base, data->coreIndex(), data->notifyIndex(), capturePolicy);
- }
- }
-
- if (_contextObject) {
- QQmlPropertyData *data = lookupQmlCompliantProperty(_contextObject, name);
- if (data) {
- // Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
- if (data->isFunction())
- return Reference::fromName(this, name);
-
- Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
- Reference::PropertyCapturePolicy capturePolicy;
- if (!data->isConstant() && !data->isQmlBinding())
- capturePolicy = Reference::CaptureAtRuntime;
- else
- capturePolicy = data->isConstant() ? Reference::DontCapture : Reference::CaptureAheadOfTime;
- return Reference::fromQmlContextObject(base, data->coreIndex(), data->notifyIndex(), capturePolicy);
- }
- }
-#else
- Q_UNUSED(name)
-#endif // V4_BOOTSTRAP
- return Reference();
-}
-
#ifndef V4_BOOTSTRAP
QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision, RevisionCheck check) const
@@ -2433,7 +2026,6 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO
b->value.compiledScriptIndex = functionIndices.count() - 1;
QmlIR::CompiledFunctionOrExpression *foe = pool->New<QmlIR::CompiledFunctionOrExpression>();
- foe->disableAcceleratedLookups = true;
foe->nameIndex = 0;
QQmlJS::AST::ExpressionNode *expr;
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index 6affca3ca6..56724bcda5 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -345,7 +345,6 @@ struct Q_QML_PRIVATE_EXPORT CompiledFunctionOrExpression
QQmlJS::AST::Node *parentNode = nullptr; // FunctionDeclaration, Statement or Expression
QQmlJS::AST::Node *node = nullptr; // FunctionDeclaration, Statement or Expression
quint32 nameIndex = 0;
- bool disableAcceleratedLookups = false;
CompiledFunctionOrExpression *next = nullptr;
};
@@ -606,47 +605,16 @@ struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
{
JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator, QV4::Compiler::Module *jsModule,
QQmlJS::Engine *jsEngine, QQmlJS::AST::UiProgram *qmlRoot,
- QQmlTypeNameCache *imports, const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames);
-
- struct IdMapping
- {
- QString name;
- int idIndex;
- QQmlPropertyCache *type;
- };
- typedef QVector<IdMapping> ObjectIdMapping;
-
- void beginContextScope(const ObjectIdMapping &objectIds, QQmlPropertyCache *contextObject);
- void beginObjectScope(QQmlPropertyCache *scopeObject);
+ const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames);
// Returns mapping from input functions to index in IR::Module::functions / compiledData->runtimeFunctions
QVector<int> generateJSCodeForFunctionsAndBindings(const QList<CompiledFunctionOrExpression> &functions);
- int defineFunction(const QString &name, AST::Node *ast,
- AST::FormalParameterList *formals,
- AST::StatementList *body) override;
-
-protected:
- void beginFunctionBodyHook() override;
- bool canAccelerateGlobalLookups() const override { return !_disableAcceleratedLookups; }
- Reference fallbackNameLookup(const QString &name) override;
-
private:
- // returns nullptr if lookup needs to happen by name
- QQmlPropertyData *lookupQmlCompliantProperty(QQmlPropertyCache *cache, const QString &name);
-
QString sourceCode;
QQmlJS::Engine *jsEngine; // needed for memory pool
QQmlJS::AST::UiProgram *qmlRoot;
- QQmlTypeNameCache *imports;
const QV4::Compiler::StringTableGenerator *stringPool;
-
- bool _disableAcceleratedLookups;
- ObjectIdMapping _idObjects;
- QQmlPropertyCache *_contextObject;
- QQmlPropertyCache *_scopeObject;
- int _qmlContextSlot;
- int _importedScriptsSlot;
};
struct Q_QML_PRIVATE_EXPORT IRLoader {
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index f753c78b1a..66d3afc7a0 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -146,7 +146,7 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlTypeCompiler::compile()
document->jsModule.fileName = typeData->urlString();
document->jsModule.finalUrl = typeData->finalUrlString();
QmlIR::JSCodeGen v4CodeGenerator(document->code, &document->jsGenerator, &document->jsModule, &document->jsParserEngine,
- document->program, typeNameCache.data(), &document->jsGenerator.stringTable, engine->v8engine()->illegalNames());
+ document->program, &document->jsGenerator.stringTable, engine->v8engine()->illegalNames());
QQmlJSCodeGenerator jsCodeGen(this, &v4CodeGenerator);
if (!jsCodeGen.generateCodeForComponents())
return nullptr;
@@ -766,10 +766,6 @@ void QQmlScriptStringScanner::scan()
if (!pd || pd->propType() != scriptStringMetaType)
continue;
- QmlIR::CompiledFunctionOrExpression *foe = obj->functionsAndExpressions->slowAt(binding->value.compiledScriptIndex);
- if (foe)
- foe->disableAcceleratedLookups = true;
-
QString script = compiler->bindingAsString(obj, binding->value.compiledScriptIndex);
binding->stringIndex = compiler->registerString(script);
}
@@ -1323,24 +1319,6 @@ bool QQmlJSCodeGenerator::compileComponent(int contextObject)
contextObject = componentBinding->value.objectIndex;
}
- QmlIR::JSCodeGen::ObjectIdMapping idMapping;
- idMapping.reserve(obj->namedObjectsInComponent.count);
- for (int i = 0; i < obj->namedObjectsInComponent.count; ++i) {
- const int objectIndex = obj->namedObjectsInComponent.at(i);
- QmlIR::JSCodeGen::IdMapping m;
- const QmlIR::Object *obj = qmlObjects.at(objectIndex);
- m.name = stringAt(obj->idNameIndex);
- m.idIndex = obj->id;
- m.type = propertyCaches->at(objectIndex);
-
- auto *tref = resolvedType(obj->inheritedTypeNameIndex);
- if (tref && tref->isFullyDynamicType)
- m.type = nullptr;
-
- idMapping << m;
- }
- v4CodeGen->beginContextScope(idMapping, propertyCaches->at(contextObject));
-
if (!compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject))
return false;
@@ -1354,16 +1332,9 @@ bool QQmlJSCodeGenerator::compileJavaScriptCodeInObjectsRecursively(int objectIn
return true;
if (object->functionsAndExpressions->count > 0) {
- QQmlPropertyCache *scopeObject = propertyCaches->at(scopeObjectIndex);
- v4CodeGen->beginObjectScope(scopeObject);
-
QList<QmlIR::CompiledFunctionOrExpression> functionsToCompile;
- for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; foe = foe->next) {
- const bool haveCustomParser = customParsers.contains(object->inheritedTypeNameIndex);
- if (haveCustomParser)
- foe->disableAcceleratedLookups = true;
+ for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; foe = foe->next)
functionsToCompile << *foe;
- }
const QVector<int> runtimeFunctionIndices = v4CodeGen->generateJSCodeForFunctionsAndBindings(functionsToCompile);
const QList<QQmlError> jsErrors = v4CodeGen->qmlErrors();
if (!jsErrors.isEmpty()) {
diff --git a/src/qml/compiler/qv4bytecodehandler.cpp b/src/qml/compiler/qv4bytecodehandler.cpp
index a34472010b..e1fc0c6ee3 100644
--- a/src/qml/compiler/qv4bytecodehandler.cpp
+++ b/src/qml/compiler/qv4bytecodehandler.cpp
@@ -225,21 +225,6 @@ std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint
COLLECTOR_BEGIN_INSTR(StoreSuperProperty)
COLLECTOR_END_INSTR(StoreSuperProperty)
- COLLECTOR_BEGIN_INSTR(StoreScopeObjectProperty)
- COLLECTOR_END_INSTR(StoreScopeObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(LoadScopeObjectProperty)
- COLLECTOR_END_INSTR(LoadScopeObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(StoreContextObjectProperty)
- COLLECTOR_END_INSTR(StoreContextObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(LoadContextObjectProperty)
- COLLECTOR_END_INSTR(LoadContextObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(LoadIdObject)
- COLLECTOR_END_INSTR(LoadIdObject)
-
COLLECTOR_BEGIN_INSTR(Yield)
COLLECTOR_END_INSTR(Yield)
@@ -276,12 +261,6 @@ std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint
COLLECTOR_BEGIN_INSTR(CallQmlContextPropertyLookup)
COLLECTOR_END_INSTR(CallQmlContextPropertyLookup)
- COLLECTOR_BEGIN_INSTR(CallScopeObjectProperty)
- COLLECTOR_END_INSTR(CallScopeObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(CallContextObjectProperty)
- COLLECTOR_END_INSTR(CallContextObjectProperty)
-
COLLECTOR_BEGIN_INSTR(CallWithSpread)
COLLECTOR_END_INSTR(CallWithSpread)
@@ -546,12 +525,6 @@ std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint
COLLECTOR_BEGIN_INSTR(GetTemplateObject)
COLLECTOR_END_INSTR(GetTemplateObject)
- COLLECTOR_BEGIN_INSTR(LoadQmlContext)
- COLLECTOR_END_INSTR(LoadQmlContext)
-
- COLLECTOR_BEGIN_INSTR(LoadQmlImportedScripts)
- COLLECTOR_END_INSTR(LoadQmlImportedScripts)
-
COLLECTOR_BEGIN_INSTR(TailCall)
COLLECTOR_END_INSTR(TailCall)
}
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index de87d6d48c..b0bec5b6f2 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1875,8 +1875,6 @@ bool Codegen::visit(CallExpression *ast)
switch (base.type) {
case Reference::Member:
case Reference::Subscript:
- case Reference::QmlScopeObject:
- case Reference::QmlContextObject:
base = base.asLValue();
break;
case Reference::Name:
@@ -1938,21 +1936,7 @@ bool Codegen::visit(CallExpression *ast)
void Codegen::handleCall(Reference &base, Arguments calldata, int slotForFunction, int slotForThisObject)
{
//### Do we really need all these call instructions? can's we load the callee in a temp?
- if (base.type == Reference::QmlScopeObject) {
- Instruction::CallScopeObjectProperty call;
- call.base = base.qmlBase.stackSlot();
- call.name = base.qmlCoreIndex;
- call.argc = calldata.argc;
- call.argv = calldata.argv;
- bytecodeGenerator->addInstruction(call);
- } else if (base.type == Reference::QmlContextObject) {
- Instruction::CallContextObjectProperty call;
- call.base = base.qmlBase.stackSlot();
- call.name = base.qmlCoreIndex;
- call.argc = calldata.argc;
- call.argv = calldata.argv;
- bytecodeGenerator->addInstruction(call);
- } else if (base.type == Reference::Member) {
+ if (base.type == Reference::Member) {
if (!disable_lookups && useFastLookups) {
Instruction::CallPropertyLookup call;
call.base = base.propertyBase.stackSlot();
@@ -2363,11 +2347,6 @@ Codegen::Reference Codegen::referenceForName(const QString &name, bool isLhs, co
return r;
}
- // This hook allows implementing QML lookup semantics
- Reference fallback = fallbackNameLookup(name);
- if (fallback.type != Reference::Invalid)
- return fallback;
-
Reference r = Reference::fromName(this, name);
r.global = useFastLookups && (resolved.type == Context::ResolvedName::Global || resolved.type == Context::ResolvedName::QmlGlobal);
r.qmlGlobal = resolved.type == Context::ResolvedName::QmlGlobal;
@@ -2387,12 +2366,6 @@ void Codegen::loadClosure(int closureId)
}
}
-Codegen::Reference Codegen::fallbackNameLookup(const QString &name)
-{
- Q_UNUSED(name)
- return Reference();
-}
-
bool Codegen::visit(IdentifierExpression *ast)
{
if (hasError)
@@ -3101,8 +3074,6 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
bytecodeGenerator->addInstruction(yield);
}
- beginFunctionBodyHook();
-
statementList(body);
if (!hasError) {
@@ -4039,10 +4010,6 @@ bool Codegen::Reference::operator==(const Codegen::Reference &other) const
return index == other.index;
case Const:
return constant == other.constant;
- case QmlScopeObject:
- case QmlContextObject:
- return qmlCoreIndex == other.qmlCoreIndex && qmlNotifyIndex == other.qmlNotifyIndex
- && capturePolicy == other.capturePolicy;
}
return true;
}
@@ -4100,9 +4067,7 @@ Codegen::Reference Codegen::Reference::storeConsumeAccumulator() const
Codegen::Reference Codegen::Reference::baseObject() const
{
- if (type == Reference::QmlScopeObject || type == Reference::QmlContextObject) {
- return Reference::fromStackSlot(codegen, qmlBase.stackSlot());
- } else if (type == Reference::Member) {
+ if (type == Reference::Member) {
RValue rval = propertyBase;
if (!rval.isValid())
return Reference::fromConst(codegen, Encode::undefined());
@@ -4187,8 +4152,6 @@ bool Codegen::Reference::storeWipesAccumulator() const
case Name:
case Member:
case Subscript:
- case QmlScopeObject:
- case QmlContextObject:
return true;
}
}
@@ -4268,18 +4231,6 @@ void Codegen::Reference::storeAccumulator() const
store.index = elementSubscript.stackSlot();
codegen->bytecodeGenerator->addInstruction(store);
} return;
- case QmlScopeObject: {
- Instruction::StoreScopeObjectProperty store;
- store.base = qmlBase;
- store.propertyIndex = qmlCoreIndex;
- codegen->bytecodeGenerator->addInstruction(store);
- } return;
- case QmlContextObject: {
- Instruction::StoreContextObjectProperty store;
- store.base = qmlBase;
- store.propertyIndex = qmlCoreIndex;
- codegen->bytecodeGenerator->addInstruction(store);
- } return;
case Invalid:
case Accumulator:
case Const:
@@ -4436,24 +4387,6 @@ QT_WARNING_POP
load.base = elementBase;
codegen->bytecodeGenerator->addInstruction(load);
} return;
- case QmlScopeObject: {
- Instruction::LoadScopeObjectProperty load;
- load.base = qmlBase;
- load.propertyIndex = qmlCoreIndex;
- load.captureRequired = capturePolicy == CaptureAtRuntime;
- codegen->bytecodeGenerator->addInstruction(load);
- if (capturePolicy == CaptureAheadOfTime)
- codegen->_context->scopeObjectPropertyDependencies.insert(qmlCoreIndex, qmlNotifyIndex);
- } return;
- case QmlContextObject: {
- Instruction::LoadContextObjectProperty load;
- load.base = qmlBase;
- load.propertyIndex = qmlCoreIndex;
- load.captureRequired = capturePolicy == CaptureAtRuntime;
- codegen->bytecodeGenerator->addInstruction(load);
- if (capturePolicy == CaptureAheadOfTime)
- codegen->_context->contextObjectPropertyDependencies.insert(qmlCoreIndex, qmlNotifyIndex);
- } return;
case Invalid:
break;
}
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index b1cc4c090a..ad86483132 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -184,9 +184,7 @@ public:
Member,
Subscript,
Import,
- QmlScopeObject,
- QmlContextObject,
- LastLValue = QmlContextObject,
+ LastLValue = Import,
Const
} type = Invalid;
@@ -223,10 +221,6 @@ public:
bool isValid() const { return type != Invalid; }
bool loadTriggersSideEffect() const {
switch (type) {
- case QmlScopeObject:
- return capturePolicy != DontCapture;
- case QmlContextObject:
- return capturePolicy != DontCapture;
case Name:
case Member:
case Subscript:
@@ -245,28 +239,6 @@ public:
return isStackSlot();
}
- enum PropertyCapturePolicy {
- /*
- We're reading a property from the scope or context object, but it's a CONSTANT property,
- so we don't need to register a dependency at all.
- */
- DontCapture,
- /*
- We're reading the property of a QObject, and we know that it's the
- scope object or context object, which we know very well. Instead of registering a
- property capture every time, we can do that ahead of time and then register all those
- captures in one shot in registerQmlDependencies().
- */
- CaptureAheadOfTime,
- /*
- We're reading the property of a QObject, and we're not quite sure where
- the QObject comes from or what it is. So, when reading that property at run-time,
- make sure that we capture where we read that property so that if it changes we can
- re-evaluate the entire expression.
- */
- CaptureAtRuntime
- };
-
static Reference fromAccumulator(Codegen *cg) {
return Reference(cg, Accumulator);
}
@@ -333,22 +305,6 @@ public:
r.isReadonly = true;
return r;
}
- static Reference fromQmlScopeObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, PropertyCapturePolicy capturePolicy) {
- Reference r(base.codegen, QmlScopeObject);
- r.qmlBase = base.storeOnStack().stackSlot();
- r.qmlCoreIndex = coreIndex;
- r.qmlNotifyIndex = notifyIndex;
- r.capturePolicy = capturePolicy;
- return r;
- }
- static Reference fromQmlContextObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, PropertyCapturePolicy capturePolicy) {
- Reference r(base.codegen, QmlContextObject);
- r.qmlBase = base.storeOnStack().stackSlot();
- r.qmlCoreIndex = coreIndex;
- r.qmlNotifyIndex = notifyIndex;
- r.capturePolicy = capturePolicy;
- return r;
- }
static Reference fromThis(Codegen *cg) {
Reference r = fromStackSlot(cg, CallData::This);
r.isReadonly = true;
@@ -403,12 +359,6 @@ public:
Moth::StackSlot elementBase;
RValue elementSubscript;
};
- struct { // QML scope/context object case
- Moth::StackSlot qmlBase;
- qint16 qmlCoreIndex;
- qint16 qmlNotifyIndex;
- PropertyCapturePolicy capturePolicy;
- };
Moth::StackSlot property; // super property
};
QString name;
@@ -598,12 +548,6 @@ protected:
Reference referenceForPropertyName(const Codegen::Reference &object, AST::PropertyName *name);
- // Hooks provided to implement QML lookup semantics
- virtual bool canAccelerateGlobalLookups() const { return true; }
- virtual Reference fallbackNameLookup(const QString &name);
-
- virtual void beginFunctionBodyHook() {}
-
void emitReturn(const Reference &expr);
// nodes
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index d63b1fd2b9..1341c91e97 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -73,7 +73,7 @@
QT_BEGIN_NAMESPACE
// Bump this whenever the compiler data structures change in an incompatible way.
-#define QV4_DATA_STRUCTURE_VERSION 0x19
+#define QV4_DATA_STRUCTURE_VERSION 0x20
class QIODevice;
class QQmlPropertyCache;
@@ -288,21 +288,10 @@ struct Function
quint16_le nRegisters;
Location location;
- // Qml Extensions Begin
- // Array of resolved ID objects
- size_t dependingIdObjectsOffset() const { return lineNumberOffset() + nLineNumbers * sizeof(CodeOffsetToLine); }
- quint16_le nDependingIdObjects;
- quint16_le nDependingContextProperties;
- // Array of int pairs (property index and notify index)
- size_t dependingContextPropertiesOffset() const { return dependingIdObjectsOffset() + nDependingIdObjects * sizeof(quint32); }
- quint16_le nDependingScopeProperties;
- // Array of int pairs (property index and notify index)
- size_t dependingScopePropertiesOffset() const { return dependingContextPropertiesOffset() + nDependingContextProperties * sizeof(quint32); }
- // Qml Extensions End
-
// Keep all unaligned data at the end
quint8 flags;
quint8 padding1;
+ quint16 padding2;
// quint32 formalsIndex[nFormals]
// quint32 localsIndex[nLocals]
@@ -310,9 +299,6 @@ struct Function
const quint32_le *formalsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + formalsOffset); }
const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); }
const CodeOffsetToLine *lineNumberTable() const { return reinterpret_cast<const CodeOffsetToLine *>(reinterpret_cast<const char *>(this) + lineNumberOffset()); }
- const quint32_le *qmlIdObjectDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingIdObjectsOffset()); }
- const quint32_le *qmlContextPropertiesDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingContextPropertiesOffset()); }
- const quint32_le *qmlScopePropertiesDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingScopePropertiesOffset()); }
// --- QQmlPropertyCacheCreator interface
const quint32_le *formalsBegin() const { return formalsTable(); }
@@ -321,11 +307,8 @@ struct Function
const char *code() const { return reinterpret_cast<const char *>(this) + codeOffset; }
- inline bool hasQmlDependencies() const { return nDependingIdObjects > 0 || nDependingContextProperties > 0 || nDependingScopeProperties > 0; }
-
- static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies, int codeSize) {
- int trailingData = (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies +
- 2 * nPropertyDependencies)*sizeof (quint32) + nLines*sizeof(CodeOffsetToLine);
+ static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int codeSize) {
+ int trailingData = (nFormals + nLocals + nInnerfunctions)*sizeof (quint32) + nLines*sizeof(CodeOffsetToLine);
size_t size = align(align(sizeof(Function)) + size_t(trailingData)) + align(codeSize);
Q_ASSERT(size < INT_MAX);
return int(size);
@@ -335,7 +318,7 @@ struct Function
return (a + 7) & ~size_t(7);
}
};
-static_assert(sizeof(Function) == 52, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Function) == 48, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Method {
enum Type {
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index a3c9347c67..4d85f25d4b 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -427,28 +427,6 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
function->nRegisters = irFunction->registerCountInFunction;
- function->nDependingIdObjects = 0;
- function->nDependingContextProperties = 0;
- function->nDependingScopeProperties = 0;
-
- if (!irFunction->idObjectDependencies.isEmpty()) {
- function->nDependingIdObjects = irFunction->idObjectDependencies.count();
- Q_ASSERT(function->dependingIdObjectsOffset() == currentOffset);
- currentOffset += function->nDependingIdObjects * sizeof(quint32);
- }
-
- if (!irFunction->contextObjectPropertyDependencies.isEmpty()) {
- function->nDependingContextProperties = irFunction->contextObjectPropertyDependencies.count();
- Q_ASSERT(function->dependingContextPropertiesOffset() == currentOffset);
- currentOffset += function->nDependingContextProperties * sizeof(quint32) * 2;
- }
-
- if (!irFunction->scopeObjectPropertyDependencies.isEmpty()) {
- function->nDependingScopeProperties = irFunction->scopeObjectPropertyDependencies.count();
- Q_ASSERT(function->dependingScopePropertiesOffset() == currentOffset);
- currentOffset += function->nDependingScopeProperties * sizeof(quint32) * 2;
- }
-
function->location.line = irFunction->line;
function->location.column = irFunction->column;
@@ -468,25 +446,6 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
// write line numbers
memcpy(f + function->lineNumberOffset(), irFunction->lineNumberMapping.constData(), irFunction->lineNumberMapping.size()*sizeof(CompiledData::CodeOffsetToLine));
- // write QML dependencies
- quint32_le *writtenDeps = (quint32_le *)(f + function->dependingIdObjectsOffset());
- for (int id : irFunction->idObjectDependencies) {
- Q_ASSERT(id >= 0);
- *writtenDeps++ = static_cast<quint32>(id);
- }
-
- writtenDeps = (quint32_le *)(f + function->dependingContextPropertiesOffset());
- for (auto property : irFunction->contextObjectPropertyDependencies) {
- *writtenDeps++ = property.key(); // property index
- *writtenDeps++ = property.value(); // notify index
- }
-
- writtenDeps = (quint32_le *)(f + function->dependingScopePropertiesOffset());
- for (auto property : irFunction->scopeObjectPropertyDependencies) {
- *writtenDeps++ = property.key(); // property index
- *writtenDeps++ = property.value(); // notify index
- }
-
// write byte code
memcpy(f + function->codeOffset, irFunction->code.constData(), irFunction->code.size());
}
@@ -683,10 +642,8 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
Context *f = module->functions.at(i);
blockAndFunctionOffsets[i] = nextOffset;
- const int qmlIdDepsCount = f->idObjectDependencies.count();
- const int qmlPropertyDepsCount = f->scopeObjectPropertyDependencies.count() + f->contextObjectPropertyDependencies.count();
quint32 size = QV4::CompiledData::Function::calculateSize(f->arguments.size(), f->locals.size(), f->lineNumberMapping.size(), f->nestedContexts.size(),
- qmlIdDepsCount, qmlPropertyDepsCount, f->code.size());
+ f->code.size());
functionSize += size - f->code.size();
nextOffset += size;
}
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index c9e54c0d1b..8f3b60e395 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -276,11 +276,6 @@ struct Context {
}
};
- // Qml extension:
- SmallSet<int> idObjectDependencies;
- PropertyDependencyMap contextObjectPropertyDependencies;
- PropertyDependencyMap scopeObjectPropertyDependencies;
-
Context(Context *parent, ContextType type)
: parent(parent)
, contextType(type)
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index d2e95b83c4..c6c8caffba 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -330,26 +330,6 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << dumpRegister(property, nFormals);
MOTH_END_INSTR(StoreSuperProperty)
- MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
- d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]";
- MOTH_END_INSTR(StoreScopeObjectProperty)
-
- MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
- d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]" << (captureRequired ? " (capture)" : " (no capture)");
- MOTH_END_INSTR(LoadScopeObjectProperty)
-
- MOTH_BEGIN_INSTR(StoreContextObjectProperty)
- d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]";
- MOTH_END_INSTR(StoreContextObjectProperty)
-
- MOTH_BEGIN_INSTR(LoadContextObjectProperty)
- d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]" << (captureRequired ? " (capture)" : " (no capture)");
- MOTH_END_INSTR(LoadContextObjectProperty)
-
- MOTH_BEGIN_INSTR(LoadIdObject)
- d << dumpRegister(base, nFormals) << "[" << index << "]";
- MOTH_END_INSTR(LoadIdObject)
-
MOTH_BEGIN_INSTR(Yield)
MOTH_END_INSTR(Yield)
@@ -396,14 +376,6 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << index << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(CallQmlContextPropertyLookup)
- MOTH_BEGIN_INSTR(CallScopeObjectProperty)
- d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals);
- MOTH_END_INSTR(CallScopeObjectProperty)
-
- MOTH_BEGIN_INSTR(CallContextObjectProperty)
- d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals);
- MOTH_END_INSTR(CallContextObjectProperty)
-
MOTH_BEGIN_INSTR(CallWithSpread)
d << "new" << dumpRegister(func, nFormals) << dumpRegister(thisObject, nFormals) << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(CallWithSpread)
@@ -724,14 +696,6 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << index;
MOTH_END_INSTR(GetTemplateObject)
- MOTH_BEGIN_INSTR(LoadQmlContext)
- d << dumpRegister(result, nFormals);
- MOTH_END_INSTR(LoadQmlContext)
-
- MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
- d << dumpRegister(result, nFormals);
- MOTH_END_INSTR(LoadQmlImportedScripts)
-
MOTH_BEGIN_INSTR(TailCall)
d << dumpRegister(func, nFormals) << dumpRegister(thisObject, nFormals) << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(TailCall)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 1c77e6050c..25fca3c0b0 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -91,8 +91,6 @@ QT_BEGIN_NAMESPACE
#define INSTR_StoreNameStrict(op) INSTRUCTION(op, StoreNameStrict, 1, name)
#define INSTR_LoadProperty(op) INSTRUCTION(op, LoadProperty, 1, name)
#define INSTR_GetLookup(op) INSTRUCTION(op, GetLookup, 1, index)
-#define INSTR_LoadScopeObjectProperty(op) INSTRUCTION(op, LoadScopeObjectProperty, 3, propertyIndex, base, captureRequired)
-#define INSTR_LoadContextObjectProperty(op) INSTRUCTION(op, LoadContextObjectProperty, 3, propertyIndex, base, captureRequired)
#define INSTR_LoadIdObject(op) INSTRUCTION(op, LoadIdObject, 2, index, base)
#define INSTR_Yield(op) INSTRUCTION(op, Yield, 0)
#define INSTR_YieldStar(op) INSTRUCTION(op, YieldStar, 0)
@@ -102,8 +100,6 @@ QT_BEGIN_NAMESPACE
#define INSTR_SetLookup(op) INSTRUCTION(op, SetLookup, 2, index, base)
#define INSTR_LoadSuperProperty(op) INSTRUCTION(op, LoadSuperProperty, 1, property)
#define INSTR_StoreSuperProperty(op) INSTRUCTION(op, StoreSuperProperty, 1, property)
-#define INSTR_StoreScopeObjectProperty(op) INSTRUCTION(op, StoreScopeObjectProperty, 2, base, propertyIndex)
-#define INSTR_StoreContextObjectProperty(op) INSTRUCTION(op, StoreContextObjectProperty, 2, base, propertyIndex)
#define INSTR_LoadElement(op) INSTRUCTION(op, LoadElement, 1, base)
#define INSTR_StoreElement(op) INSTRUCTION(op, StoreElement, 2, base, index)
#define INSTR_CallValue(op) INSTRUCTION(op, CallValue, 3, name, argc, argv)
@@ -115,8 +111,6 @@ QT_BEGIN_NAMESPACE
#define INSTR_CallPossiblyDirectEval(op) INSTRUCTION(op, CallPossiblyDirectEval, 2, argc, argv)
#define INSTR_CallGlobalLookup(op) INSTRUCTION(op, CallGlobalLookup, 3, index, argc, argv)
#define INSTR_CallQmlContextPropertyLookup(op) INSTRUCTION(op, CallQmlContextPropertyLookup, 3, index, argc, argv)
-#define INSTR_CallScopeObjectProperty(op) INSTRUCTION(op, CallScopeObjectProperty, 4, name, base, argc, argv)
-#define INSTR_CallContextObjectProperty(op) INSTRUCTION(op, CallContextObjectProperty, 4, name, base, argc, argv)
#define INSTR_CallWithSpread(op) INSTRUCTION(op, CallWithSpread, 4, func, thisObject, argc, argv)
#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3, func, argc, argv)
#define INSTR_ConstructWithSpread(op) INSTRUCTION(op, ConstructWithSpread, 3, func, argc, argv)
@@ -196,7 +190,6 @@ QT_BEGIN_NAMESPACE
#define INSTR_Div(op) INSTRUCTION(op, Div, 1, lhs)
#define INSTR_Mod(op) INSTRUCTION(op, Mod, 1, lhs)
#define INSTR_Sub(op) INSTRUCTION(op, Sub, 1, lhs)
-#define INSTR_LoadQmlContext(op) INSTRUCTION(op, LoadQmlContext, 1, result)
#define INSTR_LoadQmlImportedScripts(op) INSTRUCTION(op, LoadQmlImportedScripts, 1, result)
#define INSTR_InitializeBlockDeadTemporalZone(op) INSTRUCTION(op, InitializeBlockDeadTemporalZone, 2, firstReg, count)
#define INSTR_ThrowOnNullOrUndefined(op) INSTRUCTION(op, ThrowOnNullOrUndefined, 0)
@@ -241,11 +234,6 @@ QT_BEGIN_NAMESPACE
F(SetLookup) \
F(LoadSuperProperty) \
F(StoreSuperProperty) \
- F(StoreScopeObjectProperty) \
- F(StoreContextObjectProperty) \
- F(LoadScopeObjectProperty) \
- F(LoadContextObjectProperty) \
- F(LoadIdObject) \
F(ConvertThisToObject) \
F(ToObject) \
F(Jump) \
@@ -300,8 +288,6 @@ QT_BEGIN_NAMESPACE
F(CallPossiblyDirectEval) \
F(CallGlobalLookup) \
F(CallQmlContextPropertyLookup) \
- F(CallScopeObjectProperty) \
- F(CallContextObjectProperty) \
F(CallWithSpread) \
F(Construct) \
F(ConstructWithSpread) \
@@ -332,8 +318,6 @@ QT_BEGIN_NAMESPACE
F(CreateMappedArgumentsObject) \
F(CreateUnmappedArgumentsObject) \
F(CreateRestParameter) \
- F(LoadQmlContext) \
- F(LoadQmlImportedScripts) \
F(Yield) \
F(YieldStar) \
F(Resume) \
diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp
index 47cef3b3bd..1e4288e3c9 100644
--- a/src/qml/jit/qv4baselinejit.cpp
+++ b/src/qml/jit/qv4baselinejit.cpp
@@ -347,66 +347,6 @@ void BaselineJIT::generate_StoreSuperProperty(int property)
as->checkException();
}
-
-void BaselineJIT::generate_StoreScopeObjectProperty(int base, int propertyIndex)
-{
- STORE_ACC();
- as->prepareCallWithArgCount(4);
- as->passAccumulatorAsArg(3);
- as->passInt32AsArg(propertyIndex, 2);
- as->passJSSlotAsArg(base, 1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeQmlScopeObjectProperty, CallResultDestination::Ignore);
- as->checkException();
-}
-
-void BaselineJIT::generate_StoreContextObjectProperty(int base, int propertyIndex)
-{
- STORE_ACC();
- as->prepareCallWithArgCount(4);
- as->passAccumulatorAsArg(3);
- as->passInt32AsArg(propertyIndex, 2);
- as->passJSSlotAsArg(base, 1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeQmlContextObjectProperty, CallResultDestination::Ignore);
- as->checkException();
-}
-
-void BaselineJIT::generate_LoadScopeObjectProperty(int propertyIndex, int base, int captureRequired)
-{
- STORE_IP();
- as->prepareCallWithArgCount(4);
- as->passInt32AsArg(captureRequired, 3);
- as->passInt32AsArg(propertyIndex, 2);
- as->passJSSlotAsArg(base, 1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlScopeObjectProperty, CallResultDestination::InAccumulator);
- as->checkException();
-}
-
-void BaselineJIT::generate_LoadContextObjectProperty(int propertyIndex, int base, int captureRequired)
-{
- STORE_IP();
- as->prepareCallWithArgCount(4);
- as->passInt32AsArg(captureRequired, 3);
- as->passInt32AsArg(propertyIndex, 2);
- as->passJSSlotAsArg(base, 1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlContextObjectProperty, CallResultDestination::InAccumulator);
- as->checkException();
-}
-
-void BaselineJIT::generate_LoadIdObject(int index, int base)
-{
- STORE_IP();
- as->prepareCallWithArgCount(3);
- as->passInt32AsArg(index, 2);
- as->passJSSlotAsArg(base, 1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlIdObject, CallResultDestination::InAccumulator);
- as->checkException();
-}
-
void BaselineJIT::generate_Yield()
{
// #####
@@ -536,33 +476,6 @@ void BaselineJIT::generate_CallQmlContextPropertyLookup(int index, int argc, int
as->checkException();
}
-void BaselineJIT::generate_CallScopeObjectProperty(int propIdx, int base, int argc, int argv)
-{
- STORE_IP();
- as->prepareCallWithArgCount(5);
- as->passInt32AsArg(argc, 4);
- as->passJSSlotAsArg(argv, 3);
- as->passInt32AsArg(propIdx, 2);
- as->passJSSlotAsArg(base, 1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlScopeObjectProperty, CallResultDestination::InAccumulator);
- as->checkException();
-}
-
-void BaselineJIT::generate_CallContextObjectProperty(int propIdx, int base, int argc, int argv)
-{
- STORE_IP();
- as->prepareCallWithArgCount(5);
- as->passInt32AsArg(argc, 4);
- as->passJSSlotAsArg(argv, 3);
- as->passInt32AsArg(propIdx, 2);
- as->passJSSlotAsArg(base, 1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlContextObjectProperty, CallResultDestination::InAccumulator);
- as->checkException();
-}
-
-
void BaselineJIT::generate_CallWithSpread(int func, int thisObject, int argc, int argv)
{
STORE_IP();
@@ -981,22 +894,6 @@ void BaselineJIT::generate_Sub(int lhs) { as->sub(lhs); }
// as->checkException();
//}
-void BaselineJIT::generate_LoadQmlContext(int result)
-{
- as->prepareCallWithArgCount(1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlContext, CallResultDestination::InAccumulator);
- as->storeReg(result);
-}
-
-void BaselineJIT::generate_LoadQmlImportedScripts(int result)
-{
- as->prepareCallWithArgCount(1);
- as->passEngineAsArg(0);
- BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlImportedScripts, CallResultDestination::InAccumulator);
- as->storeReg(result);
-}
-
void BaselineJIT::generate_InitializeBlockDeadTemporalZone(int firstReg, int count)
{
as->loadValue(Value::emptyValue().rawValue());
diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h
index 4db1eb1806..6646eb713e 100644
--- a/src/qml/jit/qv4baselinejit_p.h
+++ b/src/qml/jit/qv4baselinejit_p.h
@@ -108,15 +108,6 @@ public:
void generate_SetLookup(int index, int base) override;
void generate_LoadSuperProperty(int property) override;
void generate_StoreSuperProperty(int property) override;
- void generate_StoreScopeObjectProperty(int base,
- int propertyIndex) override;
- void generate_StoreContextObjectProperty(int base,
- int propertyIndex) override;
- void generate_LoadScopeObjectProperty(int propertyIndex, int base,
- int captureRequired) override;
- void generate_LoadContextObjectProperty(int propertyIndex, int base,
- int captureRequired) override;
- void generate_LoadIdObject(int index, int base) override;
void generate_Yield() override;
void generate_YieldStar() override;
void generate_Resume(int) override;
@@ -130,8 +121,6 @@ public:
void generate_CallPossiblyDirectEval(int argc, int argv) override;
void generate_CallGlobalLookup(int index, int argc, int argv) override;
void generate_CallQmlContextPropertyLookup(int index, int argc, int argv) override;
- void generate_CallScopeObjectProperty(int propIdx, int base, int argc, int argv) override;
- void generate_CallContextObjectProperty(int propIdx, int base, int argc, int argv) override;
void generate_CallWithSpread(int func, int thisObject, int argc, int argv) override;
void generate_TailCall(int func, int thisObject, int argc, int argv) override;
void generate_Construct(int func, int argc, int argv) override;
@@ -213,8 +202,6 @@ public:
void generate_Div(int lhs) override;
void generate_Mod(int lhs) override;
void generate_Sub(int lhs) override;
- void generate_LoadQmlContext(int result) override;
- void generate_LoadQmlImportedScripts(int result) override;
void generate_InitializeBlockDeadTemporalZone(int firstReg, int count) override;
void generate_ThrowOnNullOrUndefined() override;
void generate_GetTemplateObject(int index) override;
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 941c37de5b..51a9b92967 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -78,7 +78,6 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
, codeData(function->code())
, jittedCode(nullptr)
, codeRef(nullptr)
- , hasQmlDependencies(function->hasQmlDependencies())
{
Scope scope(engine);
Scoped<InternalClass> ic(scope, engine->internalClasses(EngineBase::Class_CallContext));
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 029dd7786b..62c5d24fc4 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -80,7 +80,6 @@ struct Q_QML_EXPORT Function {
Heap::InternalClass *internalClass;
uint nFormals;
int interpreterCallCount = 0;
- bool hasQmlDependencies;
bool isEval = false;
Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 711c910906..053581226f 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -233,7 +233,7 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QObject
return result;
}
-ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property, bool captureRequired)
+ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property)
{
QQmlData::flushPendingBinding(object, QQmlPropertyIndex(property->coreIndex()));
@@ -259,7 +259,7 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje
QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : nullptr;
- if (captureRequired && ep && ep->propertyCapture && !property->isConstant())
+ if (ep && ep->propertyCapture && !property->isConstant())
ep->propertyCapture->captureProperty(object, property->coreIndex(), property->notifyIndex());
if (property->isVarProperty()) {
@@ -357,26 +357,6 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String
return getProperty(v4, d()->object(), result);
}
-ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, bool captureRequired)
-{
- if (QQmlData::wasDeleted(object))
- return QV4::Encode::null();
- QQmlData *ddata = QQmlData::get(object, /*create*/false);
- if (!ddata)
- return QV4::Encode::undefined();
-
- if (Q_UNLIKELY(!ddata->propertyCache)) {
- ddata->propertyCache = QQmlEnginePrivate::get(engine)->cache(object->metaObject());
- ddata->propertyCache->addref();
- }
-
- QQmlPropertyCache *cache = ddata->propertyCache;
- Q_ASSERT(cache);
- QQmlPropertyData *property = cache->property(propertyIndex);
- Q_ASSERT(property); // We resolved this property earlier, so it better exist!
- return getProperty(engine, object, property, captureRequired);
-}
-
ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty)
{
if (QQmlData::wasDeleted(object)) {
@@ -873,7 +853,7 @@ ReturnedValue QObjectWrapper::virtualResolveLookupGetter(const Object *object, E
if (!ddata || !ddata->propertyCache) {
QQmlPropertyData local;
QQmlPropertyData *property = QQmlPropertyCache::property(engine->jsEngine(), qobj, name, qmlContext, local);
- return getProperty(engine, qobj, property, /*captureRequired*/true);
+ return getProperty(engine, qobj, property);
}
QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobj, qmlContext);
@@ -919,7 +899,7 @@ ReturnedValue QObjectWrapper::lookupGetter(Lookup *lookup, ExecutionEngine *engi
return revertLookup();
QQmlPropertyData *property = lookup->qobjectLookup.propertyData;
- return getProperty(engine, qobj, property, /*captureRequired = */true);
+ return getProperty(engine, qobj, property);
}
bool QObjectWrapper::virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup,
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index a09e7b6e95..471f352c2a 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -176,13 +176,12 @@ struct Q_QML_EXPORT QObjectWrapper : public Object
using Object::get;
- static ReturnedValue getProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, bool captureRequired);
static void setProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, const Value &value);
void setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value);
void destroyObject(bool lastCall);
- static ReturnedValue getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property, bool captureRequired = true);
+ static ReturnedValue getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property);
static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup);
static ReturnedValue lookupGetter(Lookup *l, ExecutionEngine *engine, const Value &object);
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 7163a51af1..85d06bcabe 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1457,38 +1457,6 @@ ReturnedValue Runtime::method_callWithReceiver(ExecutionEngine *engine, const Va
return static_cast<const FunctionObject &>(func).call(thisObject, argv, argc);
}
-ReturnedValue Runtime::method_callQmlScopeObjectProperty(ExecutionEngine *engine, Value *base,
- int propertyIndex, Value *argv, int argc)
-{
- Scope scope(engine);
- ScopedFunctionObject fo(scope, method_loadQmlScopeObjectProperty(engine, *base, propertyIndex,
- /*captureRequired*/true));
- if (!fo) {
- QString error = QStringLiteral("Property '%1' of scope object is not a function").arg(propertyIndex);
- return engine->throwTypeError(error);
- }
-
- QObject *qmlScopeObj = static_cast<QmlContext *>(base)->d()->qml()->scopeObject;
- ScopedValue qmlScopeValue(scope, QObjectWrapper::wrap(engine, qmlScopeObj));
- return fo->call(qmlScopeValue, argv, argc);
-}
-
-ReturnedValue Runtime::method_callQmlContextObjectProperty(ExecutionEngine *engine, Value *base,
- int propertyIndex, Value *argv, int argc)
-{
- Scope scope(engine);
- ScopedFunctionObject fo(scope, method_loadQmlContextObjectProperty(engine, *base, propertyIndex,
- /*captureRequired*/true));
- if (!fo) {
- QString error = QStringLiteral("Property '%1' of context object is not a function").arg(propertyIndex);
- return engine->throwTypeError(error);
- }
-
- QObject *qmlContextObj = static_cast<QmlContext *>(base)->d()->qml()->context->contextData()->contextObject;
- ScopedValue qmlContextValue(scope, QObjectWrapper::wrap(engine, qmlContextObj));
- return fo->call(qmlContextValue, argv, argc);
-}
-
struct CallArgs {
Value *argv;
int argc;
@@ -1904,65 +1872,11 @@ QV4::ReturnedValue Runtime::method_createRestParameter(ExecutionEngine *engine,
return engine->newArrayObject(values, nValues)->asReturnedValue();
}
-
-ReturnedValue Runtime::method_loadQmlContext(NoThrowEngine *engine)
-{
- Heap::QmlContext *ctx = engine->qmlContext();
- Q_ASSERT(ctx);
- return ctx->asReturnedValue();
-}
-
ReturnedValue Runtime::method_regexpLiteral(ExecutionEngine *engine, int id)
{
Heap::RegExpObject *ro = engine->newRegExpObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeRegularExpressions[id].as<RegExp>());
return ro->asReturnedValue();
}
-
-ReturnedValue Runtime::method_loadQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
-{
- const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::getProperty(engine, c.d()->qml()->scopeObject, propertyIndex, captureRequired);
-}
-
-ReturnedValue Runtime::method_loadQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
-{
- const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::getProperty(engine, (*c.d()->qml()->context)->contextObject, propertyIndex, captureRequired);
-}
-
-ReturnedValue Runtime::method_loadQmlIdObject(ExecutionEngine *engine, const Value &c, uint index)
-{
- const QmlContext &qmlContext = static_cast<const QmlContext &>(c);
- QQmlContextData *context = *qmlContext.d()->qml()->context;
- if (!context || index >= (uint)context->idValueCount)
- return Encode::undefined();
-
- QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : nullptr;
- if (ep && ep->propertyCapture)
- ep->propertyCapture->captureProperty(&context->idValues[index].bindings);
-
- return QObjectWrapper::wrap(engine, context->idValues[index].data());
-}
-
-void Runtime::method_storeQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)
-{
- const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::setProperty(engine, c.d()->qml()->scopeObject, propertyIndex, value);
-}
-
-void Runtime::method_storeQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)
-{
- const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::setProperty(engine, (*c.d()->qml()->context)->contextObject, propertyIndex, value);
-}
-
-ReturnedValue Runtime::method_loadQmlImportedScripts(NoThrowEngine *engine)
-{
- QQmlContextData *context = engine->callingQmlContext();
- if (!context)
- return Encode::undefined();
- return context->importedScripts.value();
-}
#endif // V4_BOOTSTRAP
ReturnedValue Runtime::method_uMinus(const Value &value)
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index aa4ac27621..4b3905c56f 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -195,19 +195,7 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
F(Bool, compareInstanceof, (ExecutionEngine *engine, const Value &left, const Value &right)) \
F(Bool, compareIn, (ExecutionEngine *engine, const Value &left, const Value &right)) \
\
- F(ReturnedValue, regexpLiteral, (ExecutionEngine *engine, int id)) \
- \
- /* qml */ \
- F(ReturnedValue, loadQmlContext, (NoThrowEngine *engine)) \
- F(ReturnedValue, loadQmlImportedScripts, (NoThrowEngine *engine)) \
- F(ReturnedValue, loadQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
- F(ReturnedValue, loadQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
- F(ReturnedValue, loadQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index)) \
- F(ReturnedValue, callQmlScopeObjectProperty, (ExecutionEngine *engine, Value *base, int propertyIndex, Value *argv, int argc)) \
- F(ReturnedValue, callQmlContextObjectProperty, (ExecutionEngine *engine, Value *base, int propertyIndex, Value *argv, int argc)) \
- \
- F(void, storeQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
- F(void, storeQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
+ F(ReturnedValue, regexpLiteral, (ExecutionEngine *engine, int id))
struct Q_QML_PRIVATE_EXPORT Runtime {
Runtime();
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 2d9337b03e..ea2217499f 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -646,37 +646,6 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreSuperProperty)
- MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
- STORE_ACC();
- Runtime::method_storeQmlScopeObjectProperty(engine, STACK_VALUE(base), propertyIndex, accumulator);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(StoreScopeObjectProperty)
-
- MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
- STORE_IP();
- acc = Runtime::method_loadQmlScopeObjectProperty(engine, STACK_VALUE(base), propertyIndex, captureRequired);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(LoadScopeObjectProperty)
-
- MOTH_BEGIN_INSTR(StoreContextObjectProperty)
- STORE_IP();
- STORE_ACC();
- Runtime::method_storeQmlContextObjectProperty(engine, STACK_VALUE(base), propertyIndex, accumulator);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(StoreContextObjectProperty)
-
- MOTH_BEGIN_INSTR(LoadContextObjectProperty)
- STORE_IP();
- acc = Runtime::method_loadQmlContextObjectProperty(engine, STACK_VALUE(base), propertyIndex, captureRequired);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(LoadContextObjectProperty)
-
- MOTH_BEGIN_INSTR(LoadIdObject)
- STORE_IP();
- acc = Runtime::method_loadQmlIdObject(engine, STACK_VALUE(base), index);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(LoadIdObject)
-
MOTH_BEGIN_INSTR(Yield)
frame->yield = code;
frame->yieldIsIterator = false;
@@ -794,18 +763,6 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
CHECK_EXCEPTION;
MOTH_END_INSTR(CallQmlContextPropertyLookup)
- MOTH_BEGIN_INSTR(CallScopeObjectProperty)
- STORE_IP();
- acc = Runtime::method_callQmlScopeObjectProperty(engine, stack + base, name, stack + argv, argc);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(CallScopeObjectProperty)
-
- MOTH_BEGIN_INSTR(CallContextObjectProperty)
- STORE_IP();
- acc = Runtime::method_callQmlContextObjectProperty(engine, stack + base, name, stack + argv, argc);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(CallContextObjectProperty)
-
MOTH_BEGIN_INSTR(CallWithSpread)
STORE_IP();
acc = Runtime::method_callWithSpread(engine, STACK_VALUE(func), STACK_VALUE(thisObject), stack + argv, argc);
@@ -1425,14 +1382,6 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
#endif // QT_CONFIG(qml_debug)
MOTH_END_INSTR(Debug)
- MOTH_BEGIN_INSTR(LoadQmlContext)
- STACK_VALUE(result) = Runtime::method_loadQmlContext(static_cast<QV4::NoThrowEngine*>(engine));
- MOTH_END_INSTR(LoadQmlContext)
-
- MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
- STACK_VALUE(result) = Runtime::method_loadQmlImportedScripts(static_cast<QV4::NoThrowEngine*>(engine));
- MOTH_END_INSTR(LoadQmlImportedScripts)
-
handleUnwind:
Q_ASSERT(engine->hasException || frame->unwindLevel);
if (!frame->unwindHandler) {
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index eea3670191..7f0442d034 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -260,8 +260,6 @@ protected:
} else {
clearError();
}
-
- cancelPermanentGuards();
}
ep->dereferenceScarceResources();
@@ -643,24 +641,22 @@ QVector<QQmlProperty> QQmlBinding::dependencies() const
if (!m_target.data())
return dependencies;
- for (const auto &guardList : { permanentGuards, activeGuards }) {
- for (QQmlJavaScriptExpressionGuard *guard = guardList.first(); guard; guard = guardList.next(guard)) {
- if (guard->signalIndex() == -1) // guard's sender is a QQmlNotifier, not a QObject*.
- continue;
+ for (QQmlJavaScriptExpressionGuard *guard = activeGuards.first(); guard; guard = activeGuards.next(guard)) {
+ if (guard->signalIndex() == -1) // guard's sender is a QQmlNotifier, not a QObject*.
+ continue;
- QObject *senderObject = guard->senderAsObject();
- if (!senderObject)
- continue;
+ QObject *senderObject = guard->senderAsObject();
+ if (!senderObject)
+ continue;
- const QMetaObject *senderMeta = senderObject->metaObject();
- if (!senderMeta)
- continue;
+ const QMetaObject *senderMeta = senderObject->metaObject();
+ if (!senderMeta)
+ continue;
- for (int i = 0; i < senderMeta->propertyCount(); i++) {
- QMetaProperty property = senderMeta->property(i);
- if (property.notifySignalIndex() == QMetaObjectPrivate::signal(senderMeta, guard->signalIndex()).methodIndex()) {
- dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(senderObject->metaObject()->property(i).name())));
- }
+ for (int i = 0; i < senderMeta->propertyCount(); i++) {
+ QMetaProperty property = senderMeta->property(i);
+ if (property.notifySignalIndex() == QMetaObjectPrivate::signal(senderMeta, guard->signalIndex()).methodIndex()) {
+ dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(senderObject->metaObject()->property(i).name())));
}
}
}
@@ -670,7 +666,7 @@ QVector<QQmlProperty> QQmlBinding::dependencies() const
bool QQmlBinding::hasDependencies() const
{
- return !permanentGuards.isEmpty() || !activeGuards.isEmpty() || translationsCaptured();
+ return !activeGuards.isEmpty() || translationsCaptured();
}
class QObjectPointerBinding: public QQmlNonbindingBinding
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 380163202a..9a3a5218e0 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -109,7 +109,6 @@ QQmlJavaScriptExpression::~QQmlJavaScriptExpression()
}
clearActiveGuards();
- clearPermanentGuards();
clearError();
if (m_scopeObject.isT2()) // notify DeleteWatcher of our deletion.
m_scopeObject.asT2()->_s = nullptr;
@@ -118,12 +117,8 @@ QQmlJavaScriptExpression::~QQmlJavaScriptExpression()
void QQmlJavaScriptExpression::setNotifyOnValueChanged(bool v)
{
activeGuards.setFlagValue(v);
- permanentGuards.setFlagValue(v);
- if (!v) {
+ if (!v)
clearActiveGuards();
- clearPermanentGuards();
- m_permanentDependenciesRegistered = false;
- }
}
void QQmlJavaScriptExpression::resetNotifyOnValueChanged()
@@ -216,10 +211,6 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
QV4::ReturnedValue res = v4Function->call(&callData->thisObject, callData->args, callData->argc(), static_cast<QV4::ExecutionContext *>(m_qmlScope.valueRef()));
QV4::Scope scope(v4);
QV4::ScopedValue result(scope, res);
- if (v4Function->hasQmlDependencies) {
- QV4::Heap::QmlContext *qc = m_qmlScope.as<QV4::QmlContext>()->d();
- QQmlPropertyCapture::registerQmlDependencies(qc, v4, v4Function->compiledFunction);
- }
if (scope.hasException()) {
if (watcher.wasDeleted())
@@ -254,7 +245,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
return result->asReturnedValue();
}
-void QQmlPropertyCapture::captureProperty(QQmlNotifier *n, Duration duration)
+void QQmlPropertyCapture::captureProperty(QQmlNotifier *n)
{
if (watcher->wasDeleted())
return;
@@ -274,17 +265,14 @@ void QQmlPropertyCapture::captureProperty(QQmlNotifier *n, Duration duration)
g->connect(n);
}
- if (duration == Permanently)
- expression->permanentGuards.prepend(g);
- else
- expression->activeGuards.prepend(g);
+ expression->activeGuards.prepend(g);
}
/*! \internal
\a n is in the signal index range (see QObjectPrivate::signalIndex()).
*/
-void QQmlPropertyCapture::captureProperty(QObject *o, int c, int n, Duration duration, bool doNotify)
+void QQmlPropertyCapture::captureProperty(QObject *o, int c, int n, bool doNotify)
{
if (watcher->wasDeleted())
return;
@@ -323,61 +311,8 @@ void QQmlPropertyCapture::captureProperty(QObject *o, int c, int n, Duration dur
g->connect(o, n, engine, doNotify);
}
- if (duration == Permanently)
- expression->permanentGuards.prepend(g);
- else
- expression->activeGuards.prepend(g);
- }
-}
-
-void QQmlPropertyCapture::registerQmlDependencies(QV4::Heap::QmlContext *context, const QV4::ExecutionEngine *engine, const QV4::CompiledData::Function *compiledFunction)
-{
- // Let the caller check and avoid the function call :)
- Q_ASSERT(compiledFunction->hasQmlDependencies());
-
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine->qmlEngine());
- if (!ep)
- return;
- QQmlPropertyCapture *capture = ep->propertyCapture;
- if (!capture || capture->watcher->wasDeleted())
- return;
-
- if (capture->expression->m_permanentDependenciesRegistered)
- return;
-
- capture->expression->m_permanentDependenciesRegistered = true;
-
- QV4::Heap::QQmlContextWrapper *wrapper = context->qml();
- QQmlContextData *qmlContext = wrapper->context->contextData();
-
- const quint32_le *idObjectDependency = compiledFunction->qmlIdObjectDependencyTable();
- const int idObjectDependencyCount = compiledFunction->nDependingIdObjects;
- for (int i = 0; i < idObjectDependencyCount; ++i, ++idObjectDependency) {
- Q_ASSERT(int(*idObjectDependency) < qmlContext->idValueCount);
- capture->captureProperty(&qmlContext->idValues[*idObjectDependency].bindings,
- QQmlPropertyCapture::Permanently);
- }
-
- Q_ASSERT(qmlContext->contextObject);
- const quint32_le *contextPropertyDependency = compiledFunction->qmlContextPropertiesDependencyTable();
- const int contextPropertyDependencyCount = compiledFunction->nDependingContextProperties;
- for (int i = 0; i < contextPropertyDependencyCount; ++i) {
- const int propertyIndex = *contextPropertyDependency++;
- const int notifyIndex = *contextPropertyDependency++;
- capture->captureProperty(qmlContext->contextObject, propertyIndex, notifyIndex,
- QQmlPropertyCapture::Permanently);
- }
-
- QObject *scopeObject = wrapper->scopeObject;
- const quint32_le *scopePropertyDependency = compiledFunction->qmlScopePropertiesDependencyTable();
- const int scopePropertyDependencyCount = compiledFunction->nDependingScopeProperties;
- for (int i = 0; i < scopePropertyDependencyCount; ++i) {
- const int propertyIndex = *scopePropertyDependency++;
- const int notifyIndex = *scopePropertyDependency++;
- capture->captureProperty(scopeObject, propertyIndex, notifyIndex,
- QQmlPropertyCapture::Permanently);
+ expression->activeGuards.prepend(g);
}
-
}
QQmlError QQmlJavaScriptExpression::error(QQmlEngine *engine) const
@@ -471,13 +406,6 @@ void QQmlJavaScriptExpression::clearActiveGuards()
g->Delete();
}
-void QQmlJavaScriptExpression::clearPermanentGuards()
-{
- m_permanentDependenciesRegistered = false;
- while (QQmlJavaScriptExpressionGuard *g = permanentGuards.takeFirst())
- g->Delete();
-}
-
void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *e, void **)
{
QQmlJavaScriptExpression *expression =
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index de3fba0774..453c8ab8a8 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -144,7 +144,6 @@ public:
QQmlError error(QQmlEngine *) const;
void clearError();
void clearActiveGuards();
- void clearPermanentGuards();
QQmlDelayedError *delayedError();
static QV4::ReturnedValue evalFunction(QQmlContextData *ctxt, QObject *scope,
@@ -153,14 +152,6 @@ public:
protected:
void createQmlBinding(QQmlContextData *ctxt, QObject *scope, const QString &code, const QString &filename, quint16 line);
- void cancelPermanentGuards() const
- {
- if (m_permanentDependenciesRegistered) {
- for (QQmlJavaScriptExpressionGuard *it = permanentGuards.first(); it; it = permanentGuards.next(it))
- it->cancelNotify();
- }
- }
-
void setupFunction(QV4::ExecutionContext *qmlContext, QV4::Function *f);
void setCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit);
@@ -169,7 +160,6 @@ protected:
// activeGuards:flag2 - useSharedContext
QBiPointer<QObject, DeleteWatcher> m_scopeObject;
QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> activeGuards;
- QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> permanentGuards;
void setTranslationsCaptured(bool captured) { m_error.setFlagValue(captured); }
bool translationsCaptured() const { return m_error.flag(); }
@@ -186,7 +176,6 @@ private:
QQmlContextData *m_context;
QQmlJavaScriptExpression **m_prevExpression;
QQmlJavaScriptExpression *m_nextExpression;
- bool m_permanentDependenciesRegistered = false;
QV4::PersistentValue m_qmlScope;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> m_compilationUnit;
@@ -204,14 +193,8 @@ public:
Q_ASSERT(errorString == nullptr);
}
- enum Duration {
- OnlyOnce,
- Permanently
- };
-
- static void registerQmlDependencies(QV4::Heap::QmlContext *context, const QV4::ExecutionEngine *engine, const QV4::CompiledData::Function *compiledFunction);
- void captureProperty(QQmlNotifier *, Duration duration = OnlyOnce);
- void captureProperty(QObject *, int, int, Duration duration = OnlyOnce, bool doNotify = true);
+ void captureProperty(QQmlNotifier *);
+ void captureProperty(QObject *, int, int, bool doNotify = true);
void captureTranslation() { translationCaptured = true; }
QQmlEngine *engine;
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 006825cc93..69b7876cf6 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -1605,8 +1605,7 @@ ReturnedValue ModelObject::virtualGet(const Managed *m, PropertyKey id, const Va
if (QQmlEngine *qmlEngine = that->engine()->qmlEngine()) {
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine);
if (ep && ep->propertyCapture)
- ep->propertyCapture->captureProperty(that->object(), -1, role->index,
- QQmlPropertyCapture::OnlyOnce, false);
+ ep->propertyCapture->captureProperty(that->object(), -1, role->index, /*doNotify=*/ false);
}
const int elementIndex = that->d()->elementIndex();