private MethodDefinition Manage(MethodDefinition method) { var _type = this.m_Type.Type(method.IsConstructor ? "<<Constructor>>" : $"<{ method.Name }>", TypeAttributes.NestedPublic | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract); foreach (var _generic in method.DeclaringType.GenericParameters.Concat(method.GenericParameters)) { _type.GenericParameters.Add(_generic.Copy(_type)); } var _importation = new Importation(method, _type); var _method = _type.Method(method.IsConstructor ? "<Constructor>" : method.Name, MethodAttributes.Static | MethodAttributes.Private); if (!method.IsStatic) { _method.Parameter("this", ParameterAttributes.None, _method.Resolve(method.DeclaringType)); } _method.ReturnType = _method.Resolve(method.ReturnType); _method.Body.InitLocals = method.Body.InitLocals; _method.DebugInformation.Scope = method.DebugInformation.Scope; _method.Body.MaxStackSize = method.Body.MaxStackSize; _method.Body.LocalVarToken = method.Body.LocalVarToken; foreach (var _parameter in method.Parameters) { _method.Parameter(_parameter.Name, _parameter.Attributes, _method.Resolve(_parameter.ParameterType)); } foreach (var _variable in method.Body.Variables) { _method.Body.Variable(_method.Resolve(_variable.VariableType)); } var _dictionary = new Dictionary <Instruction, Instruction>(); foreach (var _instruction in method.Body.Instructions) { _method.Body.Instructions.Add(this.Copy(method, _method, _importation, _instruction, _dictionary)); } foreach (var _exception in method.Body.ExceptionHandlers) { _method.Body.ExceptionHandlers.Add(new ExceptionHandler(_exception.HandlerType) { CatchType = _exception.CatchType, TryStart = this.Copy(method, _method, _importation, _exception.TryStart, _dictionary), TryEnd = this.Copy(method, _method, _importation, _exception.TryEnd, _dictionary), HandlerType = _exception.HandlerType, HandlerStart = this.Copy(method, _method, _importation, _exception.HandlerStart, _dictionary), HandlerEnd = this.Copy(method, _method, _importation, _exception.HandlerEnd, _dictionary) }); } if (method.DebugInformation != null && method.DebugInformation.Scope != null) { if (method.DebugInformation.Scope.Variables != null) { _method.DebugInformation.Scope.Variables.Clear(); foreach (var _variable in method.DebugInformation.Scope.Variables) { _method.DebugInformation.Scope.Variables.Add(new VariableDebugInformation(_method.Body.Variables[_variable.Index], _variable.Name)); } } } _method.Body.OptimizeMacros(); return(_method); }
private FieldDefinition Manage(MethodDefinition method) { var _type = this.m_Type.Type(method.IsConstructor ? "<<Constructor>>" : $"<{ method.Name }>", TypeAttributes.NestedPublic | TypeAttributes.Abstract | TypeAttributes.Sealed); foreach (var _parameter in this.m_Type.GenericParameters) { _type.GenericParameters.Add(_parameter.Copy(_type)); } foreach (var _parameter in method.GenericParameters) { _type.GenericParameters.Add(_parameter.Copy(_type)); } var _handle = _type.Field <object>("<Handle>", FieldAttributes.Static | FieldAttributes.Public).Relative(); var _authentic = _type.Field <IntPtr>("<Authentic>", FieldAttributes.Static | FieldAttributes.Public).Relative(); var _auxiliary = _type.Field <IntPtr>("<Auxiliary>", FieldAttributes.Static | FieldAttributes.Public).Relative(); var _field = _type.Field <IntPtr>("<Pointer>", FieldAttributes.Static | FieldAttributes.Public); var _pointer = _field.Relative(); var _update = _type.Method("<Update>", MethodAttributes.Static | MethodAttributes.Private); _update.Parameter <IntPtr>("<Pointer>"); var _return = Instruction.Create(OpCodes.Ret); using (_update.Body.Lock(_handle)) { _update.Body.Emit(OpCodes.Ldsfld, _auxiliary); using (_update.Body.True()) { _update.Body.Emit(OpCodes.Ldarg_0); _update.Body.Emit(OpCodes.Stsfld, _auxiliary); _update.Body.Emit(OpCodes.Leave, _return); } _update.Body.Emit(OpCodes.Ldarg_0); _update.Body.Emit(OpCodes.Stsfld, _pointer); } _update.Body.Emit(_return); var _primary = _type.Method(method.IsConstructor ? "<Constructor>" : method.Name, MethodAttributes.Static | MethodAttributes.Private); _primary.ReturnType = _primary.Resolve(method.ReturnType); if (!method.IsStatic) { _primary.Parameter("this", ParameterAttributes.None, _primary.Resolve(method.DeclaringType)); } foreach (var _parameter in method.Parameters) { _primary.Parameter(_parameter.Name, _parameter.Attributes, _primary.Resolve(_parameter.ParameterType)); } _primary.Body.Variable <IntPtr>(); _primary.Body.Emit(OpCodes.Ldsfld, _handle); _primary.Body.Emit(OpCodes.Call, Metadata.Method(() => Monitor.Enter(Metadata <object> .Value))); _primary.Body.Emit(Metadata <Action <MethodBase> > .Type); _primary.Body.Emit(typeof(Metadata)); _primary.Body.Emit(OpCodes.Ldstr, "Broadcast"); _primary.Body.Emit(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly); _primary.Body.Emit(OpCodes.Call, Metadata <Type> .Method(_Type => _Type.GetMethod(Metadata <string> .Value, Metadata <BindingFlags> .Value))); _primary.Body.Emit(OpCodes.Call, Metadata.Method(() => Delegate.CreateDelegate(Metadata <Type> .Value, Metadata <MethodInfo> .Value))); var _importation = new Importation(method, _type); //_primary.Body.Emit(_importation[method]); //TODO THONGTO _primary.Body.Emit(method); if (method.GenericParameters.Count > 0) { _primary.Body.Emit(OpCodes.Ldc_I4, method.GenericParameters.Count); _primary.Body.Emit(OpCodes.Newarr, typeof(Type)); for (var i = 0; i < method.GenericParameters.Count; i++) { _primary.Body.Emit(OpCodes.Dup); _primary.Body.Emit(OpCodes.Ldc_I4, i); _primary.Body.Emit(_type.GenericParameters.Skip(method.DeclaringType.GenericParameters.Count).ElementAt(i)); _primary.Body.Emit(OpCodes.Stelem_Ref); } _primary.Body.Emit(OpCodes.Callvirt, Metadata <MethodInfo> .Method(_Method => _Method.MakeGenericMethod(Metadata <Type[]> .Value))); } _primary.Body.Emit(OpCodes.Callvirt, Metadata <Action <MethodBase> > .Method(_Action => _Action.Invoke(Metadata <MethodBase> .Value))); _primary.Body.Emit(OpCodes.Ldsfld, _pointer); _primary.Body.Emit(OpCodes.Stloc_0); _primary.Body.Emit(OpCodes.Ldsfld, _auxiliary); using (_primary.Body.True()) { _primary.Body.Emit(OpCodes.Ldsfld, _auxiliary); _primary.Body.Emit(OpCodes.Stloc_0); _primary.Body.Emit(OpCodes.Ldloc_0); _primary.Body.Emit(OpCodes.Stsfld, _pointer); _primary.Body.Emit(OpCodes.Ldsfld, Metadata.Field(() => IntPtr.Zero)); _primary.Body.Emit(OpCodes.Stsfld, _auxiliary); } _primary.Body.Emit(OpCodes.Ldsfld, _handle); _primary.Body.Emit(OpCodes.Call, Metadata.Method(() => Monitor.Exit(Metadata <object> .Value))); for (var _index = 0; _index < _primary.Parameters.Count; _index++) { switch (_index) { case 0: _primary.Body.Emit(OpCodes.Ldarg_0); break; case 1: _primary.Body.Emit(OpCodes.Ldarg_1); break; case 2: _primary.Body.Emit(OpCodes.Ldarg_2); break; case 3: _primary.Body.Emit(OpCodes.Ldarg_3); break; default: _primary.Body.Emit(OpCodes.Ldarg_S, _primary.Parameters[_index]); break; } } _primary.Body.Emit(OpCodes.Ldloc_0); _primary.Body.Emit(OpCodes.Calli, _primary.ReturnType, _primary.Parameters); _primary.Body.Emit(OpCodes.Ret); _primary.Body.OptimizeMacros(); var _initializer = _type.Initializer(); var _variable = _initializer.Body.Variable <RuntimeMethodHandle>(); _initializer.Body.Variable <Func <IntPtr> >(); _initializer.Body.Emit(OpCodes.Newobj, Metadata.Constructor(() => new object())); _initializer.Body.Emit(OpCodes.Stsfld, _handle); //var met = new MethodReference(this.m_Authentic[method].Name, _primary.ReturnType, this.m_Authentic[method].DeclaringType.MakeGenericType(_type.GenericParameters.Take(this.m_Type.GenericParameters.Count))); //foreach (var p in met.GenericParameters) { met.GenericParameters.Add(new GenericParameter(p.Name, met)); } //foreach (var _parameter in this.m_Authentic[method].Parameters) { met.Parameters.Add(new ParameterDefinition(_parameter.Name, _parameter.Attributes, _parameter.ParameterType.IsMethodGenericParameterType() ? _type.GenericParameterType(_parameter.ParameterType.Name) : _parameter.ParameterType)); } //_initializer.Body.Emit(met.MakeGenericMethod(_type.GenericParameters.Reverse().Take(method.GenericParameters.Count).Reverse().ToArray())); _initializer.Body.Emit(_importation[this.m_Authentic[method]]); _initializer.Body.Emit(OpCodes.Callvirt, Intermediate.GetMethodHandle); _initializer.Body.Emit(OpCodes.Stloc_0); _initializer.Body.Emit(OpCodes.Ldloca_S, _variable); _initializer.Body.Emit(OpCodes.Callvirt, Intermediate.GetFunctionPointer); _initializer.Body.Emit(OpCodes.Stsfld, _authentic); _initializer.Body.Emit(OpCodes.Ldsfld, _authentic); _initializer.Body.Emit(OpCodes.Stsfld, _auxiliary); //var met2 = new MethodReference(_primary.Name, _primary.ReturnType, _type.MakeGenericType(_type.GenericParameters)); //foreach (var _parameter in _primary.Parameters) { met2.Parameters.Add(new ParameterDefinition(_parameter.Name, _parameter.Attributes, _parameter.ParameterType.IsMethodGenericParameterType() ? _type.GenericParameterType(_parameter.ParameterType.Name) : _parameter.ParameterType)); } //_initializer.Body.Emit(met2); //_initializer.Body.Emit(new MethodReference(_primary.Name, _primary.ReturnType, this.m_Authentic[method].DeclaringType.MakeGenericType(_type.GenericParameters))); _initializer.Body.Emit(_importation[_primary]); _initializer.Body.Emit(OpCodes.Callvirt, Intermediate.GetMethodHandle); _initializer.Body.Emit(OpCodes.Stloc_0); _initializer.Body.Emit(OpCodes.Ldloca_S, _variable); _initializer.Body.Emit(OpCodes.Callvirt, Intermediate.GetFunctionPointer); _initializer.Body.Emit(OpCodes.Stsfld, _pointer); _initializer.Body.Emit(OpCodes.Ret); _initializer.Body.OptimizeMacros(); return(_field); }
static public void Manage(this MethodDefinition method) { var _attribute = method.CustomAttributes.SingleOrDefault(_Attribute => _Attribute.AttributeType.Resolve() == method.Module.Import(typeof(AsyncStateMachineAttribute)).Resolve()); if (_attribute == null) { return; } var _genericity = method.DeclaringType.GenericParameters.Concat(method.GenericParameters).ToArray(); var _type = _attribute.ConstructorArguments[0].Value as TypeDefinition; var _factory = _type.Field <Func <IAdvice> >("<Factory>", FieldAttributes.Public | FieldAttributes.Static); var _advice = _type.Field <IAdvice>("<Advice>", FieldAttributes.Public); _type.IsBeforeFieldInit = true; var _intializer = _type.Initializer(); _intializer.Body.Emit(OpCodes.Call, Metadata.Property(() => Advisor.Null).GetGetMethod(true)); _intializer.Body.Emit(OpCodes.Stsfld, _factory.Relative()); _intializer.Body.Emit(OpCodes.Ret); var _constructor = _type.Methods.SingleOrDefault(m => m.IsConstructor && !m.IsStatic); if (_constructor == null) { _constructor = _type.Initializer(); } _constructor.Body = new MethodBody(_constructor); _constructor.Body.Emit(OpCodes.Ldarg_0); _constructor.Body.Emit(OpCodes.Call, Metadata.Constructor(() => new object())); _constructor.Body.Emit(OpCodes.Ldarg_0); _constructor.Body.Emit(OpCodes.Ldsfld, _constructor.Module.Import(_factory.Relative())); _constructor.Body.Emit(OpCodes.Callvirt, Metadata <Func <IAdvice> > .Method(_Function => _Function.Invoke())); _constructor.Body.Emit(OpCodes.Stfld, _advice.Relative()); _constructor.Body.Emit(OpCodes.Ret); var _move = _type.Methods.Single(_Method => _Method.Name == "MoveNext"); var _importation = new Importation(method, _move); var _task = _move.Body.Variable <Task>(); var _instance = null as FieldReference; if (!method.IsStatic) { _instance = _type.Fields.SingleOrDefault(_Field => _Field.Name == "<>4__this"); if (_instance == null) { _instance = _type.Field("<>4__this", FieldAttributes.Public, _importation[method.DeclaringType]); var _variable = method.Body.Variables.Single(_Variable => _Variable.VariableType.Resolve() == _type); method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Stfld, _genericity.Length > 0 ? new FieldReference(_instance.Name, method.DeclaringType, _type.MakeGenericType(_genericity)) : _instance)); method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldarg_0)); method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldloc, _variable)); } _instance = (_instance as FieldDefinition).Relative(); } var _state = _type.Fields.Single(_Field => _Field.Name == "<>1__state").Relative(); var _builder = _type.Fields.Single(_Field => _Field.Name == "<>t__builder").Relative(); var _offset = 0; var _begin = _move.Body.Instructions[_offset]; var _resume = Instruction.Create(OpCodes.Ldarg_0); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldarg_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldfld, _state)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldc_I4_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Bge, _resume)); if (_instance != null) { _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldarg_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldfld, _advice.Relative())); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldarg_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldfld, _instance)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Instance <object>(Metadata <object> .Value)).GetGenericMethodDefinition()).MakeGenericMethod(_instance.FieldType)))); } foreach (var _parameter in method.Parameters) { var _field = null as FieldReference; _field = _type.Fields.SingleOrDefault(_Field => _Field.Name == _parameter.Name); if (_field == null) { _field = _type.Field(_parameter.Name, FieldAttributes.Public, _importation[_parameter.ParameterType]); var _variable = method.Body.Variables.Single(_Variable => _Variable.VariableType.Resolve() == _type); method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Stfld, _genericity.Length > 0 ? new FieldReference(_field.Name, _parameter.ParameterType, _type.MakeGenericType(_genericity)) : _field)); method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldarg, _parameter)); method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldloc, _variable)); } _field = (_field as FieldDefinition).Relative(); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldarg_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldfld, _advice.Relative())); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldarg_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldflda, _field)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Argument <object>(ref Metadata <object> .Value)).GetGenericMethodDefinition()).MakeGenericMethod(_field.FieldType)))); } _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldarg_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldfld, _advice.Relative())); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Callvirt, _move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Begin())))); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Br_S, _begin)); _move.Body.Instructions.Insert(_offset++, _resume); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldfld, _advice.Relative())); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Callvirt, _move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Continue())))); while (_offset < _move.Body.Instructions.Count) { var _instruction = _move.Body.Instructions[_offset]; if (_instruction.OpCode == OpCodes.Callvirt) { if (_instruction.Operand is MethodReference) { var _operand = _instruction.Operand as MethodReference; if (_operand.Name == "GetAwaiter") { var _action = _move.Body.Instructions[_offset - 1].Operand as MethodReference; _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Stloc, _task)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldarg_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldfld, _advice.Relative())); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldtoken, _action)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldtoken, _action.DeclaringType)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Call, _move.Module.Import(Metadata.Method(() => MethodInfo.GetMethodFromHandle(Metadata <RuntimeMethodHandle> .Value, Metadata <RuntimeTypeHandle> .Value))))); //TODO Virtuoze => cache it! _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldloc, _task)); if (_action.ReturnType.Resolve() == _move.Module.Import(typeof(Task)).Resolve()) { _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Callvirt, _move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Await(Metadata <MethodInfo> .Value, Metadata <Task> .Value))))); } else { _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Callvirt, _move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Await(Metadata <MethodInfo> .Value, Metadata <Task <object> > .Value)).GetGenericMethodDefinition()).MakeGenericMethod((_action.ReturnType as GenericInstanceType).GenericArguments[0]))); } _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldloc, _task)); } } } else if (_instruction.OpCode == OpCodes.Call) { if (_instruction.Operand is MethodReference) { var _operand = _instruction.Operand as MethodReference; if (_operand.Name == "get_IsCompleted") { var _continue = _move.Body.Instructions[++_offset]; _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Dup)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Brfalse_S, _continue)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldarg_0)); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Ldfld, _advice.Relative())); _move.Body.Instructions.Insert(_offset++, Instruction.Create(OpCodes.Callvirt, _move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Continue())))); } else if (_operand.Name == "SetResult") { var _return = _type.Method("<Return>", MethodAttributes.Public); if (_operand.HasParameters) { var _parameter = new ParameterDefinition("<Value>", ParameterAttributes.None, (_builder.FieldType as GenericInstanceType).GenericArguments[0]); _return.Parameters.Add(_parameter); var _exception = _return.Body.Variable <Exception>(); var _disposed = _return.Body.Variable <bool>(); var _end = Instruction.Create(OpCodes.Ret); _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _return.Body.Emit(OpCodes.Ldarga_S, _parameter); _return.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Return(ref Metadata <object> .Value)).GetGenericMethodDefinition()).MakeGenericMethod(_parameter.ParameterType))); _return.Body.Emit(OpCodes.Ldc_I4_1); _return.Body.Emit(OpCodes.Stloc_1); _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _return.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IDisposable> .Method(_IDisposable => _IDisposable.Dispose())))); _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldflda, _builder); _return.Body.Emit(OpCodes.Ldarg_1); _return.Body.Emit(OpCodes.Call, _operand); _return.Body.Emit(OpCodes.Ret); var _catch = _return.Body.Emit(OpCodes.Stloc_0); _return.Body.Emit(OpCodes.Ldloc_1); using (_return.Body.False()) { _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _return.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IDisposable> .Method(_IDisposable => _IDisposable.Dispose())))); } _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldflda, _builder); _return.Body.Emit(OpCodes.Ldloc_0); var _method = _move.Module.Import(_builder.FieldType.Resolve().Methods.Single(_Method => _Method.Name == "SetException")); _method.DeclaringType = _builder.FieldType; _return.Body.Emit(OpCodes.Call, _method); _return.Body.Emit(OpCodes.Ret); _return.Body.Emit(OpCodes.Ret); _return.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch) { TryStart = _return.Body.Instructions[0], TryEnd = _return.Body.Instructions[_catch], HandlerStart = _return.Body.Instructions[_catch], HandlerEnd = _return.Body.Instructions[_return.Body.Instructions.Count - 1], CatchType = _exception.VariableType }); _return.Body.OptimizeMacros(); _instruction.Operand = _type.HasGenericParameters ? _return.MakeHostInstanceGeneric(_type.GenericParameters.ToArray()) : _return; _move.Body.Instructions[_offset - 2].OpCode = OpCodes.Nop; } else { var _exception = _return.Body.Variable <Exception>(); var _disposed = _return.Body.Variable <bool>(); var _end = Instruction.Create(OpCodes.Ret); _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _return.Body.Emit(OpCodes.Callvirt, _move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Return()))); _return.Body.Emit(OpCodes.Ldc_I4_1); _return.Body.Emit(OpCodes.Stloc_1); _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _return.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IDisposable> .Method(_IDisposable => _IDisposable.Dispose())))); _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldflda, _builder); _return.Body.Emit(OpCodes.Call, _operand); _return.Body.Emit(OpCodes.Ret); var _catch = _return.Body.Emit(OpCodes.Stloc_0); _return.Body.Emit(OpCodes.Ldloc_1); using (_return.Body.False()) { _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _return.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IDisposable> .Method(_IDisposable => _IDisposable.Dispose())))); } _return.Body.Emit(OpCodes.Ldarg_0); _return.Body.Emit(OpCodes.Ldflda, _builder); _return.Body.Emit(OpCodes.Ldloc_0); var _method = _move.Module.Import(_builder.FieldType.Resolve().Methods.Single(_Method => _Method.Name == "SetException")); _method.DeclaringType = _builder.FieldType; _return.Body.Emit(OpCodes.Call, _method); _return.Body.Emit(OpCodes.Ret); _return.Body.Emit(OpCodes.Ret); _return.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch) { TryStart = _return.Body.Instructions[0], TryEnd = _return.Body.Instructions[_catch], HandlerStart = _return.Body.Instructions[_catch], HandlerEnd = _return.Body.Instructions[_return.Body.Instructions.Count - 1], CatchType = _exception.VariableType, }); _return.Body.OptimizeMacros(); _instruction.Operand = _type.HasGenericParameters ? _return.MakeHostInstanceGeneric(_type.GenericParameters.ToArray()) : _return; _move.Body.Instructions[_offset - 1].OpCode = OpCodes.Nop; } } else if (_operand.Name == "SetException") { var _throw = _type.Method("<Throw>", MethodAttributes.Public); var _parameter = new ParameterDefinition("<Exception>", ParameterAttributes.None, _throw.Module.Import(typeof(Exception))); _throw.Parameters.Add(_parameter); if (_builder.FieldType.IsGenericInstance) { var _value = new VariableDefinition((_builder.FieldType as GenericInstanceType).GenericArguments[0]); _throw.Body.Variables.Add(_value); var _disposed = _throw.Body.Variable <bool>(); _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _throw.Body.Emit(OpCodes.Ldarg_S, _parameter); _throw.Body.Emit(OpCodes.Ldloca_S, _value); _throw.Body.Emit(OpCodes.Callvirt, _move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Throw(ref Metadata <Exception> .Value, ref Metadata <object> .Value)).GetGenericMethodDefinition()).MakeGenericMethod(_value.VariableType)); _throw.Body.Emit(OpCodes.Ldc_I4_1); _throw.Body.Emit(OpCodes.Stloc_1); _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _throw.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IDisposable> .Method(_IDisposable => _IDisposable.Dispose())))); _throw.Body.Emit(OpCodes.Ldarg_1); using (_throw.Body.True()) { _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldflda, _builder); _throw.Body.Emit(OpCodes.Ldarg_1); _throw.Body.Emit(OpCodes.Call, _operand); _throw.Body.Emit(OpCodes.Ret); } _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldflda, _builder); _throw.Body.Emit(OpCodes.Ldloc_0); var _method = _move.Module.Import(_move.Module.Import(_builder.FieldType.Resolve().Methods.Single(_Method => _Method.Name == "SetResult" && _Method.Parameters[0].ParameterType.IsGenericParameter))); _method.DeclaringType = _builder.FieldType; _throw.Body.Emit(OpCodes.Call, _method); _throw.Body.Emit(OpCodes.Ret); var _catch = _throw.Body.Emit(OpCodes.Starg, _parameter); _throw.Body.Emit(OpCodes.Ldloc_1); using (_throw.Body.False()) { _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _throw.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IDisposable> .Method(_IDisposable => _IDisposable.Dispose())))); } _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldflda, _builder); _throw.Body.Emit(OpCodes.Ldarg_1); _throw.Body.Emit(OpCodes.Call, _operand); _throw.Body.Emit(OpCodes.Ret); _throw.Body.Emit(OpCodes.Ret); _throw.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch) { TryStart = _throw.Body.Instructions[0], TryEnd = _throw.Body.Instructions[_catch], HandlerStart = _throw.Body.Instructions[_catch], HandlerEnd = _throw.Body.Instructions[_throw.Body.Instructions.Count - 1], CatchType = _parameter.ParameterType, }); } else { var _disposed = _throw.Body.Variable <bool>(); _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _throw.Body.Emit(OpCodes.Ldarga_S, _parameter); _throw.Body.Emit(OpCodes.Callvirt, _move.Module.Import(Metadata <IAdvice> .Method(_Advice => _Advice.Throw(ref Metadata <Exception> .Value)))); _throw.Body.Emit(OpCodes.Ldc_I4_1); _throw.Body.Emit(OpCodes.Stloc_0); _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _throw.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IDisposable> .Method(_IDisposable => _IDisposable.Dispose())))); _throw.Body.Emit(OpCodes.Ldarg_1); using (_throw.Body.True()) { _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldflda, _builder); _throw.Body.Emit(OpCodes.Ldarg_1); _throw.Body.Emit(OpCodes.Call, _operand); _throw.Body.Emit(OpCodes.Ret); } _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldflda, _builder); var _method = _move.Module.Import(_builder.FieldType.Resolve().Methods.Single(_Method => _Method.Name == "SetResult" && _Method.Parameters.Count == 0)); _method.DeclaringType = _builder.FieldType; _throw.Body.Emit(OpCodes.Call, _method); _throw.Body.Emit(OpCodes.Ret); var _catch = _throw.Body.Emit(OpCodes.Starg, _parameter); _throw.Body.Emit(OpCodes.Ldloc_0); using (_throw.Body.False()) { _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldfld, _advice.Relative()); _throw.Body.Emit(OpCodes.Callvirt, _move.Module.Import(_move.Module.Import(Metadata <IDisposable> .Method(_IDisposable => _IDisposable.Dispose())))); } _throw.Body.Emit(OpCodes.Ldarg_0); _throw.Body.Emit(OpCodes.Ldflda, _builder); _throw.Body.Emit(OpCodes.Ldarg_1); _throw.Body.Emit(OpCodes.Call, _operand); _throw.Body.Emit(OpCodes.Ret); _throw.Body.Emit(OpCodes.Ret); _throw.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch) { TryStart = _throw.Body.Instructions[0], TryEnd = _throw.Body.Instructions[_catch], HandlerStart = _throw.Body.Instructions[_catch], HandlerEnd = _throw.Body.Instructions[_throw.Body.Instructions.Count - 1], CatchType = _parameter.ParameterType, }); } _throw.Body.OptimizeMacros(); _instruction.Operand = _type.HasGenericParameters ? _throw.MakeHostInstanceGeneric(_type.GenericParameters.ToArray()) : _throw; _move.Body.Instructions[_offset - 2].OpCode = OpCodes.Nop; } } } _offset++; } _move.Body.OptimizeMacros(); }
private Instruction Copy(MethodDefinition source, MethodDefinition destination, Importation importation, Instruction instruction, Dictionary <Instruction, Instruction> dictionary) { if (instruction == null) { return(null); } if (dictionary.TryGetValue(instruction, out var _instruction)) { return(_instruction); } var _operand = instruction.Operand; if (_operand == null) { _instruction = Instruction.Create(instruction.OpCode); } else if (_operand is ParameterDefinition) { _instruction = Instruction.Create(instruction.OpCode, destination.Parameter((_operand as ParameterDefinition).Name)); } else if (_operand is VariableDefinition) { _instruction = Instruction.Create(instruction.OpCode, destination.Body.Variable((_operand as VariableDefinition).Index)); } else if (_operand is FieldReference) { _instruction = Instruction.Create(instruction.OpCode, importation[_operand as FieldReference]); } else if (_operand is MethodReference) { _instruction = Instruction.Create(instruction.OpCode, importation[_operand as MethodReference]); } else if (_operand is TypeReference) { _instruction = Instruction.Create(instruction.OpCode, importation[_operand as TypeReference]); } else if (_operand is string) { _instruction = Instruction.Create(instruction.OpCode, _operand as string); } else if (_operand is sbyte) { _instruction = Instruction.Create(instruction.OpCode, (sbyte)_operand); } else if (_operand is long) { _instruction = Instruction.Create(instruction.OpCode, (long)_operand); } else if (_operand is int) { _instruction = Instruction.Create(instruction.OpCode, (int)_operand); } else if (_operand is float) { _instruction = Instruction.Create(instruction.OpCode, (float)_operand); } else if (_operand is double) { _instruction = Instruction.Create(instruction.OpCode, (double)_operand); } else if (_operand is Instruction) { _instruction = Instruction.Create(instruction.OpCode, this.Copy(source, destination, importation, _operand as Instruction, dictionary)); } else if (_operand is Instruction[]) { _instruction = Instruction.Create(instruction.OpCode, (_operand as Instruction[]).Select(_Instruction => this.Copy(source, destination, importation, _Instruction, dictionary)).ToArray()); } else if (_operand is CallSite) { _instruction = Instruction.Create(instruction.OpCode, _operand as CallSite); } else { throw new NotSupportedException(); } //var _sequence = instruction.SequencePoint; var _sequence = source.DebugInformation.GetSequencePoint(instruction); _instruction.Offset = instruction.Offset; if (_sequence != null) { destination.DebugInformation.SequencePoints.Add ( new SequencePoint(_instruction, _sequence.Document) { StartLine = _sequence.StartLine, StartColumn = _sequence.StartColumn, EndLine = _sequence.EndLine, EndColumn = _sequence.EndColumn } ); //_instruction.SequencePoint = new SequencePoint(_sequence.Document) //{ // StartLine = _sequence.StartLine, // StartColumn = _sequence.StartColumn, // EndLine = _sequence.EndLine, // EndColumn = _sequence.EndColumn //}; } dictionary.Add(instruction, _instruction); return(_instruction); }