diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-05-11 22:23:56 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-13 12:55:20 +0000 |
commit | 3d5ba9f86e32950204bfcdf6591c4740a8ef7507 (patch) | |
tree | 9c599ad6b7fd2bd06d0880dde70ff21d6f522bef /src/qml/jit | |
parent | 2d6b08bd17377aa6bcb663029a196a8d19cac6ac (diff) |
Add instructions to simplify for-of loops
Added an IteratorNext instruction to fetch the next
iteration value (empty if the iterator is done).
This will also help to implement array destructuring without
requiring huge amounts of byte code.
Change-Id: If96c1e81471e5e2b0b7b2af122238d87741aa371
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jit')
-rw-r--r-- | src/qml/jit/qv4assembler.cpp | 19 | ||||
-rw-r--r-- | src/qml/jit/qv4assembler_p.h | 1 | ||||
-rw-r--r-- | src/qml/jit/qv4jit.cpp | 21 | ||||
-rw-r--r-- | src/qml/jit/qv4jit_p.h | 2 |
4 files changed, 42 insertions, 1 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index c73b3919ae..736dfd0908 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -707,6 +707,12 @@ struct PlatformAssembler64 : PlatformAssemblerCommon patches.push_back({ jump, offset }); } + void jumpEmpty(int offset) + { + auto jump = branch64(Equal, AccumulatorRegister, TrustedImm64(Primitive::emptyValue().asReturnedValue())); + patches.push_back({ jump, offset }); + } + void toBoolean(std::function<void(RegisterID)> continuation) { urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerConvertible_Shift), ScratchRegister); @@ -1150,6 +1156,14 @@ struct PlatformAssembler32 : PlatformAssemblerCommon patches.push_back({ jump, offset }); } + void jumpEmpty(int offset) + { + auto notEqual = branch32(NotEqual, AccumulatorRegisterTag, TrustedImm32(Primitive::emptyValue().asReturnedValue() >> 32)); + auto jump = branch32(Equal, AccumulatorRegisterValue, TrustedImm32(Primitive::emptyValue().asReturnedValue() & 0xffffffff)); + notEqual.link(this); + patches.push_back({ jump, offset }); + } + void toBoolean(std::function<void(RegisterID)> continuation) { urshift32(AccumulatorRegisterTag, TrustedImm32(Value::IsIntegerConvertible_Shift - 32), @@ -2001,6 +2015,11 @@ void Assembler::jumpNotUndefined(int offset) pasm()->jumpNotUndefined(offset); } +void JIT::Assembler::jumpEmpty(int offset) +{ + pasm()->jumpEmpty(offset); +} + void Assembler::jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset) { pasm()->jumpStrictEqualStackSlotInt(lhs, rhs, offset); diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index f9a74edc77..99ae48e5ed 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -141,6 +141,7 @@ public: void jumpTrue(int offset); void jumpFalse(int offset); void jumpNotUndefined(int offset); + void jumpEmpty(int offset); void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset); void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset); diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp index 4f95232f0d..77024176ae 100644 --- a/src/qml/jit/qv4jit.cpp +++ b/src/qml/jit/qv4jit.cpp @@ -714,6 +714,17 @@ void BaselineJIT::generate_GetIterator(int iterator) as->checkException(); } +void BaselineJIT::generate_IteratorNext() +{ + as->saveAccumulatorInFrame(); + as->prepareCallWithArgCount(2); + as->passAccumulatorAsArg(1); + as->passEngineAsArg(0); + JIT_GENERATE_RUNTIME_CALL(Runtime::method_iteratorNext, Assembler::ResultInAccumulator); + as->checkException(); +} + + static ReturnedValue deleteMemberHelper(QV4::Function *function, const QV4::Value &base, int member) { auto engine = function->internalClass->engine; @@ -907,6 +918,7 @@ void BaselineJIT::generate_Jump(int offset) { as->jump(instructionOffset() + off void BaselineJIT::generate_JumpTrue(int offset) { as->jumpTrue(instructionOffset() + offset); } void BaselineJIT::generate_JumpFalse(int offset) { as->jumpFalse(instructionOffset() + offset); } void BaselineJIT::generate_JumpNotUndefined(int offset) { as->jumpNotUndefined(instructionOffset() + offset); } +void BaselineJIT::generate_JumpEmpty(int offset) { as->jumpEmpty(instructionOffset() + offset); } void BaselineJIT::generate_CmpEqNull() { as->cmpeqNull(); } void BaselineJIT::generate_CmpNeNull() { as->cmpneNull(); } @@ -1264,6 +1276,9 @@ void BaselineJIT::collectLabelsInBytecode() MOTH_BEGIN_INSTR(GetIterator) MOTH_END_INSTR(GetIterator) + MOTH_BEGIN_INSTR(IteratorNext) + MOTH_END_INSTR(IteratorNext) + MOTH_BEGIN_INSTR(DeleteMember) MOTH_END_INSTR(DeleteMember) @@ -1320,7 +1335,11 @@ void BaselineJIT::collectLabelsInBytecode() MOTH_BEGIN_INSTR(JumpNotUndefined) addLabel(code - start + offset); - MOTH_END_INSTR(JumpUndefined) + MOTH_END_INSTR(JumpNotUndefined) + + MOTH_BEGIN_INSTR(JumpEmpty) + addLabel(code - start + offset); + MOTH_END_INSTR(JumpEmpty) MOTH_BEGIN_INSTR(CmpEqNull) MOTH_END_INSTR(CmpEqNull) diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h index 333cf05f09..d395ea908c 100644 --- a/src/qml/jit/qv4jit_p.h +++ b/src/qml/jit/qv4jit_p.h @@ -186,6 +186,7 @@ public: void generate_PopScriptContext() override; void generate_PopContext(int reg) override; void generate_GetIterator(int iterator) override; + void generate_IteratorNext() override; void generate_DeleteMember(int member, int base) override; void generate_DeleteSubscript(int base, int index) override; void generate_DeleteName(int name) override; @@ -206,6 +207,7 @@ public: void generate_JumpTrue(int offset) override; void generate_JumpFalse(int offset) override; void generate_JumpNotUndefined(int offset) override; + void generate_JumpEmpty(int offset) override; void generate_CmpEqNull() override; void generate_CmpNeNull() override; void generate_CmpEqInt(int lhs) override; |