/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Microsoft Public License. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Microsoft Public License, please send an email to
* dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Microsoft Public License.
*
* You must not remove this notice, or any other, from this software.
*
*
* ***************************************************************************/
using System;
using System.Reflection;
using System.Reflection.Emit;
using Microsoft.Scripting.Utils;
namespace Microsoft.Scripting.Generation{
public abstract class DynamicILGen : ILGen {
internal DynamicILGen(ILGenerator il)
: base(il) {
}
public T CreateDelegate<T>() {
MethodInfo mi;
return CreateDelegate<T>(out mi);
}
public abstract T CreateDelegate<T>(out MethodInfo mi);
public abstract MethodInfo Finish();
}
class DynamicILGenMethod : DynamicILGen {
private readonly DynamicMethod _dm;
internal DynamicILGenMethod(DynamicMethod dm, ILGenerator il)
: base(il) {
_dm = dm;
}
public override T CreateDelegate<T>(out MethodInfo mi) {
ContractUtils.Requires(typeof(T).IsSubclassOf(typeof(Delegate)), "T");
mi = _dm;
return (T)(object)_dm.CreateDelegate(typeof(T), null);
}
public override MethodInfo Finish() {
return _dm;
}
}
class DynamicILGenType : DynamicILGen {
private readonly TypeBuilder _tb;
private readonly MethodBuilder _mb;
internal DynamicILGenType(TypeBuilder tb, MethodBuilder mb, ILGenerator il)
: base(il) {
_tb = tb;
_mb = mb;
}
public override T CreateDelegate<T>(out MethodInfo mi) {
ContractUtils.Requires(typeof(T).IsSubclassOf(typeof(Delegate)), "T");
mi = CreateMethod();
return (T)(object)Delegate.CreateDelegate(typeof(T), mi);
}
private MethodInfo CreateMethod() {
Type t = _tb.CreateType();
return t.GetMethod(_mb.Name);
}
public override MethodInfo Finish() {
return CreateMethod();
}
}
}
|