Skip to content

Commit a6dd19c

Browse files
author
NielsDev
committed
Runtime work, implement ldftn, work on delegates
1 parent 2a04493 commit a6dd19c

12 files changed

Lines changed: 180 additions & 8 deletions

File tree

CSharpLLVM/CSharpLLVM.csproj

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@
9494
</ItemGroup>
9595
<ItemGroup>
9696
<Compile Include="Compilation\Branch.cs" />
97-
<Compile Include="Compilation\BuiltinRuntimeFunctions.cs" />
97+
<Compile Include="Runtime\Builtin\BuiltinRuntimeFunctions.cs" />
98+
<Compile Include="Runtime\CIL\CILRuntimeMethodCompiler.cs" />
9899
<Compile Include="Compilation\TypeKind.cs" />
99100
<Compile Include="Generator\Instructions\Arrays\EmitLdelem_Any.cs" />
100101
<Compile Include="Generator\Instructions\Arrays\EmitLdelem_Ref.cs" />
@@ -148,6 +149,10 @@
148149
<Compile Include="Helpers\NameHelper.cs" />
149150
<Compile Include="Helpers\PredicateHelper.cs" />
150151
<Compile Include="Helpers\RuntimeHelper.cs" />
152+
<Compile Include="Runtime\CIL\DelegatesHandler.cs" />
153+
<Compile Include="Runtime\CIL\IRuntimeHandler.cs" />
154+
<Compile Include="Runtime\CIL\MethodHandlerAttribute.cs" />
155+
<Compile Include="Runtime\CIL\RuntimeHandlerAttribute.cs" />
151156
<Compile Include="Stack\ILStack.cs" />
152157
<Compile Include="Generator\CodeGenerator.cs" />
153158
<Compile Include="Compilation\Compiler.cs" />

CSharpLLVM/Compilation/Compiler.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using CSharpLLVM.Generator;
77
using CSharpLLVM.Helpers;
88
using CSharpLLVM.Lookups;
9+
using CSharpLLVM.Runtime.Builtin;
910

1011
namespace CSharpLLVM.Compilation
1112
{

CSharpLLVM/Compilation/MethodCompiler.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using CSharpLLVM.Generator;
22
using CSharpLLVM.Helpers;
3+
using CSharpLLVM.Runtime.CIL;
34
using Mono.Cecil;
45
using Swigged.LLVM;
56
using System;
@@ -9,6 +10,7 @@ namespace CSharpLLVM.Compilation
910
class MethodCompiler
1011
{
1112
private Compiler mCompiler;
13+
private CILRuntimeMethodCompiler mRuntimeCompiler;
1214

1315
/// <summary>
1416
/// Creates a new MethodCompiler.
@@ -17,6 +19,7 @@ class MethodCompiler
1719
public MethodCompiler(Compiler compiler)
1820
{
1921
mCompiler = compiler;
22+
mRuntimeCompiler = new CILRuntimeMethodCompiler(compiler);
2023
}
2124

2225
/// <summary>
@@ -27,6 +30,10 @@ public void CreateDeclaration(MethodDefinition methodDef)
2730
{
2831
string methodName = NameHelper.CreateMethodName(methodDef);
2932
int paramCount = methodDef.Parameters.Count;
33+
34+
// CIL runtime method?
35+
if (methodDef.IsRuntime && !mRuntimeCompiler.MustHandleMethod(methodDef))
36+
return;
3037

3138
// If we expect an instance reference as first argument, then we need to make sure our for loop has an offset.
3239
int offset = 0;
@@ -69,6 +76,11 @@ public void Compile(MethodDefinition methodDef)
6976
string methodName = NameHelper.CreateMethodName(methodDef);
7077
ValueRef? function = mCompiler.Lookup.GetFunction(methodName);
7178

79+
// It is possible we didn't create a declaration because we don't want to generate this method.
80+
// In that case, don't continue.
81+
if (!function.HasValue)
82+
return;
83+
7284
// A method has internal linkage if one (or both) of the following is true:
7385
// 1) The method is a private method.
7486
// 2) The compiler got an option to set the linkage of instance methods to internal.

CSharpLLVM/Generator/CodeGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public CodeGenerator()
2222
foreach (Type type in types)
2323
{
2424
// Check and get handler.
25-
InstructionHandlerAttribute attrib = (InstructionHandlerAttribute)type.GetCustomAttribute(typeof(InstructionHandlerAttribute), false);
25+
InstructionHandlerAttribute attrib = (InstructionHandlerAttribute)type.GetCustomAttribute(typeof(InstructionHandlerAttribute));
2626
if (attrib == null)
2727
continue;
2828

CSharpLLVM/Generator/Instructions/Objects/EmitNewobj.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using CSharpLLVM.Helpers;
55
using Mono.Cecil;
66
using CSharpLLVM.Compilation;
7+
using System;
78

89
namespace CSharpLLVM.Generator.Instructions.Objects
910
{
@@ -23,21 +24,23 @@ public void Emit(Instruction instruction, MethodContext context, BuilderRef buil
2324
TypeRef type = TypeHelper.GetTypeRefFromType(ctor.DeclaringType);
2425

2526
ValueRef objPtr;
26-
bool ptr = objType.IsClass && !objType.IsValueType;
27+
bool ptr = (objType.IsClass && !objType.IsValueType);
2728
if (ptr)
2829
{
2930
// This type is a class, therefor we have a specialised "newobj" method.
3031
objPtr = LLVM.BuildCall(builder, context.Compiler.Lookup.GetNewobjMethod(ctor.DeclaringType.Resolve()), new ValueRef[0], "newobj");
3132
}
3233
else
3334
{
34-
// Not a class, no specialised method.
35+
// Not a class, allocate on stack.
3536
objPtr = LLVM.BuildAlloca(builder, type, "newobj");
3637
}
3738

3839
// Constructor.
3940
ValueRef? ctorFunc = context.Compiler.Lookup.GetFunction(NameHelper.CreateMethodName(ctor));
40-
41+
if (!ctorFunc.HasValue)
42+
throw new Exception("Constructor not found: " + ctor);
43+
4144
// Get .ctor parameters.
4245
int paramCount = 1 + ctor.Parameters.Count;
4346
ValueRef[] values = new ValueRef[paramCount];
@@ -46,6 +49,13 @@ public void Emit(Instruction instruction, MethodContext context, BuilderRef buil
4649
{
4750
StackElement element = context.CurrentStack.Pop();
4851
values[i] = element.Value;
52+
53+
// Cast needed?
54+
TypeRef paramType = TypeHelper.GetTypeRefFromType(ctor.Parameters[i - 1].ParameterType);
55+
if (element.Type != paramType)
56+
{
57+
CastHelper.HelpIntAndPtrCast(builder, ref values[i], ref element.Type, paramType, "ctorcallcast");
58+
}
4959
}
5060

5161
// Call .ctor.

CSharpLLVM/Generator/Instructions/StoreLoad/EmitLdftn.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
using Swigged.LLVM;
2+
using Mono.Cecil;
23
using Mono.Cecil.Cil;
34
using CSharpLLVM.Compilation;
5+
using CSharpLLVM.Stack;
6+
using CSharpLLVM.Helpers;
7+
using System;
48

59
namespace CSharpLLVM.Generator.Instructions.StoreLoad
610
{
@@ -15,7 +19,10 @@ class EmitLdftn : ICodeEmitter
1519
/// <param name="builder">The builder.</param>
1620
public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
1721
{
18-
// TODO.
22+
MethodDefinition method = (MethodDefinition)instruction.Operand;
23+
ValueRef result = LLVM.BuildIntToPtr(builder, context.Compiler.Lookup.GetFunction(NameHelper.CreateMethodName(method)).Value, TypeHelper.NativeIntType, "ldftn");
24+
StackElement element = new StackElement(result, typeof(IntPtr).GetTypeReference(), TypeHelper.NativeIntType);
25+
context.CurrentStack.Push(element);
1926
}
2027
}
2128
}

CSharpLLVM/Compilation/BuiltinRuntimeFunctions.cs renamed to CSharpLLVM/Runtime/Builtin/BuiltinRuntimeFunctions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
using CSharpLLVM.Helpers;
1+
using CSharpLLVM.Compilation;
2+
using CSharpLLVM.Helpers;
23
using Swigged.LLVM;
34

4-
namespace CSharpLLVM.Compilation
5+
namespace CSharpLLVM.Runtime.Builtin
56
{
67
class BuiltinRuntimeFunctions
78
{
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using CSharpLLVM.Compilation;
2+
using Mono.Cecil;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Reflection;
6+
7+
namespace CSharpLLVM.Runtime.CIL
8+
{
9+
class CILRuntimeMethodCompiler
10+
{
11+
private Compiler mCompiler;
12+
private Dictionary<string, Tuple<IRuntimeHandler, MethodInfo>> mLookup = new Dictionary<string, Tuple<IRuntimeHandler, MethodInfo>>();
13+
14+
/// <summary>
15+
/// Creates a new CILRuntimeMethodCompiler.
16+
/// </summary>
17+
/// <param name="compiler">The compiler.</param>
18+
public CILRuntimeMethodCompiler(Compiler compiler)
19+
{
20+
mCompiler = compiler;
21+
initHandlers();
22+
}
23+
24+
/// <summary>
25+
/// Initializes the handlers.
26+
/// </summary>
27+
private void initHandlers()
28+
{
29+
// Load code emitters.
30+
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
31+
foreach (Type type in types)
32+
{
33+
// Check and get handler.
34+
RuntimeHandlerAttribute classAttrib = (RuntimeHandlerAttribute)type.GetCustomAttribute(typeof(RuntimeHandlerAttribute));
35+
if (classAttrib == null)
36+
continue;
37+
38+
IRuntimeHandler handler = (IRuntimeHandler)Activator.CreateInstance(type);
39+
MethodInfo[] methods = type.GetMethods();
40+
foreach (MethodInfo method in methods)
41+
{
42+
// Check and get method handler.
43+
MethodHandlerAttribute methodAttrib = (MethodHandlerAttribute)method.GetCustomAttribute(typeof(MethodHandlerAttribute));
44+
if (methodAttrib == null)
45+
continue;
46+
47+
string fullName = string.Format("{0}.{1}", classAttrib.TypeName, methodAttrib.MethodName);
48+
mLookup.Add(fullName, new Tuple<IRuntimeHandler, MethodInfo>(handler, method));
49+
}
50+
}
51+
}
52+
53+
/// <summary>
54+
/// Returns true if we must handle the method, false if we can ignore it.
55+
/// </summary>
56+
/// <param name="method">The runtime method.</param>
57+
/// <returns>True if we must handle the method, false if we can ignore it.</returns>
58+
public bool MustHandleMethod(MethodDefinition method)
59+
{
60+
string fullName = string.Format("{0}.{1}", method.DeclaringType.BaseType, method.Name);
61+
return mLookup.ContainsKey(fullName);
62+
}
63+
}
64+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Swigged.LLVM;
2+
using System;
3+
4+
namespace CSharpLLVM.Runtime.CIL
5+
{
6+
[RuntimeHandler(typeof(MulticastDelegate))]
7+
class DelegatesHandler : IRuntimeHandler
8+
{
9+
[MethodHandler(".ctor")]
10+
public void compileCtor(BuilderRef builder)
11+
{
12+
13+
}
14+
15+
[MethodHandler("Invoke")]
16+
public void compileInvoke(BuilderRef builder)
17+
{
18+
19+
}
20+
}
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace CSharpLLVM.Runtime.CIL
8+
{
9+
interface IRuntimeHandler
10+
{
11+
12+
}
13+
}

0 commit comments

Comments
 (0)