From 643b55b4af53b2df8492b2aa533476d7677d8d7f 2021-12-12 16:51:35 From: MH Date: 2021-12-12 16:51:35 Subject: [PATCH] Prepare for rewrite of monomorphs in type table --- diff --git a/src/protocol/parser/type_table.rs b/src/protocol/parser/type_table.rs index 18947e699fc1be5cc114d4c1294b17214879dac1..aededc074c1301700a3785eb48fefd5a8c241b92 100644 --- a/src/protocol/parser/type_table.rs +++ b/src/protocol/parser/type_table.rs @@ -315,16 +315,6 @@ pub struct PolymorphicVariable { is_in_use: bool, // a polymorphic argument may be defined, but not used by the type definition } -/// Data associated with a monomorphized procedure type. Has the wrong name, -/// because it will also be used to store expression data for a non-polymorphic -/// procedure. (in that case, there will only ever be one) -pub struct ProcedureMonomorph { - // Expression data for one particular monomorph - pub concrete_type: ConcreteType, - pub arg_types: Vec, - pub expr_data: Vec, -} - /// `EnumType` is the classical C/C++ enum type. It has various variants with /// an assigned integer value. The integer values may be user-defined, /// compiler-defined, or a mix of the two. If a user assigns the same enum @@ -346,10 +336,6 @@ pub struct EnumVariant { pub value: i64, } -pub struct EnumMonomorph { - pub concrete_type: ConcreteType, -} - /// `UnionType` is the algebraic datatype (or sum type, or discriminated union). /// A value is an element of the union, identified by its tag, and may contain /// a single subtype. @@ -373,37 +359,6 @@ pub struct UnionVariant { pub tag_value: i64, } -pub struct UnionMonomorph { - pub concrete_type: ConcreteType, - pub variants: Vec, - // stack_size is the size of the union on the stack, includes the tag - pub stack_size: usize, - pub stack_alignment: usize, - // heap_size contains the allocated size of the union in the case it - // is used to break a type loop. If it is 0, then it doesn't require - // allocation and lives entirely on the stack. - pub heap_size: usize, - pub heap_alignment: usize, -} - -pub struct UnionMonomorphVariant { - pub lives_on_heap: bool, - pub embedded: Vec, -} - -pub struct UnionMonomorphEmbedded { - pub concrete_type: ConcreteType, - // Note that the meaning of the offset (and alignment) depend on whether or - // not the variant lives on the stack/heap. If it lives on the stack then - // they refer to the offset from the start of the union value (so the first - // embedded type lives at a non-zero offset, because the union tag sits in - // the front). If it lives on the heap then it refers to the offset from the - // allocated memory region (so the first embedded type lives at a 0 offset). - pub size: usize, - pub alignment: usize, - pub offset: usize, -} - /// `StructType` is a generic C-like struct type (or record type, or product /// type) type. pub struct StructType { @@ -416,20 +371,6 @@ pub struct StructField { pub parser_type: ParserType, } -pub struct StructMonomorph { - pub concrete_type: ConcreteType, - pub fields: Vec, - pub size: usize, - pub alignment: usize, -} - -pub struct StructMonomorphField { - pub concrete_type: ConcreteType, - pub size: usize, - pub alignment: usize, - pub offset: usize, -} - /// `FunctionType` is what you expect it to be: a particular function's /// signature. pub struct FunctionType { @@ -462,6 +403,101 @@ pub struct MonomorphExpression { pub(crate) field_or_monomorph_idx: i32, } +//------------------------------------------------------------------------------ +// Type monomorph storage +//------------------------------------------------------------------------------ + +/// Union of all possible type monomorphs. The term "monomorph" is perhaps not +/// entirely correct: nonpolymorphic types will also get a "monomorph" entry to +/// store the size/offset/alignment data of all types. +enum TypeMonomorph { + Enum(EnumMonomorph), + Struct(StructMonomorph), + Union(UnionMonomorph), + Procedure(ProcedureMonomorph), // functions, components + Tuple(TupleMonomorph), +} + +/// Enum monomorph +pub struct EnumMonomorph { + pub concrete_type: ConcreteType, + pub size: usize, + pub alignment: usize, +} + +/// Struct monomorph +pub struct StructMonomorph { + pub concrete_type: ConcreteType, + pub fields: Vec, + pub size: usize, + pub alignment: usize, +} + +pub struct StructMonomorphField { + pub concrete_type: ConcreteType, + pub size: usize, + pub alignment: usize, + pub offset: usize, +} + +/// Union monomorph +pub struct UnionMonomorph { + pub concrete_type: ConcreteType, + pub variants: Vec, + // stack_size is the size of the union on the stack, includes the tag + pub stack_size: usize, + pub stack_alignment: usize, + // heap_size contains the allocated size of the union in the case it + // is used to break a type loop. If it is 0, then it doesn't require + // allocation and lives entirely on the stack. + pub heap_size: usize, + pub heap_alignment: usize, +} + +pub struct UnionMonomorphVariant { + pub lives_on_heap: bool, + pub embedded: Vec, +} + +pub struct UnionMonomorphEmbedded { + pub concrete_type: ConcreteType, + // Note that the meaning of the offset (and alignment) depend on whether or + // not the variant lives on the stack/heap. If it lives on the stack then + // they refer to the offset from the start of the union value (so the first + // embedded type lives at a non-zero offset, because the union tag sits in + // the front). If it lives on the heap then it refers to the offset from the + // allocated memory region (so the first embedded type lives at a 0 offset). + pub size: usize, + pub alignment: usize, + pub offset: usize, +} + +/// Procedure (functions and components of all possible types) monomorph. Also +/// stores the expression type data from the typechecking/inferencing pass. +pub struct ProcedureMonomorph { + // Expression data for one particular monomorph + pub concrete_type: ConcreteType, + pub arg_types: Vec, + pub expr_data: Vec, +} + +/// Tuple monomorph. Again a kind of exception because one cannot define a named +/// tuple type containing explicit polymorphic variables. But again: we need to +/// store size/offset/alignment information, so we do it here. +pub struct TupleMonomorph { + pub concrete_type: ConcreteType, + pub size: usize, + pub alignment: usize, + pub members: Vec +} + +pub struct TupleMonomorphMember { + pub concrete_type: ConcreteType, + pub size: usize, + pub alignment: usize, + pub offset: usize, +} + //------------------------------------------------------------------------------ // Type table //------------------------------------------------------------------------------ @@ -1390,6 +1426,8 @@ impl TypeTable { debug_assert!(definition.monomorphs.is_empty()); definition.monomorphs.push(EnumMonomorph{ concrete_type: definition_type, + size: 0, + alignment: 0, }); 0 },