add support to handle tostulover choice (#8)

from 7bd3db8e21
This commit is contained in:
2026-05-01 16:34:57 +08:00
parent aafe7411e2
commit 50e76bbb6b

View File

@@ -418,11 +418,12 @@ impl<'a> Disasm<'a> {
} }
} else { } else {
self.stack.clear(); self.stack.clear();
self.variables.clear(); // self.variables.clear();
} }
} else { } else {
// DO NOT clear variables here. Variables are local registers and persist across math/logic ops.
self.stack.clear(); self.stack.clear();
self.variables.clear(); // self.variables.clear();
} }
self.pre_is_hover_text_move = is_hover_text_move; self.pre_is_hover_text_move = is_hover_text_move;
self.pre_is_hover_text_push = is_hover_text_push; self.pre_is_hover_text_push = is_hover_text_push;
@@ -540,37 +541,29 @@ impl<'a> Disasm<'a> {
} }
} }
self.stack.clear(); self.stack.clear();
self.variables.clear(); // self.variables.clear();
continue; continue;
} }
match instr.opcode { match instr.opcode {
ENTER => { ENTER => {
current_func_args = Some((instr.offset, instr.operands[0].value())); current_func_args = Some((instr.offset, instr.operands[0].value()));
self.stack.clear(); self.stack.clear();
self.variables.clear(); self.variables.clear(); // Safe to clear here, entering a new function frame
} }
MOV if instr.operands[0].typ() == OperandType::Variable => { MOV => {
self.variables self.handle_mov_instruction(instr)?;
.insert(instr.operands[0].value(), instr.operands[1]);
} }
PUSH => { PUSH => {
if instr.operands[0].typ() == OperandType::Variable self.handle_push_instruction(instr)?;
&& self.variables.contains_key(&instr.operands[0].value())
{
let var = self.variables.get(&instr.operands[0].value()).unwrap();
self.stack.push(*var);
} else {
self.stack.push(instr.operands[0]);
}
} }
RET => { RET => {
current_func_args = None; current_func_args = None;
self.stack.clear(); self.stack.clear();
self.variables.clear(); self.variables.clear(); // Safe to clear here, leaving function frame
} }
_ => { _ => {
self.stack.clear(); self.stack.clear();
self.variables.clear(); // self.variables.clear();
} }
} }
} }
@@ -579,8 +572,13 @@ impl<'a> Disasm<'a> {
fn handle_mov_instruction(&mut self, instr: Instruction) -> Result<()> { fn handle_mov_instruction(&mut self, instr: Instruction) -> Result<()> {
if instr.operands[0].typ() == OperandType::Variable { if instr.operands[0].typ() == OperandType::Variable {
self.variables let mut rhs = instr.operands[1].clone();
.insert(instr.operands[0].value(), instr.operands[1]); if rhs.typ() == OperandType::Variable {
self.variables.get(&rhs.value()).map(|resolved| {
rhs = resolved.clone();
});
}
self.variables.insert(instr.operands[0].value(), rhs);
} }
Ok(()) Ok(())
} }
@@ -626,10 +624,10 @@ impl<'a> Disasm<'a> {
} }
fn handle_call_instruction(&mut self, instr: Instruction) -> Result<()> { fn handle_call_instruction(&mut self, instr: Instruction) -> Result<()> {
self.handle_call_instruction_internal(instr)?; let err = self.handle_call_instruction_internal(instr);
self.stack.clear(); self.stack.clear();
self.variables.clear(); // self.variables.clear();
Ok(()) err
} }
fn handle_call_instruction_internal(&mut self, instr: Instruction) -> Result<()> { fn handle_call_instruction_internal(&mut self, instr: Instruction) -> Result<()> {
@@ -683,10 +681,10 @@ impl<'a> Disasm<'a> {
} }
fn handle_message_instruction(&mut self) -> Result<()> { fn handle_message_instruction(&mut self) -> Result<()> {
self.handle_message_instruction_internal()?; let err = self.handle_message_instruction_internal();
self.stack.clear(); self.stack.clear();
self.variables.clear(); // self.variables.clear();
Ok(()) err
} }
fn handle_another_message(&mut self) -> Result<()> { fn handle_another_message(&mut self) -> Result<()> {
@@ -747,10 +745,10 @@ impl<'a> Disasm<'a> {
} }
fn handle_select_choice_instruction(&mut self) -> Result<()> { fn handle_select_choice_instruction(&mut self) -> Result<()> {
self.handle_select_choice_instruction_internal()?; let err = self.handle_select_choice_instruction_internal();
self.stack.clear(); self.stack.clear();
self.variables.clear(); // self.variables.clear();
Ok(()) err
} }
fn handle_select_choice_instruction_internal(&mut self) -> Result<()> { fn handle_select_choice_instruction_internal(&mut self) -> Result<()> {