diff --git a/src/compile.rs b/src/compile.rs index fae828d..345a04d 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -385,12 +385,15 @@ impl Compiler { items, body, } => { - if *is_async { - let end_labels = items - .iter() - .map(|item| { - let end_label = self.new_label(); - self.compile_expression(&item.context_expr)?; + let is_async = *is_async; + + let end_labels = items + .iter() + .map(|item| { + let end_label = self.new_label(); + self.compile_expression(&item.context_expr)?; + + if is_async { self.emit(Instruction::BeforeAsyncWith); self.emit(Instruction::GetAwaitable); self.emit(Instruction::LoadConst { @@ -398,60 +401,39 @@ impl Compiler { }); self.emit(Instruction::YieldFrom); self.emit(Instruction::SetupAsyncWith { end: end_label }); - match &item.optional_vars { - Some(var) => { - self.compile_store(var)?; - } - None => { - self.emit(Instruction::Pop); - } + } else { + self.emit(Instruction::SetupWith { end: end_label }); + } + + match &item.optional_vars { + Some(var) => { + self.compile_store(var)?; } - Ok(end_label) - }) - .collect::, CompileError>>()?; + None => { + self.emit(Instruction::Pop); + } + } + Ok(end_label) + }) + .collect::, CompileError>>()?; - self.compile_statements(body)?; + self.compile_statements(body)?; - for end_label in end_labels { - self.emit(Instruction::PopBlock); - self.emit(Instruction::EnterFinally); - self.set_label(end_label); - self.emit(Instruction::WithCleanupStart); + for end_label in end_labels { + self.emit(Instruction::PopBlock); + self.emit(Instruction::EnterFinally); + self.set_label(end_label); + self.emit(Instruction::WithCleanupStart); + + if is_async { self.emit(Instruction::GetAwaitable); self.emit(Instruction::LoadConst { value: bytecode::Constant::None, }); self.emit(Instruction::YieldFrom); - self.emit(Instruction::WithCleanupFinish); } - } else { - let end_labels = items - .iter() - .map(|item| { - let end_label = self.new_label(); - self.compile_expression(&item.context_expr)?; - self.emit(Instruction::SetupWith { end: end_label }); - match &item.optional_vars { - Some(var) => { - self.compile_store(var)?; - } - None => { - self.emit(Instruction::Pop); - } - } - Ok(end_label) - }) - .collect::, CompileError>>()?; - self.compile_statements(body)?; - - for end_label in end_labels { - self.emit(Instruction::PopBlock); - self.emit(Instruction::EnterFinally); - self.set_label(end_label); - self.emit(Instruction::WithCleanupStart); - self.emit(Instruction::WithCleanupFinish); - } + self.emit(Instruction::WithCleanupFinish); } } For {