aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4codegen.cpp16
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/compiler/qv4compiler.cpp2
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h4
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp13
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h8
-rw-r--r--src/qml/jsruntime/qv4context.cpp10
-rw-r--r--src/qml/jsruntime/qv4function_p.h1
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; }