diff options
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 87 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 13 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 2 |
4 files changed, 44 insertions, 62 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index be53b14786..a9b0d67630 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -202,7 +202,6 @@ unsigned int SimpleCallContext::variableCount() const bool ExecutionContext::deleteProperty(String *name) { Scope scope(this); - bool hasWith = false; ScopedContext ctx(scope, this); for (; ctx; ctx = ctx->d()->outer) { switch (ctx->d()->type) { @@ -213,7 +212,6 @@ bool ExecutionContext::deleteProperty(String *name) break; } case Heap::ExecutionContext::Type_WithContext: { - hasWith = true; ScopedObject withObject(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject); if (withObject->hasProperty(name)) return withObject->deleteProperty(name); @@ -225,15 +223,16 @@ bool ExecutionContext::deleteProperty(String *name) return global->deleteProperty(name); break; } - case Heap::ExecutionContext::Type_CallContext: + case Heap::ExecutionContext::Type_CallContext: { + Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d()); + uint index = c->v4Function->internalClass->find(name); + if (index < UINT_MAX) + // ### throw in strict mode? + return false; + Q_FALLTHROUGH(); + } case Heap::ExecutionContext::Type_SimpleCallContext: { Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d()); - if (c->v4Function && (c->v4Function->needsActivation() || hasWith)) { - uint index = c->v4Function->internalClass->find(name); - if (index < UINT_MAX) - // ### throw in strict mode? - return false; - } ScopedObject qml(scope, c->activation); if (qml && qml->hasProperty(name)) return qml->deleteProperty(name); @@ -376,13 +375,10 @@ ReturnedValue ExecutionContext::getProperty(String *name) if (name->equals(d()->engine->id_this())) return thisObject().asReturnedValue(); - bool hasWith = false; - bool hasCatchScope = false; ScopedContext ctx(scope, this); for (; ctx; ctx = ctx->d()->outer) { switch (ctx->d()->type) { case Heap::ExecutionContext::Type_CatchContext: { - hasCatchScope = true; Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d()); if (c->exceptionVarName->isEqualTo(name->d())) return c->exceptionValue.asReturnedValue(); @@ -390,7 +386,6 @@ ReturnedValue ExecutionContext::getProperty(String *name) } case Heap::ExecutionContext::Type_WithContext: { ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject); - hasWith = true; bool hasProperty = false; v = w->get(name, &hasProperty); if (hasProperty) { @@ -406,18 +401,23 @@ ReturnedValue ExecutionContext::getProperty(String *name) return v->asReturnedValue(); break; } - case Heap::ExecutionContext::Type_CallContext: + case Heap::ExecutionContext::Type_CallContext: { + Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d()); + uint index = c->v4Function->internalClass->find(name); + if (index < UINT_MAX) { + if (index < c->v4Function->nFormals) + return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue(); + Q_ASSERT(c->type = Heap::ExecutionContext::Type_CallContext); + return c->locals[index - c->v4Function->nFormals].asReturnedValue(); + } + if (c->v4Function->isNamedExpression()) { + if (c->function && name->equals(ScopedString(scope, c->v4Function->name()))) + return c->function->asReturnedValue(); + } + Q_FALLTHROUGH(); + } case Heap::ExecutionContext::Type_SimpleCallContext: { Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d()); - if (c->v4Function && (c->v4Function->needsActivation() || hasWith || hasCatchScope)) { - uint index = c->v4Function->internalClass->find(name); - if (index < UINT_MAX) { - if (index < c->v4Function->nFormals) - return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue(); - Q_ASSERT(c->type = Heap::ExecutionContext::Type_CallContext); - return static_cast<Heap::CallContext *>(c)->locals[index - c->v4Function->nFormals].asReturnedValue(); - } - } ScopedObject activation(scope, c->activation); if (activation) { bool hasProperty = false; @@ -425,12 +425,6 @@ ReturnedValue ExecutionContext::getProperty(String *name) if (hasProperty) return v->asReturnedValue(); } - if (c->v4Function->isNamedExpression()) { - Q_ASSERT(c->type == Heap::CallContext::Type_CallContext); - Heap::CallContext *ctx = static_cast<Heap::CallContext *>(c); - if (ctx->function && name->equals(ScopedString(scope, c->v4Function->name()))) - return ctx->function->asReturnedValue(); - } break; } case Heap::ExecutionContext::Type_QmlContext: { @@ -457,13 +451,10 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) if (name->equals(d()->engine->id_this())) return thisObject().asReturnedValue(); - bool hasWith = false; - bool hasCatchScope = false; ScopedContext ctx(scope, this); for (; ctx; ctx = ctx->d()->outer) { switch (ctx->d()->type) { case Heap::ExecutionContext::Type_CatchContext: { - hasCatchScope = true; Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d()); if (c->exceptionVarName->isEqualTo(name->d())) return c->exceptionValue.asReturnedValue(); @@ -471,7 +462,6 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) } case Heap::ExecutionContext::Type_WithContext: { ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject); - hasWith = true; bool hasProperty = false; v = w->get(name, &hasProperty); if (hasProperty) { @@ -488,19 +478,22 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) return v->asReturnedValue(); break; } - case Heap::ExecutionContext::Type_CallContext: + case Heap::ExecutionContext::Type_CallContext: { + Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d()); + uint index = c->v4Function->internalClass->find(name); + if (index < UINT_MAX) { + if (index < c->v4Function->nFormals) + return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue(); + return c->locals[index - c->v4Function->nFormals].asReturnedValue(); + } + if (c->v4Function->isNamedExpression()) { + if (c->function && name->equals(ScopedString(scope, c->v4Function->name()))) + return c->function->asReturnedValue(); + } + Q_FALLTHROUGH(); + } case Heap::ExecutionContext::Type_SimpleCallContext: { Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d()); - if (c->v4Function && (c->v4Function->needsActivation() || hasWith || hasCatchScope)) { - Q_ASSERT(c->type == Heap::CallContext::Type_CallContext); - Heap::CallContext *ctx = static_cast<Heap::CallContext *>(c); - uint index = c->v4Function->internalClass->find(name); - if (index < UINT_MAX) { - if (index < c->v4Function->nFormals) - return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue(); - return ctx->locals[index - c->v4Function->nFormals].asReturnedValue(); - } - } ScopedObject activation(scope, c->activation); if (activation) { bool hasProperty = false; @@ -508,12 +501,6 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) if (hasProperty) return v->asReturnedValue(); } - if (c->v4Function->isNamedExpression()) { - Q_ASSERT(c->type == Heap::CallContext::Type_CallContext); - Heap::CallContext *ctx = static_cast<Heap::CallContext *>(c); - if (ctx->function && name->equals(ScopedString(scope, c->v4Function->name()))) - return ctx->function->asReturnedValue(); - } break; } case Heap::ExecutionContext::Type_QmlContext: { diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index dd3208c7e9..b3feae4293 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -83,11 +83,12 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, 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)); - - canUseSimpleCall = !needsActivation() && !(compiledFunction->flags & CompiledData::Function::HasCatchOrWith) && - compiledFunction->nFormals <= QV4::Global::ReservedArgumentCount && - compiledFunction->nLocals == 0 && !isNamedExpression(); + canUseSimpleCall = compiledFunction->nInnerFunctions == 0 && + !(compiledFunction->flags & CompiledData::Function::HasDirectEval) && + !(compiledFunction->flags & CompiledData::Function::UsesArgumentsObject) && + !(compiledFunction->flags & CompiledData::Function::HasCatchOrWith) && + nFormals <= QV4::Global::ReservedArgumentCount && + compiledFunction->nLocals == 0 && !isNamedExpression(); } Function::~Function() @@ -119,7 +120,7 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr for (quint32 i = 0; i < compiledFunction->nLocals; ++i) internalClass = internalClass->addMember(compilationUnit->runtimeStrings[localsIndices[i]]->identifier, Attr_NotConfigurable); - activationRequired = true; + canUseSimpleCall = false; } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index ff5febd19c..b11c8af94a 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -69,7 +69,6 @@ struct Q_QML_EXPORT Function { // first nArguments names in internalClass are the actual arguments InternalClass *internalClass; uint nFormals; - bool activationRequired; bool hasQmlDependencies; bool canUseSimpleCall; @@ -89,9 +88,6 @@ struct Q_QML_EXPORT Function { inline bool isStrict() const { return compiledFunction->flags & CompiledData::Function::IsStrict; } inline bool isNamedExpression() const { return compiledFunction->flags & CompiledData::Function::IsNamedExpression; } - inline bool needsActivation() const - { return activationRequired; } - inline bool canUseSimpleFunction() const { return canUseSimpleCall; } QQmlSourceLocation sourceLocation() const diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index c7dac7d3e5..d375153058 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -84,7 +84,6 @@ DECLARE_HEAP_OBJECT(FunctionObject, Object) { 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; } const QV4::Object *protoProperty() const { return propertyData(Index_Prototype)->cast<QV4::Object>(); } }; @@ -160,7 +159,6 @@ struct Q_QML_EXPORT FunctionObject: Object { static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function); - bool needsActivation() const { return d()->needsActivation(); } bool strictMode() const { return d()->function ? d()->function->isStrict() : false; } bool isBinding() const; bool isBoundFunction() const; |