mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-08 10:44:20 +01:00
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:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user