本文整理汇总了C#中ILGen.Emit方法的典型用法代码示例。如果您正苦于以下问题:C# ILGen.Emit方法的具体用法?C# ILGen.Emit怎么用?C# ILGen.Emit使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ILGen
的用法示例。
在下文中一共展示了ILGen.Emit方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Compile
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
{
il.Emit(OpCodes.Ldarg_1);
il.EmitInt(locals.DefineConstant(args[0]));
il.Emit(OpCodes.Ldelem_Ref);
st.Push(typeof(System.Object));
}
示例2: Create
internal static Type Create(GenContext context, Type baseClass)
{
//ModuleBuilder mb = context.ModuleBldr;
string name = baseClass.Name + "_impl";
//TypeBuilder baseTB = context.ModuleBldr.DefineType(name, TypeAttributes.Class | TypeAttributes.Public, baseClass);
TypeBuilder baseTB = context.AssemblyGen.DefinePublicType(name, baseClass, true);
ObjExpr.MarkAsSerializable(baseTB);
baseTB.DefineDefaultConstructor(MethodAttributes.Public);
FieldBuilder metaField = baseTB.DefineField("_meta", typeof(IPersistentMap), FieldAttributes.Public);
MethodBuilder metaMB = baseTB.DefineMethod("meta", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(IPersistentMap), Type.EmptyTypes);
ILGen gen = new ILGen(metaMB.GetILGenerator());
gen.EmitLoadArg(0);
gen.EmitFieldGet(metaField);
gen.Emit(OpCodes.Ret);
MethodBuilder withMB = baseTB.DefineMethod("withMeta", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(IObj), new Type[] { typeof(IPersistentMap)});
gen = new ILGen(withMB.GetILGenerator());
gen.EmitLoadArg(0);
gen.EmitCall(Compiler.Method_Object_MemberwiseClone);
gen.Emit(OpCodes.Castclass, baseTB);
gen.Emit(OpCodes.Dup);
gen.EmitLoadArg(1);
gen.EmitFieldSet(metaField);
gen.Emit(OpCodes.Ret);
for (int i = 0; i < 20; i++ )
DefineDelegateFieldAndOverride(baseTB, i);
return baseTB.CreateType();
}
示例3: FixReturn
internal void FixReturn(ILGen cg)
{
cg.EmitLoadArg(_argIndex);
cg.Emit(OpCodes.Ldloc, _refSlot);
cg.Emit(OpCodes.Ldfld, _refSlot.LocalType.GetDeclaredField("Value"));
cg.EmitStoreValueIndirect(_argType.GetElementType());
}
示例4: EmitArgument
internal static ReturnFixer EmitArgument(ILGen cg, int argIndex, Type argType) {
cg.EmitLoadArg(argIndex);
if (!argType.IsByRef) {
cg.EmitBoxing(argType);
return null;
}
Type elementType = argType.GetElementType();
cg.EmitLoadValueIndirect(elementType);
Type concreteType = typeof(StrongBox<>).MakeGenericType(elementType);
cg.EmitNew(concreteType, new Type[] { elementType });
LocalBuilder refSlot = cg.DeclareLocal(concreteType);
cg.Emit(OpCodes.Dup);
cg.Emit(OpCodes.Stloc, refSlot);
return new ReturnFixer(refSlot, argIndex, argType);
}
示例5: EmitClrCallStub
/// <summary>
/// Generates stub to receive the CLR call and then call the dynamic language code.
/// </summary>
private object[] EmitClrCallStub(ILGen cg) {
List<ReturnFixer> fixers = new List<ReturnFixer>(0);
// Create strongly typed return type from the site.
// This will, among other things, generate tighter code.
Type[] siteTypes = MakeSiteSignature();
CallSite callSite = CallSite.Create(DynamicSiteHelpers.MakeCallSiteDelegate(siteTypes), InvokeBinder);
Type siteType = callSite.GetType();
Type convertSiteType = null;
CallSite convertSite = null;
if (_returnType != typeof(void)) {
convertSite = CallSite.Create(DynamicSiteHelpers.MakeCallSiteDelegate(typeof(object), _returnType), ConvertBinder);
convertSiteType = convertSite.GetType();
}
// build up constants array
object[] constants = new object[] { TargetPlaceHolder, CallSitePlaceHolder, ConvertSitePlaceHolder };
const int TargetIndex = 0, CallSiteIndex = 1, ConvertSiteIndex = 2;
LocalBuilder convertSiteLocal = null;
FieldInfo convertTarget = null;
if (_returnType != typeof(void)) {
// load up the conversesion logic on the stack
convertSiteLocal = cg.DeclareLocal(convertSiteType);
EmitConstantGet(cg, ConvertSiteIndex, convertSiteType);
cg.Emit(OpCodes.Dup);
cg.Emit(OpCodes.Stloc, convertSiteLocal);
convertTarget = convertSiteType.GetField("Target");
cg.EmitFieldGet(convertTarget);
cg.Emit(OpCodes.Ldloc, convertSiteLocal);
}
// load up the invoke logic on the stack
LocalBuilder site = cg.DeclareLocal(siteType);
EmitConstantGet(cg, CallSiteIndex, siteType);
cg.Emit(OpCodes.Dup);
cg.Emit(OpCodes.Stloc, site);
FieldInfo target = siteType.GetField("Target");
cg.EmitFieldGet(target);
cg.Emit(OpCodes.Ldloc, site);
EmitConstantGet(cg, TargetIndex, typeof(object));
for (int i = 0; i < _parameters.Length; i++) {
if (_parameters[i].ParameterType.IsByRef) {
ReturnFixer rf = ReturnFixer.EmitArgument(cg, i + 1, _parameters[i].ParameterType);
if (rf != null) fixers.Add(rf);
} else {
cg.EmitLoadArg(i + 1);
}
}
// emit the invoke for the call
cg.EmitCall(target.FieldType, "Invoke");
// emit the invoke for the convert
if (_returnType == typeof(void)) {
cg.Emit(OpCodes.Pop);
} else {
cg.EmitCall(convertTarget.FieldType, "Invoke");
}
// fixup any references
foreach (ReturnFixer rf in fixers) {
rf.FixReturn(cg);
}
cg.Emit(OpCodes.Ret);
return constants;
}
示例6: EmitUnsupported
private static void EmitUnsupported(ILGen gen, string name)
{
gen.EmitString(name); // gen.Emit(OpCodes.Ldstr, name);
gen.EmitNew(CtorInfo_NotImplementedException_1); // gen.Emit(OpCodes.Newobj, CtorInfo_NotImplementedException_1);
gen.Emit(OpCodes.Throw);
}
示例7: EmitMain
static void EmitMain(GenContext context, TypeBuilder proxyTB, string mainName, FieldBuilder mainFB)
{
MethodBuilder cb = proxyTB.DefineMethod("Main",MethodAttributes.Public| MethodAttributes.Static,CallingConventions.Standard,typeof(void),new Type[] { typeof(String[]) });
ILGen gen = new ILGen(cb.GetILGenerator()); ;
Label noMainLabel = gen.DefineLabel();
Label endLabel = gen.DefineLabel();
EmitGetVar(gen, mainFB);
gen.Emit(OpCodes.Dup);
gen.Emit(OpCodes.Brfalse_S, noMainLabel);
gen.Emit(OpCodes.Castclass, typeof(IFn));
gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0);
gen.EmitCall(Method_RT_seq); // gen.Emit(OpCodes.Call, Method_RT_seq);
gen.EmitCall(Method_IFn_applyTo_Object_ISeq); // gen.Emit(OpCodes.Call, Method_IFn_applyTo_Object_ISeq);
gen.Emit(OpCodes.Pop);
gen.Emit(OpCodes.Br_S, endLabel);
// no main found
gen.MarkLabel(noMainLabel);
EmitUnsupported(gen, mainName);
gen.MarkLabel(endLabel);
gen.Emit(OpCodes.Ret);
//context.AssyBldr.SetEntryPoint(cb);
context.AssemblyBuilder.SetEntryPoint(cb);
}
示例8: EmitGetVar
static void EmitGetVar(ILGen gen, FieldBuilder fb)
{
Label falseLabel = gen.DefineLabel();
Label endLabel = gen.DefineLabel();
gen.EmitFieldGet(fb); // gen.Emit(OpCodes.Ldsfld,fb);
gen.Emit(OpCodes.Dup);
gen.EmitCall(Method_Var_isBound); // gen.Emit(OpCodes.Call, Method_Var_IsBound);
gen.Emit(OpCodes.Brfalse_S,falseLabel);
gen.Emit(OpCodes.Call,Method_Var_get);
gen.Emit(OpCodes.Br_S,endLabel);
gen.MarkLabel(falseLabel);
gen.Emit(OpCodes.Pop);
gen.EmitNull(); // gen.Emit(OpCodes.Ldnull);
gen.MarkLabel(endLabel);
}
示例9: EmitForwardingMethod
private static void EmitForwardingMethod(TypeBuilder proxyTB,
bool isStatic,
FieldBuilder regularFB,
FieldBuilder overloadFB,
MethodSignature sig,
ElseGenDelegate elseGen)
{
MethodAttributes attributes;
CallingConventions conventions;
if (isStatic)
{
attributes = MethodAttributes.Public | MethodAttributes.Static;
conventions = CallingConventions.Standard;
}
else
{
attributes = MethodAttributes.Public | MethodAttributes.Virtual;
conventions = CallingConventions.HasThis;
}
MethodBuilder mb = proxyTB.DefineMethod(sig.Name, attributes, conventions, sig.ReturnType, sig.ParamTypes);
ILGen gen = new ILGen(mb.GetILGenerator());
Label foundLabel = gen.DefineLabel();
Label elseLabel = gen.DefineLabel();
Label endLabel = gen.DefineLabel();
if (sig.ParamTypes.Length > 18)
elseGen(gen);
else
{
if (overloadFB != null)
{
EmitGetVar(gen, overloadFB);
gen.Emit(OpCodes.Dup);
gen.Emit(OpCodes.Brtrue_S, foundLabel);
gen.Emit(OpCodes.Pop);
}
EmitGetVar(gen, regularFB);
gen.Emit(OpCodes.Dup);
gen.Emit(OpCodes.Brfalse_S, elseLabel);
if (overloadFB != null)
gen.MarkLabel(foundLabel);
gen.Emit(OpCodes.Castclass, typeof(IFn));
if (!isStatic)
gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0);
for (int i = 0; i < sig.ParamTypes.Length; i++)
{
gen.EmitLoadArg(isStatic ? i : i + 1); // gen.Emit(OpCodes.Ldarg, i + 1);
if (sig.ParamTypes[i].IsValueType)
gen.Emit(OpCodes.Box, sig.ParamTypes[i]);
}
gen.EmitCall(Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]);
//gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]);
if (sig.ReturnType == typeof(void))
gen.Emit(OpCodes.Pop);
else if (sig.ReturnType.IsValueType)
gen.Emit(OpCodes.Unbox_Any,sig.ReturnType);
gen.Emit(OpCodes.Br_S, endLabel);
gen.MarkLabel(elseLabel);
gen.Emit(OpCodes.Pop);
elseGen(gen);
gen.MarkLabel(endLabel);
gen.Emit(OpCodes.Ret);
}
}
示例10: EmitExposers
private static void EmitExposers(TypeBuilder proxyTB, Type superClass, IPersistentMap exposesFields)
{
for ( ISeq s = RT.seq(exposesFields); s != null; s = s.next() )
{
IMapEntry me = (IMapEntry)s.first();
Symbol protectedFieldSym = (Symbol)me.key();
IPersistentMap accessMap = (IPersistentMap)me.val();
string fieldName = protectedFieldSym.Name;
Symbol getterSym = (Symbol)accessMap.valAt(_getKw, null);
Symbol setterSym = (Symbol)accessMap.valAt(_setKW, null);
FieldInfo fld = null;
if ( getterSym != null || setterSym != null )
fld = superClass.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance);
if (getterSym != null)
{
MethodAttributes attribs = MethodAttributes.Public;
if (fld.IsStatic)
attribs |= MethodAttributes.Static;
MethodBuilder mb = proxyTB.DefineMethod(getterSym.Name, attribs, fld.FieldType, Type.EmptyTypes);
ILGen gen = new ILGen(mb.GetILGenerator());
//if (fld.IsStatic)
// gen.Emit(OpCodes.Ldsfld, fld);
//else
//{
// gen.Emit(OpCodes.Ldarg_0);
// gen.Emit(OpCodes.Ldfld, fld);
//}
if (!fld.IsStatic)
gen.EmitLoadArg(0);
gen.EmitFieldGet(fld);
gen.Emit(OpCodes.Ret);
}
if (setterSym != null)
{
MethodAttributes attribs = MethodAttributes.Public;
if (fld.IsStatic)
attribs |= MethodAttributes.Static;
MethodBuilder mb = proxyTB.DefineMethod(setterSym.Name, attribs, typeof(void), new Type[] { fld.FieldType });
ILGen gen = new ILGen(mb.GetILGenerator());
if (fld.IsStatic)
{
gen.Emit(OpCodes.Ldarg_0);
//gen.Emit(OpCodes.Stsfld, fld);
}
else
{
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
//gen.Emit(OpCodes.Stfld, fld);
}
gen.EmitFieldSet(fld);
gen.Emit(OpCodes.Ret);
}
}
}
示例11: DefineStaticCtor
/// <summary>
/// Set up Var fields and (maybe) load assembly for the namespace.
/// </summary>
/// <param name="proxyTB"></param>
/// <param name="varMap"></param>
/// <param name="loadImplNameSpace"></param>
/// <param name="implNamespace"></param>
private static void DefineStaticCtor(TypeBuilder proxyTB, string prefix, Dictionary<string, FieldBuilder> varMap, bool loadImplNameSpace, string implNamespace, string implCname)
{
ConstructorBuilder cb = proxyTB.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard,Type.EmptyTypes);
ILGen gen = new ILGen(cb.GetILGenerator());
foreach (KeyValuePair<string, FieldBuilder> pair in varMap)
{
gen.EmitString(implNamespace); // gen.Emit(OpCodes.Ldstr, implNamespace);
gen.EmitString(prefix + pair.Key); // gen.Emit(OpCodes.Ldstr, prefix + pair.Key);
gen.EmitCall(Method_Var_internPrivate); // gen.Emit(OpCodes.Call, Method_Var_internPrivate);
gen.Emit(OpCodes.Stsfld, pair.Value);
}
if (loadImplNameSpace)
{
gen.EmitString("clojure.core"); // gen.Emit(OpCodes.Ldstr, "clojure.core");
gen.EmitString("load"); // gen.Emit(OpCodes.Ldstr, "load");
gen.EmitCall(Method_RT_var2); // gen.Emit(OpCodes.Call, Method_RT_var2);
gen.EmitString("/" + implCname); // gen.Emit(OpCodes.Ldstr, "/" + implCname);
gen.EmitCall(Compiler.Methods_IFn_invoke[1]); // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[1]);
gen.Emit(OpCodes.Pop);
}
gen.Emit(OpCodes.Ret);
}
示例12: DefineCtors
static void DefineCtors(TypeBuilder proxyTB,
Type superClass,
string initName,
string postInitName,
ISeq ctorsTypes,
FieldBuilder initFB,
FieldBuilder postInitFB,
FieldBuilder stateFB,
string factoryName)
{
for (ISeq s = ctorsTypes; s != null; s = s.next())
{
IMapEntry me = (IMapEntry)s.first();
ISeq thisParamTypesV = (ISeq)me.key();
ISeq baseParamTypesV = (ISeq)me.val();
Type[] thisParamTypes = CreateTypeArray(thisParamTypesV);
Type[] baseParamTypes = CreateTypeArray(baseParamTypesV);
BindingFlags flags = BindingFlags.CreateInstance| BindingFlags.NonPublic| BindingFlags.Public| BindingFlags.Instance;
ConstructorInfo superCtor = superClass.GetConstructor(flags,null,baseParamTypes,null);
if (superCtor == null || superCtor.IsPrivate)
throw new InvalidOperationException("Base class constructor missing or private");
ConstructorBuilder cb = proxyTB.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, thisParamTypes);
ILGen gen = new ILGen(cb.GetILGenerator());
Label noInitLabel = gen.DefineLabel();
Label noPostInitLabel = gen.DefineLabel();
Label endPostInitLabel = gen.DefineLabel();
Label endLabel = gen.DefineLabel();
LocalBuilder locSuperArgs = gen.DeclareLocal(typeof(object));
LocalBuilder locInitVal = gen.DeclareLocal(typeof(object));
if (initFB != null)
{
// init supplied
EmitGetVar(gen, initFB);
gen.Emit(OpCodes.Dup);
gen.Emit(OpCodes.Brfalse_S, noInitLabel);
gen.Emit(OpCodes.Castclass, typeof(IFn));
// box init args
for (int i = 0; i < thisParamTypes.Length; i++)
{
gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1);
if (thisParamTypes[i].IsValueType)
gen.Emit(OpCodes.Box,thisParamTypes[i]);
}
gen.EmitCall(Compiler.Methods_IFn_invoke[thisParamTypes.Length]); // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[thisParamTypes.Length]);
// Expecting: [[super-ctor-args...] state]
// store the init return in a local
gen.Emit(OpCodes.Dup);
gen.Emit(OpCodes.Stloc,locInitVal);
// store the first element in a local
gen.EmitInt(0); // gen.Emit(OpCodes.Ldc_I4_0);
gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth);
gen.Emit(OpCodes.Stloc, locSuperArgs);
// Stack this + super-ctor-args + call base-class ctor.
gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0);
for (int i = 0; i < baseParamTypes.Length; i++)
{
gen.Emit(OpCodes.Ldloc, locSuperArgs);
gen.EmitInt(i); // gen.Emit(OpCodes.Ldc_I4, i);
gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth);
if (baseParamTypes[i].IsValueType)
gen.Emit(OpCodes.Unbox_Any, baseParamTypes[i]);
else
gen.Emit(OpCodes.Castclass, baseParamTypes[i]);
}
gen.Emit(OpCodes.Call, superCtor);
if (stateFB != null)
{
gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldloc, locInitVal);
gen.EmitInt(1); // gen.Emit(OpCodes.Ldc_I4_1);
gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth);
gen.Emit(OpCodes.Castclass, typeof(object));
gen.EmitFieldSet(stateFB); // gen.Emit(OpCodes.Stfld, stateFB);
}
gen.Emit(OpCodes.Br_S, endLabel);
// No init found
gen.MarkLabel(noInitLabel);
gen.Emit(OpCodes.Pop);
EmitUnsupported(gen, initName);
gen.MarkLabel(endLabel);
}
//.........这里部分代码省略.........
示例13: CreateSuperCall
private static void CreateSuperCall(TypeBuilder proxyTB, Symbol p, MethodInfo mi)
{
Type[] paramTypes = CreateTypeArray(mi.GetParameters());
MethodBuilder mb = proxyTB.DefineMethod(p.Name, MethodAttributes.Public, CallingConventions.HasThis, mi.ReturnType, paramTypes);
ILGen gen = new ILGen(mb.GetILGenerator());
gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0);
for (int i = 0; i < paramTypes.Length; i++)
gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1);
gen.Emit(OpCodes.Call, mi); // not gen.EmitCall(mi); -- we need call versus callvirt
gen.Emit(OpCodes.Ret);
}
示例14: SaveToAssembly
/// <summary>
/// This takes an assembly name including extension and saves the provided ScriptCode objects into the assembly.
///
/// The provided script codes can constitute code from multiple languages. The assemblyName can be either a fully qualified
/// or a relative path. The DLR will simply save the assembly to the desired location. The assembly is created by the DLR and
/// if a file already exists than an exception is raised.
///
/// The DLR determines the internal format of the ScriptCode and the DLR can feel free to rev this as appropriate.
/// </summary>
public static void SaveToAssembly(string assemblyName, params SavableScriptCode[] codes) {
ContractUtils.RequiresNotNull(assemblyName, "assemblyName");
ContractUtils.RequiresNotNullItems(codes, "codes");
// break the assemblyName into it's dir/name/extension
string dir = Path.GetDirectoryName(assemblyName);
if (String.IsNullOrEmpty(dir)) {
dir = Environment.CurrentDirectory;
}
string name = Path.GetFileNameWithoutExtension(assemblyName);
string ext = Path.GetExtension(assemblyName);
// build the assembly & type gen that all the script codes will live in...
AssemblyGen ag = new AssemblyGen(new AssemblyName(name), dir, ext, /*emitSymbols*/false);
TypeBuilder tb = ag.DefinePublicType("DLRCachedCode", typeof(object), true);
TypeGen tg = new TypeGen(ag, tb);
var symbolDict = new Dictionary<SymbolId, FieldBuilder>();
// then compile all of the code
Dictionary<Type, List<CodeInfo>> langCtxBuilders = new Dictionary<Type, List<CodeInfo>>();
foreach (SavableScriptCode sc in codes) {
List<CodeInfo> builders;
if (!langCtxBuilders.TryGetValue(sc.LanguageContext.GetType(), out builders)) {
langCtxBuilders[sc.LanguageContext.GetType()] = builders = new List<CodeInfo>();
}
KeyValuePair<MethodBuilder, Type> compInfo = sc.CompileForSave(tg, symbolDict);
builders.Add(new CodeInfo(compInfo.Key, sc, compInfo.Value));
}
MethodBuilder mb = tb.DefineMethod(
"GetScriptCodeInfo",
MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static,
typeof(MutableTuple<Type[], Delegate[][], string[][], string[][]>),
Type.EmptyTypes);
ILGen ilgen = new ILGen(mb.GetILGenerator());
var langsWithBuilders = langCtxBuilders.ToArray();
// lang ctx array
ilgen.EmitArray(typeof(Type), langsWithBuilders.Length, (index) => {
ilgen.Emit(OpCodes.Ldtoken, langsWithBuilders[index].Key);
ilgen.EmitCall(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));
});
// builders array of array
ilgen.EmitArray(typeof(Delegate[]), langsWithBuilders.Length, (index) => {
List<CodeInfo> builders = langsWithBuilders[index].Value;
ilgen.EmitArray(typeof(Delegate), builders.Count, (innerIndex) => {
ilgen.EmitNull();
ilgen.Emit(OpCodes.Ldftn, builders[innerIndex].Builder);
ilgen.EmitNew(
builders[innerIndex].DelegateType,
new[] { typeof(object), typeof(IntPtr) }
);
});
});
// paths array of array
ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => {
List<CodeInfo> builders = langsWithBuilders[index].Value;
ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => {
ilgen.EmitString(builders[innerIndex].Code.SourceUnit.Path);
});
});
// 4th element in tuple - custom per-language data
ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => {
List<CodeInfo> builders = langsWithBuilders[index].Value;
ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => {
ICustomScriptCodeData data = builders[innerIndex].Code as ICustomScriptCodeData;
if (data != null) {
ilgen.EmitString(data.GetCustomScriptCodeData());
} else {
ilgen.Emit(OpCodes.Ldnull);
}
});
});
ilgen.EmitNew(
typeof(MutableTuple<Type[], Delegate[][], string[][], string[][]>),
new[] { typeof(Type[]), typeof(Delegate[][]), typeof(string[][]), typeof(string[][]) }
);
ilgen.Emit(OpCodes.Ret);
//.........这里部分代码省略.........
示例15: BuildConstructors
private void BuildConstructors(IList<ConstructorBuilderInfo>/*!*/ ctors) {
foreach (var ctor in ctors) {
// ctor(... RubyClass! class ..., <visible params>) : base(<hidden params>, <visible params>) { _class = class; }
// ctor(... RubyClass! class ..., <visible params>) : base(... RubyOps.GetContextFromClass(class) ..., <visible params>) { _class = class; }
// ctor(RubyClass! class) : base(RubyOps.GetDefaultExceptionMessage(class)) { _class = class; }
ConstructorBuilder cb = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctor.ParameterTypes);
ILGen il = new ILGen(cb.GetILGenerator());
int paramIndex = 0;
int argIndex = 0;
// We need to initialize before calling base ctor since the ctor can call virtual methods.
// _immediateClass = immediateClass:
if (!IsDerivedRubyType) {
il.EmitLoadArg(0);
il.EmitLoadArg(1 + ctor.ClassParamIndex);
il.EmitFieldSet(ImmediateClassField);
}
// base ctor call:
il.EmitLoadArg(0);
ConstructorInfo msgCtor;
if (ctor.ParameterTypes.Length == 1 && ctor.Adjustment == SignatureAdjustment.InsertClass &&
_tb.IsSubclassOf(typeof(Exception)) && IsAvailable(msgCtor = _tb.BaseType.GetConstructor(_exceptionMessageSignature))) {
// a parameterless exception constructor should use Ruby default message:
il.EmitLoadArg(1);
il.EmitCall(Methods.GetDefaultExceptionMessage);
il.Emit(OpCodes.Call, msgCtor);
} else {
if (ctor.Adjustment == SignatureAdjustment.InsertClass) {
paramIndex++;
}
while (paramIndex < ctor.ParameterTypes.Length) {
if (ctor.Adjustment == SignatureAdjustment.ConvertClassToContext && argIndex == ctor.ContextArgIndex) {
il.EmitLoadArg(1 + ctor.ClassParamIndex);
il.EmitCall(Methods.GetContextFromModule);
} else {
ClsTypeEmitter.DefineParameterCopy(cb, paramIndex, ctor.BaseParameters[argIndex]);
il.EmitLoadArg(1 + paramIndex);
}
argIndex++;
paramIndex++;
}
il.Emit(OpCodes.Call, ctor.BaseCtor);
}
il.Emit(OpCodes.Ret);
}
}