Skip to content

Commit

Permalink
Codegen and IR fix
Browse files Browse the repository at this point in the history
  • Loading branch information
LPeter1997 committed Nov 12, 2024
1 parent f0526b6 commit d418c40
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 15 deletions.
30 changes: 26 additions & 4 deletions src/Draco.Compiler/Internal/Codegen/MetadataCodegen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -526,11 +526,12 @@ private void EncodeModule(IModule module, TypeDefinitionHandle? parent, ref int

private FieldDefinitionHandle EncodeField(FieldSymbol field)
{
var visibility = GetFieldVisibility(field.Visibility);
var attributes = GetFieldVisibility(field.Visibility);
if (field.IsStatic) attributes |= FieldAttributes.Static;

// Definition
return this.AddFieldDefinition(
attributes: visibility | FieldAttributes.Static,
attributes: attributes,
name: field.Name,
signature: this.EncodeFieldSignature(field));
}
Expand Down Expand Up @@ -691,16 +692,37 @@ private TypeDefinitionHandle EncodeClass(IClass @class, TypeDefinitionHandle? pa
index: genericIndex++);
}

// Properties
// TODO: Copypasta
var firstProperty = null as PropertyDefinitionHandle?;
var propertyHandleMap = new Dictionary<Symbol, PropertyDefinitionHandle>();
foreach (var prop in @class.Properties)
{
var propHandle = this.EncodeProperty(definitionHandle, prop);
firstProperty ??= propHandle;
propertyHandleMap.Add(prop, propHandle);
}
if (firstProperty is not null) this.MetadataBuilder.AddPropertyMap(definitionHandle, firstProperty.Value);

// Procedures
foreach (var proc in @class.Procedures.Values)
{
var specialName = proc.Symbol is DefaultConstructorSymbol
? ".ctor"
: null;
this.EncodeProcedure(proc, specialName: specialName);
var handle = this.EncodeProcedure(proc, specialName: specialName);
++procIndex;

// Todo: properties
// TODO: Copypasta
if (proc.Symbol is IPropertyAccessorSymbol propAccessor)
{
// This is an accessor
var isGetter = propAccessor.Property.Getter == propAccessor;
this.MetadataBuilder.AddMethodSemantics(
association: propertyHandleMap[propAccessor.Property],
semantics: isGetter ? MethodSemanticsAttributes.Getter : MethodSemanticsAttributes.Setter,
methodDefinition: handle);
}
}

// Fields
Expand Down
18 changes: 17 additions & 1 deletion src/Draco.Compiler/Internal/OptimizingIr/Codegen/ClassCodegen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
using Draco.Compiler.Internal.Lowering;
using Draco.Compiler.Internal.OptimizingIr.Model;
using Draco.Compiler.Internal.Symbols;
using Draco.Compiler.Internal.Symbols.Source;
using Draco.Compiler.Internal.Symbols.Syntax;
using Draco.Compiler.Internal.Symbols.Synthetized.AutoProperty;

namespace Draco.Compiler.Internal.OptimizingIr.Codegen;

Expand Down Expand Up @@ -36,7 +39,20 @@ public override void VisitFunction(FunctionSymbol functionSymbol)

public override void VisitField(FieldSymbol fieldSymbol)
{
// No-op, the Class model reads it up from the symbol
if (fieldSymbol is not SyntaxFieldSymbol and not AutoPropertyBackingFieldSymbol) return;

// TODO: Initializer value
@class.DefineField(fieldSymbol);
}

public override void VisitProperty(PropertySymbol propertySymbol)
{
// TODO: Not flexible, won't work for non-auto props
if (propertySymbol is not SyntaxAutoPropertySymbol) return;

@class.DefineProperty(propertySymbol);

// TODO: Initializer value
}

private BoundNode RewriteBody(BoundNode body)
Expand Down
12 changes: 8 additions & 4 deletions src/Draco.Compiler/Internal/OptimizingIr/Model/Class.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ internal sealed class Class(TypeSymbol symbol) : IClass

public IReadOnlyList<TypeParameterSymbol> Generics => this.Symbol.GenericParameters;
public IReadOnlyDictionary<FunctionSymbol, IProcedure> Procedures => this.procedures;
public IReadOnlyList<FieldSymbol> Fields => InterlockedUtils.InitializeDefault(
ref this.fields,
() => this.Symbol.DefinedMembers.OfType<FieldSymbol>().ToImmutableArray());
private ImmutableArray<FieldSymbol> fields;

public IReadOnlySet<FieldSymbol> Fields => this.fields;
public IReadOnlySet<PropertySymbol> Properties => this.properties;

private readonly HashSet<FieldSymbol> fields = [];
private readonly HashSet<PropertySymbol> properties = [];
private readonly Dictionary<FunctionSymbol, IProcedure> procedures = [];

public void DefineField(FieldSymbol fieldSymbol) => this.fields.Add(fieldSymbol);
public void DefineProperty(PropertySymbol propertySymbol) => this.properties.Add(propertySymbol);

public Procedure DefineProcedure(FunctionSymbol functionSymbol)
{
if (!this.procedures.TryGetValue(functionSymbol, out var result))
Expand Down
18 changes: 12 additions & 6 deletions src/Draco.Compiler/Internal/OptimizingIr/Model/IClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,33 @@ namespace Draco.Compiler.Internal.OptimizingIr.Model;
internal interface IClass
{
/// <summary>
/// The symbol of this type.
/// The symbol of this class.
/// </summary>
public TypeSymbol Symbol { get; }

/// <summary>
/// The name of this type.
/// The name of this class.
/// </summary>
public string Name { get; }

/// <summary>
/// The generic parameters on this type.
/// The generic parameters on this class.
/// </summary>
public IReadOnlyList<TypeParameterSymbol> Generics { get; }

// TODO: Fields and props should be order-dependent for classes and modules too
/// <summary>
/// The fields on this type.
/// The fields on this class.
/// </summary>
public IReadOnlyList<FieldSymbol> Fields { get; }
public IReadOnlySet<FieldSymbol> Fields { get; }

/// <summary>
/// The procedures on this type.
/// The properties within this class.
/// </summary>
public IReadOnlySet<PropertySymbol> Properties { get; }

/// <summary>
/// The procedures on this class.
/// </summary>
public IReadOnlyDictionary<FunctionSymbol, IProcedure> Procedures { get; }
}

0 comments on commit d418c40

Please sign in to comment.