Implement the AddImm opcode

It is a simple opcode. The hard part was finding a sqlite statement
that uses it =)
This commit is contained in:
Glauber Costa
2025-07-30 11:02:21 -05:00
parent 218c2e65ff
commit 9e8ba5263b
4 changed files with 50 additions and 1 deletions

View File

@@ -6190,6 +6190,37 @@ pub fn op_shift_left(
Ok(InsnFunctionStepResult::Step)
}
pub fn op_add_imm(
program: &Program,
state: &mut ProgramState,
insn: &Insn,
pager: &Rc<Pager>,
mv_store: Option<&Rc<MvStore>>,
) -> Result<InsnFunctionStepResult> {
let Insn::AddImm { register, value } = insn else {
unreachable!("unexpected Insn {:?}", insn)
};
let current = &state.registers[*register];
let current_value = match current {
Register::Value(val) => val,
Register::Aggregate(_) => &Value::Null,
Register::Record(_) => &Value::Null,
};
let int_val = match current_value {
Value::Integer(i) => i + value,
Value::Float(f) => (*f as i64) + value,
Value::Text(s) => s.as_str().parse::<i64>().unwrap_or(0) + value,
Value::Blob(_) => *value, // BLOB becomes the added value
Value::Null => *value, // NULL becomes the added value
};
state.registers[*register] = Register::Value(Value::Integer(int_val));
state.pc += 1;
Ok(InsnFunctionStepResult::Step)
}
pub fn op_variable(
program: &Program,
state: &mut ProgramState,

View File

@@ -1358,6 +1358,15 @@ pub fn insn_to_str(
0,
format!("r[{dest}]=r[{lhs}] << r[{rhs}]"),
),
Insn::AddImm { register, value } => (
"AddImm",
*register as i32,
*value as i32,
0,
Value::build_text(""),
0,
format!("r[{register}]=r[{register}]+{value}"),
),
Insn::Variable { index, dest } => (
"Variable",
usize::from(*index) as i32,

View File

@@ -877,6 +877,14 @@ pub enum Insn {
dest: usize,
},
/// Add immediate value to register and force integer conversion.
/// Add the constant P2 to the value in register P1. The result is always an integer.
/// To force any register to be an integer, just add 0.
AddImm {
register: usize, // P1: target register
value: i64, // P2: immediate value to add
},
/// Get parameter variable.
Variable {
index: NonZero<usize>,
@@ -1106,6 +1114,7 @@ impl Insn {
Insn::ParseSchema { .. } => execute::op_parse_schema,
Insn::ShiftRight { .. } => execute::op_shift_right,
Insn::ShiftLeft { .. } => execute::op_shift_left,
Insn::AddImm { .. } => execute::op_add_imm,
Insn::Variable { .. } => execute::op_variable,
Insn::ZeroOrNull { .. } => execute::op_zero_or_null,
Insn::Not { .. } => execute::op_not,