summaryrefslogtreecommitdiff
path: root/compiler/ILEmitter/ILMethodEmitterManager.cs
blob: d5ce85ddf2c1da733a0ac27ffa42945d32a0eb7c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System.Reflection;
using System.Reflection.Emit;

namespace AtLangCompiler.ILEmitter;

internal class ILMethodEmitterManager
{
    private readonly MethodEmitterFactory factory;
    private readonly ILGenerator il;

    public ILMethodEmitterManager(ILGenerator il, LocalBuilder dictLocal)
    {
        this.il = il ?? throw new ArgumentNullException(nameof(il));
        _ = dictLocal ?? throw new ArgumentNullException(nameof(dictLocal));

        IServiceProvider serviceProvider = DIConfiguration.ConfigureServices(il, dictLocal, this);
        this.factory = new MethodEmitterFactory(serviceProvider);
    }

    internal void EmitStatement(ASTNode node)
    {
        object emitter = factory.CreateEmitter(node);
        Type nodeType = node.GetType();

        Type emitterType = typeof(IMethodEmitter<>).MakeGenericType(nodeType);

        if (typeof(IMethodEmitter<ASTNode>).IsAssignableFrom(emitter.GetType()))
        {
            emitterType = typeof(IMethodEmitter<ASTNode>);
        }

        MethodInfo emitMethod = emitterType.GetMethod(nameof(IMethodEmitter<ASTNode>.EmitIL))!;
        emitMethod.Invoke(emitter, [node]);
    }
}