@@ -180,11 +180,45 @@ impl ByteCompiler<'_, '_> {
180180 self . emit_opcode ( Opcode :: ValueNotNullOrUndefined ) ;
181181 self . emit_opcode ( Opcode :: GetIterator ) ;
182182
183+ // TODO: maybe, refactor this to be more condensed.
184+ let handler_index = self . push_handler ( ) ;
183185 for element in pattern. bindings ( ) {
184186 self . compile_array_pattern_element ( element, def) ;
185187 }
188+ let handler_end_address = self . next_opcode_location ( ) ;
186189
190+ self . emit_opcode ( Opcode :: PushFalse ) ;
191+
192+ let exit = self . jump ( ) ;
193+ let handler_address = self . next_opcode_location ( ) ;
194+ self . emit_opcode ( Opcode :: Exception ) ;
195+ self . emit_opcode ( Opcode :: PushTrue ) ;
196+ self . patch_jump ( exit) ;
197+
198+ self . handlers [ handler_index as usize ] . handler = handler_address;
199+ self . handlers [ handler_index as usize ] . range . end = handler_end_address;
200+
201+ let iterator_close_handler = self . push_handler ( ) ;
187202 self . iterator_close ( false ) ;
203+
204+ let exit = self . jump ( ) ;
205+ let iterator_close_handler_address = self . next_opcode_location ( ) ;
206+ {
207+ let jump = self . jump_if_false ( ) ;
208+ self . emit_opcode ( Opcode :: Throw ) ;
209+ self . patch_jump ( jump) ;
210+ }
211+ self . emit_opcode ( Opcode :: ReThrow ) ;
212+ self . patch_jump ( exit) ;
213+
214+ let jump = self . jump_if_false ( ) ;
215+ self . emit_opcode ( Opcode :: Throw ) ;
216+ self . patch_jump ( jump) ;
217+
218+ self . handlers [ iterator_close_handler as usize ] . handler =
219+ iterator_close_handler_address;
220+ self . handlers [ iterator_close_handler as usize ] . range . end =
221+ iterator_close_handler_address;
188222 }
189223 }
190224 }
@@ -198,15 +232,15 @@ impl ByteCompiler<'_, '_> {
198232 match element {
199233 // ArrayBindingPattern : [ Elision ]
200234 Elision => {
201- self . emit_opcode ( Opcode :: IteratorNext ) ;
235+ self . emit_opcode ( Opcode :: IteratorNextWithoutPop ) ;
202236 }
203237 // SingleNameBinding : BindingIdentifier Initializer[opt]
204238 SingleName {
205239 ident,
206240 default_init,
207241 } => {
208- self . emit_opcode ( Opcode :: IteratorNext ) ;
209- self . emit_opcode ( Opcode :: IteratorValue ) ;
242+ self . emit_opcode ( Opcode :: IteratorNextWithoutPop ) ;
243+ self . emit_opcode ( Opcode :: IteratorValueWithoutPop ) ;
210244 if let Some ( init) = default_init {
211245 let skip = self . emit_opcode_with_operand ( Opcode :: JumpIfNotUndefined ) ;
212246 self . compile_expr ( init, true ) ;
@@ -216,17 +250,17 @@ impl ByteCompiler<'_, '_> {
216250 }
217251 PropertyAccess { access } => {
218252 self . access_set ( Access :: Property { access } , false , |compiler, _level| {
219- compiler. emit_opcode ( Opcode :: IteratorNext ) ;
220- compiler. emit_opcode ( Opcode :: IteratorValue ) ;
253+ compiler. emit_opcode ( Opcode :: IteratorNextWithoutPop ) ;
254+ compiler. emit_opcode ( Opcode :: IteratorValueWithoutPop ) ;
221255 } ) ;
222256 }
223257 // BindingElement : BindingPattern Initializer[opt]
224258 Pattern {
225259 pattern,
226260 default_init,
227261 } => {
228- self . emit_opcode ( Opcode :: IteratorNext ) ;
229- self . emit_opcode ( Opcode :: IteratorValue ) ;
262+ self . emit_opcode ( Opcode :: IteratorNextWithoutPop ) ;
263+ self . emit_opcode ( Opcode :: IteratorValueWithoutPop ) ;
230264
231265 if let Some ( init) = default_init {
232266 let skip = self . emit_opcode_with_operand ( Opcode :: JumpIfNotUndefined ) ;
0 commit comments