Skip to content

Commit

Permalink
Update MetadataCodegen.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
LPeter1997 committed Dec 4, 2023
1 parent 769fb32 commit 04eea0a
Showing 1 changed file with 64 additions and 19 deletions.
83 changes: 64 additions & 19 deletions src/Draco.Compiler/Internal/Codegen/MetadataCodegen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Xml.Linq;
using Draco.Compiler.Api;
using Draco.Compiler.Internal.OptimizingIr.Model;
using Draco.Compiler.Internal.Symbols;
Expand Down Expand Up @@ -380,15 +381,27 @@ private void EncodeAssembly()
}
}

private void EncodeModule(IModule module, TypeDefinitionHandle? parentModule = null, int fieldIndex = 1, int procIndex = 1)
private void EncodeModule(IModule module)
{
var currentFieldIndex = fieldIndex;
var currentProcIndex = procIndex;
var fieldIndex = 1;
var procIndex = 1;
this.EncodeModule(module, parent: null, fieldIndex: ref fieldIndex, procIndex: ref procIndex);
}

private void EncodeModule(
IModule module,
TypeDefinitionHandle? parent,
ref int fieldIndex,
ref int procIndex)
{
var startFieldIndex = fieldIndex;
var startProcIndex = procIndex;

// Go through globals
foreach (var global in module.Globals)
{
this.EncodeGlobal(global);
currentFieldIndex++;
++fieldIndex;
}

// Go through procedures
Expand All @@ -402,22 +415,17 @@ private void EncodeModule(IModule module, TypeDefinitionHandle? parentModule = n

// If this is the entry point, save it
if (ReferenceEquals(this.assembly.EntryPoint, procedure)) this.EntryPointHandle = handle;
currentProcIndex++;

++procIndex;
}

// Compile global initializer too
this.EncodeProcedure(module.GlobalInitializer, specialName: ".cctor");
currentProcIndex++;
++procIndex;

TypeAttributes visibility;
if (module.Symbol.Visibility == Api.Semantics.Visibility.Public)
{
visibility = parentModule is not null ? TypeAttributes.NestedPublic : TypeAttributes.Public;
}
else
{
visibility = parentModule is not null ? TypeAttributes.NestedAssembly : TypeAttributes.NotPublic;
}
var visibility = module.Symbol.Visibility == Api.Semantics.Visibility.Public
? (parent is not null ? TypeAttributes.NestedPublic : TypeAttributes.Public)
: (parent is not null ? TypeAttributes.NestedAssembly : TypeAttributes.NotPublic);
var attributes = visibility | TypeAttributes.Class | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit | TypeAttributes.Abstract | TypeAttributes.Sealed;

var name = string.IsNullOrEmpty(module.Name) ? CompilerConstants.DefaultModuleName : module.Name;
Expand All @@ -428,19 +436,56 @@ private void EncodeModule(IModule module, TypeDefinitionHandle? parentModule = n
@namespace: default,
name: name,
baseType: this.systemObjectReference,
fieldList: MetadataTokens.FieldDefinitionHandle(fieldIndex),
methodList: MetadataTokens.MethodDefinitionHandle(procIndex));
fieldList: MetadataTokens.FieldDefinitionHandle(startFieldIndex),
methodList: MetadataTokens.MethodDefinitionHandle(startProcIndex));

// If this isn't top level module, we specify nested relationship
if (parentModule is not null) this.MetadataBuilder.AddNestedType(createdModule, parentModule.Value);
if (parent is not null) this.MetadataBuilder.AddNestedType(createdModule, parent.Value);

// We encode every class
foreach (var @class in module.Classes.Values)
{
this.EncodeClass(@class, parent: createdModule, fieldIndex: ref fieldIndex, procIndex: ref procIndex);
}

// We encode every submodule
foreach (var subModule in module.Submodules.Values)
{
this.EncodeModule(subModule, createdModule, currentFieldIndex, currentProcIndex);
this.EncodeModule(subModule, parent: createdModule, fieldIndex: ref fieldIndex, procIndex: ref procIndex);
}
}

private TypeDefinitionHandle EncodeClass(
IClass @class,
TypeDefinitionHandle? parent,
ref int fieldIndex,
ref int procIndex)
{
var startFieldIndex = fieldIndex;
var startProcIndex = procIndex;

// TODO: Go through members

var visibility = @class.Symbol.Visibility == Api.Semantics.Visibility.Public
? (parent is not null ? TypeAttributes.NestedPublic : TypeAttributes.Public)
: (parent is not null ? TypeAttributes.NestedAssembly : TypeAttributes.NotPublic);
var attributes = visibility | TypeAttributes.Class | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit | TypeAttributes.Sealed;

// Create the type
var createdClass = this.AddTypeDefinition(
attributes: attributes,
@namespace: default,
name: @class.Name,
baseType: this.systemObjectReference,
fieldList: MetadataTokens.FieldDefinitionHandle(startFieldIndex),
methodList: MetadataTokens.MethodDefinitionHandle(startProcIndex));

// If this isn't top level module, we specify nested relationship
if (parent is not null) this.MetadataBuilder.AddNestedType(createdClass, parent.Value);

return createdClass;
}

private FieldDefinitionHandle EncodeGlobal(GlobalSymbol global)
{
var visibility = global.Visibility switch
Expand Down

0 comments on commit 04eea0a

Please sign in to comment.