Skip to content

Commit

Permalink
[FIX] fixed segmentation fault due to wrong stack usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Aug 28, 2024
1 parent 957afd1 commit dedfb91
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 13 deletions.
7 changes: 1 addition & 6 deletions src/IR/nodes/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,8 @@ impl Ir for Call<Function, Vec<Var>, Var> {
fn uses(&self, var: &Var) -> bool {
let mut uses = false;

if self.inner3 == *var {
uses = true;
}


for arg in &self.inner2 {
if *arg == *var {
if arg.name == var.name {
uses = true;
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/Target/target_descr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,21 @@ impl BackendInfos {
}
}

/// Delets the variable of the varsStorage (giving out it's resources)
/// Delets the variable of the varsStorage (freeing its resources)
pub(crate) fn drop(&mut self, var: &Var) {
if let Some(loc) = &self.varsStorage.get(var) {
if let VarStorage::Register(reg) = &loc {
self.dropReg(reg.clone());
} // don't decrease the stack offset because if it isn't at the bottom other variables will may be overriden
} else {
panic!("variable {} has no location", var.name);
}
}

pub(crate) fn increase_mem(&mut self) {
self.shadow += 8;
}

/// Adds the register back to the usable registers in the front
pub(crate) fn dropReg(&mut self, reg: Box<dyn Reg>) {
self.openUsableRegisters64.push_front(reg.from(reg.sub64()));
Expand Down
4 changes: 1 addition & 3 deletions src/Target/x64/asm/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ impl Optimize<Instr> for Vec<Instr> {

if instr.mnemonic == Mnemonic::StartOptimization {
optimize = true;
}

if instr.mnemonic == Mnemonic::EndOptimization {
} else if instr.mnemonic == Mnemonic::EndOptimization {
optimize = false;
}

Expand Down
26 changes: 23 additions & 3 deletions src/Target/x64/compilation/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@ pub(crate) fn CompileCall(call: &Call<Function, Vec<Var>, Var>, registry: &mut T
let var = registry.backend.getVarByReg(reg.clone());

if let Some(var) = var { // get the var
asm.push( Instr::with2(Mnemonic::Mov, Operand::Mem(x64Reg::Rbp - (offset as u32)), Operand::Reg(reg.clone())) );
saved_var_memory_locations.insert(var.clone(), offset);
offset += 8;
if block.isVarUsedAfterNode(&boxed, &var) || call.inner2.contains(var)/* && registry.call.args64().contains(reg.as_any().downcast_ref::<x64Reg>().unwrap())*/ {
asm.push( Instr::with2(Mnemonic::Mov, Operand::Mem(x64Reg::Rbp - (offset as u32)), Operand::Reg(reg.clone())) );
saved_var_memory_locations.insert(var.clone(), offset);
offset += 8;
} /*else {
eprintln!("don't save {} which has location {:?}", var, reg);
}*/
}
}
}

let mut reg_args = 0;

let mut to_pop = vec![];

for arg in &call.inner2 {
let loc = if let Some((x, y)) = registry.backend.varsStorage.get_key_value(arg) {
(x, y)
Expand All @@ -54,6 +60,9 @@ pub(crate) fn CompileCall(call: &Call<Function, Vec<Var>, Var>, registry: &mut T
if args.contains(reg.as_any().downcast_ref::<x64Reg>().unwrap()) {
if let Some(offset) = saved_var_memory_locations.get(arg) {
asm.push( Instr::with2(Mnemonic::Mov, Operand::Reg(args[reg_args].boxed()), Operand::Mem(x64Reg::Rbp - (*offset as u32))));
} else {
eprintln!("arg {:?} wasn't saved but it needs to be put into {:?}", reg, args[reg_args]);
asm.push(Instr::with2(Mnemonic::Mov, Operand::Reg(args[reg_args].boxed()), Operand::Reg(reg.clone())));
}
} else {
asm.push(Instr::with2(Mnemonic::Mov, Operand::Reg(args[reg_args].boxed()), Operand::Reg(reg.clone())));
Expand All @@ -62,6 +71,7 @@ pub(crate) fn CompileCall(call: &Call<Function, Vec<Var>, Var>, registry: &mut T
reg_args += 1;
} else {
asm.push( Instr::with1(Mnemonic::Push, Operand::Reg(reg.clone())));
to_pop.push(reg.clone());
}
},
VarStorage::Memory(mem) => {
Expand All @@ -81,9 +91,17 @@ pub(crate) fn CompileCall(call: &Call<Function, Vec<Var>, Var>, registry: &mut T
}
}

if registry.call.reset_eax() {
asm.push( Instr::with2(Mnemonic::Xor, Operand::Reg(x64Reg::Eax.boxed()), Operand::Reg(x64Reg::Eax.boxed())));
}

asm.push( Instr::with1(Mnemonic::Call, Operand::Imm(0)) );
asm.push( Instr::with1(Mnemonic::Link, Operand::LinkDestination(call.inner1.name.to_string(), -4)) );

for reg in to_pop {
asm.push( Instr::with1(Mnemonic::Pop, Operand::Reg(reg)) );
}

if call.inner1.ty.ret != TypeMetadata::Void && block.isVarUsedAfterNode(&boxed, &call.inner3){
let store = if let Some(reg) = registry.backend.getOpenRegBasedOnTy(call.inner3.ty) {
match call.inner1.ty.ret {
Expand Down Expand Up @@ -118,6 +136,8 @@ pub(crate) fn CompileCall(call: &Call<Function, Vec<Var>, Var>, registry: &mut T
}

for (var, off) in saved_var_memory_locations {
registry.backend.increase_mem();

let reg = if let Some(VarStorage::Register(reg)) = registry.backend.varsStorage.get(&var) {
reg.to_owned()
} else { todo!() }; // shouldn't happen
Expand Down

0 comments on commit dedfb91

Please sign in to comment.