[SRE] Implemented missing SRE features.
#if !FULL_AOT_RUNTIME
using System;
+using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Globalization;
return ilgen;
}
+ public void SetMethodBody (byte[] il, int maxStack, byte[] localSignature,
+ IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)
+ {
+ var ilgen = GetILGenerator ();
+ ilgen.Init (il, maxStack, localSignature, exceptionHandlers, tokenFixups);
+ }
+
+
public void SetCustomAttribute (CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
#if !FULL_AOT_RUNTIME
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Diagnostics.SymbolStore;
using System.Runtime.InteropServices;
internal struct ILExceptionInfo {
#pragma warning disable 169
#pragma warning disable 414
- ILExceptionBlock[] handlers;
+ internal ILExceptionBlock[] handlers;
internal int start;
- int len;
+ internal int len;
internal Label end;
#pragma warning restore 169
#pragma warning restore 414
}
}
- // Used by DynamicILGenerator
+ // Used by MethodBuilder.SetMethodBody
+ internal void SetExceptionHandlers (ILExceptionInfo[] exHandlers) {
+ this.ex_handlers = exHandlers;
+ }
+
+ // Used by MethodBuilder.SetMethodBody
+ internal void SetTokenFixups (ILTokenInfo[] tokenFixups) {
+ this.token_fixups = tokenFixups;
+ }
+
+ // Used by DynamicILGenerator and MethodBuilder.SetMethodBody
internal void SetCode (byte[] code, int max_stack) {
// Make a copy to avoid possible security problems
this.code = (byte[])code.Clone ();
this.cur_stack = 0;
}
+ internal void Init (byte[] il, int maxStack, byte[] localSignature,
+ IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)
+ {
+ SetCode (il, maxStack);
+
+ // FIXME: Process local signature
+
+ // Process exception handlers
+ if (exceptionHandlers != null) {
+ // Group exception handlers by try blocks
+ var tryBlocks = new Dictionary <Tuple<int, int>, List<ExceptionHandler>> ();
+ foreach (var h in exceptionHandlers) {
+ List<ExceptionHandler> list;
+ var key = new Tuple <int, int> (h.TryOffset, h.TryLength);
+ if (!tryBlocks.TryGetValue (key, out list)) {
+ list = new List<ExceptionHandler> ();
+ tryBlocks.Add (key, list);
+ }
+ list.Add (h);
+ }
+
+ // Generate ILExceptionInfo from tryBlocks
+ var infos = new List<ILExceptionInfo> ();
+ foreach (var kv in tryBlocks) {
+ var info = new ILExceptionInfo () {
+ start = kv.Key.Item1,
+ len = kv.Key.Item2,
+ handlers = new ILExceptionBlock [kv.Value.Count],
+ };
+ infos.Add (info);
+ var i = 0;
+ foreach (var b in kv.Value) {
+ info.handlers [i++] = new ILExceptionBlock () {
+ start = b.HandlerOffset,
+ len = b.HandlerLength,
+ filter_offset = b.FilterOffset,
+ type = (int) b.Kind,
+ extype = module.ResolveType (b.ExceptionTypeToken),
+ };
+ }
+ }
+
+ SetExceptionHandlers (infos.ToArray ());
+ }
+
+ // Process token fixups
+ if (tokenFixups != null) {
+ var tokenInfos = new List<ILTokenInfo> ();
+ foreach (var pos in tokenFixups) {
+ var token = (int) BitConverter.ToUInt32 (il, pos);
+ var tokenInfo = new ILTokenInfo () {
+ code_pos = pos,
+ member = ((ModuleBuilder) module).ResolveOrGetRegisteredToken (token, null, null)
+ };
+ tokenInfos.Add (tokenInfo);
+ }
+
+ SetTokenFixups (tokenInfos.ToArray ());
+ }
+ }
+
+
internal TokenGenerator TokenGenerator {
get {
return token_gen;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Diagnostics.SymbolStore;
+using System.Collections.Generic;
namespace System.Reflection.Emit
{
}
}
+ public void SetMethodBody (byte[] il, int maxStack, byte[] localSignature,
+ IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)
+ {
+ var ilgen = GetILGenerator ();
+ ilgen.Init (il, maxStack, localSignature, exceptionHandlers, tokenFixups);
+ }
+
public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
throw NotSupported ();
return new MethodToken (GetToken (method));
}
+
+ public MethodToken GetMethodToken (MethodInfo method, IEnumerable<Type> optionalParameterTypes)
+ {
+ if (method == null)
+ throw new ArgumentNullException ("method");
+
+ return new MethodToken (GetToken (method, optionalParameterTypes));
+ }
public MethodToken GetArrayMethodToken (Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
{
{
if (con == null)
throw new ArgumentNullException ("con");
- if (con.DeclaringType.Module != this)
- throw new InvalidOperationException ("The constructor is not in this module");
+
return new MethodToken (GetToken (con));
}
+
+ public MethodToken GetConstructorToken (ConstructorInfo constructor, IEnumerable<Type> optionalParameterTypes)
+ {
+ if (constructor == null)
+ throw new ArgumentNullException ("constructor");
+
+ return new MethodToken (GetToken (constructor, optionalParameterTypes));
+ }
public FieldToken GetFieldToken (FieldInfo field)
{
if (field == null)
throw new ArgumentNullException ("field");
- if (field.DeclaringType.Module != this)
- throw new InvalidOperationException ("The method is not in this module");
+
return new FieldToken (GetToken (field));
}
return getToken (this, member, create_open_instance);
}
+ internal int GetToken (MethodBase method, IEnumerable<Type> opt_param_types) {
+ if (opt_param_types == null)
+ return getToken (this, method, true);
+
+ var optParamTypes = new List<Type> (opt_param_types);
+ return getMethodToken (this, method, optParamTypes.ToArray ());
+ }
+
internal int GetToken (MethodBase method, Type[] opt_param_types) {
return getMethodToken (this, method, opt_param_types);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void RegisterToken (object obj, int token);
+ /*
+ * Returns MemberInfo registered with the given token.
+ */
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern object GetRegisteredToken (int token);
+
internal TokenGenerator GetTokenGenerator () {
if (token_gen == null)
token_gen = new ModuleBuilderTokenGenerator (this);
return m;
}
+ internal MemberInfo ResolveOrGetRegisteredToken (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments)
+ {
+ ResolveTokenError error;
+ MemberInfo m = ResolveMemberToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
+ if (m != null)
+ return m;
+
+ m = GetRegisteredToken (metadataToken) as MemberInfo;
+ if (m == null)
+ throw resolve_token_exception (metadataToken, error, "MemberInfo");
+ else
+ return m;
+ }
+
public override MethodBase ResolveMethod (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
ResolveTokenError error;
return DefineNestedType (name, attr, parent, null, packSize, UnspecifiedTypeSize);
}
+ public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packSize,
+ int typeSize)
+ {
+ return DefineNestedType (name, attr, parent, null, packSize, typeSize);
+ }
+
[ComVisible (true)]
public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes)
{
+++ /dev/null
-//
-// System.Reflection/ExceptionHandlingClauseOptions.cs
-//
-// Author:
-// Zoltan Varga (vargaz@gmail.com)
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace System.Reflection {
-
- [ComVisible (true)]
- [Flags]
- public enum ExceptionHandlingClauseOptions {
- Clause = 0x0,
- Filter = 0x1,
- Finally = 0x2,
- Fault = 0x4
- }
-
-}
--- /dev/null
+ //
+ // MethodBuilderTestIL.cs - NUnit Test Cases for MethodBuilder.CreateMethodBody and MethodBuilder.SetMethodBody
+ //
+ // Marcos Henrich (marcos.henrich@xamarin.com)
+ //
+ // (C) Xamarin, Inc.
+
+ using System;
+ using System.Linq;
+ using System.Reflection;
+ using System.Reflection.Emit;
+ using System.Threading;
+
+ using NUnit.Framework;
+ using System.IO;
+
+ namespace MonoTests.System.Reflection.Emit
+ {
+ public abstract class MethodBuilderTestIL
+ {
+ protected abstract void SetIL (MethodBuilder methodBuilder, MemoryStream ilStream);
+
+ public static ModuleBuilder CreateModuleBuilder ()
+ {
+ AppDomain currentDom = Thread.GetDomain ();
+
+ AssemblyBuilder assemblyBuilder = currentDom.DefineDynamicAssembly (
+ new AssemblyName ("NewDynamicAssembly"),
+ AssemblyBuilderAccess.Run);
+
+ return assemblyBuilder.DefineDynamicModule ("NewModule");
+ }
+
+ public static object Invoke (Type type, MethodBuilder methodBuilder, params object[] parameters)
+ {
+ var method = type.GetMethods ().First (m => {
+ if (m.Name != methodBuilder.Name)
+ return false;
+ var params1 = m.GetParameters ();
+ var params2 = methodBuilder.GetParameters ();
+ if (params1.Length != params2.Length)
+ return false;
+ for (var i = 0; i < params1.Length; i++)
+ if (params1 [i].ParameterType.FullName != params2 [i].ParameterType.FullName)
+ return false;
+
+ return true;
+ });
+
+ object inst = Activator.CreateInstance (type, new object [0]);
+
+ return method.Invoke (inst, parameters);
+ }
+
+ [Test]
+ public void CallMethodRef ()
+ {
+ var expected = "value";
+
+ var moduleBuilder = CreateModuleBuilder ();
+ var typeBuilder = moduleBuilder.DefineType ("NewType");
+
+ var methodBuilder1 = typeBuilder.DefineMethod ("NewMethod1",
+ MethodAttributes.Public | MethodAttributes.Static,
+ typeof (string),
+ Type.EmptyTypes);
+
+ var gen1 = methodBuilder1.GetILGenerator ();
+ gen1.Emit (OpCodes.Ldstr, expected);
+ gen1.Emit (OpCodes.Ret);
+
+ var methodBuilder2 = typeBuilder.DefineMethod ("NewMethod2",
+ MethodAttributes.Public | MethodAttributes.Static,
+ typeof (string),
+ Type.EmptyTypes);
+
+ var ilStream = new MemoryStream ();
+ var ilWriter = new BinaryWriter (ilStream);
+ ilWriter.Write ((byte) 0x28); // call
+ ilWriter.Write ((int) moduleBuilder.GetMethodToken (methodBuilder1).Token);
+ ilWriter.Write ((byte) 0x2A); // ret
+
+ SetIL (methodBuilder2, ilStream);
+
+ var type = typeBuilder.CreateType ();
+
+ Assert.AreEqual (expected, Invoke (type, methodBuilder2));
+ }
+
+ [Test]
+ public void CallMethodDef ()
+ {
+ var expected = "value";
+
+ var moduleBuilder1 = CreateModuleBuilder ();
+ var typeBuilder1 = moduleBuilder1.DefineType ("NewType1", TypeAttributes.Public);
+
+ var methodBuilder1 = typeBuilder1.DefineMethod ("NewMethod1",
+ MethodAttributes.Public | MethodAttributes.Static,
+ typeof (string),
+ Type.EmptyTypes);
+
+ var gen1 = methodBuilder1.GetILGenerator ();
+ gen1.Emit (OpCodes.Ldstr, expected);
+ gen1.Emit (OpCodes.Ret);
+
+ typeBuilder1.CreateType ();
+
+ var moduleBuilder2 = CreateModuleBuilder ();
+ var typeBuilder2 = moduleBuilder2.DefineType ("NewType2");
+
+ var methodBuilder2 = typeBuilder2.DefineMethod ("NewMethod2",
+ MethodAttributes.Public | MethodAttributes.Static,
+ typeof (string),
+ Type.EmptyTypes);
+
+ var ilStream = new MemoryStream ();
+ var ilWriter = new BinaryWriter (ilStream);
+ ilWriter.Write ((byte) 0x28); // call
+ ilWriter.Write ((int) moduleBuilder2.GetMethodToken (methodBuilder1).Token);
+ ilWriter.Write ((byte) 0x2A); // ret
+
+ SetIL (methodBuilder2, ilStream);
+
+ var type = typeBuilder2.CreateType ();
+
+ Assert.AreEqual (expected, Invoke (type, methodBuilder2));
+ }
+ }
+
+ /*
+ * Tests MethodBuilder.CreateMethodBody
+ */
+ [TestFixture]
+ public class MethodBuilderTestIL_CreateMethodBody : MethodBuilderTestIL
+ {
+ protected override void SetIL (MethodBuilder methodBuilder, MemoryStream ilStream)
+ {
+ methodBuilder.CreateMethodBody (ilStream.ToArray (), (int) ilStream.Length);
+ }
+ }
+
+ /*
+ * Tests MethodBuilder.SetMethodBody
+ */
+ [TestFixture]
+ public class MethodBuilderTestIL_SetMethodBody : MethodBuilderTestIL
+ {
+ protected override void SetIL (MethodBuilder methodBuilder, MemoryStream ilStream)
+ {
+ methodBuilder.SetMethodBody (ilStream.ToArray (), 999, null, null, null);
+ }
+ }
+ }
catch (ArgumentException) {
}
}
+
+ [Test]
+ public void GetMethodTokenNullParam ()
+ {
+ AssemblyName an = genAssemblyName ();
+ AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run);
+ ModuleBuilder module = ab.DefineDynamicModule ("mod");
+
+ var method = typeof (object).GetMethod ("GetType");
+
+ // ArgumentNullException should not occur.
+ module.GetMethodToken (method, null);
+ }
+
+ [Test]
+ public void GetConstructorTokenNullParam ()
+ {
+ AssemblyName an = genAssemblyName ();
+ AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run);
+ ModuleBuilder module = ab.DefineDynamicModule ("mod");
+
+ var method = typeof (object).GetConstructor (Type.EmptyTypes);
+
+ // ArgumentNullException should not occur.
+ module.GetConstructorToken (method, null);
+ }
}
}
System.Reflection/CustomAttributeTypedArgument.cs
System.Reflection/EventInfo.cs
System.Reflection/ExceptionHandlingClause.cs
-System.Reflection/ExceptionHandlingClauseOptions.cs
System.Reflection/FieldInfo.cs
System.Reflection/ImageFileMachine.cs
System.Reflection/LocalVariableInfo.cs
../../../external/referencesource/mscorlib/system/reflection/membertypes.cs
../../../external/referencesource/mscorlib/system/reflection/methodattributes.cs
../../../external/referencesource/mscorlib/system/reflection/methodbase.cs
+../../../external/referencesource/mscorlib/system/reflection/methodbody.cs
../../../external/referencesource/mscorlib/system/reflection/methodimplattributes.cs
../../../external/referencesource/mscorlib/system/reflection/missing.cs
../../../external/referencesource/mscorlib/system/reflection/obfuscateassemblyattribute.cs
../../../external/referencesource/mscorlib/system/reflection/typefilter.cs
../../../external/referencesource/mscorlib/system/reflection/typeinfo.cs
+../../../external/referencesource/mscorlib/system/reflection/emit/methodbuilder.cs
+
../../../external/referencesource/mscorlib/system/resources/__fastresourcecomparer.cs
../../../external/referencesource/mscorlib/system/resources/__hresults.cs
../../../external/referencesource/mscorlib/system/resources/filebasedresourcegroveler.cs
System.Reflection.Emit/GenericTypeParameterBuilderTest.cs
System.Reflection.Emit/ILGeneratorTest.cs
System.Reflection.Emit/MethodBuilderTest.cs
+System.Reflection.Emit/MethodBuilderTestIL.cs
System.Reflection.Emit/MethodOnTypeBuilderInstTest.cs
System.Reflection.Emit/MethodRentalTest.cs
System.Reflection.Emit/ModuleBuilderTest.cs
ICALL_TYPE(METHODB, "System.Reflection.Emit.MethodBuilder", METHODB_1)
ICALL(METHODB_1, "MakeGenericMethod", mono_reflection_bind_generic_method_parameters)
-ICALL_TYPE(MODULEB, "System.Reflection.Emit.ModuleBuilder", MODULEB_8)
+ICALL_TYPE(MODULEB, "System.Reflection.Emit.ModuleBuilder", MODULEB_10)
+ICALL(MODULEB_10, "GetRegisteredToken", ves_icall_ModuleBuilder_GetRegisteredToken)
ICALL(MODULEB_8, "RegisterToken", ves_icall_ModuleBuilder_RegisterToken)
ICALL(MODULEB_1, "WriteToFile", ves_icall_ModuleBuilder_WriteToFile)
ICALL(MODULEB_2, "basic_init", mono_image_module_basic_init)
mono_image_register_token (mb->dynamic_image, token, obj);
}
+ICALL_EXPORT MonoObject*
+ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
+{
+ gpointer obj;
+
+ mono_loader_lock ();
+ obj = mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
+ mono_loader_unlock ();
+
+ return obj;
+}
+
static gboolean
get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
{