aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-02-10 17:04:32 +0100
committerLars Knoll <lars.knoll@qt.io>2018-04-25 17:49:09 +0000
commitb59b727035c4c1a4d235432cc67e5d89d3a24cd3 (patch)
treeb452f39eab452a8a472dfc5c9b7e89ab4a354c1f /src/qml/compiler
parent2683a22364f742e3809b6c48570b0b4aaf37b31f (diff)
ES6: add support for default arguments for function parameters
The parser can also handle rest parameters correctly, this will however require some additional work in the runtime to support it correctly. Change-Id: Ib6f4d27683774966b2d2aac075494d2f5066d2a2 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h6
-rw-r--r--src/qml/compiler/qv4codegen.cpp31
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp4
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
4 files changed, 40 insertions, 3 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index e69f2cd310..9bd9d82e0d 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -181,6 +181,12 @@ public:
return addJumpInstruction(data);
}
+ Q_REQUIRED_RESULT Jump jumpNotUndefined()
+ {
+ Instruction::JumpNotUndefined data;
+ return addJumpInstruction(data);
+ }
+
void jumpStrictEqual(const StackSlot &lhs, const Label &target)
{
Instruction::CmpStrictEqual cmp;
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index fa4772a99b..bc0c62e9be 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2210,12 +2210,20 @@ static bool endsWithReturn(Node *node)
return false;
}
+static bool isSimpleParameterList(AST::FormalParameterList *formals)
+{
+ while (formals) {
+ if (formals->isRest || formals->defaultExpression)
+ return false;
+ formals = formals->next;
+ }
+ return true;
+}
+
int Codegen::defineFunction(const QString &name, AST::Node *ast,
AST::FormalParameterList *formals,
AST::SourceElements *body)
{
- Q_UNUSED(formals);
-
enterContext(ast);
if (_context->functionIndex >= 0)
@@ -2316,7 +2324,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
}
}
if (_context->usesArgumentsObject == Context::ArgumentsObjectUsed) {
- if (_context->isStrict) {
+ if (_context->isStrict || !isSimpleParameterList(formals)) {
Instruction::CreateUnmappedArgumentsObject setup;
bytecodeGenerator->addInstruction(setup);
} else {
@@ -2331,6 +2339,23 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
bytecodeGenerator->addInstruction(convert);
}
+ while (formals) {
+ if (formals->isRest) {
+ // #### implement me
+ throwSyntaxError(formals->firstSourceLocation(), QString::fromLatin1("Support for rest parameters not implemented!"));
+ }
+ if (formals->defaultExpression) {
+ RegisterScope scope(this);
+ Reference f = referenceForName(formals->name.toString(), true);
+ f.loadInAccumulator();
+ BytecodeGenerator::Jump jump = bytecodeGenerator->jumpNotUndefined();
+ expression(formals->defaultExpression).loadInAccumulator();
+ f.storeConsumeAccumulator();
+ jump.link();
+ }
+ formals = formals->next;
+ }
+
beginFunctionBodyHook();
sourceElements(body);
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 450fa50528..362bc40b31 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -473,6 +473,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << ABSOLUTE_OFFSET();
MOTH_END_INSTR(JumpFalse)
+ MOTH_BEGIN_INSTR(JumpNotUndefined)
+ d << ABSOLUTE_OFFSET();
+ MOTH_END_INSTR(JumpNotUndefined)
+
MOTH_BEGIN_INSTR(CmpEqNull)
MOTH_END_INSTR(CmpEqNull)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 7dd639c94c..df9be62672 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -133,6 +133,7 @@ QT_BEGIN_NAMESPACE
#define INSTR_Jump(op) INSTRUCTION(op, Jump, 1, offset)
#define INSTR_JumpTrue(op) INSTRUCTION(op, JumpTrue, 1, offset)
#define INSTR_JumpFalse(op) INSTRUCTION(op, JumpFalse, 1, offset)
+#define INSTR_JumpNotUndefined(op) INSTRUCTION(op, JumpNotUndefined, 1, offset)
#define INSTR_CmpEqNull(op) INSTRUCTION(op, CmpEqNull, 0)
#define INSTR_CmpNeNull(op) INSTRUCTION(op, CmpNeNull, 0)
#define INSTR_CmpEqInt(op) INSTRUCTION(op, CmpEqInt, 1, lhs)
@@ -249,6 +250,7 @@ QT_BEGIN_NAMESPACE
F(Jump) \
F(JumpTrue) \
F(JumpFalse) \
+ F(JumpNotUndefined) \
F(CmpEqNull) \
F(CmpNeNull) \
F(CmpEqInt) \