diff options
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 16 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilercontext_p.h | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 13 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions_p.h | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 1 |
8 files changed, 28 insertions, 28 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 872833bfd3..f7c89e75fa 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1488,7 +1488,7 @@ Codegen::Reference Codegen::referenceForName(const QString &name, bool isLhs) } while (c->parent) { - if (c->forceLookupByName() || (c->isNamedFunctionExpression && c->name == name)) + if (c->forceLookupByName()) goto loadByName; Context::Member m = c->findMember(name); @@ -2068,8 +2068,20 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, if (it->canEscape) { it->index = _context->locals.size(); _context->locals.append(local); + if (it->type == Context::ThisFunctionName) { + // move the name from the stack to the call context + Instruction::LoadReg load; + load.reg = CallData::Function; + bytecodeGenerator->addInstruction(load); + Instruction::StoreLocal store; + store.index = it->index; + bytecodeGenerator->addInstruction(store); + } } else { - it->index = bytecodeGenerator->newRegister(); + if (it->type == Context::ThisFunctionName) + it->index = CallData::Function; + else + it->index = bytecodeGenerator->newRegister(); } } } else { diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 882fe06086..79476dbe5e 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -207,7 +207,7 @@ struct Function IsStrict = 0x1, HasDirectEval = 0x2, UsesArgumentsObject = 0x4, - IsNamedExpression = 0x8, +// Unused = 0x8, HasCatchOrWith = 0x10, CanUseSimpleCall = 0x20 }; diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index b726d75c8d..a3c203b136 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -302,8 +302,6 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte function->flags |= CompiledData::Function::UsesArgumentsObject; if (irFunction->isStrict) function->flags |= CompiledData::Function::IsStrict; - if (irFunction->isNamedFunctionExpression) - function->flags |= CompiledData::Function::IsNamedExpression; if (irFunction->hasTry || irFunction->hasWith) function->flags |= CompiledData::Function::HasCatchOrWith; if (irFunction->canUseSimpleCall()) diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h index b796a5f149..f35125e719 100644 --- a/src/qml/compiler/qv4compilercontext_p.h +++ b/src/qml/compiler/qv4compilercontext_p.h @@ -109,6 +109,7 @@ struct Context { enum MemberType { UndefinedMember, + ThisFunctionName, VariableDefinition, VariableDeclaration, FunctionDefinition @@ -140,7 +141,6 @@ struct Context { bool hasDirectEval = false; bool hasNestedFunctions = false; bool isStrict = false; - bool isNamedFunctionExpression = false; bool usesThis = false; bool hasTry = false; bool hasWith = false; @@ -217,7 +217,7 @@ struct Context { bool canUseSimpleCall() const { return nestedContexts.isEmpty() && locals.isEmpty() && arguments.size() <= QV4::Global::ReservedArgumentCount && - !hasTry && !hasWith && !isNamedFunctionExpression && + !hasTry && !hasWith && usesArgumentsObject == ArgumentsObjectNotUsed && !hasDirectEval; } diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index 8c41d89bd4..6a9b064bd8 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -252,11 +252,11 @@ bool ScanFunctions::visit(FunctionExpression *ast) return true; } -void ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName, bool isExpression) +void ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName) { if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments"))) _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode")); - enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : 0, isExpression); + enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : 0); } void ScanFunctions::endVisit(FunctionExpression *) @@ -285,7 +285,7 @@ bool ScanFunctions::visit(ObjectLiteral *ast) bool ScanFunctions::visit(PropertyGetterSetter *ast) { TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true); - enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/0, /*isExpression*/false); + enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/0); return true; } @@ -296,7 +296,7 @@ void ScanFunctions::endVisit(PropertyGetterSetter *) bool ScanFunctions::visit(FunctionDeclaration *ast) { - enterFunction(ast, /*enterName*/ true, /*isExpression */false); + enterFunction(ast, /*enterName*/ true); return true; } @@ -386,7 +386,7 @@ bool ScanFunctions::visit(Block *ast) { return false; } -void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr, bool isExpression) +void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr) { if (_context) { _context->hasNestedFunctions = true; @@ -400,7 +400,8 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete enterEnvironment(ast, FunctionCode); checkForArguments(formals); - _context->isNamedFunctionExpression = isExpression && !name.isEmpty(); + if (!name.isEmpty()) + _context->addLocalVar(name, Context::ThisFunctionName, QQmlJS::AST::VariableDeclaration::FunctionScope); _context->formals = formals; if (body && !_context->isStrict) diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h index d3588ecfed..0b898e587d 100644 --- a/src/qml/compiler/qv4compilerscanfunctions_p.h +++ b/src/qml/compiler/qv4compilerscanfunctions_p.h @@ -88,10 +88,10 @@ public: void leaveEnvironment(); void enterQmlScope(AST::Node *ast, const QString &name) - { enterFunction(ast, name, /*formals*/0, /*body*/0, /*expr*/0, /*isExpression*/false); } + { enterFunction(ast, name, /*formals*/0, /*body*/0, /*expr*/0); } void enterQmlFunction(AST::FunctionDeclaration *ast) - { enterFunction(ast, false, false); } + { enterFunction(ast, false); } protected: using Visitor::visit; @@ -113,7 +113,7 @@ protected: bool visit(AST::ExpressionStatement *ast) override; bool visit(AST::FunctionExpression *ast) override; - void enterFunction(AST::FunctionExpression *ast, bool enterName, bool isExpression = true); + void enterFunction(AST::FunctionExpression *ast, bool enterName); void endVisit(AST::FunctionExpression *) override; @@ -138,7 +138,7 @@ protected: bool visit(AST::Block *ast) override; protected: - void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::FunctionBody *body, AST::FunctionExpression *expr, bool isExpression); + void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::FunctionBody *body, AST::FunctionExpression *expr); void calcEscapingVariables(); // fields: diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index d672df40e8..6de6424f0e 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -287,11 +287,6 @@ ReturnedValue ExecutionContext::getProperty(String *name) uint index = c->internalClass->find(id); if (index < UINT_MAX) return c->locals[index].asReturnedValue(); - if (c->v4Function->isNamedExpression()) { - Scope scope(this); - if (c->function && name->equals(ScopedString(scope, c->v4Function->name()))) - return c->function->asReturnedValue(); - } Q_FALLTHROUGH(); } case Heap::ExecutionContext::Type_WithContext: @@ -334,11 +329,6 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) uint index = c->internalClass->find(id); if (index < UINT_MAX) return c->locals[index].asReturnedValue(); - if (c->v4Function->isNamedExpression()) { - Scope scope(this); - if (c->function && name->equals(ScopedString(scope, c->v4Function->name()))) - return c->function->asReturnedValue(); - } Q_FALLTHROUGH(); } case Heap::ExecutionContext::Type_GlobalContext: { diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index f0e325ec3a..87a75c6b7d 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -91,7 +91,6 @@ struct Q_QML_EXPORT Function { inline bool usesArgumentsObject() const { return compiledFunction->flags & CompiledData::Function::UsesArgumentsObject; } inline bool isStrict() const { return compiledFunction->flags & CompiledData::Function::IsStrict; } - inline bool isNamedExpression() const { return compiledFunction->flags & CompiledData::Function::IsNamedExpression; } inline bool canUseSimpleFunction() const { return canUseSimpleCall; } |