Skip to content

Commit

Permalink
WIP: start fixing drop issues
Browse files Browse the repository at this point in the history
  • Loading branch information
yorickpeterse committed Dec 8, 2024
1 parent 6db033d commit a08ee42
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 98 deletions.
73 changes: 55 additions & 18 deletions compiler/src/mir/specialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ fn shapes_compatible_with_bounds(
// This ultimately ensures that we don't try to specialize some
// method over e.g. `Option[Int32]` where it's exected `Int32`
// implements a certain trait when it doesn't.
let ins = match shape {
Shape::Stack(v) | Shape::StackMut(v) | Shape::StackRef(v) => v,
_ => continue,
};
let Some(ins) = shape.as_stack_instance() else { continue };

if !TypeChecker::new(db).class_compatible_with_bound(ins, bound) {
return false;
Expand Down Expand Up @@ -401,6 +398,35 @@ impl<'a, 'b> Specialize<'a, 'b> {
.specialize(reg.value_type);
}

// TODO: remove
//for block in &mut method.body.blocks {
// for ins in &mut block.instructions {
// let idx = match ins {
// Instruction::CallStatic(i) => i.type_arguments,
// Instruction::CallInstance(i) => i.type_arguments,
// Instruction::Send(i) => i.type_arguments,
// Instruction::CallDynamic(i) => i.type_arguments,
// _ => None,
// };
//
// let Some(targs) =
// idx.and_then(|i| mir.type_arguments.get_mut(i))
// else {
// continue;
// };
//
// for typ in targs.values_mut() {
// *typ = TypeSpecializer::new(
// &mut self.state.db,
// self.intern,
// &self.shapes,
// &mut self.classes,
// )
// .specialize(*typ);
// }
// }
//}

for block in &mut method.body.blocks {
for instruction in &mut block.instructions {
match instruction {
Expand Down Expand Up @@ -839,6 +865,15 @@ impl<'a, 'b> Specialize<'a, 'b> {
// `Iter[String]` produce a different method ID.
let spec_key = ordered_shapes_from_map(&base_shapes);

// TODO: remove
for shape in &spec_key {
let Some(ins) = shape.as_stack_instance() else { continue };
assert!(ins
.instance_of()
.specialization_source(&self.state.db)
.is_some());
}

if let Some(new) = method.specialization(&self.state.db, &spec_key) {
return (new, method_shapes);
}
Expand Down Expand Up @@ -928,6 +963,15 @@ impl<'a, 'b> Specialize<'a, 'b> {
.map(|p| *shapes.get(&p).unwrap())
.collect();

// TODO: remove
for shape in &key {
let Some(ins) = shape.as_stack_instance() else { continue };
assert!(ins
.instance_of()
.specialization_source(&self.state.db)
.is_some());
}

if let Some(new) = method.specialization(&self.state.db, &key) {
return new;
}
Expand Down Expand Up @@ -1340,25 +1384,20 @@ impl<'a, 'b, 'c> ExpandDrop<'a, 'b, 'c> {
| Shape::Float(_)
| Shape::Nil
| Shape::Boolean
| Shape::Pointer => {
self.ignore_value(block_id, after_id);
}
Shape::Stack(t) if t.instance_of().is_copy_type(self.db) => {
| Shape::Pointer
| Shape::Copy(_) => {
self.ignore_value(block_id, after_id);
}
Shape::Stack(_) => {
self.drop_owned(block_id, after_id, val, ins.dropper, loc);
}
Shape::Mut | Shape::Ref => {
self.drop_reference(block_id, after_id, val, loc);
}
Shape::Atomic | Shape::String => {
self.drop_atomic(block_id, after_id, val, loc);
}
Shape::Owned => {
Shape::Owned | Shape::Inline(_) => {
self.drop_owned(block_id, after_id, val, ins.dropper, loc);
}
Shape::StackRef(t) | Shape::StackMut(t) => {
Shape::InlineRef(t) | Shape::InlineMut(t) => {
self.drop_stack_borrow(block_id, after_id, val, t, loc);
}
}
Expand Down Expand Up @@ -1542,7 +1581,8 @@ impl<'a, 'b, 'c> ExpandBorrow<'a, 'b, 'c> {
| Shape::Float(_)
| Shape::Nil
| Shape::Boolean
| Shape::Pointer => {
| Shape::Pointer
| Shape::Copy(_) => {
// These values should be left as-is.
}
Shape::Mut | Shape::Ref | Shape::Owned => {
Expand All @@ -1551,10 +1591,7 @@ impl<'a, 'b, 'c> ExpandBorrow<'a, 'b, 'c> {
Shape::Atomic | Shape::String => {
self.block_mut(block_id).increment_atomic(val, loc);
}
Shape::Stack(t) if t.instance_of().is_copy_type(self.db) => {
// Nothing to do
}
Shape::Stack(t) | Shape::StackRef(t) | Shape::StackMut(t) => {
Shape::Inline(t) | Shape::InlineRef(t) | Shape::InlineMut(t) => {
self.borrow_inline_type(block_id, val, t, loc);
}
}
Expand Down
36 changes: 21 additions & 15 deletions compiler/src/symbol_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,26 @@ pub(crate) fn format_shape(db: &Database, shape: Shape, buf: &mut String) {
Shape::Atomic => write!(buf, "a"),
Shape::Nil => write!(buf, "n"),
Shape::Pointer => write!(buf, "p"),
Shape::Stack(ins) => {
let _ = write!(buf, "SO{}.", ins.instance_of().module(db).name(db));
Shape::Copy(ins) => {
let _ = write!(buf, "C{}.", ins.instance_of().module(db).name(db));

format_class_name(db, ins.instance_of(), buf);
Ok(())
}
Shape::StackRef(ins) => {
let _ = write!(buf, "SR{}.", ins.instance_of().module(db).name(db));
Shape::Inline(ins) => {
let _ = write!(buf, "IO{}.", ins.instance_of().module(db).name(db));

format_class_name(db, ins.instance_of(), buf);
Ok(())
}
Shape::StackMut(ins) => {
let _ = write!(buf, "SM{}.", ins.instance_of().module(db).name(db));
Shape::InlineRef(ins) => {
let _ = write!(buf, "IR{}.", ins.instance_of().module(db).name(db));

format_class_name(db, ins.instance_of(), buf);
Ok(())
}
Shape::InlineMut(ins) => {
let _ = write!(buf, "IM{}.", ins.instance_of().module(db).name(db));

format_class_name(db, ins.instance_of(), buf);
Ok(())
Expand Down Expand Up @@ -212,17 +218,17 @@ mod tests {
&mut db,
vec![
Shape::Int(64, Sign::Signed),
Shape::Stack(ClassInstance::new(cls2)),
Shape::Inline(ClassInstance::new(cls2)),
],
);
cls2.set_shapes(&mut db, vec![Shape::String]);
cls3.set_shapes(
&mut db,
vec![Shape::StackRef(ClassInstance::new(cls2))],
vec![Shape::InlineRef(ClassInstance::new(cls2))],
);
cls4.set_shapes(
&mut db,
vec![Shape::StackMut(ClassInstance::new(cls2))],
vec![Shape::InlineMut(ClassInstance::new(cls2))],
);

assert_eq!(name(&db, Shape::Owned), "o");
Expand All @@ -237,16 +243,16 @@ mod tests {
assert_eq!(name(&db, Shape::Nil), "n");
assert_eq!(name(&db, Shape::Pointer), "p");
assert_eq!(
name(&db, Shape::Stack(ClassInstance::new(cls1))),
"SOa.b.c.A#i64SOa.b.c.B#s"
name(&db, Shape::Inline(ClassInstance::new(cls1))),
"IOa.b.c.A#i64IOa.b.c.B#s"
);
assert_eq!(
name(&db, Shape::StackMut(ClassInstance::new(cls3))),
"SMa.b.c.C#SRa.b.c.B#s"
name(&db, Shape::InlineMut(ClassInstance::new(cls3))),
"IMa.b.c.C#IRa.b.c.B#s"
);
assert_eq!(
name(&db, Shape::StackRef(ClassInstance::new(cls4))),
"SRa.b.c.D#SMa.b.c.B#s"
name(&db, Shape::InlineRef(ClassInstance::new(cls4))),
"IRa.b.c.D#IMa.b.c.B#s"
);
}
}
Loading

0 comments on commit a08ee42

Please sign in to comment.