diff options
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 31 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 22 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 3 |
7 files changed, 48 insertions, 24 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index f50c5ab017..d5e2a57b20 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -98,6 +98,12 @@ Heap::QmlContext *ExecutionContext::newQmlContext(QmlContextWrapper *qml) return d()->engine->memoryManager->alloc<QmlContext>(this, qml); } +Heap::QmlContext *ExecutionContext::newQmlContext(QQmlContextData *context, QObject *scopeObject) +{ + Scope scope(this); + Scoped<QmlContextWrapper> qml(scope, QmlContextWrapper::qmlScope(scope.engine, context, scopeObject)); + return d()->engine->memoryManager->alloc<QmlContext>(this, qml); +} void ExecutionContext::createMutableBinding(String *name, bool deletable) { diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 2667bbe0b2..63f8cbaac4 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -153,6 +153,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed Heap::WithContext *newWithContext(Object *with); Heap::CatchContext *newCatchContext(String *exceptionVarName, const Value &exceptionValue); Heap::QmlContext *newQmlContext(QmlContextWrapper *qml); + Heap::QmlContext *newQmlContext(QQmlContextData *context, QObject *scopeObject); void createMutableBinding(String *name, bool deletable); diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 98a4490211..66b2125a4f 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -70,14 +70,45 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, arg = mm->alloc<String>(mm, arg->d(), engine->newString(QString(0xfffe))); } } + nFormals = compiledFunction->nFormals; const quint32 *localsIndices = compiledFunction->localsTable(); for (quint32 i = 0; i < compiledFunction->nLocals; ++i) internalClass = internalClass->addMember(compilationUnit->runtimeStrings[localsIndices[i]]->identifier, Attr_NotConfigurable); + + activationRequired = compiledFunction->nInnerFunctions > 0 || (compiledFunction->flags & (CompiledData::Function::HasDirectEval | CompiledData::Function::UsesArgumentsObject)); } Function::~Function() { } +void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> ¶meters) +{ + internalClass = engine->emptyClass; + + // iterate backwards, so we get the right ordering for duplicate names + Scope scope(engine); + ScopedString arg(scope); + for (int i = parameters.size() - 1; i >= 0; --i) { + arg = engine->newString(QString::fromUtf8(parameters.at(i))); + while (1) { + InternalClass *newClass = internalClass->addMember(arg, Attr_NotConfigurable); + if (newClass != internalClass) { + internalClass = newClass; + break; + } + // duplicate arguments, need some trick to store them + arg = engine->memoryManager->alloc<String>(engine->memoryManager, arg->d(), engine->newString(QString(0xfffe))); + } + } + nFormals = parameters.size(); + + const quint32 *localsIndices = compiledFunction->localsTable(); + for (quint32 i = 0; i < compiledFunction->nLocals; ++i) + internalClass = internalClass->addMember(compilationUnit->runtimeStrings[localsIndices[i]]->identifier, Attr_NotConfigurable); + + activationRequired = true; +} + QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 10a03bca94..534aa1b750 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -49,11 +49,16 @@ struct Q_QML_EXPORT Function { // first nArguments names in internalClass are the actual arguments InternalClass *internalClass; + uint nFormals; + bool activationRequired; Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function, ReturnedValue (*codePtr)(ExecutionEngine *, const uchar *)); ~Function(); + // used when dynamically assigning signal handlers (QQmlConnection) + void updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> ¶meters); + inline Heap::String *name() { return compilationUnit->runtimeStrings[compiledFunction->nameIndex]; } @@ -64,7 +69,7 @@ struct Q_QML_EXPORT Function { inline bool isNamedExpression() const { return compiledFunction->flags & CompiledData::Function::IsNamedExpression; } inline bool needsActivation() const - { return compiledFunction->nInnerFunctions > 0 || (compiledFunction->flags & (CompiledData::Function::HasDirectEval | CompiledData::Function::UsesArgumentsObject)); } + { return activationRequired; } }; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 329ecd70fc..525f806d7a 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -206,36 +206,18 @@ Heap::FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *sco return scope->d()->engine->memoryManager->alloc<SimpleScriptFunction>(scope, function, createProto); } -static ReturnedValue signalParameterGetter(QV4::CallContext *ctx, uint parameterIndex) -{ - QV4::Scope scope(ctx); - QV4::Scoped<CallContext> signalEmittingContext(scope, ctx->d()->parent.cast<Heap::CallContext>()); - Q_ASSERT(signalEmittingContext && signalEmittingContext->d()->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext); - return signalEmittingContext->argument(parameterIndex); -} - Heap::FunctionObject *FunctionObject::createQmlFunction(QQmlContextData *qmlContext, QObject *scopeObject, Function *runtimeFunction, const QList<QByteArray> &signalParameters, QString *error) { ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(qmlContext->engine); QV4::Scope valueScope(engine); - QV4::Scoped<QmlContextWrapper> qmlScopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(engine, qmlContext, scopeObject)); ScopedContext global(valueScope, valueScope.engine->rootContext()); - QV4::Scoped<QmlContext> wrapperContext(valueScope, global->newQmlContext(qmlScopeObject)); + QV4::Scoped<QmlContext> wrapperContext(valueScope, global->newQmlContext(qmlContext, scopeObject)); engine->popContext(); if (!signalParameters.isEmpty()) { if (error) QQmlPropertyCache::signalParameterStringForJS(engine, signalParameters, error); - QV4::ScopedProperty p(valueScope); - QV4::ScopedString s(valueScope); - int index = 0; - foreach (const QByteArray ¶m, signalParameters) { - QV4::ScopedFunctionObject g(valueScope, engine->memoryManager->alloc<QV4::IndexedBuiltinFunction>(wrapperContext, index++, signalParameterGetter)); - p->setGetter(g); - p->setSetter(0); - s = engine->newString(QString::fromUtf8(param)); - qmlScopeObject->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable); - } + runtimeFunction->updateInternalClass(engine, signalParameters); } QV4::ScopedFunctionObject function(valueScope, QV4::FunctionObject::createScriptFunction(wrapperContext, runtimeFunction)); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 4509923bde..d903db65a4 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -61,7 +61,7 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object { FunctionObject(InternalClass *ic, QV4::Object *prototype); ~FunctionObject(); - unsigned int formalParameterCount() { return function ? function->compiledFunction->nFormals : 0; } + unsigned int formalParameterCount() { return function ? function->nFormals : 0; } unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; } bool needsActivation() const { return function ? function->needsActivation() : false; } diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index b55973cdc8..12415e1583 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -989,9 +989,8 @@ QV4::Heap::QmlContext *QQmlObjectCreator::currentQmlContext() { if (!_qmlContext->objectValue()) { QV4::Scope valueScope(v4); - QV4::Scoped<QV4::QmlContextWrapper> qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(v4, context, _scopeObject)); QV4::ScopedContext global(valueScope, v4->rootContext()); - _qmlContext->setM(global->newQmlContext(qmlScope)); + _qmlContext->setM(global->newQmlContext(context, _scopeObject)); v4->popContext(); } return _qmlContext->d(); |