Deduplicate async/normal with compilation code

This commit is contained in:
Noah 2019-10-17 11:36:23 -05:00 committed by coolreader18
parent ae825125a5
commit 19f62b97a3

View file

@ -385,12 +385,15 @@ impl<O: OutputStream> Compiler<O> {
items, items,
body, body,
} => { } => {
if *is_async { let is_async = *is_async;
let end_labels = items let end_labels = items
.iter() .iter()
.map(|item| { .map(|item| {
let end_label = self.new_label(); let end_label = self.new_label();
self.compile_expression(&item.context_expr)?; self.compile_expression(&item.context_expr)?;
if is_async {
self.emit(Instruction::BeforeAsyncWith); self.emit(Instruction::BeforeAsyncWith);
self.emit(Instruction::GetAwaitable); self.emit(Instruction::GetAwaitable);
self.emit(Instruction::LoadConst { self.emit(Instruction::LoadConst {
@ -398,6 +401,10 @@ impl<O: OutputStream> Compiler<O> {
}); });
self.emit(Instruction::YieldFrom); self.emit(Instruction::YieldFrom);
self.emit(Instruction::SetupAsyncWith { end: end_label }); self.emit(Instruction::SetupAsyncWith { end: end_label });
} else {
self.emit(Instruction::SetupWith { end: end_label });
}
match &item.optional_vars { match &item.optional_vars {
Some(var) => { Some(var) => {
self.compile_store(var)?; self.compile_store(var)?;
@ -417,43 +424,18 @@ impl<O: OutputStream> Compiler<O> {
self.emit(Instruction::EnterFinally); self.emit(Instruction::EnterFinally);
self.set_label(end_label); self.set_label(end_label);
self.emit(Instruction::WithCleanupStart); self.emit(Instruction::WithCleanupStart);
if is_async {
self.emit(Instruction::GetAwaitable); self.emit(Instruction::GetAwaitable);
self.emit(Instruction::LoadConst { self.emit(Instruction::LoadConst {
value: bytecode::Constant::None, value: bytecode::Constant::None,
}); });
self.emit(Instruction::YieldFrom); 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::<Result<Vec<_>, 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 { For {
is_async, is_async,
target, target,