SeekRowid VM instruction

This commit is contained in:
jussisaurio 2024-07-28 19:18:05 +03:00
parent d965998cdf
commit 97dfae437c
3 changed files with 61 additions and 0 deletions

View file

@ -270,6 +270,10 @@ impl ProgramBuilder {
} => {
*end_offset = to_offset;
}
Insn::SeekRowid { target_pc, .. } => {
assert!(*target_pc < 0);
*target_pc = to_offset;
}
_ => {
todo!("missing resolve_label for {:?}", insn);
}

View file

@ -383,6 +383,28 @@ pub fn insn_to_str(program: &Program, addr: InsnReference, insn: &Insn, indent:
.unwrap_or(format!("cursor {}", cursor_id).as_str())
),
),
Insn::SeekRowid {
cursor_id,
src_reg,
target_pc,
} => (
"SeekRowid",
*cursor_id as i32,
*src_reg as i32,
*target_pc as i32,
OwnedValue::Text(Rc::new("".to_string())),
0,
format!(
"if (r[{}]!={}.rowid) goto {}",
src_reg,
&program.cursor_ref[*cursor_id]
.1
.as_ref()
.map(|x| x.get_name())
.unwrap_or(format!("cursor {}", cursor_id).as_str()),
target_pc
),
),
Insn::DecrJumpZero { reg, target_pc } => (
"DecrJumpZero",
*reg as i32,

View file

@ -222,6 +222,13 @@ pub enum Insn {
dest: usize,
},
// Seek to a rowid in the cursor. If not found, jump to the given PC. Otherwise, continue to the next instruction.
SeekRowid {
cursor_id: CursorID,
src_reg: usize,
target_pc: BranchOffset,
},
// Decrement the given register and jump to the given PC if the result is zero.
DecrJumpZero {
reg: usize,
@ -779,6 +786,34 @@ impl Program {
}
state.pc += 1;
}
Insn::SeekRowid {
cursor_id,
src_reg,
target_pc,
} => {
let cursor = cursors.get_mut(cursor_id).unwrap();
let rowid = match &state.registers[*src_reg] {
OwnedValue::Integer(rowid) => *rowid as u64,
_ => {
return Err(LimboError::InternalError(
"SeekRowid: the value in the register is not an integer".into(),
));
}
};
match cursor.seek_rowid(rowid)? {
CursorResult::Ok(found) => {
if !found {
state.pc = *target_pc;
} else {
state.pc += 1;
}
}
CursorResult::IO => {
// If there is I/O, the instruction is restarted.
return Ok(StepResult::IO);
}
}
}
Insn::DecrJumpZero { reg, target_pc } => {
assert!(*target_pc >= 0);
match state.registers[*reg] {