aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4context.cpp6
-rw-r--r--src/qml/jsruntime/qv4context_p.h1
-rw-r--r--src/qml/jsruntime/qv4function.cpp31
-rw-r--r--src/qml/jsruntime/qv4function_p.h7
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp22
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp3
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> &parameters)
+{
+ 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> &parameters);
+
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 &param, 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();