aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-03-20 22:40:07 +0100
committerLars Knoll <lars.knoll@qt.io>2018-04-26 21:37:48 +0000
commit1b30e8f94cc15352583e8e1f27139676683f62af (patch)
treef149be122d7e31d915f718a65ae7e9fb01f751b5
parent09cd6f8020b7c25eaaf959a48c452b01aebcf627 (diff)
Implement support for the ** and **= operators
Change-Id: I58a21e70fdd040175b52465d6ba52e7fceaf6398 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/compiler/qv4codegen.cpp11
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp4
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/jit/qv4jit.cpp19
-rw-r--r--src/qml/jit/qv4jit_p.h1
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp7
-rw-r--r--src/qml/parser/qqmljs.g18
-rw-r--r--src/qml/parser/qqmljsast_p.h2
-rw-r--r--src/qml/parser/qqmljslexer.cpp4
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations25
10 files changed, 66 insertions, 27 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 29a916bd7e..1feb61ce59 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -727,6 +727,7 @@ static QSOperator::Op baseOp(int op)
case QSOperator::InplaceAdd: return QSOperator::Add;
case QSOperator::InplaceLeftShift: return QSOperator::LShift;
case QSOperator::InplaceMod: return QSOperator::Mod;
+ case QSOperator::InplaceExp: return QSOperator::Exp;
case QSOperator::InplaceMul: return QSOperator::Mul;
case QSOperator::InplaceOr: return QSOperator::BitOr;
case QSOperator::InplaceRightShift: return QSOperator::RShift;
@@ -836,6 +837,7 @@ bool Codegen::visit(BinaryExpression *ast)
case QSOperator::InplaceAdd:
case QSOperator::InplaceLeftShift:
case QSOperator::InplaceMod:
+ case QSOperator::InplaceExp:
case QSOperator::InplaceMul:
case QSOperator::InplaceOr:
case QSOperator::InplaceRightShift:
@@ -885,6 +887,7 @@ bool Codegen::visit(BinaryExpression *ast)
case QSOperator::StrictNotEqual:
case QSOperator::Add:
case QSOperator::Div:
+ case QSOperator::Exp:
case QSOperator::Mod:
case QSOperator::Mul:
case QSOperator::Sub:
@@ -937,6 +940,14 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
}
break;
}
+ case QSOperator::Exp: {
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ Instruction::Exp exp;
+ exp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(exp);
+ break;
+ }
case QSOperator::Mul: {
left = left.storeOnStack();
right.loadInAccumulator();
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index dbdef418a0..c50e9c8379 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -608,6 +608,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << "acc, " << rhs;
MOTH_END_INSTR(ShlConst)
+ MOTH_BEGIN_INSTR(Exp)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Exp)
+
MOTH_BEGIN_INSTR(Mul)
d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Mul)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 7047c74803..763e0adce1 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -171,6 +171,7 @@ QT_BEGIN_NAMESPACE
#define INSTR_UShrConst(op) INSTRUCTION(op, UShrConst, 1, rhs)
#define INSTR_ShrConst(op) INSTRUCTION(op, ShrConst, 1, rhs)
#define INSTR_ShlConst(op) INSTRUCTION(op, ShlConst, 1, rhs)
+#define INSTR_Exp(op) INSTRUCTION(op, Exp, 1, lhs)
#define INSTR_Mul(op) INSTRUCTION(op, Mul, 1, lhs)
#define INSTR_Div(op) INSTRUCTION(op, Div, 1, lhs)
#define INSTR_Mod(op) INSTRUCTION(op, Mod, 1, lhs)
@@ -290,6 +291,7 @@ QT_BEGIN_NAMESPACE
F(UShrConst) \
F(ShrConst) \
F(ShlConst) \
+ F(Exp) \
F(Mul) \
F(Div) \
F(Mod) \
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp
index 429d721ba2..aa9c244a60 100644
--- a/src/qml/jit/qv4jit.cpp
+++ b/src/qml/jit/qv4jit.cpp
@@ -912,6 +912,22 @@ void BaselineJIT::generate_UShrConst(int rhs) { as->ushrConst(rhs); }
void BaselineJIT::generate_ShrConst(int rhs) { as->shrConst(rhs); }
void BaselineJIT::generate_ShlConst(int rhs) { as->shlConst(rhs); }
+static ReturnedValue expHelper(const Value &base, const Value &exp)
+{
+ double b = base.toNumber();
+ double e = exp.toNumber();
+ return QV4::Encode(pow(b,e));
+}
+
+void BaselineJIT::generate_Exp(int lhs) {
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(2);
+ as->passAccumulatorAsArg(1);
+ as->passRegAsArg(lhs, 0);
+ JIT_GENERATE_RUNTIME_CALL(expHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+}
void BaselineJIT::generate_Mul(int lhs) { as->mul(lhs); }
void BaselineJIT::generate_Div(int lhs) { as->div(lhs); }
void BaselineJIT::generate_Mod(int lhs) { as->mod(lhs); }
@@ -1335,6 +1351,9 @@ void BaselineJIT::collectLabelsInBytecode()
MOTH_BEGIN_INSTR(ShlConst)
MOTH_END_INSTR(ShlConst)
+ MOTH_BEGIN_INSTR(Exp)
+ MOTH_END_INSTR(Exp)
+
MOTH_BEGIN_INSTR(Mul)
MOTH_END_INSTR(Mul)
diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h
index 62866895c4..7861cdec38 100644
--- a/src/qml/jit/qv4jit_p.h
+++ b/src/qml/jit/qv4jit_p.h
@@ -237,6 +237,7 @@ public:
void generate_UShrConst(int rhs) override;
void generate_ShrConst(int rhs) override;
void generate_ShlConst(int rhs) override;
+ void generate_Exp(int lhs) override;
void generate_Mul(int lhs) override;
void generate_Div(int lhs) override;
void generate_Mod(int lhs) override;
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index a2a602ac58..f2c9f836ae 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -1273,6 +1273,13 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
}
MOTH_END_INSTR(Sub)
+ MOTH_BEGIN_INSTR(Exp)
+ const Value left = STACK_VALUE(lhs);
+ double base = left.toNumber();
+ double exp = ACC.toNumber();
+ acc = QV4::Encode(pow(base,exp));
+ MOTH_END_INSTR(Exp)
+
MOTH_BEGIN_INSTR(Mul)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(Value::integerCompatible(left, ACC))) {
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 7defdb8a08..6ee4fe2b18 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -63,7 +63,8 @@
%token T_RBRACE "}" T_RBRACKET "]" T_REMAINDER "%"
%token T_REMAINDER_EQ "%=" T_RETURN "return" T_RPAREN ")"
%token T_SEMICOLON ";" T_AUTOMATIC_SEMICOLON T_STAR "*"
-%token T_STAR_STAR "**" T_STAR_EQ "*=" T_STRING_LITERAL "string literal"
+%token T_STAR_STAR "**" T_STAR_STAR_EQ "**=" T_STAR_EQ "*="
+%token T_STRING_LITERAL "string literal"
%token T_PROPERTY "property" T_SIGNAL "signal" T_READONLY "readonly"
%token T_SWITCH "switch" T_THIS "this" T_THROW "throw"
%token T_TILDE "~" T_TRY "try" T_TYPEOF "typeof"
@@ -2186,7 +2187,13 @@ UnaryExpression: T_NOT UnaryExpression;
ExponentiationExpression: UnaryExpression;
ExponentiationExpression: UpdateExpression T_STAR_STAR ExponentiationExpression;
-/. case $rule_number: { UNIMPLEMENTED; } ./
+/.
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Exp, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
+./
MultiplicativeExpression: ExponentiationExpression;
@@ -2489,6 +2496,13 @@ AssignmentOperator: T_STAR_EQ;
} break;
./
+AssignmentOperator: T_STAR_STAR_EQ;
+/.
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceExp;
+ } break;
+./
+
AssignmentOperator: T_DIVIDE_EQ;
/.
case $rule_number: {
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index cd5c3a1021..6992985097 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -77,6 +77,8 @@ enum Op {
Div,
InplaceDiv,
Equal,
+ Exp,
+ InplaceExp,
Ge,
Gt,
In,
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index 1165183483..1617f3dfa5 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -661,6 +661,10 @@ again:
return T_STAR_EQ;
} else if (_char == QLatin1Char('*')) {
scanChar();
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_STAR_STAR_EQ;
+ }
return T_STAR_STAR;
}
return T_STAR;
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 3acbee0d14..753381698f 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -5496,34 +5496,9 @@ language/expressions/equals/get-symbol-to-prim-err
language/expressions/equals/symbol-abstract-equality-comparison
language/expressions/equals/symbol-strict-equality-comparison
language/expressions/equals/to-prim-hint
-language/expressions/exponentiation/applying-the-exp-operator_A1
-language/expressions/exponentiation/applying-the-exp-operator_A11
-language/expressions/exponentiation/applying-the-exp-operator_A12
-language/expressions/exponentiation/applying-the-exp-operator_A13
-language/expressions/exponentiation/applying-the-exp-operator_A14
-language/expressions/exponentiation/applying-the-exp-operator_A15
-language/expressions/exponentiation/applying-the-exp-operator_A16
-language/expressions/exponentiation/applying-the-exp-operator_A17
-language/expressions/exponentiation/applying-the-exp-operator_A18
-language/expressions/exponentiation/applying-the-exp-operator_A19
-language/expressions/exponentiation/applying-the-exp-operator_A2
-language/expressions/exponentiation/applying-the-exp-operator_A20
-language/expressions/exponentiation/applying-the-exp-operator_A21
-language/expressions/exponentiation/applying-the-exp-operator_A22
-language/expressions/exponentiation/applying-the-exp-operator_A23
-language/expressions/exponentiation/applying-the-exp-operator_A3
-language/expressions/exponentiation/applying-the-exp-operator_A4
-language/expressions/exponentiation/applying-the-exp-operator_A5
-language/expressions/exponentiation/applying-the-exp-operator_A6
language/expressions/exponentiation/applying-the-exp-operator_A7
language/expressions/exponentiation/applying-the-exp-operator_A8
-language/expressions/exponentiation/applying-the-exp-operator_A9
-language/expressions/exponentiation/exp-assignment-operator
-language/expressions/exponentiation/exp-operator
-language/expressions/exponentiation/exp-operator-evaluation-order
-language/expressions/exponentiation/exp-operator-precedence-unary-expression-semantics
language/expressions/exponentiation/exp-operator-precedence-update-expression-semantics
-language/expressions/exponentiation/int32_min-exponent
language/expressions/exponentiation/order-of-evaluation
language/expressions/function/arguments-with-arguments-fn
language/expressions/function/arguments-with-arguments-lex