From d399d3d1f9a1c0eeac7bf6b2e3d3d166af3459c5 Mon Sep 17 00:00:00 2001 From: IsaacShelton Date: Wed, 28 Aug 2024 13:19:13 -0500 Subject: [PATCH] Removed old reference-counting and lifetime analysis code --- src/ast/datatype/kind/display.rs | 3 - src/ast/datatype/kind/mod.rs | 1 - src/ast/structure/mod.rs | 1 - src/c/translation/types/composite.rs | 1 - src/interpreter_env/mod.rs | 1 - src/ir/mod.rs | 23 - src/lower/mod.rs | 142 +---- src/parser/annotation.rs | 2 - src/parser/parse_annotation.rs | 1 - src/parser/parse_structure.rs | 3 - src/parser/parse_type.rs | 6 - src/resolve/core_structure_info.rs | 21 +- src/resolve/destination.rs | 15 +- src/resolve/error.rs | 6 +- src/resolve/expr/member_expr.rs | 4 +- src/resolve/expr/mod.rs | 16 +- .../expr/short_circuiting_binary_operation.rs | 3 +- src/resolve/expr/struct_literal.rs | 6 +- src/resolve/lifetime.rs | 509 ------------------ src/resolve/mod.rs | 48 +- src/resolve/stmt.rs | 4 +- src/resolved/mod.rs | 46 +- tests/{member_pod => member}/main.adept | 2 +- tests/run.sh | 3 +- tests/structure_literals/main.adept | 2 +- tests/structure_literals_abbr/main.adept | 1 - tests/structure_pod/main.adept | 10 - tests/type_aliases/main.adept | 1 - 28 files changed, 41 insertions(+), 840 deletions(-) delete mode 100644 src/resolve/lifetime.rs rename tests/{member_pod => member}/main.adept (79%) delete mode 100644 tests/structure_pod/main.adept diff --git a/src/ast/datatype/kind/display.rs b/src/ast/datatype/kind/display.rs index 3586ded6..1f42f06c 100644 --- a/src/ast/datatype/kind/display.rs +++ b/src/ast/datatype/kind/display.rs @@ -29,9 +29,6 @@ impl Display for &TypeKind { TypeKind::Pointer(inner) => { write!(f, "ptr<{inner}>")?; } - TypeKind::PlainOldData(inner) => { - write!(f, "pod<{inner}>")?; - } TypeKind::Void => { write!(f, "void")?; } diff --git a/src/ast/datatype/kind/mod.rs b/src/ast/datatype/kind/mod.rs index 96388e8c..8f431f3a 100644 --- a/src/ast/datatype/kind/mod.rs +++ b/src/ast/datatype/kind/mod.rs @@ -15,7 +15,6 @@ pub enum TypeKind { Floating(FloatSize), Pointer(Box), FixedArray(Box), - PlainOldData(Box), Void, Named(String), AnonymousStruct(AnonymousStruct), diff --git a/src/ast/structure/mod.rs b/src/ast/structure/mod.rs index 9fff8f1b..f6c84f44 100644 --- a/src/ast/structure/mod.rs +++ b/src/ast/structure/mod.rs @@ -7,7 +7,6 @@ pub struct Structure { pub name: String, pub fields: IndexMap, pub is_packed: bool, - pub prefer_pod: bool, pub source: Source, } diff --git a/src/c/translation/types/composite.rs b/src/c/translation/types/composite.rs index 27136203..b25e8f76 100644 --- a/src/c/translation/types/composite.rs +++ b/src/c/translation/types/composite.rs @@ -95,7 +95,6 @@ pub fn make_composite( name: name.clone(), fields, is_packed, - prefer_pod: true, source: composite.source, }); diff --git a/src/interpreter_env/mod.rs b/src/interpreter_env/mod.rs index 909f7f21..87abbad1 100644 --- a/src/interpreter_env/mod.rs +++ b/src/interpreter_env/mod.rs @@ -108,7 +108,6 @@ pub fn setup_build_system_interpreter_symbols(file: &mut AstFile) { }, )]), is_packed: false, - prefer_pod: false, source, }); diff --git a/src/ir/mod.rs b/src/ir/mod.rs index 7347822b..9ecd2e7b 100644 --- a/src/ir/mod.rs +++ b/src/ir/mod.rs @@ -377,29 +377,6 @@ impl Type { Type::Pointer(Box::new(self.clone())) } - pub fn reference_counted_pointer(&self) -> Self { - // Don't allow wrapping pointer values with reference counting - // This will catch us if we accidentally nest more than once - assert!(!self.is_pointer()); - - Type::Pointer(Box::new(self.reference_counted_no_pointer())) - } - - pub fn reference_counted_no_pointer(&self) -> Self { - let subtypes = vec![ - // Reference count - Field::basic(Type::U64, Source::internal()), - // Value - Field::basic(self.clone(), Source::internal()), - ]; - - Type::AnonymousComposite(TypeComposite { - fields: subtypes, - is_packed: false, - source: Source::internal(), - }) - } - pub fn is_integer_like(&self) -> bool { matches!( self, diff --git a/src/lower/mod.rs b/src/lower/mod.rs index 4ff3e9c9..99995f0e 100644 --- a/src/lower/mod.rs +++ b/src/lower/mod.rs @@ -216,17 +216,7 @@ fn lower_stmts( for stmt in stmts.iter() { result = match &stmt.kind { - StmtKind::Return(expr, drops) => { - for variable_key in drops.drops.iter() { - lower_drop( - builder, - &ir_module.target, - *variable_key, - function, - resolved_ast, - )?; - } - + StmtKind::Return(expr) => { let instruction = ir::Instruction::Return(if let Some(expr) = expr { Some(lower_expr( builder, @@ -311,43 +301,11 @@ fn lower_stmts( Value::Literal(Literal::Void) } }; - - for variable_key in stmt.drops.iter() { - lower_drop( - builder, - &ir_module.target, - *variable_key, - function, - resolved_ast, - )?; - } } Ok(result) } -fn lower_drop( - builder: &mut Builder, - target: &Target, - variable_key: VariableStorageKey, - function: &resolved::Function, - resolved_ast: &resolved::Ast, -) -> Result<(), LowerError> { - let variable = function - .variables - .get(variable_key) - .expect("referenced variable to exist"); - - if variable.resolved_type.kind.is_managed_structure() { - let variable_pointer = lower_variable_to_value(variable_key); - let variable_type = lower_type(target, &variable.resolved_type, resolved_ast)?; - let heap_pointer = builder.push(ir::Instruction::Load((variable_pointer, variable_type))); - builder.push(ir::Instruction::Free(heap_pointer)); - } - - Ok(()) -} - fn lower_type( target: &Target, resolved_type: &resolved::Type, @@ -390,12 +348,7 @@ fn lower_type( resolved_ast, )?))), resolved::TypeKind::Void => Ok(ir::Type::Void), - resolved::TypeKind::ManagedStructure(_, structure_ref) => { - Ok(ir::Type::Structure(*structure_ref).reference_counted_pointer()) - } - resolved::TypeKind::PlainOldData(_, structure_ref) => { - Ok(ir::Type::Structure(*structure_ref)) - } + resolved::TypeKind::Structure(_, structure_ref) => Ok(ir::Type::Structure(*structure_ref)), resolved::TypeKind::AnonymousStruct() => { todo!("lower anonymous struct") } @@ -450,33 +403,11 @@ fn lower_destination( subject, structure_ref, index, - memory_management, .. } => { let subject_pointer = lower_destination(builder, ir_module, subject, function, resolved_ast)?; - let subject_pointer = match memory_management { - resolved::MemoryManagement::None => subject_pointer, - resolved::MemoryManagement::ReferenceCounted => { - // Load pointer from pointed object - - let struct_type = - ir::Type::Structure(*structure_ref).reference_counted_no_pointer(); - - let subject_pointer = builder.push(ir::Instruction::Load(( - subject_pointer, - struct_type.pointer(), - ))); - - builder.push(ir::Instruction::Member { - struct_type, - subject_pointer, - index: 1, - }) - } - }; - Ok(builder.push(ir::Instruction::Member { subject_pointer, struct_type: ir::Type::Structure(*structure_ref), @@ -733,36 +664,11 @@ fn lower_expr( structure_ref, index, field_type, - memory_management, } = &**member; let subject_pointer = lower_destination(builder, ir_module, subject, function, resolved_ast)?; - let subject_pointer = match memory_management { - resolved::MemoryManagement::None => subject_pointer, - resolved::MemoryManagement::ReferenceCounted => { - // Take off reference counted wrapper - - // Get inner structure type - let struct_type = - ir::Type::Structure(*structure_ref).reference_counted_no_pointer(); - - // Load pointer to referece counted wrapper - let subject_pointer = builder.push(ir::Instruction::Load(( - subject_pointer, - struct_type.pointer(), - ))); - - // Obtain pointer to inner data - builder.push(ir::Instruction::Member { - subject_pointer, - struct_type, - index: 1, - }) - } - }; - // Access member of structure let member = builder.push(ir::Instruction::Member { subject_pointer, @@ -802,7 +708,6 @@ fn lower_expr( let StructureLiteral { structure_type, fields, - memory_management, } = &**structure_literal; let result_ir_type = lower_type(&ir_module.target, structure_type, resolved_ast)?; @@ -820,48 +725,7 @@ fn lower_expr( // Drop the index part of the values let values = values.drain(..).map(|(_, value)| value).collect(); - match memory_management { - resolved::MemoryManagement::None => { - Ok(builder.push(ir::Instruction::StructureLiteral(result_ir_type, values))) - } - resolved::MemoryManagement::ReferenceCounted => { - let flat = builder.push(ir::Instruction::StructureLiteral( - result_ir_type.clone(), - values, - )); - - let wrapper_struct_type = result_ir_type.reference_counted_no_pointer(); - - let heap_memory = - builder.push(ir::Instruction::Malloc(wrapper_struct_type.clone())); - - // TODO: Assert that malloc didn't return NULL - - let at_reference_count = builder.push(ir::Instruction::Member { - subject_pointer: heap_memory.clone(), - struct_type: wrapper_struct_type.clone(), - index: 0, - }); - - builder.push(ir::Instruction::Store(ir::Store { - new_value: ir::Value::Literal(Literal::Unsigned64(1)), - destination: at_reference_count, - })); - - let at_value = builder.push(ir::Instruction::Member { - subject_pointer: heap_memory.clone(), - struct_type: wrapper_struct_type.clone(), - index: 1, - }); - - builder.push(ir::Instruction::Store(ir::Store { - new_value: flat, - destination: at_value, - })); - - Ok(heap_memory) - } - } + Ok(builder.push(ir::Instruction::StructureLiteral(result_ir_type, values))) } ExprKind::UnaryOperation(unary_operation) => { let inner = lower_expr( diff --git a/src/parser/annotation.rs b/src/parser/annotation.rs index c88ade72..8f2157ca 100644 --- a/src/parser/annotation.rs +++ b/src/parser/annotation.rs @@ -18,7 +18,6 @@ pub enum AnnotationKind { Foreign, ThreadLocal, Packed, - Pod, AbideAbi, } @@ -34,7 +33,6 @@ impl Display for AnnotationKind { Self::Foreign => "foreign", Self::ThreadLocal => "thread_local", Self::Packed => "packed", - Self::Pod => "pod", Self::AbideAbi => "abide_abi", }) } diff --git a/src/parser/parse_annotation.rs b/src/parser/parse_annotation.rs index 00227e62..49eb944c 100644 --- a/src/parser/parse_annotation.rs +++ b/src/parser/parse_annotation.rs @@ -25,7 +25,6 @@ impl<'a, I: Inflow> Parser<'a, I> { "foreign" => AnnotationKind::Foreign, "thread_local" => AnnotationKind::ThreadLocal, "packed" => AnnotationKind::Packed, - "pod" => AnnotationKind::Pod, "abide_abi" => AnnotationKind::AbideAbi, _ => { return Err(ParseErrorKind::UnrecognizedAnnotation { diff --git a/src/parser/parse_structure.rs b/src/parser/parse_structure.rs index 33820d45..d3e4258b 100644 --- a/src/parser/parse_structure.rs +++ b/src/parser/parse_structure.rs @@ -22,12 +22,10 @@ impl<'a, I: Inflow> Parser<'a, I> { self.ignore_newlines(); let mut is_packed = false; - let mut prefer_pod = false; for annotation in annotations { match annotation.kind { AnnotationKind::Packed => is_packed = true, - AnnotationKind::Pod => prefer_pod = true, _ => return Err(self.unexpected_annotation(&annotation, Some("for structure"))), } } @@ -66,7 +64,6 @@ impl<'a, I: Inflow> Parser<'a, I> { name, fields, is_packed, - prefer_pod, source, }) } diff --git a/src/parser/parse_type.rs b/src/parser/parse_type.rs index cbe133e6..daecc253 100644 --- a/src/parser/parse_type.rs +++ b/src/parser/parse_type.rs @@ -86,12 +86,6 @@ impl<'a, I: Inflow> Parser<'a, I> { count, }))) } - "pod" => { - self.parse_token(TokenKind::OpenAngle, Some("to specify inner type of 'pod'"))?; - let inner = self.parse_type(None::<&str>, None::<&str>)?; - self.parse_type_parameters_close()?; - Ok(TypeKind::PlainOldData(Box::new(inner))) - } identifier => Ok(TypeKind::Named(identifier.into())), }?; diff --git a/src/resolve/core_structure_info.rs b/src/resolve/core_structure_info.rs index 04c39bc6..389de94f 100644 --- a/src/resolve/core_structure_info.rs +++ b/src/resolve/core_structure_info.rs @@ -1,27 +1,18 @@ use super::error::{ResolveError, ResolveErrorKind}; use crate::{ - resolved::{self, MemoryManagement, StructureRef}, + resolved::{self, StructureRef}, source_files::Source, }; pub fn get_core_structure_info( resolved_type: &resolved::Type, source: Source, -) -> Result<(&str, StructureRef, MemoryManagement), ResolveError> { +) -> Result<(&str, StructureRef), ResolveError> { match &resolved_type.kind { - resolved::TypeKind::PlainOldData(name, structure_ref) => { - Ok((name, *structure_ref, resolved::MemoryManagement::None)) + resolved::TypeKind::Structure(name, structure_ref) => Ok((name, *structure_ref)), + _ => Err(ResolveErrorKind::CannotCreateStructLiteralForNonStructure { + bad_type: resolved_type.to_string(), } - resolved::TypeKind::ManagedStructure(name, structure_ref) => Ok(( - name, - *structure_ref, - resolved::MemoryManagement::ReferenceCounted, - )), - _ => Err( - ResolveErrorKind::CannotCreateStructLiteralForNonPlainOldDataStructure { - bad_type: resolved_type.to_string(), - } - .at(source), - ), + .at(source)), } } diff --git a/src/resolve/destination.rs b/src/resolve/destination.rs index ace6f2b6..b78caafb 100644 --- a/src/resolve/destination.rs +++ b/src/resolve/destination.rs @@ -1,5 +1,5 @@ use super::error::{ResolveError, ResolveErrorKind}; -use crate::resolved::{Destination, DestinationKind, ExprKind, Member, TypeKind, TypedExpr}; +use crate::resolved::{Destination, DestinationKind, ExprKind, Member, TypedExpr}; pub fn resolve_expr_to_destination(typed_expr: TypedExpr) -> Result { let source = typed_expr.expr.source; @@ -14,26 +14,13 @@ pub fn resolve_expr_to_destination(typed_expr: TypedExpr) -> Result (), - TypeKind::ManagedStructure(..) => (), - _ => { - return Err(ResolveErrorKind::CannotMutate { - bad_type: subject.resolved_type.to_string(), - } - .at(source)) - } - } - DestinationKind::Member { subject: Box::new(subject), structure_ref, index, field_type, - memory_management, } } ExprKind::ArrayAccess(array_access) => DestinationKind::ArrayAccess(array_access), diff --git a/src/resolve/error.rs b/src/resolve/error.rs index b2633101..b3861949 100644 --- a/src/resolve/error.rs +++ b/src/resolve/error.rs @@ -81,7 +81,7 @@ pub enum ResolveErrorKind { FieldDoesNotExist { field_name: String, }, - CannotCreateStructLiteralForNonPlainOldDataStructure { + CannotCreateStructLiteralForNonStructure { bad_type: String, }, MissingFields { @@ -270,10 +270,10 @@ impl Display for ResolveErrorKind { ResolveErrorKind::FieldDoesNotExist { field_name } => { write!(f, "Field '{}' does not exist", field_name)?; } - ResolveErrorKind::CannotCreateStructLiteralForNonPlainOldDataStructure { bad_type } => { + ResolveErrorKind::CannotCreateStructLiteralForNonStructure { bad_type } => { write!( f, - "Cannot create struct literal for non-plain-old-data structure '{}'", + "Cannot create struct literal for non-structure '{}'", bad_type )?; } diff --git a/src/resolve/expr/member_expr.rs b/src/resolve/expr/member_expr.rs index 7d036022..fe30107a 100644 --- a/src/resolve/expr/member_expr.rs +++ b/src/resolve/expr/member_expr.rs @@ -19,8 +19,7 @@ pub fn resolve_member_expr( ) -> Result { let resolved_subject = resolve_expr(ctx, subject, None, Initialized::Require)?; - let (_, structure_ref, memory_management) = - get_core_structure_info(&resolved_subject.resolved_type, source)?; + let (_, structure_ref) = get_core_structure_info(&resolved_subject.resolved_type, source)?; let structure = ctx .resolved_ast @@ -58,7 +57,6 @@ pub fn resolve_member_expr( structure_ref, index, field_type: found_field.resolved_type.clone(), - memory_management, })), source, ), diff --git a/src/resolve/expr/mod.rs b/src/resolve/expr/mod.rs index 9ac7fc37..5120fe2a 100644 --- a/src/resolve/expr/mod.rs +++ b/src/resolve/expr/mod.rs @@ -154,18 +154,20 @@ pub fn resolve_expr( source, ), )), - ast::ExprKind::String(value) => { - let type_kind = ctx.type_search_ctx.find_type_or_error("String", source)?; + ast::ExprKind::String(_value) => { + return Err(ResolveErrorKind::StringTypeNotDefined.at(source)); - let structure_ref = match type_kind { - resolved::TypeKind::ManagedStructure(_, structure_ref) => structure_ref, - _ => return Err(ResolveErrorKind::StringTypeNotDefined.at(source)), - }; + // NOTE: We don't support string types yet, but once we do, we will need + // something like this: + + /* + let type_kind = ctx.type_search_ctx.find_type_or_error("String", source)?; Ok(TypedExpr::new( - resolved::TypeKind::ManagedStructure("String".into(), *structure_ref).at(source), + resolved::TypeKind::Structure("String".into(), *structure_ref).at(source), resolved::Expr::new(resolved::ExprKind::String(value.clone()), source), )) + */ } ast::ExprKind::Call(call) => resolve_call_expr(ctx, call, source), ast::ExprKind::DeclareAssign(declare_assign) => { diff --git a/src/resolve/expr/short_circuiting_binary_operation.rs b/src/resolve/expr/short_circuiting_binary_operation.rs index 4dc81bb7..ac8fba21 100644 --- a/src/resolve/expr/short_circuiting_binary_operation.rs +++ b/src/resolve/expr/short_circuiting_binary_operation.rs @@ -6,7 +6,7 @@ use crate::{ error::{ResolveError, ResolveErrorKind}, Initialized, }, - resolved::{self, Drops, TypedExpr}, + resolved::{self, TypedExpr}, source_files::Source, }; @@ -78,7 +78,6 @@ pub fn resolve_short_circuiting_binary_operation_expr( operator: binary_operation.operator, left, right, - drops: Drops::default(), }, )), source, diff --git a/src/resolve/expr/struct_literal.rs b/src/resolve/expr/struct_literal.rs index bb24b32d..4966ed36 100644 --- a/src/resolve/expr/struct_literal.rs +++ b/src/resolve/expr/struct_literal.rs @@ -44,11 +44,10 @@ pub fn resolve_struct_literal_expr( &mut Default::default(), )?; - let (struct_name, structure_ref, memory_management) = - get_core_structure_info(&resolved_type, source)?; + let (struct_name, structure_ref) = get_core_structure_info(&resolved_type, source)?; let structure_type = - resolved::TypeKind::PlainOldData(struct_name.to_string(), structure_ref).at(source); + resolved::TypeKind::Structure(struct_name.to_string(), structure_ref).at(source); let mut next_index = 0; let mut resolved_fields = IndexMap::new(); @@ -173,7 +172,6 @@ pub fn resolve_struct_literal_expr( resolved::ExprKind::StructureLiteral(Box::new(StructureLiteral { structure_type, fields: resolved_fields, - memory_management, })), ast_type.source, ), diff --git a/src/resolve/lifetime.rs b/src/resolve/lifetime.rs deleted file mode 100644 index 6effbd2f..00000000 --- a/src/resolve/lifetime.rs +++ /dev/null @@ -1,509 +0,0 @@ -use crate::resolved::{ - Destination, DestinationKind, Drops, Expr, ExprKind, Function, Stmt, StmtKind, - VariableStorageKey, -}; -use bit_vec::BitVec; - -// Temporary logging function for testing -macro_rules! lifetime_log { - ($($rest:tt)*) => { - if false { - std::println!($($rest)*) - } - } -} - -struct VariableUsageSet { - declared: BitVec, - used: BitVec, -} - -impl VariableUsageSet { - pub fn new(count: usize) -> Self { - Self { - declared: BitVec::from_elem(count, false), - used: BitVec::from_elem(count, false), - } - } - - pub fn declare(&mut self, storage: VariableStorageKey) { - self.declared.set(storage.index, true); - } - - pub fn mark_used(&mut self, storage: VariableStorageKey) { - self.used.set(storage.index, true); - } - - pub fn union_with(&mut self, other: &Self) { - self.used.or(&other.used); - self.declared.or(&other.declared); - } - - pub fn iter_used(&self) -> impl ExactSizeIterator + DoubleEndedIterator + '_ { - self.used.iter() - } - - pub fn iter_declared(&self) -> impl ExactSizeIterator + DoubleEndedIterator + '_ { - self.declared.iter() - } -} - -#[derive(Clone, Debug)] -struct InsertDropsCtx { - variables_count: usize, - depth: i32, - message: &'static str, -} - -impl InsertDropsCtx { - pub fn new(variables_count: usize) -> Self { - Self { - variables_count, - depth: 1, - message: "Nothing", - } - } - - pub fn deeper(&self, message: &'static str) -> Self { - Self { - variables_count: self.variables_count, - depth: self.depth + 1, - message, - } - } - - pub fn log_declare(&self, variable: VariableStorageKey) { - lifetime_log!( - "[DEPTH {} {} DECLARE] Variable {}", - self.depth, - &self.message, - variable.index - ); - } - - pub fn log_use(&self, variable: VariableStorageKey) { - lifetime_log!( - "[DEPTH {} {} USE] Variable {}", - self.depth, - &self.message, - variable.index - ); - } - - pub fn log_drop(&self, variable_index: usize, drop_after: usize) { - lifetime_log!( - "[DEPTH {} {}] dropping variable {} after stmt {}", - self.depth, - self.message, - variable_index, - drop_after - ); - } -} - -pub fn insert_drops(function: &mut Function) { - // Search through statements top to bottom, and record which statement each variable storage - // key is last used by - - insert_drops_for_stmts( - InsertDropsCtx::new(function.variables.count()), - &mut function.stmts, - ); - - let mut active_set = ActiveSet::new(function.variables.count()); - integrate_active_set_for_stmts(&mut function.stmts, &mut active_set); -} - -fn insert_drops_for_stmts(ctx: InsertDropsCtx, stmts: &mut [Stmt]) -> VariableUsageSet { - let mut last_use_in_this_scope = vec![0_usize; ctx.variables_count]; - let mut scope = VariableUsageSet::new(ctx.variables_count); - - for (stmt_index, stmt) in stmts.iter_mut().enumerate() { - let mentioned = match &mut stmt.kind { - StmtKind::Return(expr, _) => { - if let Some(expr) = expr { - insert_drops_for_expr(ctx.clone(), expr) - } else { - VariableUsageSet::new(ctx.variables_count) - } - } - StmtKind::Expr(expr) => insert_drops_for_expr(ctx.clone(), &mut expr.expr), - StmtKind::Declaration(declaration) => { - ctx.log_declare(declaration.key); - scope.declare(declaration.key); - last_use_in_this_scope[declaration.key.index] = stmt_index; - - if let Some(expr) = &mut declaration.value { - insert_drops_for_expr(ctx.clone(), expr) - } else { - VariableUsageSet::new(ctx.variables_count) - } - } - StmtKind::Assignment(assignment) => { - let mut mentioned = insert_drops_for_expr(ctx.clone(), &mut assignment.value); - mentioned.union_with(&insert_drops_for_destination( - ctx.clone(), - &mut assignment.destination, - )); - mentioned - } - }; - - scope.union_with(&mentioned); - - for (mention_index, did_declare) in mentioned.iter_declared().enumerate() { - if did_declare { - last_use_in_this_scope[mention_index] = stmt_index; - } - } - - for (mention_index, did_mention) in mentioned.iter_used().enumerate() { - if did_mention { - last_use_in_this_scope[mention_index] = stmt_index; - } - } - } - - // For each variable declared in reverse declaration order, - for (variable_index, did_declare) in scope.iter_declared().enumerate().rev() { - if !did_declare { - continue; - } - - let drop_after = last_use_in_this_scope[variable_index]; - - ctx.log_drop(variable_index, drop_after); - - stmts[drop_after].drops.push(VariableStorageKey { - index: variable_index, - }); - } - - scope -} - -fn insert_drops_for_expr(ctx: InsertDropsCtx, expr: &mut Expr) -> VariableUsageSet { - let mut mini_scope = VariableUsageSet::new(ctx.variables_count); - - match &mut expr.kind { - ExprKind::Variable(variable) => { - ctx.log_use(variable.key); - mini_scope.mark_used(variable.key); - } - ExprKind::GlobalVariable(..) => (), - ExprKind::BooleanLiteral(..) - | ExprKind::IntegerLiteral(..) - | ExprKind::IntegerKnown(_) - | ExprKind::FloatingLiteral(..) - | ExprKind::String(..) - | ExprKind::NullTerminatedString(..) => (), - ExprKind::Call(call) => { - for argument in call.arguments.iter_mut() { - mini_scope.union_with(&insert_drops_for_expr(ctx.clone(), &mut argument.expr)); - } - } - ExprKind::DeclareAssign(declare_assign) => { - mini_scope.union_with(&insert_drops_for_expr( - ctx.clone(), - &mut declare_assign.value, - )); - - ctx.log_declare(declare_assign.key); - mini_scope.declare(declare_assign.key); - } - ExprKind::BasicBinaryOperation(operation) => { - mini_scope.union_with(&insert_drops_for_expr( - ctx.clone(), - &mut operation.left.expr, - )); - mini_scope.union_with(&insert_drops_for_expr( - ctx.clone(), - &mut operation.right.expr, - )); - } - ExprKind::ShortCircuitingBinaryOperation(operation) => { - mini_scope.union_with(&insert_drops_for_expr( - ctx.clone(), - &mut operation.left.expr, - )); - - let hidden_scope = - &insert_drops_for_expr(ctx.deeper("short circuitable"), &mut operation.right.expr); - - // Variables declared in the potentially skipped section need to be dropped - // in the case that the section is executed - for (variable_index, did_declare) in hidden_scope.iter_declared().enumerate() { - if did_declare { - operation.drops.push(VariableStorageKey { - index: variable_index, - }); - - lifetime_log!( - "[DEPTH {} {}] dropping variable {} after short circuit op", - ctx.depth, - ctx.message, - variable_index - ); - } - } - - mini_scope.used.or(&hidden_scope.used); - } - ExprKind::IntegerExtend(cast) - | ExprKind::IntegerTruncate(cast) - | ExprKind::FloatExtend(cast) => { - mini_scope.union_with(&insert_drops_for_expr(ctx, &mut cast.value)); - } - ExprKind::IntegerCast(cast_from) => { - mini_scope.union_with(&insert_drops_for_expr(ctx, &mut cast_from.cast.value)); - } - ExprKind::Member(member) => { - mini_scope.union_with(&insert_drops_for_destination(ctx, &mut member.subject)); - } - ExprKind::StructureLiteral { .. } => (), - ExprKind::UnaryOperation(operation) => { - mini_scope.union_with(&insert_drops_for_expr( - ctx.clone(), - &mut operation.inner.expr, - )); - } - ExprKind::Conditional(conditional) => { - if let Some(branch) = conditional.branches.first_mut() { - let condition_scope = - insert_drops_for_expr(ctx.clone(), &mut branch.condition.expr); - - mini_scope.union_with(&condition_scope); - } - - lifetime_log!("warning: declaring variables in conditions of non-first branches is not properly handled yet"); - - for branch in conditional.branches.iter_mut() { - let inner_scope = - insert_drops_for_stmts(ctx.deeper("if branch"), &mut branch.block.stmts); - mini_scope.used.or(&inner_scope.used); - } - - if let Some(otherwise) = &mut conditional.otherwise { - let inner_scope = - insert_drops_for_stmts(ctx.deeper("otherwise branch"), &mut otherwise.stmts); - mini_scope.used.or(&inner_scope.used); - } - } - ExprKind::While(while_loop) => { - mini_scope.union_with(&insert_drops_for_expr( - ctx.clone(), - &mut while_loop.condition, - )); - - let inner_scope = - insert_drops_for_stmts(ctx.deeper("while body"), &mut while_loop.block.stmts); - mini_scope.used.or(&inner_scope.used); - } - ExprKind::ArrayAccess(array_access) => { - mini_scope.union_with(&insert_drops_for_expr( - ctx.clone(), - &mut array_access.subject, - )); - mini_scope.union_with(&insert_drops_for_expr(ctx.clone(), &mut array_access.index)); - } - ExprKind::EnumMemberLiteral(_enum_member_literal) => (), - ExprKind::ResolvedNamedExpression(_name, resolved_expr) => { - mini_scope = insert_drops_for_expr(ctx, resolved_expr); - } - ExprKind::Zeroed(_resolved_type) => (), - ExprKind::InterpreterSyscall(_syscall, args) => { - for argument in args.iter_mut() { - mini_scope.union_with(&insert_drops_for_expr(ctx.clone(), argument)); - } - } - } - - mini_scope -} - -fn insert_drops_for_destination( - ctx: InsertDropsCtx, - destination: &mut Destination, -) -> VariableUsageSet { - let mut mini_scope = VariableUsageSet::new(ctx.variables_count); - - match &mut destination.kind { - DestinationKind::Variable(variable) => { - ctx.log_use(variable.key); - mini_scope.mark_used(variable.key); - } - DestinationKind::GlobalVariable(_) => (), - DestinationKind::Member { subject, .. } => { - mini_scope.union_with(&insert_drops_for_destination(ctx, subject)); - } - DestinationKind::ArrayAccess(array_access) => { - mini_scope.union_with(&insert_drops_for_expr( - ctx.clone(), - &mut array_access.subject, - )); - mini_scope.union_with(&insert_drops_for_expr(ctx.clone(), &mut array_access.index)); - } - } - - mini_scope -} - -#[derive(Clone, Debug)] -struct ActiveSet { - pub active: BitVec, -} - -impl ActiveSet { - pub fn new(count: usize) -> Self { - Self { - active: BitVec::from_elem(count, false), - } - } - - pub fn activate(&mut self, variable: VariableStorageKey) { - self.active.set(variable.index, true); - } - - pub fn deactivate_drops(&mut self, drops: &Drops) { - for variable in drops.iter() { - self.active.set(variable.index, false); - } - } -} - -fn integrate_active_set_for_stmts(stmts: &mut [Stmt], parent_active_set: &mut ActiveSet) { - let mut active_set = parent_active_set.clone(); - - for stmt in stmts.iter_mut() { - match &mut stmt.kind { - StmtKind::Return(value, drops) => { - stmt.drops.drops.clear(); - - if let Some(value) = value { - integrate_active_set_for_expr(value, &mut active_set); - } - - for (variable_index, active) in active_set.active.iter().enumerate().rev() { - if active { - /* - println!( - "[RETURN DROP] variable {} during return stmt {}", - variable_index, _stmt_i, - ); - */ - - drops.push(VariableStorageKey { - index: variable_index, - }); - } - } - } - StmtKind::Expr(expr) => { - integrate_active_set_for_expr(&mut expr.expr, &mut active_set); - } - StmtKind::Declaration(declaration) => { - if let Some(value) = &mut declaration.value { - integrate_active_set_for_expr(value, &mut active_set); - } - - active_set.activate(declaration.key); - } - StmtKind::Assignment(assignment) => { - integrate_active_set_for_expr(&mut assignment.value, &mut active_set); - } - } - - active_set.deactivate_drops(&stmt.drops); - } -} - -fn integrate_active_set_for_expr(expr: &mut Expr, active_set: &mut ActiveSet) { - match &mut expr.kind { - ExprKind::Variable(_) - | ExprKind::GlobalVariable(_) - | ExprKind::BooleanLiteral(_) - | ExprKind::IntegerLiteral(_) - | ExprKind::IntegerKnown(_) - | ExprKind::FloatingLiteral(..) - | ExprKind::String(_) - | ExprKind::NullTerminatedString(_) - | ExprKind::EnumMemberLiteral(_) => (), - ExprKind::Call(call) => { - for argument in call.arguments.iter_mut() { - integrate_active_set_for_expr(&mut argument.expr, active_set); - } - } - ExprKind::DeclareAssign(declare_assign) => { - integrate_active_set_for_expr(&mut declare_assign.value, active_set); - active_set.activate(declare_assign.key); - } - ExprKind::BasicBinaryOperation(operation) => { - integrate_active_set_for_expr(&mut operation.left.expr, active_set); - integrate_active_set_for_expr(&mut operation.right.expr, active_set); - } - ExprKind::ShortCircuitingBinaryOperation(operation) => { - integrate_active_set_for_expr(&mut operation.left.expr, active_set); - integrate_active_set_for_expr(&mut operation.right.expr, active_set); - active_set.deactivate_drops(&operation.drops); - } - ExprKind::IntegerExtend(..) - | ExprKind::IntegerTruncate(..) - | ExprKind::IntegerCast(..) - | ExprKind::FloatExtend(..) => - { - #[allow(clippy::unused_unit)] - () - } - ExprKind::Member(member) => { - integrate_active_set_for_destination(&mut member.subject, active_set); - } - ExprKind::StructureLiteral(structure_literal) => { - for (_name, (expr, _index)) in structure_literal.fields.iter_mut() { - integrate_active_set_for_expr(expr, active_set); - } - } - ExprKind::UnaryOperation(operation) => { - integrate_active_set_for_expr(&mut operation.inner.expr, active_set); - } - ExprKind::Conditional(conditional) => { - for branch in conditional.branches.iter_mut() { - integrate_active_set_for_expr(&mut branch.condition.expr, active_set); - integrate_active_set_for_stmts(&mut branch.block.stmts, active_set); - } - - if let Some(otherwise) = &mut conditional.otherwise { - integrate_active_set_for_stmts(&mut otherwise.stmts, active_set); - } - } - ExprKind::While(while_loop) => { - integrate_active_set_for_expr(&mut while_loop.condition, active_set); - integrate_active_set_for_stmts(&mut while_loop.block.stmts, active_set); - } - ExprKind::ArrayAccess(array_access) => { - integrate_active_set_for_expr(&mut array_access.subject, active_set); - integrate_active_set_for_expr(&mut array_access.index, active_set); - } - ExprKind::ResolvedNamedExpression(_name, resolved_expr) => { - integrate_active_set_for_expr(resolved_expr.as_mut(), active_set); - } - ExprKind::Zeroed(_resolved_type) => (), - ExprKind::InterpreterSyscall(_syscall, args) => { - for argument in args.iter_mut() { - integrate_active_set_for_expr(argument, active_set); - } - } - } -} - -fn integrate_active_set_for_destination(destination: &mut Destination, active_set: &mut ActiveSet) { - match &mut destination.kind { - DestinationKind::Variable(_) | DestinationKind::GlobalVariable(_) => (), - DestinationKind::Member { subject, .. } => { - integrate_active_set_for_destination(subject, active_set); - } - DestinationKind::ArrayAccess(array_access) => { - integrate_active_set_for_expr(&mut array_access.subject, active_set); - integrate_active_set_for_expr(&mut array_access.index, active_set); - } - } -} diff --git a/src/resolve/mod.rs b/src/resolve/mod.rs index d11263a6..582984f1 100644 --- a/src/resolve/mod.rs +++ b/src/resolve/mod.rs @@ -5,7 +5,6 @@ mod error; mod expr; mod function_search_ctx; mod global_search_ctx; -mod lifetime; mod stmt; mod type_search_ctx; mod unify_types; @@ -176,19 +175,11 @@ pub fn resolve<'a>( source: structure.source, }); - if structure.prefer_pod { - type_search_ctx.put_type( - structure.name.clone(), - resolved::TypeKind::PlainOldData(structure.name.clone(), structure_key), - structure.source, - )?; - } else { - type_search_ctx.put_type( - structure.name.clone(), - resolved::TypeKind::ManagedStructure(structure.name.clone(), structure_key), - structure.source, - )?; - } + type_search_ctx.put_type( + structure.name.clone(), + resolved::TypeKind::Structure(structure.name.clone(), structure_key), + structure.source, + )?; } } @@ -386,8 +377,6 @@ pub fn resolve<'a>( .expect("resolved function head to exist"); resolved_function.stmts = resolved_stmts; - - lifetime::insert_drops(resolved_function); } } } @@ -465,33 +454,6 @@ fn resolve_type<'a>( } } } - ast::TypeKind::PlainOldData(inner) => match &inner.kind { - ast::TypeKind::Named(name) => { - let resolved_inner_kind = type_search_ctx - .find_type_or_error(name, ast_type.source) - .cloned()?; - - let structure_ref = match resolved_inner_kind { - resolved::TypeKind::ManagedStructure(_, structure_ref) => structure_ref, - resolved::TypeKind::PlainOldData(_, structure_ref) => structure_ref, - _ => { - return Err(ResolveErrorKind::CannotCreatePlainOldDataOfNonStructure { - bad_type: inner.to_string(), - } - .at(inner.source)); - } - }; - - Ok(resolved::TypeKind::PlainOldData( - name.clone(), - structure_ref, - )) - } - _ => Err(ResolveErrorKind::CannotCreatePlainOldDataOfNonStructure { - bad_type: inner.to_string(), - } - .at(inner.source)), - }, ast::TypeKind::Floating(size) => Ok(resolved::TypeKind::Floating(*size)), ast::TypeKind::AnonymousStruct(..) => todo!("resolve anonymous struct type"), ast::TypeKind::AnonymousUnion(..) => todo!("resolve anonymous union type"), diff --git a/src/resolve/stmt.rs b/src/resolve/stmt.rs index c702c0cc..79e3c399 100644 --- a/src/resolve/stmt.rs +++ b/src/resolve/stmt.rs @@ -7,7 +7,7 @@ use super::{ }; use crate::{ ast::{self, ConformBehavior}, - resolved::{self, Drops}, + resolved, }; pub fn resolve_stmts( @@ -79,7 +79,7 @@ pub fn resolve_stmt( }; Ok(resolved::Stmt::new( - resolved::StmtKind::Return(return_value, Drops::default()), + resolved::StmtKind::Return(return_value), source, )) } diff --git a/src/resolved/mod.rs b/src/resolved/mod.rs index 5f0b3c16..f2d9af05 100644 --- a/src/resolved/mod.rs +++ b/src/resolved/mod.rs @@ -21,7 +21,6 @@ use std::{ ffi::CString, fmt::{Debug, Display}, }; -use thin_vec::ThinVec; pub use variable_storage::VariableStorage; new_key_type! { @@ -144,9 +143,8 @@ pub enum TypeKind { FloatLiteral(f64), Floating(FloatSize), Pointer(Box), - PlainOldData(String, StructureRef), + Structure(String, StructureRef), Void, - ManagedStructure(String, StructureRef), AnonymousStruct(), AnonymousUnion(), AnonymousEnum(AnonymousEnum), @@ -261,9 +259,8 @@ impl TypeKind { TypeKind::Floating(_) | TypeKind::FloatLiteral(_) | TypeKind::Pointer(_) - | TypeKind::PlainOldData(_, _) + | TypeKind::Structure(_, _) | TypeKind::Void - | TypeKind::ManagedStructure(_, _) | TypeKind::AnonymousStruct(..) | TypeKind::AnonymousUnion(..) | TypeKind::FixedArray(..) @@ -310,11 +307,8 @@ impl Display for TypeKind { TypeKind::Pointer(inner) => { write!(f, "ptr<{}>", inner.kind)?; } - TypeKind::PlainOldData(name, _) => { - write!(f, "pod<{}>", name)?; - } TypeKind::Void => f.write_str("void")?, - TypeKind::ManagedStructure(name, _) => f.write_str(name)?, + TypeKind::Structure(name, _) => f.write_str(name)?, TypeKind::AnonymousStruct() => f.write_str("(anonymous struct)")?, TypeKind::AnonymousUnion() => f.write_str("(anonymous union)")?, TypeKind::AnonymousEnum(..) => f.write_str("(anonymous enum)")?, @@ -333,37 +327,17 @@ impl Display for TypeKind { pub struct Stmt { pub kind: StmtKind, pub source: Source, - pub drops: Drops, } impl Stmt { pub fn new(kind: StmtKind, source: Source) -> Self { - Self { - kind, - source, - drops: Drops::default(), - } - } -} - -#[derive(Clone, Debug, Default)] -pub struct Drops { - pub drops: ThinVec, -} - -impl Drops { - pub fn push(&mut self, variable: VariableStorageKey) { - self.drops.push(variable); - } - - pub fn iter(&self) -> impl Iterator + '_ { - self.drops.iter() + Self { kind, source } } } #[derive(Clone, Debug, Unwrap)] pub enum StmtKind { - Return(Option, Drops), + Return(Option), Expr(TypedExpr), Declaration(Declaration), Assignment(Assignment), @@ -419,12 +393,6 @@ impl Expr { } } -#[derive(Clone, Debug)] -pub enum MemoryManagement { - None, - ReferenceCounted, -} - #[derive(Clone, Debug)] pub enum ExprKind { Variable(Box), @@ -478,7 +446,6 @@ pub struct Member { pub subject: Destination, pub structure_ref: StructureRef, pub index: usize, - pub memory_management: MemoryManagement, pub field_type: Type, } @@ -486,7 +453,6 @@ pub struct Member { pub struct StructureLiteral { pub structure_type: Type, pub fields: IndexMap, - pub memory_management: MemoryManagement, } // Make sure ExprKind doesn't accidentally become huge @@ -575,7 +541,6 @@ pub enum DestinationKind { structure_ref: StructureRef, index: usize, field_type: Type, - memory_management: MemoryManagement, }, ArrayAccess(Box), } @@ -677,7 +642,6 @@ pub struct ShortCircuitingBinaryOperation { pub operator: ShortCircuitingBinaryOperator, pub left: TypedExpr, pub right: TypedExpr, - pub drops: Drops, } #[derive(Clone, Debug)] diff --git a/tests/member_pod/main.adept b/tests/member/main.adept similarity index 79% rename from tests/member_pod/main.adept rename to tests/member/main.adept index d839f40e..c39a3622 100644 --- a/tests/member_pod/main.adept +++ b/tests/member/main.adept @@ -5,7 +5,7 @@ func printf(format ptr, ...) int struct Vector3i (x int, y int, z int) func main { - vector pod = pod { x: 0, y: 0, z: 0 } + vector Vector3i = Vector3i { x: 0, y: 0, z: 0 } vector.x = 123 vector.y = 456 diff --git a/tests/run.sh b/tests/run.sh index 7af4bd32..9114ab27 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -43,7 +43,7 @@ compile integer_unsigned_overflow compile integer_value_conforming compile math_floats compile math_simple -compile member_pod +compile member compile_module modules_headers compile_module modules_simple compile multiline_comments @@ -58,7 +58,6 @@ compile signed_unsigned_promotion compile structure_definitions compile structure_literals compile structure_literals_abbr -compile structure_pod compile unary_operators compile type_aliases compile ufcs diff --git a/tests/structure_literals/main.adept b/tests/structure_literals/main.adept index 298da6e1..bb382104 100644 --- a/tests/structure_literals/main.adept +++ b/tests/structure_literals/main.adept @@ -5,7 +5,7 @@ func printf(format ptr, ...) int struct Vector3i (x int, y int, z int) func main { - vector := pod { + vector := Vector3i { x: 123, y: 456, z: 789, diff --git a/tests/structure_literals_abbr/main.adept b/tests/structure_literals_abbr/main.adept index f135a4c0..4c2c5610 100644 --- a/tests/structure_literals_abbr/main.adept +++ b/tests/structure_literals_abbr/main.adept @@ -2,7 +2,6 @@ #[foreign] func printf(format ptr, ...) int -#[pod] struct Vector3i (x i32, y i32, z i32) func main { diff --git a/tests/structure_pod/main.adept b/tests/structure_pod/main.adept deleted file mode 100644 index 744a3810..00000000 --- a/tests/structure_pod/main.adept +++ /dev/null @@ -1,10 +0,0 @@ - -#[foreign] -func printf(format ptr, ...) int - -struct Vector3i (x int, y int, z int) - -func main { - vector pod = pod { x: 0, y: 0, z: 0 } -} - diff --git a/tests/type_aliases/main.adept b/tests/type_aliases/main.adept index 156b0d60..6990002e 100644 --- a/tests/type_aliases/main.adept +++ b/tests/type_aliases/main.adept @@ -2,7 +2,6 @@ #[foreign] func printf(format ptr, ...) int -#[pod] struct Integer (value s32) typealias s32 = i32