Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'calli' into develop

  • Loading branch information...
commit a0bc14ad584f684a0f3587b973cc358dbb731ff7 2 parents efc59fa + 3469219
@thefiddler thefiddler authored
View
2  Source/Generator.Rewrite/Generator.Rewrite.csproj
@@ -23,7 +23,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Commandlineparameters>../../OpenTK/Debug/OpenTK.dll ../../../OpenTK.snk</Commandlineparameters>
+ <Commandlineparameters>../../OpenTK/Debug/OpenTK.dll ../../../OpenTK.snk -debug</Commandlineparameters>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
View
182 Source/Generator.Rewrite/Program.cs
@@ -34,14 +34,17 @@ static void Main(string[] args)
{
if (args.Length == 0)
{
- Console.WriteLine("Usage: rewrite [file.dll] [file.snk]");
+ Console.WriteLine("Usage: rewrite [file.dll] [file.snk] [options]");
+ Console.WriteLine("[options] is:");
+ Console.WriteLine(" -debug (enable calls to GL.GetError())");
return;
}
var program = new Program();
var file = args[0];
- var key = args.Length >= 2 ? args[1] : null;
- program.Rewrite(file, key);
+ var key = args[1];
+ var options = args.Where(a => a.StartsWith("-") || a.StartsWith("/"));
+ program.Rewrite(file, key, options);
}
// mscorlib types
@@ -55,7 +58,7 @@ static void Main(string[] args)
// OpenTK.BindingsBase
static TypeDefinition TypeBindingsBase;
- void Rewrite(string file, string keyfile)
+ void Rewrite(string file, string keyfile, IEnumerable<string> options)
{
// Specify assembly read and write parameters
// We want to keep a valid symbols file (pdb or mdb)
@@ -123,7 +126,7 @@ void Rewrite(string file, string keyfile)
{
foreach (var type in module.Types)
{
- Rewrite(type);
+ Rewrite(type, options);
}
}
}
@@ -136,7 +139,7 @@ void Rewrite(string file, string keyfile)
assembly.Write(file, write_params);
}
- void Rewrite(TypeDefinition type)
+ void Rewrite(TypeDefinition type, IEnumerable<string> options)
{
var entry_points = type.Fields.FirstOrDefault(f => f.Name == "EntryPoints");
if (entry_points != null)
@@ -146,7 +149,7 @@ void Rewrite(TypeDefinition type)
entry_signatures.AddRange(type.Methods
.Where(t => t.CustomAttributes.Any(a => a.AttributeType.Name == "SlotAttribute")));
- Rewrite(type, entry_points, entry_signatures);
+ Rewrite(type, entry_points, entry_signatures, options);
RemoveNativeSignatures(type, entry_signatures);
}
@@ -162,7 +165,7 @@ void Rewrite(TypeDefinition type)
}
void Rewrite(TypeDefinition type, FieldDefinition entry_points,
- List<MethodDefinition> entry_signatures)
+ List<MethodDefinition> entry_signatures, IEnumerable<string> options)
{
// Rewrite all wrapper methods
var wrapper_signatures = new List<MethodDefinition>();
@@ -182,7 +185,7 @@ void Rewrite(TypeDefinition type)
.First(a => a.AttributeType.Name == "SlotAttribute")
.ConstructorArguments[0].Value;
- ProcessMethod(wrapper, signature, slot, entry_points);
+ ProcessMethod(wrapper, signature, slot, entry_points, options);
}
}
@@ -192,7 +195,7 @@ void Rewrite(TypeDefinition type)
{
foreach (var nested_type in type.NestedTypes)
{
- Rewrite(nested_type, entry_points, entry_signatures);
+ Rewrite(nested_type, entry_points, entry_signatures, options);
}
}
}
@@ -223,7 +226,8 @@ void RemoveSupportingAttributes(TypeDefinition type)
}
// Create body for method
- static void ProcessMethod(MethodDefinition wrapper, MethodDefinition native, int slot, FieldDefinition entry_points)
+ static void ProcessMethod(MethodDefinition wrapper, MethodDefinition native, int slot,
+ FieldDefinition entry_points, IEnumerable<string> options)
{
var body = wrapper.Body;
var il = body.GetILProcessor();
@@ -233,6 +237,12 @@ static void ProcessMethod(MethodDefinition wrapper, MethodDefinition native, int
// Declare pinned variables for every reference and array parameter
// and push each parameter on the stack
+ DebugVariables vars = null;
+ if (options.Contains("-debug"))
+ {
+ vars = EmitDebugPrologue(wrapper, il);
+ }
+
// Patch convenience wrappers
if (wrapper.Parameters.Count == native.Parameters.Count)
{
@@ -266,6 +276,11 @@ static void ProcessMethod(MethodDefinition wrapper, MethodDefinition native, int
{
EmitStringEpilogue(wrapper, body, il);
}
+
+ if (options.Contains("-debug"))
+ {
+ EmitDebugEpilogue(wrapper, il, vars);
+ }
// return
il.Emit(OpCodes.Ret);
@@ -279,6 +294,151 @@ static void ProcessMethod(MethodDefinition wrapper, MethodDefinition native, int
body.OptimizeMacros();
}
+ class DebugVariables
+ {
+ public TypeDefinition ErrorHelperType;
+ public VariableDefinition ErrorHelperLocal;
+ public MethodReference Get_CurrentContext;
+ public MethodReference Set_ErrorChecking;
+ public Instruction BeginTry;
+ }
+
+ static DebugVariables EmitDebugPrologue(MethodDefinition wrapper, ILProcessor il)
+ {
+
+ DebugVariables vars = null;
+ if (il.Body.Method.Name != "GetError")
+ {
+ // Pull out the namespace name, method fullname will look
+ // something like "type namespace.class::method(type arg)"
+ var module = il.Body.Method.FullName;
+ module = module.Substring(module.IndexOf(' ') + 1);
+ module = module.Substring(0, module.IndexOf("::"));
+ module = module.Substring(0, module.LastIndexOf('.'));
+
+ // Only works for Graphics modules due to hardcoded use of
+ // OpenTK.Graphics.GraphicsContext
+ if (module == "OpenTK.Graphics.OpenGL4" ||
+ module == "OpenTK.Graphics.OpenGL" ||
+ module == "OpenTK.Graphics.ES10" ||
+ module == "OpenTK.Graphics.ES11" ||
+ module == "OpenTK.Graphics.ES20" ||
+ module == "OpenTK.Graphics.ES30")
+ {
+ var errorHelperType = wrapper.Module.GetType(module, "ErrorHelper");
+
+ if (errorHelperType != null)
+ {
+ vars = new DebugVariables();
+ vars.ErrorHelperType = errorHelperType;
+
+ // GraphicsContext type
+ var graphicsContext = wrapper.Module.Types.First(
+ type => type.FullName == "OpenTK.Graphics.GraphicsContext");
+
+ // IGraphicsContext type
+ var iGraphicsContext = wrapper.Module.Types.First(
+ type => type.FullName == "OpenTK.Graphics.IGraphicsContext");
+
+ // Get the constructor that takes a GraphicsContext parameter
+ var ctor = vars.ErrorHelperType.GetConstructors().FirstOrDefault(
+ c => c.Parameters.Count == 1 &&
+ c.Parameters[0].ParameterType.FullName == iGraphicsContext.FullName);
+
+ if (ctor == null)
+ {
+ throw new InvalidOperationException(
+ String.Format(
+ "{0} does needs a constructor taking {1}",
+ errorHelperType,
+ graphicsContext));
+ }
+
+ // GraphicsContext.CurrentContext property getter
+ vars.Get_CurrentContext = graphicsContext.Methods.First(
+ method => method.Name == "get_CurrentContext");
+
+ vars.Set_ErrorChecking = graphicsContext.Methods.First(
+ method => method.Name == "set_ErrorChecking");
+
+ vars.ErrorHelperLocal = new VariableDefinition(vars.ErrorHelperType);
+
+ // using (new ErrorHelper(GraphicsContext.CurrentContext)) { ...
+ il.Body.Variables.Add(vars.ErrorHelperLocal);
+ il.Emit(OpCodes.Ldloca, vars.ErrorHelperLocal);
+ il.Emit(OpCodes.Call, vars.Get_CurrentContext);
+ il.Emit(OpCodes.Call, ctor);
+
+ vars.BeginTry = Instruction.Create(OpCodes.Nop);
+ il.Append(vars.BeginTry);
+
+ // Special case Begin to turn off error checking.
+ if (il.Body.Method.Name == "Begin")
+ {
+ il.Emit(OpCodes.Call, vars.Get_CurrentContext);
+ il.Emit(OpCodes.Ldc_I4_0);
+ il.Emit(OpCodes.Conv_I1);
+ il.Emit(OpCodes.Call, vars.Set_ErrorChecking);
+ }
+ }
+ }
+ }
+
+ return vars;
+ }
+
+ static void EmitDebugEpilogue(MethodDefinition wrapper, ILProcessor il, DebugVariables vars)
+ {
+ if (vars != null)
+ {
+ var disposeMethod = vars.ErrorHelperType.Methods.First(
+ method => method.Name == "Dispose");
+
+ // Store then reload the result from the call
+ var resultLocal = new VariableDefinition(wrapper.ReturnType);
+ if (resultLocal.VariableType.FullName != Program.TypeVoid.FullName)
+ {
+ il.Body.Variables.Add(resultLocal);
+ il.Emit(OpCodes.Stloc, resultLocal);
+ }
+
+ // Special case End to turn on error checking.
+ if (il.Body.Method.Name == "End")
+ {
+ il.Emit(OpCodes.Call, vars.Get_CurrentContext);
+ il.Emit(OpCodes.Ldc_I4_1);
+ il.Emit(OpCodes.Conv_I1);
+ il.Emit(OpCodes.Call, vars.Set_ErrorChecking);
+ }
+
+ // We need a NOP to set up the finally handler range correctly.
+ var nopInstruction = Instruction.Create(OpCodes.Nop);
+ var loadInstruction = Instruction.Create(OpCodes.Ldloca, vars.ErrorHelperLocal);
+ var disposeInstruction = Instruction.Create(OpCodes.Call, disposeMethod);
+ var endFinallyInstruction = Instruction.Create(OpCodes.Endfinally);
+ var endTryInstruction = Instruction.Create(OpCodes.Leave, nopInstruction);
+
+ il.Append(endTryInstruction);
+ il.Append(loadInstruction);
+ il.Append(disposeInstruction);
+ il.Append(endFinallyInstruction);
+ il.Append(nopInstruction);
+
+ var finallyHandler = new ExceptionHandler(ExceptionHandlerType.Finally);
+ finallyHandler.TryStart = vars.BeginTry;
+ finallyHandler.TryEnd = loadInstruction;
+ finallyHandler.HandlerStart = loadInstruction;
+ finallyHandler.HandlerEnd = nopInstruction;
+
+ il.Body.ExceptionHandlers.Add(finallyHandler);
+
+ if (resultLocal.VariableType.FullName != Program.TypeVoid.FullName)
+ {
+ il.Emit(OpCodes.Ldloc, resultLocal);
+ }
+ }
+ }
+
private static void EmitReturnTypeWrapper(MethodDefinition wrapper, MethodDefinition native, MethodBody body, ILProcessor il)
{
if (wrapper.Parameters.Count < native.Parameters.Count)
View
4 Source/OpenTK/OpenTK.csproj
@@ -811,9 +811,9 @@
</PropertyGroup>
<ItemGroup />
<Target Name="AfterBuild">
- <Exec Command="$(OutputPath)..\..\Tools\Debug\Rewrite.exe $(OutputPath)OpenTK.dll ..\..\OpenTK.snk" Condition="$(OS) == 'Windows_NT' and $(Configuration) == 'Debug'" />
+ <Exec Command="$(OutputPath)..\..\Tools\Debug\Rewrite.exe $(OutputPath)OpenTK.dll ..\..\OpenTK.snk -debug" Condition="$(OS) == 'Windows_NT' and $(Configuration) == 'Debug'" />
<Exec Command="$(OutputPath)..\..\Tools\Release\Rewrite.exe $(OutputPath)OpenTK.dll ..\..\OpenTK.snk" Condition="$(OS) == 'Windows_NT' and $(Configuration) != 'Debug'" />
- <Exec Command="mono $(OutputPath)..\..\Tools\Debug\Rewrite.exe $(OutputPath)OpenTK.dll ..\..\OpenTK.snk" Condition="$(OS) != 'Windows_NT' and $(Configuration) == 'Debug'" />
+ <Exec Command="mono $(OutputPath)..\..\Tools\Debug\Rewrite.exe $(OutputPath)OpenTK.dll ..\..\OpenTK.snk -debug" Condition="$(OS) != 'Windows_NT' and $(Configuration) == 'Debug'" />
<Exec Command="mono $(OutputPath)..\..\Tools\Release\Rewrite.exe $(OutputPath)OpenTK.dll ..\..\OpenTK.snk" Condition="$(OS) != 'Windows_NT' and $(Configuration) != 'Debug'" />
</Target>
<ProjectExtensions>
Please sign in to comment.
Something went wrong with that request. Please try again.