From a79c0c5b34b07f12cb46b1797fcb4b0df1e30720 Mon Sep 17 00:00:00 2001 From: jussisaurio Date: Sat, 17 Aug 2024 14:35:44 +0300 Subject: [PATCH] BytecodeGenerator struct was unnecessary --- core/translate/emitter.rs | 155 ++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 89 deletions(-) diff --git a/core/translate/emitter.rs b/core/translate/emitter.rs index 107bfdb70..cac0aafe3 100644 --- a/core/translate/emitter.rs +++ b/core/translate/emitter.rs @@ -70,7 +70,7 @@ pub struct SortMetadata { pub done_label: BranchOffset, } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct Metadata { // labels for the instructions that terminate the execution when a conditional check evaluates to false. typically jumps to Halt, but can also jump to AggFinal if a parent in the tree is an aggregation termination_labels: Vec, @@ -819,103 +819,80 @@ impl Emitter for Operator { } } -pub struct BytecodeGenerator { - program: ProgramBuilder, - database_header: Rc>, - metadata: Metadata, - plan: Plan, +fn prologue() -> Result<( + ProgramBuilder, + Metadata, + BranchOffset, + BranchOffset, + BranchOffset, +)> { + let mut program = ProgramBuilder::new(); + let init_label = program.allocate_label(); + let halt_label = program.allocate_label(); + + program.emit_insn_with_label_dependency( + Insn::Init { + target_pc: init_label, + }, + init_label, + ); + + let start_offset = program.offset(); + + let metadata = Metadata { + termination_labels: vec![halt_label], + ..Default::default() + }; + + Ok((program, metadata, init_label, halt_label, start_offset)) } -impl BytecodeGenerator { - pub fn new(plan: Plan, database_header: Rc>) -> Self { - Self { - program: ProgramBuilder::new(), - database_header, - metadata: Metadata { - termination_labels: Vec::new(), - next_row_labels: HashMap::new(), - rewind_labels: Vec::new(), - aggregation_start_registers: HashMap::new(), - sorts: HashMap::new(), - left_joins: HashMap::new(), - }, - plan, - } - } +fn epilogue( + program: &mut ProgramBuilder, + init_label: BranchOffset, + halt_label: BranchOffset, + start_offset: BranchOffset, +) -> Result<()> { + program.resolve_label(halt_label, program.offset()); + program.emit_insn(Insn::Halt); - fn prologue(&mut self) -> Result<(BranchOffset, BranchOffset, BranchOffset)> { - let init_label = self.program.allocate_label(); - let halt_label = self.program.allocate_label(); - self.metadata.termination_labels.push(halt_label); + program.resolve_label(init_label, program.offset()); + program.emit_insn(Insn::Transaction); - self.program.emit_insn_with_label_dependency( - Insn::Init { - target_pc: init_label, - }, - init_label, - ); + program.emit_constant_insns(); + program.emit_insn(Insn::Goto { + target_pc: start_offset, + }); - let start_offset = self.program.offset(); + program.resolve_deferred_labels(); - Ok((init_label, halt_label, start_offset)) - } + Ok(()) +} - fn epilogue( - &mut self, - init_label: BranchOffset, - halt_label: BranchOffset, - start_offset: BranchOffset, - ) -> Result<()> { - self.program - .resolve_label(halt_label, self.program.offset()); - self.program.emit_insn(Insn::Halt); +pub fn emit_program( + database_header: Rc>, + mut plan: Plan, +) -> Result { + let (mut program, mut metadata, init_label, halt_label, start_offset) = prologue()?; - self.program - .resolve_label(init_label, self.program.offset()); - self.program.emit_insn(Insn::Transaction); - - self.program.emit_constant_insns(); - self.program.emit_insn(Insn::Goto { - target_pc: start_offset, - }); - - self.program.resolve_deferred_labels(); - - Ok(()) - } - - fn build(self) -> Result { - Ok(self.program.build(self.database_header)) - } - - pub fn generate(mut self) -> Result { - let (init_label, halt_label, start_offset) = self.prologue()?; - - loop { - match self.plan.root_operator.step( - &mut self.program, - &mut self.metadata, - &self.plan.referenced_tables, - )? { - OpStepResult::Continue => {} - OpStepResult::ReadyToEmit => { - self.plan.root_operator.result_row( - &mut self.program, - &self.plan.referenced_tables, - &mut self.metadata, - None, - )?; - } - OpStepResult::Done => { - self.epilogue(init_label, halt_label, start_offset)?; - return self.build(); - } + loop { + match plan + .root_operator + .step(&mut program, &mut metadata, &plan.referenced_tables)? + { + OpStepResult::Continue => {} + OpStepResult::ReadyToEmit => { + plan.root_operator.result_row( + &mut program, + &plan.referenced_tables, + &mut metadata, + None, + )?; + } + OpStepResult::Done => { + epilogue(&mut program, init_label, halt_label, start_offset)?; + return Ok(program.build(database_header)); } } } } - -pub fn emit_program(database_header: Rc>, plan: Plan) -> Result { - let generator = BytecodeGenerator::new(plan, database_header); - generator.generate() -}