From 05a6616803af1af8b2e1ebe111dca479c201e25a Mon Sep 17 00:00:00 2001 From: jussisaurio Date: Sat, 17 Aug 2024 14:12:57 +0300 Subject: [PATCH] BytecodeGenerator struct --- core/translate/emitter.rs | 144 +++++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 50 deletions(-) diff --git a/core/translate/emitter.rs b/core/translate/emitter.rs index a772165a6..e263a4ee0 100644 --- a/core/translate/emitter.rs +++ b/core/translate/emitter.rs @@ -807,64 +807,108 @@ impl Emitter for Operator { } } -pub fn emit_program( +pub struct BytecodeGenerator { + program: ProgramBuilder, database_header: Rc>, - mut select_plan: Plan, -) -> Result { - 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(); + metadata: Metadata, + plan: Plan, +} - let mut metadata = Metadata { - termination_labels: vec![halt_label], - next_row_labels: HashMap::new(), - rewind_labels: Vec::new(), - aggregation_start_registers: HashMap::new(), - sorts: HashMap::new(), - left_joins: HashMap::new(), - }; - - loop { - match select_plan.root_operator.step( - &mut program, - &mut metadata, - &select_plan.referenced_tables, - )? { - OpStepResult::Continue => {} - OpStepResult::ReadyToEmit => { - select_plan.root_operator.result_row( - &mut program, - &select_plan.referenced_tables, - &mut metadata, - None, - )?; - } - OpStepResult::Done => { - break; - } +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, } } - 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(program.build(database_header)) + Ok((init_label, halt_label, start_offset)) + } + + 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); + + 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 => { + break; + } + } + } + + self.epilogue(init_label, halt_label, start_offset)?; + + self.build() + } +} + +pub fn emit_program(database_header: Rc>, plan: Plan) -> Result { + let generator = BytecodeGenerator::new(plan, database_header); + generator.generate() } fn table_columns(