Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to support CoreCLR #308

Closed
wants to merge 10 commits into from
10 changes: 5 additions & 5 deletions Source/Bind/Generator.Bind.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<DebugType>none</DebugType>
<DebugType>pdbonly</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Nsis|AnyCPU'">
<BaseAddress>285212672</BaseAddress>
Expand All @@ -82,11 +82,11 @@
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<DebugType>none</DebugType>
<DebugType>pdbonly</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Documentation|AnyCPU'">
<OutputPath>..\..\Binaries\Tools\Release\</OutputPath>
<DebugType>none</DebugType>
<DebugType>pdbonly</DebugType>
<WarningLevel>4</WarningLevel>
<Optimize>True</Optimize>
<DefineConstants>TRACE;</DefineConstants>
Expand Down Expand Up @@ -284,7 +284,7 @@
</ConfigurationOverrideFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMinimal|AnyCPU' ">
<DebugType>none</DebugType>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Binaries\Tools\Release\</OutputPath>
<DefineConstants>TRACE;</DefineConstants>
Expand Down Expand Up @@ -317,4 +317,4 @@
<Folder Include="Specifications\GL2\ES\3.1\" />
<Folder Include="Specifications\GL2\ES\1.1\" />
</ItemGroup>
</Project>
</Project>
6 changes: 1 addition & 5 deletions Source/Converter/Generator.Convert.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,9 @@
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Documentation|AnyCPU'">
<OutputPath>..\..\Binaries\Tools\Release\</OutputPath>
<DebugType>none</DebugType>
<WarningLevel>4</WarningLevel>
<Optimize>True</Optimize>
<DefineConstants>TRACE;</DefineConstants>
Expand All @@ -89,7 +87,6 @@
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>True</SignAssembly>
Expand Down Expand Up @@ -160,7 +157,6 @@
<BaseAddress>285212672</BaseAddress>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMinimal|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Binaries\Tools\Release\</OutputPath>
<DefineConstants>TRACE;</DefineConstants>
Expand All @@ -173,4 +169,4 @@
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
</PropertyGroup>
</Project>
</Project>
99 changes: 65 additions & 34 deletions Source/Generator.Rewrite/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ static void Main(string[] args)
Console.WriteLine("Usage: rewrite [file.dll] [file.snk] [options]");
Console.WriteLine("[options] is:");
Console.WriteLine(" -debug (enable calls to GL.GetError())");
Console.WriteLine(" -references-file=ReferenceCacheFile");
return;
}

Expand All @@ -47,10 +48,13 @@ static void Main(string[] args)
program.Rewrite(file, key, options);
}

// mscorlib types
static AssemblyDefinition mscorlib;
// Assemblies
static AssemblyDefinition coreAssembly; // System.Runtime or mscorlib

// Type defs
static TypeDefinition TypeMarshal;
static TypeDefinition TypeStringBuilder;
static TypeDefinition TypeUTF8String;
static TypeDefinition TypeVoid;
static TypeDefinition TypeIntPtr;
static TypeDefinition TypeInt32;
Expand Down Expand Up @@ -92,35 +96,64 @@ void Rewrite(string file, string keyfile, IEnumerable<string> options)
Console.Error.WriteLine("No keyfile specified or keyfile missing.");
}

// Load assembly and process all modules
var assembly = AssemblyDefinition.ReadAssembly(file, read_params);
var rewritten = assembly.CustomAttributes.FirstOrDefault(a => a.AttributeType.Name == "RewrittenAttribute");
if (rewritten == null)
// If a reference file was provided, read it and update our assembly resolver
// to use the assemblies in those path.
var referenceFile = options.FirstOrDefault(o => o.StartsWith("-references-file="));
if (referenceFile != null)
{
foreach (var module in assembly.Modules)
referenceFile = referenceFile.Substring(("-references-file").Length + 1);
List<string> references = new List<string>(100);
references.AddRange(File.ReadAllLines(referenceFile));
if (references.Count > 0)
{
foreach (var reference in module.AssemblyReferences)
var resolver = new DefaultAssemblyResolver();
read_params.AssemblyResolver = resolver;
var alreadyPresentTable = new Dictionary<string, string>(references.Count);
foreach (var ass in references)
{
var resolved = module.AssemblyResolver.Resolve(reference);
if (reference.Name == "mscorlib")
string dir = Path.GetDirectoryName(ass);
if (!alreadyPresentTable.ContainsKey(dir))
{
mscorlib = resolved;
alreadyPresentTable.Add(dir, dir);
resolver.AddSearchDirectory(dir);
}
}
}
}

if (mscorlib == null)
// Load assembly and process all modules
var assembly = AssemblyDefinition.ReadAssembly(file, read_params);
var rewritten = assembly.CustomAttributes.FirstOrDefault(a => a.AttributeType.Name == "RewrittenAttribute");
if (rewritten == null)
{
var corlib = assembly.MainModule.TypeSystem.Corlib as AssemblyNameReference;
if (corlib == null)
{
Console.Error.WriteLine("Failed to locate mscorlib");
return;
}
TypeMarshal = mscorlib.MainModule.GetType("System.Runtime.InteropServices.Marshal");
TypeStringBuilder = mscorlib.MainModule.GetType("System.Text.StringBuilder");
TypeVoid = mscorlib.MainModule.GetType("System.Void");
TypeIntPtr = mscorlib.MainModule.GetType("System.IntPtr");
TypeInt32 = mscorlib.MainModule.GetType("System.Int32");
else
{
coreAssembly = assembly.MainModule.AssemblyResolver.Resolve(corlib);
}
TypeStringBuilder = coreAssembly.MainModule.GetType("System.Text.StringBuilder");
TypeVoid = coreAssembly.MainModule.GetType("System.Void");
TypeIntPtr = coreAssembly.MainModule.GetType("System.IntPtr");
TypeInt32 = coreAssembly.MainModule.GetType("System.Int32");

TypeMarshal = coreAssembly.MainModule.GetType("System.Runtime.InteropServices.Marshal");
if (TypeMarshal == null)
{
var ass = assembly.MainModule.AssemblyResolver.Resolve("System.Runtime.InteropServices");
if (ass == null)
{
Console.WriteLine("Failed to locate System.Runtime.InteropServices.dll");
return;
}
TypeMarshal = ass.MainModule.GetType("System.Runtime.InteropServices.Marshal");
}
TypeBindingsBase = assembly.Modules.Select(m => m.GetType("OpenTK.BindingsBase")).First();
TypeUTF8String = assembly.Modules.Select(m => m.GetType("OpenTK.Platform.UTF8String")).First();

foreach (var module in assembly.Modules)
{
Expand Down Expand Up @@ -159,7 +192,7 @@ void Rewrite(TypeDefinition type, IEnumerable<string> options)
var rewritten_constructor = type.GetConstructors().First();
var rewritten = new CustomAttribute(rewritten_constructor);
rewritten.ConstructorArguments.Add(new CustomAttributeArgument(
type.Module.Import(mscorlib.MainModule.GetType("System.Boolean")), true));
type.Module.Import(coreAssembly.MainModule.GetType("System.Boolean")), true));
type.Module.Assembly.CustomAttributes.Add(rewritten);
}
}
Expand Down Expand Up @@ -460,26 +493,24 @@ private static void EmitReturnTypeWrapper(MethodDefinition wrapper, MethodDefini
{
if (wrapper.ReturnType.Name == "String")
{
// String return-type wrapper
// return new string((sbyte*)((void*)GetString()));

var intptr_to_voidpointer = wrapper.Module.Import(mscorlib.MainModule.GetType("System.IntPtr").GetMethods()
.First(m =>
{
return
m.Name == "op_Explicit" &&
m.ReturnType.Name == "Void*";
}));
// String return-type wrapper to convert from UTF8
// return OpenTK.Platform.UTF8String.String(GetString());

var string_constructor = wrapper.Module.Import(mscorlib.MainModule.GetType("System.String").GetConstructors()
var string_constructor = wrapper.Module.Import(TypeUTF8String.Methods
.First(m =>
{
var p = m.Parameters;
return p.Count > 0 && p[0].ParameterType.Name == "SByte*";
if (m.IsStatic)
{
var p = m.Parameters;
return p.Count == 1 && m.Name == "String" && p[0].ParameterType.Name == "IntPtr";
}
else
{
return false;
}
}));

il.Emit(OpCodes.Call, intptr_to_voidpointer);
il.Emit(OpCodes.Newobj, string_constructor);
il.Emit(OpCodes.Call, string_constructor);
}
else if (wrapper.ReturnType.Resolve().IsEnum)
{
Expand Down Expand Up @@ -819,7 +850,7 @@ static int EmitParameters(MethodDefinition method, MethodDefinition native, Meth
else
{
var get_length = method.Module.Import(
mscorlib.MainModule.GetType("System.Array").Methods.First(m => m.Name == "get_Length"));
coreAssembly.MainModule.GetType("System.Array").Methods.First(m => m.Name == "get_Length"));
il.Emit(OpCodes.Callvirt, get_length);
}
il.Emit(OpCodes.Brtrue, pin);
Expand Down
28 changes: 23 additions & 5 deletions Source/OpenTK/BlittableValueType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ public static class BlittableValueType<T>
static BlittableValueType()
{
Type = typeof(T);
#if _NET_CORECLR
if (Type.GetTypeInfo().IsValueType && !Type.GetTypeInfo().IsGenericType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just override with Type.GetTypeInfo instead of adding it under the compilation flag? It's supported in dot net 4.5 as well (and the recommended way, as far as I understand). Is there a need to support .Net 4?
Also, maybe it would be better to take Type.GetTypeInfo into a variable to avoid calling it twice inside the if.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been upgrading a few projects to CoreCLR and some have a minimum requirement of .NET 4.0 thus the #if. If this is not required for OpenTK, then we could simplify the code as you are suggesting.

#else
if (Type.IsValueType && !Type.IsGenericType)
#endif
{
// Does this support generic types? On Mono 2.4.3 it does
// On .Net it doesn't.
Expand Down Expand Up @@ -113,10 +117,18 @@ public static bool Check(Type type)
static bool CheckType(Type type)
{
//Debug.Print("Checking type {0} (size: {1} bytes).", type.Name, Marshal.SizeOf(type));
#if _NET_CORECLR
if (type.GetTypeInfo().IsPrimitive)
#else
if (type.IsPrimitive)
#endif
return true;

#if _NET_CORECLR
if (!type.GetTypeInfo().IsValueType)
#else
if (!type.IsValueType)
#endif
return false;

FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
Expand All @@ -135,11 +147,17 @@ static bool CheckType(Type type)
// or [StructLayout(LayoutKind.Explicit)]
static bool CheckStructLayoutAttribute(Type type)
{
StructLayoutAttribute[] attr = (StructLayoutAttribute[])
type.GetCustomAttributes(typeof(StructLayoutAttribute), true);

if ((attr == null) ||
(attr != null && attr.Length > 0 && attr[0].Value != LayoutKind.Explicit && attr[0].Pack != 1))
StructLayoutAttribute attr = null;
#if _NET_CORECLR
attr = type.GetTypeInfo().GetCustomAttribute<StructLayoutAttribute>(true);
#else
object [] attrs = type.GetCustomAttributes(typeof(StructLayoutAttribute), true);
if ((attrs != null) && (attrs.Length > 0))
{
attr = (StructLayoutAttribute) attrs[0];
}
#endif
if ((attr == null) && attr.Value != LayoutKind.Explicit && attr.Pack != 1)
return false;

return true;
Expand Down
4 changes: 4 additions & 0 deletions Source/OpenTK/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,15 @@ static void DetectUnix(out bool unix, out bool linux, out bool macos)

static bool DetectWindows()
{
#if !_NET_CORECLR
return
System.Environment.OSVersion.Platform == PlatformID.Win32NT ||
System.Environment.OSVersion.Platform == PlatformID.Win32S ||
System.Environment.OSVersion.Platform == PlatformID.Win32Windows ||
System.Environment.OSVersion.Platform == PlatformID.WinCE;
#else
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
#endif
}

static bool DetectX11()
Expand Down
4 changes: 4 additions & 0 deletions Source/OpenTK/Exceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ namespace OpenTK
/// <summary>
/// This exception is thrown when a GraphicsContext property cannot be changed after creation.
/// </summary>
#if _NET_CORECLR
public class ContextExistsException : Exception

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you shouldn't need this since you have a definition for ApplicationException (the one I commented on below).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, it was done before I felt uneasy about my changes to replace ApplicationException into just a mundane Exception.

#else
public class ContextExistsException : ApplicationException
#endif
{
string msg;

Expand Down
10 changes: 9 additions & 1 deletion Source/OpenTK/Graphics/ES10/ES.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace OpenTK.Graphics.ES10
using System;
using System.Text;
using System.Runtime.InteropServices;
using OpenTK.Platform;
#pragma warning disable 3019
#pragma warning disable 1591
#pragma warning disable 1572
Expand Down Expand Up @@ -2619,7 +2620,14 @@ unsafe System.String GetString(OpenTK.Graphics.ES10.All name)
using (new ErrorHelper(GraphicsContext.CurrentContext))
{
#endif
unsafe { return new string((sbyte*)Core.GetString((OpenTK.Graphics.ES10.All)name)); }
unsafe
{
#if !_NET_CORECLR
return new string((sbyte *) Core.GetString((OpenTK.Graphics.ES10.All)name));
#else
return UTF8String.String(Core.GetString((OpenTK.Graphics.ES10.All)name));
#endif
}
#if DEBUG
}
#endif
Expand Down
11 changes: 0 additions & 11 deletions Source/OpenTK/Graphics/ES20/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,17 +437,6 @@ public static void Viewport(Rectangle rectangle)
{
GL.Viewport(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
#if MINIMAL
public static void Viewport(OpenTK.Point location, OpenTK.Size size)
{
GL.Viewport(location.X, location.Y, size.Width, size.Height);
}

public static void Viewport(OpenTK.Rectangle rectangle)
{
GL.Viewport(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
#endif
#endregion

#pragma warning restore 3019
Expand Down
11 changes: 0 additions & 11 deletions Source/OpenTK/Graphics/ES30/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,17 +428,6 @@ public static void Viewport(Rectangle rectangle)
{
GL.Viewport(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
#if MINIMAL
public static void Viewport(OpenTK.Point location, OpenTK.Size size)
{
GL.Viewport(location.X, location.Y, size.Width, size.Height);
}

public static void Viewport(OpenTK.Rectangle rectangle)
{
GL.Viewport(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
#endif
#endregion

#pragma warning restore 3019
Expand Down
11 changes: 0 additions & 11 deletions Source/OpenTK/Graphics/OpenGL/GLHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,17 +1346,6 @@ public static void Viewport(Rectangle rectangle)
{
GL.Viewport(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
#if MINIMAL
public static void Viewport(OpenTK.Point location, OpenTK.Size size)
{
GL.Viewport(location.X, location.Y, size.Width, size.Height);
}

public static void Viewport(OpenTK.Rectangle rectangle)
{
GL.Viewport(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
#endif
#endregion

#region TexEnv
Expand Down
Loading