EmitCalli() private méthode

private EmitCalli ( System opcode, System callingConvention, System returnType, System parameterTypes, System optionalParameterTypes ) : void
opcode System
callingConvention System
returnType System
parameterTypes System
optionalParameterTypes System
Résultat void
Exemple #1
0
        static public void Emit(this ILGenerator body, IntPtr function, Type type, Signature signature)
        {
            switch (IntPtr.Size)
            {
            case 4: body.Emit(OpCodes.Ldc_I4, function.ToInt32()); break;

            case 8: body.Emit(OpCodes.Ldc_I8, function.ToInt64()); break;

            default: throw new NotSupportedException();
            }
            body.EmitCalli(OpCodes.Calli, CallingConventions.Standard, type, signature, null);
        }
Exemple #2
0
		public void TestEmitCalliWithNullReturnType ()
		{
			MethodBuilder mb = tb.DefineMethod ("F",
				MethodAttributes.Public | MethodAttributes.Static, null, new Type [] { typeof (IntPtr) });
			mb.SetImplementationFlags (MethodImplAttributes.NoInlining);
			il_gen = mb.GetILGenerator ();
			il_gen.Emit (OpCodes.Ldarg_0);
			il_gen.EmitCalli (OpCodes.Calli, CallingConvention.StdCall, null, Type.EmptyTypes);
			il_gen.Emit (OpCodes.Ret);
	
			Type dynt = tb.CreateType ();
			dynt.GetMethod ("F", BindingFlags.Public | BindingFlags.Static).Invoke (
				null, new object [] { Marshal.GetFunctionPointerForDelegate (new FooFoo (Foo)) });
		}
Exemple #3
0
 /// <summary>
 /// Generate MSIL code to emit a Calli indirect call with the given
 /// calling convention, return type and array of parameter types.
 /// </summary>
 /// <param name="il">ILGenerator object</param>
 public override void Generate(ILGenerator il)
 {
     if (il == null) {
         throw new ArgumentNullException("il");
     }
     if (Deleted) {
         return;
     }
     il.EmitCalli(OpCodes.Calli, _conv, _returnType, _parameterTypes, null);
 }
 internal void EmitIL(System.Reflection.Emit.ILGenerator ilGenerator, IMethodBody methodBody) {
   //this is painful and slow, but it seems to be the only way to get debugging information into a dynamic assembly.
   this.ilGenerator = ilGenerator;
   this.methodBody = methodBody;
   this.CreateLabelsForBranchTargets();
   this.CreateLocalBuilders();
   this.EmitNamespaceScopes();
   foreach (IOperation operation in methodBody.Operations) {
     this.CallAppropriateBeginsAndEnds(operation.Offset);
     this.EmitPdbInformationFor(operation);
     Label label;
     if (labelFor.TryGetValue((uint)operation.Offset, out label)) ilGenerator.MarkLabel(label);
     switch (operation.OperationCode) {
       case OperationCode.Array_Addr:
         ilGenerator.Emit(OpCodes.Call, this.loader.mapper.GetArrayAddrMethod((IArrayTypeReference)operation.Value, this.loader.ModuleBuilder));
         continue;
       case OperationCode.Array_Get:
         ilGenerator.Emit(OpCodes.Call, this.loader.mapper.GetArrayGetMethod((IArrayTypeReference)operation.Value, this.loader.ModuleBuilder));
         continue;
       case OperationCode.Array_Set:
         ilGenerator.Emit(OpCodes.Call, this.loader.mapper.GetArraySetMethod((IArrayTypeReference)operation.Value, this.loader.ModuleBuilder));
         continue;
       case OperationCode.Array_Create:
         ilGenerator.Emit(OpCodes.Newobj, this.loader.mapper.GetArrayCreateMethod((IArrayTypeReference)operation.Value, this.loader.ModuleBuilder));
         continue;
       case OperationCode.Array_Create_WithLowerBound:
         ilGenerator.Emit(OpCodes.Newobj, this.loader.mapper.GetArrayCreateWithLowerBoundsMethod((IArrayTypeReference)operation.Value, this.loader.ModuleBuilder));
         continue;
       case OperationCode.Beq:
       case OperationCode.Bge:
       case OperationCode.Bge_Un:
       case OperationCode.Bgt:
       case OperationCode.Bgt_Un:
       case OperationCode.Ble:
       case OperationCode.Ble_Un:
       case OperationCode.Blt:
       case OperationCode.Blt_Un:
       case OperationCode.Bne_Un:
       case OperationCode.Br:
       case OperationCode.Brfalse:
       case OperationCode.Brtrue:
       case OperationCode.Leave:
       case OperationCode.Beq_S:
       case OperationCode.Bge_S:
       case OperationCode.Bge_Un_S:
       case OperationCode.Bgt_S:
       case OperationCode.Bgt_Un_S:
       case OperationCode.Ble_S:
       case OperationCode.Ble_Un_S:
       case OperationCode.Blt_S:
       case OperationCode.Blt_Un_S:
       case OperationCode.Bne_Un_S:
       case OperationCode.Br_S:
       case OperationCode.Brfalse_S:
       case OperationCode.Brtrue_S:
       case OperationCode.Leave_S:
         //^ assume operation.Value is uint;
         ilGenerator.Emit(OpCodeFor(operation.OperationCode), labelFor[(uint)operation.Value]);
         continue;
       case OperationCode.Box:
       case OperationCode.Castclass:
       case OperationCode.Constrained_:
       case OperationCode.Cpobj:
       case OperationCode.Initobj:
       case OperationCode.Isinst:
       case OperationCode.Ldelem:
       case OperationCode.Ldelema:
       case OperationCode.Ldobj:
       case OperationCode.Mkrefany:
       case OperationCode.Refanyval:
       case OperationCode.Sizeof:
       case OperationCode.Stelem:
       case OperationCode.Stobj:
       case OperationCode.Unbox:
       case OperationCode.Unbox_Any:
         //^ assume operation.Value is ITypeReference;
         ilGenerator.Emit(OpCodeFor(operation.OperationCode), this.loader.mapper.GetType((ITypeReference)operation.Value));
         continue;
       case OperationCode.Call:
       case OperationCode.Callvirt:
       case OperationCode.Jmp:
       case OperationCode.Ldftn:
       case OperationCode.Ldvirtftn:
         //TODO: if the reference has extra arguments, use EmitCall
         //^ assume operation.Value is IMethodReference;
         var methodBase = this.loader.mapper.GetMethod((IMethodReference)operation.Value);
         if (methodBase.IsConstructor)
           ilGenerator.Emit(OpCodeFor(operation.OperationCode), (ConstructorInfo)methodBase);
         else
           ilGenerator.Emit(OpCodeFor(operation.OperationCode), (MethodInfo)methodBase);
         break;
       case OperationCode.Newobj:
         //^ assume operation.Value is IMethodReference;
         ilGenerator.Emit(OpCodes.Newobj, (ConstructorInfo)this.loader.mapper.GetMethod((IMethodReference)operation.Value));
         break;
       case OperationCode.Calli:
         //^ assume operation.Value is IFunctionPointerTypeReference;
         var functionPointer = (IFunctionPointerTypeReference)operation.Value;
         var callingConvention = MemberBuilderAllocator.GetCallingConvention(functionPointer.CallingConvention);
         var returnType = loader.mapper.GetType(functionPointer.Type);
         var parameterTypes = new Type[IteratorHelper.EnumerableCount(functionPointer.Parameters)];
         int i = 0; foreach (var parameter in functionPointer.Parameters) parameterTypes[i++] = loader.mapper.GetType(parameter.Type);
         var optionalParameterTypes = new Type[IteratorHelper.EnumerableCount(functionPointer.ExtraArgumentTypes)];
         i = 0; foreach (var parameter in functionPointer.ExtraArgumentTypes) parameterTypes[i++] = loader.mapper.GetType(parameter.Type);
         ilGenerator.EmitCalli(OpCodes.Calli, callingConvention, returnType, parameterTypes, optionalParameterTypes);
         continue;
       case OperationCode.Ldarg:
       case OperationCode.Ldarga:
       case OperationCode.Starg:
         if (operation.Value == null) //it's the this arg, which does not have an IParameterDefinition
           ilGenerator.Emit(OpCodeFor(operation.OperationCode), (short)0);
         else
           ilGenerator.Emit(OpCodeFor(operation.OperationCode), GetParameterIndex((IParameterDefinition)operation.Value));
         continue;
       case OperationCode.Ldarg_S:
       case OperationCode.Ldarga_S:
       case OperationCode.Starg_S:
         if (operation.Value == null) //it's the this arg, which does not have an IParameterDefinition
           ilGenerator.Emit(OpCodeFor(operation.OperationCode), (byte)0);
         else
           ilGenerator.Emit(OpCodeFor(operation.OperationCode), (byte)GetParameterIndex((IParameterDefinition)operation.Value));
         continue;
       case OperationCode.Ldc_I4:
         //^ assume operation.Value is int;
         ilGenerator.Emit(OpCodes.Ldc_I4, (int)operation.Value);
         continue;
       case OperationCode.Ldc_I4_S:
         //^ assume operation.Value is int;
         ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte)(int)operation.Value);
         continue;
       case OperationCode.Ldc_I8:
         //^ assume operation.Value is long;
         ilGenerator.Emit(OpCodes.Ldc_I8, (long)operation.Value);
         continue;
       case OperationCode.Ldc_R4:
         //^ assume operation.Value is float;
         ilGenerator.Emit(OpCodes.Ldc_R4, (float)operation.Value);
         continue;
       case OperationCode.Ldc_R8:
         //^ assume operation.Value is double;
         ilGenerator.Emit(OpCodes.Ldc_R8, (double)operation.Value);
         continue;
       case OperationCode.Ldfld:
       case OperationCode.Ldflda:
       case OperationCode.Ldsfld:
       case OperationCode.Ldsflda:
       case OperationCode.Stfld:
       case OperationCode.Stsfld:
         //^ assume operation.Value is IFieldReference;
         ilGenerator.Emit(OpCodeFor(operation.OperationCode), this.loader.mapper.GetField((IFieldReference)operation.Value));
         continue;
       case OperationCode.Ldloc:
       case OperationCode.Ldloca:
       case OperationCode.Stloc:
       case OperationCode.Ldloc_S:
       case OperationCode.Ldloca_S:
       case OperationCode.Stloc_S:
         //^ assume operation.Value is ILocalDefinition;
         ilGenerator.Emit(OpCodeFor(operation.OperationCode), localFor[(ILocalDefinition)operation.Value]);
         continue;
       case OperationCode.Ldstr:
         //^ assume operation.Value is string;
         ilGenerator.Emit(OpCodes.Ldstr, (string)operation.Value);
         continue;
       case OperationCode.Ldtoken:
         IFieldReference/*?*/ fieldRef = operation.Value as IFieldReference;
         if (fieldRef != null) goto case OperationCode.Ldfld;
         IMethodReference/*?*/ methodRef = operation.Value as IMethodReference;
         if (methodRef != null) goto case OperationCode.Call;
         ilGenerator.Emit(OpCodes.Ldtoken, this.loader.mapper.GetType((ITypeReference)operation.Value));
         continue;
       case OperationCode.Newarr:
         //^ assume operation.Value is IArrayTypeReference;
         ilGenerator.Emit(OpCodes.Newarr, this.loader.mapper.GetType(((IArrayTypeReference)operation.Value).ElementType));
         continue;
       //case OperationCode.No_:
       //  //^ assume operation.Value is OperationCheckFlags;
       //  writer.WriteByte((byte)(OperationCheckFlags)operation.Value); break;
       case OperationCode.Switch:
         //^ assume operation.Value is uint[];
         uint[] targets = (uint[])operation.Value;
         Label[] labels = new Label[targets.Length];
         for (int j = 0; j < targets.Length; j++) labels[j] = labelFor[targets[j]];
         ilGenerator.Emit(OpCodes.Switch, labels);
         continue;
       case OperationCode.Unaligned_:
         //^ assume operation.Value is byte;
         ilGenerator.Emit(OpCodes.Unaligned, (byte)operation.Value);
         continue;
       default:
         ilGenerator.Emit(OpCodeFor(operation.OperationCode));
         break;
     }
   }
   this.CallAppropriateBeginsAndEnds((uint)ilGenerator.ILOffset);
   this.ilGenerator = null;
   this.methodBody = null;
   this.labelFor = null;
   this.localFor = null;
 }