From daf5b828c9431b90dfccb7930b465adcd255898f Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Wed, 27 Nov 2013 01:40:12 +0100 Subject: [PATCH] Implemented string return types --- Source/OpenTK.Rewrite/Program.cs | 90 ++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 16 deletions(-) diff --git a/Source/OpenTK.Rewrite/Program.cs b/Source/OpenTK.Rewrite/Program.cs index b04af180..22413a8f 100644 --- a/Source/OpenTK.Rewrite/Program.cs +++ b/Source/OpenTK.Rewrite/Program.cs @@ -44,6 +44,8 @@ namespace OpenTK.Rewrite program.Rewrite(file, key); } + static AssemblyDefinition mscorlib; + void Rewrite(string file, string keyfile) { // Specify assembly read and write parameters @@ -87,17 +89,27 @@ namespace OpenTK.Rewrite { foreach (var module in assembly.Modules) { - if (rewritten == null) + foreach (var reference in module.AssemblyReferences) { - foreach (var reference in module.AssemblyReferences) + var resolved = module.AssemblyResolver.Resolve(reference); + if (reference.Name == "mscorlib") { - module.AssemblyResolver.Resolve(reference); + mscorlib = resolved; } + } + } - foreach (var type in module.Types) - { - Rewrite(type); - } + if (mscorlib == null) + { + Console.Error.WriteLine("Falied to locate mscorlib"); + return; + } + + foreach (var module in assembly.Modules) + { + foreach (var type in module.Types) + { + Rewrite(type); } } } @@ -138,8 +150,8 @@ namespace OpenTK.Rewrite ProcessMethod(wrapper, signature, slot, entry_points); } - //RemoveNativeSignatures(); - //RemoveSupportingAttributes(); + RemoveNativeSignatures(type, native_signatures); + RemoveSupportingAttributes(type); } if (type.Name == "RewrittenAttribute") @@ -150,21 +162,41 @@ namespace OpenTK.Rewrite } } + void RemoveNativeSignatures(TypeDefinition type, List methods) + { + while (methods.Count > 0) + { + type.Methods.Remove(methods.Last()); + methods.RemoveAt(methods.Count - 1); + } + } + + void RemoveSupportingAttributes(TypeDefinition type) + { + foreach (var method in type.Methods) + { + var attr = method.CustomAttributes; + for (int i = 0; i < attr.Count; i++) + { + if (attr[i].AttributeType.Name == "AutoGeneratedAttribute") + { + attr.RemoveAt(i); + i--; + } + } + } + } + // Create body for method static void ProcessMethod(MethodDefinition wrapper, MethodDefinition native, int slot, FieldDefinition entry_points) { - var nint = wrapper.DeclaringType.Module.Import(typeof(IntPtr)); + var nint = wrapper.DeclaringType.Module.Import(mscorlib.MainModule.GetType("System.IntPtr")); //var nint = new TypeReference("System", "IntPtr", wrapper.DeclaringType.Module, null); var body = wrapper.Body; var il = body.GetILProcessor(); var instructions = body.Instructions; instructions.Clear(); - if (wrapper.ReturnType != native.ReturnType) - { - Console.Error.WriteLine("Return type wrappers not implemented yet ({0})", native.Name); - } - // Declare pinned variables for every reference and array parameter // and push each parameter on the stack EmitParameters(wrapper, nint, body, il); @@ -233,7 +265,33 @@ namespace OpenTK.Rewrite } else if (wrapper.ReturnType != native.ReturnType) { - Console.Error.WriteLine("Return wrappers not implemented yet ({0})", native.Name); + if (wrapper.ReturnType.Name == "String") + { + // String return-type wrapper + // return new string((sbyte*)((void*)GetString())); + + var intptr_to_voidpointer = wrapper.Module.Import(typeof(IntPtr).GetMethods() + .First(m => + { + return + m.Name == "op_Explicit" && + m.ReturnType.Name == "Void*"; + })); + + var string_constructor = wrapper.Module.Import(typeof(string).GetConstructors() + .First(m => + { + var p = m.GetParameters(); + return p.Length > 0 && p[0].ParameterType.Name == "SByte*"; + })); + + il.Emit(OpCodes.Call, intptr_to_voidpointer); + il.Emit(OpCodes.Newobj, string_constructor); + } + else + { + Console.Error.WriteLine("Return wrappers not implemented yet ({0})", native.Name); + } } else {