diff --git a/es2panda/compiler/base/iterators.cpp b/es2panda/compiler/base/iterators.cpp index 08d2f57cbfbed6edb72e740852914950e445574f..4bf5f76f1fa91957cfc1f6021ad28ce338b09874 100644 --- a/es2panda/compiler/base/iterators.cpp +++ b/es2panda/compiler/base/iterators.cpp @@ -158,19 +158,21 @@ void DestructuringIterator::Step(Label *doneTarget) const Label *noClose = pg_->AllocLabel(); pg_->SetLabel(node_, labelSet.TryBegin()); + JumpIfDone(noClose); Next(); Complete(); pg_->StoreAccumulator(node_, done_); pg_->BranchIfFalse(node_, normalClose); pg_->StoreConst(node_, done_, Constant::JS_TRUE); pg_->LoadConst(node_, Constant::JS_UNDEFINED); - OnIterDone(doneTarget); pg_->Branch(node_, noClose); pg_->SetLabel(node_, normalClose); Value(); pg_->StoreAccumulator(node_, result_); + pg_->Branch(node_, labelSet.CatchEnd()); pg_->SetLabel(node_, noClose); + OnIterDone(doneTarget); pg_->SetLabel(node_, labelSet.TryEnd()); pg_->Branch(node_, labelSet.CatchEnd()); @@ -193,4 +195,10 @@ void DestructuringRestIterator::OnIterDone([[maybe_unused]] Label *doneTarget) c pg_->Branch(node_, doneTarget); } +void DestructuringIterator::JumpIfDone(Label *noClose) const +{ + pg_->LoadAccumulator(node_, done_); + pg_->BranchIfTrue(node_, noClose); +} + } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/base/iterators.h b/es2panda/compiler/base/iterators.h index 05c0eda04d30aa2288c0fec05276c7660bf5ce99..a76b3481df3a719fdaf7bbffab9eaeaa7ecd7132 100644 --- a/es2panda/compiler/base/iterators.h +++ b/es2panda/compiler/base/iterators.h @@ -102,6 +102,9 @@ public: protected: VReg done_; VReg result_; + +private: + void JumpIfDone(Label *noClose) const; }; class DestructuringRestIterator : public DestructuringIterator { diff --git a/es2panda/test/bytecode/js/destructuring/test-array-pattern-iterator-close-expected.txt b/es2panda/test/bytecode/js/destructuring/test-array-pattern-iterator-close-expected.txt index a999f19a334465be2ce6492711e5b97898a89aac..6f2ceee5a31d56ddcc2bcb30e369d51b26a33f90 100644 --- a/es2panda/test/bytecode/js/destructuring/test-array-pattern-iterator-close-expected.txt +++ b/es2panda/test/bytecode/js/destructuring/test-array-pattern-iterator-close-expected.txt @@ -20,6 +20,9 @@ sta v12 LABEL_0: LABEL_4: + lda v11 + istrue + jnez LABEL_9 lda v8 callthis0 0x5, v9 sta v10 @@ -32,13 +35,14 @@ LABEL_4: ldtrue sta v11 ldundefined - ldundefined jmp LABEL_9 LABEL_8: lda v10 ldobjbyname 0x9, value sta v12 + jmp LABEL_7 LABEL_9: + ldundefined LABEL_5: jmp LABEL_7 LABEL_6: @@ -50,6 +54,9 @@ LABEL_6: LABEL_7: sttoglobalrecord 0xb, a LABEL_10: + lda v11 + istrue + jnez LABEL_15 lda v8 callthis0 0xc, v9 sta v10 @@ -62,13 +69,14 @@ LABEL_10: ldtrue sta v11 ldundefined - ldundefined jmp LABEL_15 LABEL_14: lda v10 ldobjbyname 0x10, value sta v12 + jmp LABEL_13 LABEL_15: + ldundefined LABEL_11: jmp LABEL_13 LABEL_12: diff --git a/es2panda/test/compiler/js/language/destructuring/Destructuring-on-iterable-object-expected.txt b/es2panda/test/compiler/js/language/destructuring/Destructuring-on-iterable-object-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..d00491fd7e5bb6fa28c517a0bb32b8b506539d4d --- /dev/null +++ b/es2panda/test/compiler/js/language/destructuring/Destructuring-on-iterable-object-expected.txt @@ -0,0 +1 @@ +1 diff --git a/es2panda/test/compiler/js/language/destructuring/Destructuring-on-iterable-object.js b/es2panda/test/compiler/js/language/destructuring/Destructuring-on-iterable-object.js new file mode 100644 index 0000000000000000000000000000000000000000..ee6ad2482f43209dda9e1802f20425ffe2ce9851 --- /dev/null +++ b/es2panda/test/compiler/js/language/destructuring/Destructuring-on-iterable-object.js @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let called = 0; +let it = { + [Symbol.iterator](){ + return this; + }, + next(){ + called++; + return {done:true}; + } +} + +let [a, b, ...c] = it; +print(called); \ No newline at end of file