Ejemplo n.º 1
0
        public ImplementMembersForm(NemerleSource source, TypeBuilder ty, IEnumerable<IGrouping<FixedType.Class, IMember>> unimplementedMembers)
        {
            _source               = source;
            _ty                   = ty;
            _unimplementedMembers = unimplementedMembers;

            InitializeComponent();

            #region Init events hendlers

            _grid.CellPainting += CellPainting;
            _grid.CellValueChanged += CellValueChanged;
            _grid.CellValidating += CellValidating;
            _grid.CurrentCellDirtyStateChanged += CurrentCellDirtyStateChanged;

            #endregion
            #region Init ImageList

            imageList1.Images.AddStrip(Resources.SO_TreeViewIcons);
            _imageSize = imageList1.ImageSize.Width;
            Debug.Assert(imageList1.ImageSize.Width == imageList1.ImageSize.Height);

            #endregion

            if (_unimplementedMembers == null)
                return;

            FillTable(MakeTypeMembersMap());
        }
Ejemplo n.º 2
0
        public void SetSource(string source, int offset)
        {
            //System.Diagnostics.Debug.WriteLine(string.Format("Scan line {0}", _currentLine));

            ScanLexer lexer = GetLexer();

            if (lexer != null)
            {
                if (_currentLine >= 0 && source.Length > 0)
                {
                    if (_source != null && _source.ProjectInfo != null)
                    {
                        var ret = _source.ProjectInfo.Engine.GetActiveEnv(_source.FileIndex, _currentLine + 1);

                        if (ret.Field0 != null)
                        {
                            _env = ret.Field0;
                            _type = ret.Field1;
                        }
                    }
                }

                lexer.SetLine(_currentLine + 1, source, offset, _env, _type);
            }
        }
Ejemplo n.º 3
0
		internal static ConstructorInfo AddAutomagicSerialization(DynamicTypeWrapper wrapper, TypeBuilder typeBuilder)
		{
			ConstructorInfo serializationCtor = null;
			if (wrapper.GetClassLoader().NoAutomagicSerialization)
			{
				// do nothing
			}
			else if ((wrapper.Modifiers & IKVM.Attributes.Modifiers.Enum) != 0)
			{
				MarkSerializable(typeBuilder);
			}
			else if (wrapper.IsSubTypeOf(serializable) && IsSafeForAutomagicSerialization(wrapper))
			{
				if (wrapper.IsSubTypeOf(externalizable))
				{
					MethodWrapper ctor = wrapper.GetMethodWrapper("<init>", "()V", false);
					if (ctor != null && ctor.IsPublic)
					{
						MarkSerializable(typeBuilder);
						ctor.Link();
						serializationCtor = AddConstructor(typeBuilder, ctor, null, true);
						if (!wrapper.BaseTypeWrapper.IsSubTypeOf(serializable))
						{
							AddGetObjectData(typeBuilder);
						}
						if (wrapper.BaseTypeWrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", true) != null)
						{
							RemoveReadResolve(typeBuilder);
						}
					}
				}
				else if (wrapper.BaseTypeWrapper.IsSubTypeOf(serializable))
				{
					ConstructorInfo baseCtor = wrapper.GetBaseSerializationConstructor();
					if (baseCtor != null && (baseCtor.IsFamily || baseCtor.IsFamilyOrAssembly))
					{
						MarkSerializable(typeBuilder);
						serializationCtor = AddConstructor(typeBuilder, null, baseCtor, false);
						AddReadResolve(wrapper, typeBuilder);
					}
				}
				else
				{
					MethodWrapper baseCtor = wrapper.BaseTypeWrapper.GetMethodWrapper("<init>", "()V", false);
					if (baseCtor != null && baseCtor.IsAccessibleFrom(wrapper.BaseTypeWrapper, wrapper, wrapper))
					{
						MarkSerializable(typeBuilder);
						AddGetObjectData(typeBuilder);
#if STATIC_COMPILER
						// because the base type can be a __WorkaroundBaseClass__, we may need to replace the constructor
						baseCtor = ((AotTypeWrapper)wrapper).ReplaceMethodWrapper(baseCtor);
#endif
						baseCtor.Link();
						serializationCtor = AddConstructor(typeBuilder, baseCtor, null, true);
						AddReadResolve(wrapper, typeBuilder);
					}
				}
			}
			return serializationCtor;
		}
Ejemplo n.º 4
0
 // Helper method for nullable transform. Ideally, we would do the nullable transform upfront before
 // the types is build. Unfortunately, there does not seem to be easy way to test for Nullable<> type definition
 // without introducing type builder recursion
 private static RuntimeTypeHandle GetRuntimeTypeHandleWithNullableTransform(TypeBuilder builder, TypeDesc type)
 {
     RuntimeTypeHandle th = builder.GetRuntimeTypeHandle(type);
     if (RuntimeAugments.IsNullable(th))
         th = builder.GetRuntimeTypeHandle(((DefType)type).Instantiation[0]);
     return th;
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Default ctor
 /// </summary>
 protected NestedTypeBuilder(TypeBuilder parent, string parentFullName, ClassFile cf, InnerClass inner)
 {
     this.parent = parent;
     this.parentFullName = parentFullName;
     this.cf = cf;
     this.inner = inner;
 }
Ejemplo n.º 6
0
            private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
            {
                FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

                PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
                MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
                ILGenerator getIl = getPropMthdBldr.GetILGenerator();

                getIl.Emit(OpCodes.Ldarg_0);
                getIl.Emit(OpCodes.Ldfld, fieldBuilder);
                getIl.Emit(OpCodes.Ret);

                MethodBuilder setPropMthdBldr =
                tb.DefineMethod("set_" + propertyName,
                  MethodAttributes.Public |
                  MethodAttributes.SpecialName |
                  MethodAttributes.HideBySig,
                  null, new[] { propertyType });

                ILGenerator setIl = setPropMthdBldr.GetILGenerator();
                Label modifyProperty = setIl.DefineLabel();
                Label exitSet = setIl.DefineLabel();

                setIl.MarkLabel(modifyProperty);
                setIl.Emit(OpCodes.Ldarg_0);
                setIl.Emit(OpCodes.Ldarg_1);
                setIl.Emit(OpCodes.Stfld, fieldBuilder);

                setIl.Emit(OpCodes.Nop);
                setIl.MarkLabel(exitSet);
                setIl.Emit(OpCodes.Ret);

                propertyBuilder.SetGetMethod(getPropMthdBldr);
                propertyBuilder.SetSetMethod(setPropMthdBldr);
            }
Ejemplo n.º 7
0
            override internal void Prepare(TypeBuilder builder)
            {
                if (Type.IsCanonicalSubtype(CanonicalFormKind.Any))
                    Environment.FailFast("Canonical types do not have EETypes");

                builder.RegisterForPreparation(Type);
            }
Ejemplo n.º 8
0
 /// <summary>
 /// Default ctor
 /// </summary>
 private MethodBuilder(MethodDefinition javaMethod, TypeBuilder declaringTypeBuilder, bool convertSignedBytes, bool addJavaPrefix)
 {
     this.javaMethod = javaMethod;
     this.declaringTypeBuilder = declaringTypeBuilder;
     this.convertSignedBytes = convertSignedBytes;
     this.addJavaPrefix = addJavaPrefix;
 }
Ejemplo n.º 9
0
 override internal IntPtr Create(TypeBuilder builder)
 {
     if (Type.IsNullable)
         return builder.GetRuntimeTypeHandle(Type.Instantiation[0]).ToIntPtr();
     else
         return builder.GetRuntimeTypeHandle(Type).ToIntPtr();
 }
Ejemplo n.º 10
0
Archivo: test.cs Proyecto: mono/gert
	public void AddMethodDynamically (ref TypeBuilder myTypeBld,
			 string mthdName,
			 Type [] mthdParams,
			 Type returnType,
			 string mthdAction)
	{
		MethodBuilder myMthdBld = myTypeBld.DefineMethod (
					mthdName,
					MethodAttributes.Public |
					MethodAttributes.Static,
					returnType,
					mthdParams);

		ILGenerator ILout = myMthdBld.GetILGenerator ();

		int numParams = mthdParams.Length;

		for (byte x = 0; x < numParams; x++)
			ILout.Emit (OpCodes.Ldarg_S, x);

		if (numParams > 1) {
			for (int y = 0; y < (numParams - 1); y++) {
				switch (mthdAction) {
				case "A": ILout.Emit (OpCodes.Add);
					break;
				case "M": ILout.Emit (OpCodes.Mul);
					break;
				default: ILout.Emit (OpCodes.Add);
					break;
				}
			}
		}
		ILout.Emit (OpCodes.Ret);
	}
Ejemplo n.º 11
0
 /// <summary>
 /// Default ctor
 /// </summary>
 private MethodBuilder(MethodDefinition javaMethod, TypeBuilder declaringTypeBuilder, SignedByteMode signedByteMode)
 {
     this.javaMethod = javaMethod;
     this.declaringTypeBuilder = declaringTypeBuilder;
     this.signedByteMode = signedByteMode;
     this.addJavaPrefix = signedByteMode == SignedByteMode.HasUnsignedPartnerOnlyInReturnType;
 }
Ejemplo n.º 12
0
 internal static IEnumerable<NestedTypeBuilder> Create(TypeBuilder parent, string parentFullName, ClassFile cf, InnerClass inner)
 {
     if (cf.IsInterface && cf.Fields.Any())
     {
         yield return new NestedInterfaceConstantsTypeBuilder(parent, parentFullName, cf, inner);
     }
     yield return new NestedTypeBuilder(parent, parentFullName, cf, inner);
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public FieldBuilder(FieldDefinition javaField, TypeBuilder declaringTypeBuilder)
 {
     if (javaField == null)
         throw new ArgumentNullException("javaField");
     if (declaringTypeBuilder == null)
         throw new ArgumentNullException("declaringTypeBuilder");
     this.javaField = javaField;
     this.declaringTypeBuilder = declaringTypeBuilder;
 }
Ejemplo n.º 14
0
        public unsafe void Finish(TypeBuilder typeBuilder)
        {
            Debug.Assert(_cells.Length == 0 || _addressOfFirstCellSlot != IntPtr.Zero);

            IntPtr* realCells = (IntPtr*)_addressOfFirstCellSlot;
            for (int i = 0; i < _cells.Length; i++)
            {
                realCells[i] = _cells[i].Create(typeBuilder);
            }
        }
Ejemplo n.º 15
0
        private void BuildEntitySets(EdmEntityContainer container, IEnumerable<EntityElement> rootElements, TypeBuilder typeBuilder)
        {
            foreach (var rootEntity in rootElements)
            {
                var entitySetName = rootEntity.EntitySetName ?? rootEntity.ResolveName();
                var schemaType = typeBuilder.BuildSchemaType(rootEntity);

                container.AddEntitySet(entitySetName, (IEdmEntityType)schemaType);
            }
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="TypeBuilder">Type builder</param>
 /// <param name="Name">Name of the method</param>
 /// <param name="Attributes">Attributes for the field (public, private, etc.)</param>
 /// <param name="FieldType">Type for the field</param>
 public FieldBuilder(TypeBuilder TypeBuilder, string Name, Type FieldType, FieldAttributes Attributes)
     : base()
 {
     Contract.Requires<ArgumentNullException>(TypeBuilder!=null,"TypeBuilder");
     Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(Name),"Name");
     this.Name = Name;
     this.Type = TypeBuilder;
     this.DataType = FieldType;
     this.Attributes = Attributes;
     Builder = Type.Builder.DefineField(Name, FieldType, Attributes);
 }
Ejemplo n.º 17
0
        private MethodBuilder ImplementMethod(TypeBuilder type, string methodName, MethodAttributes methodAttr, Type returnType, Type[] paramTypes, FieldBuilder field)
        {
            MethodBuilder method = type.DefineMethod(methodName, methodAttr, returnType, paramTypes);

            ILGenerator methodILGenerator = method.GetILGenerator();
            methodILGenerator.Emit(OpCodes.Ldarg_0);
            methodILGenerator.Emit(OpCodes.Ldarg_1);
            methodILGenerator.Emit(OpCodes.Stfld, field);
            methodILGenerator.Emit(OpCodes.Ret);

            return method;
        }
Ejemplo n.º 18
0
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="typeBuilder">Type builder</param>
 /// <param name="name">Name of the method</param>
 /// <param name="attributes">Attributes for the field (public, private, etc.)</param>
 /// <param name="fieldType">Type for the field</param>
 public FieldBuilder(TypeBuilder typeBuilder, string name, Type fieldType, FieldAttributes attributes)
 {
     if (typeBuilder == null)
         throw new ArgumentNullException("typeBuilder");
     if (string.IsNullOrEmpty(name))
         throw new ArgumentNullException("name");
     Name = name;
     Type = typeBuilder;
     DataType = fieldType;
     Attributes = attributes;
     Builder = Type.Builder.DefineField(name, fieldType, attributes);
 }
Ejemplo n.º 19
0
	static void EmitCtor (TypeBuilder genericFoo) {
		ConstructorBuilder mb = genericFoo.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, null);
		ILGenerator il = mb.GetILGenerator ();
		for (int i = 0; i < 20; ++i)
				il.Emit (OpCodes.Nop);

		il.Emit (OpCodes.Ldarg_0);
		il.Emit (OpCodes.Call, typeof (object).GetConstructors()[0]);
		il.Emit (OpCodes.Ret);

		ctor = mb;
	}
        public void NotCreateOtherElements()
        {
            CompilerContext cc = new CompilerContext();
            GenericTypeBuilder gtb = new GenericTypeBuilder();
            TypeBuilder tb = new TypeBuilder();
            Testdata.ClassA classa = new Testdata.ClassA();
            System.Reflection.ReflectionClass rc = new System.Reflection.ReflectionClass();

            Assert.IsNull(TreeElementCreator.CreateFromObject("cc", cc));
            Assert.IsNull(TreeElementCreator.CreateFromObject("gtb", gtb));
            Assert.IsNull(TreeElementCreator.CreateFromObject("tb", tb));
            Assert.IsNull(TreeElementCreator.CreateFromObject("rc", rc));
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="TypeBuilder">Type builder</param>
 /// <param name="Name">Name of the method</param>
 /// <param name="Attributes">Attributes for the field (public, private, etc.)</param>
 /// <param name="FieldType">Type for the field</param>
 public FieldBuilder(TypeBuilder TypeBuilder, string Name, Type FieldType, FieldAttributes Attributes)
     : base()
 {
     if (TypeBuilder == null)
         throw new ArgumentNullException("TypeBuilder");
     if (string.IsNullOrEmpty(Name))
         throw new ArgumentNullException("Name");
     this.Name = Name;
     this.Type = TypeBuilder;
     this.DataType = FieldType;
     this.Attributes = Attributes;
     Builder = Type.Builder.DefineField(Name, FieldType, Attributes);
 }
Ejemplo n.º 22
0
            override internal void Prepare(TypeBuilder builder)
            {
                if (Type.IsCanonicalSubtype(CanonicalFormKind.Any))
                    Environment.FailFast("Canonical types do not have EETypes");

                if (Type.IsNullable)
                {
                    Debug.Assert(Type.Instantiation.Length == 1);
                    builder.RegisterForPreparation(Type.Instantiation[0]);
                }
                else
                    builder.RegisterForPreparation(Type);
            }
Ejemplo n.º 23
0
        private IEdmModel BuildModel(string namespaceName, StructuralModelElement conceptualModelElement)
        {
            var model = new EdmModel();

            var container = new EdmEntityContainer(namespaceName, DefaultContainerName);
            model.AddElement(container);

            var typeBuilder = new TypeBuilder(namespaceName);
            BuildEntitySets(container, conceptualModelElement.RootEntities, typeBuilder);

            BuildTypes(model, conceptualModelElement.Entities, typeBuilder);

            return model;
        }
Ejemplo n.º 24
0
	static void EmitTargetMethod (TypeBuilder genericFoo) {
		MethodBuilder mb = genericFoo.DefineMethod ("TargetMethod", MethodAttributes.Public, typeof (void), new Type[] {typeof (object) });
		ILGenerator il = mb.GetILGenerator ();

		for (int i = 0; i < 20; ++i)
				il.Emit (OpCodes.Nop);

		il.Emit (OpCodes.Ldtoken, genericArgs [0]);
		il.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle"));
		il.Emit (OpCodes.Call, typeof (Console).GetMethod ("WriteLine", new Type[] { typeof (object) }));
		il.Emit (OpCodes.Ret);

		targetMethod = mb;
	}
Ejemplo n.º 25
0
        public AssemblyBuilder(AssemblyDefinition assembly, ReferenceResolver resolver)
        {
            if(assembly == null)
                throw new ArgumentNullException("assembly");
            if(resolver == null)
                throw new ArgumentNullException("resolver");

            Assembly = CloneAssembly(assembly);

            this.resolver = resolver;

            resolver.Module = Assembly.MainModule;
            typeBuilder = new TypeBuilder(Assembly.MainModule, resolver);
        }
Ejemplo n.º 26
0
	static void EmitTestEvents (TypeBuilder genericFoo) {
		MethodBuilder mb = genericFoo.DefineMethod ("TestEvents", MethodAttributes.Public, typeof (void), null);
		ILGenerator il = mb.GetILGenerator ();
		for (int i = 0; i < 20; ++i)
				il.Emit (OpCodes.Nop);

		il.Emit (OpCodes.Ldarg_0);
		il.Emit (OpCodes.Ldnull);
		il.Emit (OpCodes.Callvirt, targetMethod);

		il.Emit (OpCodes.Ret);

		testEvents = mb;
	}
Ejemplo n.º 27
0
        private static IEdmEntityContainer BuildContainer(IEnumerable<EntityElement> entities, TypeBuilder typeBuilder)
        {
            var container = new EdmEntityContainer(typeBuilder.NamespaceName, DefaultContainName);

            foreach (var entityElement in entities)
            {
                var entitySetName = entityElement.EntitySetName ?? entityElement.ResolveName();
                var entityType = (IEdmEntityType)typeBuilder.ResolveComplexType(entityElement);

                container.AddEntitySet(entitySetName, entityType);
            }

            return container;
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Try to create a type builder for the given class.
 /// </summary>
 internal static bool TryCreateTypeBuilder(ClassFile cf, out TypeBuilder builder)
 {
     if (mappedTypeBuilders != null)
     {
         IMappedTypeBuilder mappedBuilder;
         if (mappedTypeBuilders.TryGetValue(cf.ClassName, out mappedBuilder))
         {
             builder = mappedBuilder.Create(cf);
             return true;
         }
     }
     builder = null;
     return false;
 }
Ejemplo n.º 29
0
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="typeBuilder">Type builder</param>
 /// <param name="name">Name of the property</param>
 /// <param name="attributes">Attributes for the property (public, private, etc.)</param>
 /// <param name="getMethodAttributes">Get method attributes</param>
 /// <param name="setMethodAttributes">Set method attributes</param>
 /// <param name="propertyType">Property type for the property</param>
 /// <param name="parameters">Parameter types for the property</param>
 public DefaultPropertyBuilder(TypeBuilder typeBuilder, string name,
                               PropertyAttributes attributes, MethodAttributes getMethodAttributes,
                               MethodAttributes setMethodAttributes,
                               Type propertyType, IEnumerable<Type> parameters)
 {
     if (typeBuilder == null)
         throw new ArgumentNullException("typeBuilder");
     if (string.IsNullOrEmpty(name))
         throw new ArgumentNullException("name");
     Name = name;
     Type = typeBuilder;
     Attributes = attributes;
     GetMethodAttributes = getMethodAttributes;
     SetMethodAttributes = setMethodAttributes;
     DataType = propertyType;
     Parameters = new List<ParameterBuilder>();
     if (parameters != null)
     {
         int x = 1;
         foreach (var parameter in parameters)
         {
             Parameters.Add(new ParameterBuilder(parameter, x));
             ++x;
         }
     }
     Field = new FieldBuilder(Type, "_" + name + "field", propertyType, FieldAttributes.Private);
     Builder = Type.Builder.DefineProperty(name, attributes, propertyType,
                                           (parameters != null && parameters.Count() > 0)
                                               ? parameters.ToArray()
                                               : System.Type.EmptyTypes);
     GetMethod = new MethodBuilder(Type, "get_" + name, getMethodAttributes, parameters, propertyType);
     GetMethod.Generator.Emit(OpCodes.Ldarg_0);
     GetMethod.Generator.Emit(OpCodes.Ldfld, Field.Builder);
     GetMethod.Generator.Emit(OpCodes.Ret);
     var setParameters = new List<Type>();
     if (parameters != null)
     {
         setParameters.AddRange(parameters);
     }
     setParameters.Add(propertyType);
     SetMethod = new MethodBuilder(Type, "set_" + name, setMethodAttributes, setParameters, typeof (void));
     SetMethod.Generator.Emit(OpCodes.Ldarg_0);
     SetMethod.Generator.Emit(OpCodes.Ldarg_1);
     SetMethod.Generator.Emit(OpCodes.Stfld, Field.Builder);
     SetMethod.Generator.Emit(OpCodes.Ret);
     Builder.SetGetMethod(GetMethod.Builder);
     Builder.SetSetMethod(SetMethod.Builder);
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Create method builders for the given method.
 /// </summary>
 internal static IEnumerable<MethodBuilder> Create(MethodDefinition javaMethod, TypeBuilder declaringTypeBuilder)
 {
     bool onlyInReturnType;
     var convertSignedBytes = ContainsSignedByte(javaMethod, out onlyInReturnType) && !AvoidConvertSignedBytes(javaMethod);
     if (onlyInReturnType && javaMethod.DeclaringClass.IsInterface)
     {
         yield return new MethodBuilder(javaMethod, declaringTypeBuilder, true, false);
     }
     else
     {
         var addJavaPrefix = convertSignedBytes && onlyInReturnType;
         yield return new MethodBuilder(javaMethod, declaringTypeBuilder, false, addJavaPrefix);
         if (convertSignedBytes)
             yield return new MethodBuilder(javaMethod, declaringTypeBuilder, true, false);
     }
 }
Ejemplo n.º 31
0
 protected Type CreateType(TypeBuilder type)
 {
     return(type.CreateTypeInfo());
 }
Ejemplo n.º 32
0
        private static Schema GetAvroSchema()
        {
            var s3 = SchemaBuilder.Record(SupportEventInfra.AVRO_TYPENAME + "_3", TypeBuilder.OptionalInt("nestedNestedValue"));
            var s2 = SchemaBuilder.Record(SupportEventInfra.AVRO_TYPENAME + "_2", TypeBuilder.OptionalInt("nestedValue"),
                                          TypeBuilder.Field("nestedNested", TypeBuilder.Union(TypeBuilder.Int(), s3)));
            var s1 = SchemaBuilder.Record(SupportEventInfra.AVRO_TYPENAME + "_1",
                                          TypeBuilder.Field("nested", TypeBuilder.Union(TypeBuilder.Int(), s2)));

            return(SchemaBuilder.Record(SupportEventInfra.AVRO_TYPENAME, TypeBuilder.Field("item", s1)));
        }
Ejemplo n.º 33
0
        private unsafe static void ImplInterface(TypeBuilder delegateBuilder, MethodInfo invokeMethod, Type[] parameterTypes, Type resultType)
        {
            Type[] unByRefTypes = new Type[parameterTypes.Length];

            bool haveByRef = false;

            for (int i = 0; i < parameterTypes.Length; i++)
            {
                if (parameterTypes[i].IsByRef || parameterTypes[i].IsPointer || parameterTypes[i] == typeof(TypedReference))
                {
                    unByRefTypes[i] = typeof(IntPtr);

                    haveByRef = true;

                    continue;
                }

                unByRefTypes[i] = parameterTypes[i];
            }

            if (resultType.IsPointer || resultType == typeof(TypedReference))
            {
                haveByRef = true;

                resultType = typeof(IntPtr);
            }

            Type interfaceType;

            if (resultType == typeof(void))
            {
                if (parameterTypes.Length >= ActionInterfaces.Length)
                {
                    return;
                }

                interfaceType = ActionInterfaces[parameterTypes.Length];

                if (interfaceType.IsGenericTypeDefinition)
                {
                    interfaceType = interfaceType.MakeGenericType(unByRefTypes);
                }
            }
            else
            {
                if (parameterTypes.Length >= FuncInterfaces.Length)
                {
                    return;
                }

                interfaceType = FuncInterfaces[parameterTypes.Length];

                if (interfaceType.IsGenericTypeDefinition)
                {
                    var genericTypes = unByRefTypes;

                    Array.Resize(ref genericTypes, unByRefTypes.Length + 1);

                    genericTypes[unByRefTypes.Length] = resultType;

                    interfaceType = interfaceType.MakeGenericType(genericTypes);
                }
            }

            if (!interfaceType.IsVisible)
            {
                return;
            }

            delegateBuilder.AddInterfaceImplementation(interfaceType);

            if (haveByRef)
            {
                var invokeBuilder = delegateBuilder.DefineMethod(
                    "InvokeImpl",
                    MethodAttributes.Public | MethodAttributes.Virtual,
                    CallingConventions.Standard,
                    resultType,
                    unByRefTypes);

                var iLGen = invokeBuilder.GetILGenerator();

                for (int i = 0; i <= unByRefTypes.Length; ++i)
                {
                    iLGen.LoadArgument(i);
                }

                iLGen.Call(invokeMethod);

                iLGen.Return();

                delegateBuilder.DefineMethodOverride(invokeBuilder, interfaceType.GetMethod("Invoke"));
            }
            else
            {
                delegateBuilder.DefineMethodOverride(invokeMethod, interfaceType.GetMethod("Invoke"));
            }
        }
        internal override void Seal(TypeDescription existing = null)
        {
            if (PocoType != null || TypeBuilder != null)
            {
                return;
            }

            var name = "POCO" + Guid.NewGuid().ToString().Replace("-", "");

            var protoMemberAttr   = typeof(ProtoMemberAttribute).GetConstructor(new[] { typeof(int) });
            var protoContractAttr = typeof(ProtoContractAttribute).GetConstructor(new Type[0]);

            var fields = new Dictionary <string, FieldInfo>();

            TypeBuilder = ModuleBuilder.DefineType(name, TypeAttributes.Public, typeof(DynamicObject), new [] { typeof(IEnumerable) });
            var ix = 1;

            foreach (var kv in Members.OrderBy(o => o.Key, StringComparer.Ordinal))
            {
                var memberAttrBuilder = new CustomAttributeBuilder(protoMemberAttr, new object[] { ix });

                kv.Value.Seal(existing);
                var propType = kv.Value.GetPocoType(existing);

                var field = TypeBuilder.DefineField(kv.Key, propType, FieldAttributes.Public);
                field.SetCustomAttribute(memberAttrBuilder);

                fields[kv.Key] = field;
                ix++;
            }

            var contractAttrBuilder = new CustomAttributeBuilder(protoContractAttr, new object[0]);

            TypeBuilder.SetCustomAttribute(contractAttrBuilder);

            // Define indexer
            var strEq = typeof(object).GetMethod("Equals", new[] { typeof(object) });

            var tryGetIndexEmit = Sigil.Emit <TryGetIndexerDelegate> .BuildMethod(TypeBuilder, "TryGetIndex", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis);

            tryGetIndexEmit.LoadArgument(2);    // object[]

            var invalid = tryGetIndexEmit.DefineLabel("invalid");

            tryGetIndexEmit
            .Duplicate()                                       // object[] object[]
            .LoadLength <object>()                             // int object[]
            .LoadConstant(1);                                  // int int object[]

            tryGetIndexEmit.UnsignedBranchIfNotEqual(invalid); // object[]

            tryGetIndexEmit
            .LoadConstant(0)                    // int object[]
            .LoadElement <object>()             // object
            .IsInstance <string>();             // int

            var valid = tryGetIndexEmit.DefineLabel("valid");

            tryGetIndexEmit
            .BranchIfTrue(valid)                // --empty--
            .LoadArgument(2);                   // object[]

            tryGetIndexEmit.MarkLabel(invalid);
            tryGetIndexEmit.Pop();              // --empty--

            tryGetIndexEmit
            .LoadArgument(3)                    // object&
            .LoadNull()                         // null object&
            .StoreIndirect(typeof(object));     // --empty--

            tryGetIndexEmit
            .LoadConstant(0)                    // int
            .Return();                          // --empty--

            tryGetIndexEmit.MarkLabel(valid);

            tryGetIndexEmit.LoadArgument(3);    // object&

            tryGetIndexEmit
            .LoadArgument(2)                    // object[] object&
            .LoadConstant(0)                    // int object[] object&
            .LoadElement <object>();            // object object&

            Sigil.Label next;
            var         done = tryGetIndexEmit.DefineLabel("done");

            foreach (var mem in Members)
            {
                next = tryGetIndexEmit.DefineLabel("next_" + mem.Key);

                var memKey = mem.Key;
                var field  = fields[memKey];

                tryGetIndexEmit
                .Duplicate()                         // object object object&
                .LoadConstant(memKey);               // string object object object&

                tryGetIndexEmit.CallVirtual(strEq);  // int object object7&

                tryGetIndexEmit.BranchIfFalse(next); // object object&

                tryGetIndexEmit
                .Pop()                               // object&
                .LoadArgument(0)                     // this object&
                .LoadField(field);                   // fieldType object&

                if (field.FieldType.IsValueType)
                {
                    tryGetIndexEmit.Box(field.FieldType); // fieldType object&
                }

                tryGetIndexEmit.Branch(done);           // fieldType object&

                tryGetIndexEmit.MarkLabel(next);        // object object&
            }

            tryGetIndexEmit
            .Pop()                                      // object&
            .LoadNull();                                // null object&

            tryGetIndexEmit.MarkLabel(done);            // *something* object&

            tryGetIndexEmit
            .StoreIndirect(typeof(object))              // --empty--
            .LoadConstant(1)                            // int
            .Return();                                  // --empty--

            var tryGetIndex = tryGetIndexEmit.CreateMethod();

            TypeBuilder.DefineMethodOverride(tryGetIndex, typeof(DynamicObject).GetMethod("TryGetIndex"));

            // Implement IEnumerable
            var getEnumeratorEmit = Sigil.Emit <Func <IEnumerator> > .BuildMethod(TypeBuilder, "GetEnumerator", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis);

            var newStrList    = typeof(List <string>).GetConstructor(new[] { typeof(int) });
            var newEnumerator = Enumerator.GetConstructor(new[] { typeof(List <string>), typeof(object) });
            var add           = typeof(List <string>).GetMethod("Add");

            getEnumeratorEmit.LoadConstant(Members.Count);
            getEnumeratorEmit.NewObject(newStrList);

            foreach (var mem in Members)
            {
                getEnumeratorEmit.Duplicate();
                getEnumeratorEmit.LoadConstant(mem.Key);
                getEnumeratorEmit.Call(add);
            }

            getEnumeratorEmit.LoadArgument(0);
            getEnumeratorEmit.NewObject(newEnumerator);
            getEnumeratorEmit.Return();

            var getEnumerator = getEnumeratorEmit.CreateMethod();

            TypeBuilder.DefineMethodOverride(getEnumerator, typeof(IEnumerable).GetMethod("GetEnumerator"));

            // Define ToString()
            var toStringEmit = Sigil.Emit <Func <string> > .BuildMethod(TypeBuilder, "ToString", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis);

            var objToString = typeof(object).GetMethod("ToString");
            var thunkField  = TypeBuilder.DefineField("__ToStringThunk", typeof(Func <object, string>), FieldAttributes.Static | FieldAttributes.Private);
            var invoke      = typeof(Func <object, string>).GetMethod("Invoke");

            toStringEmit
            .LoadField(thunkField)
            .LoadArgument(0)
            .CallVirtual(invoke)
            .Return();

            var toString = toStringEmit.CreateMethod();

            TypeBuilder.DefineMethodOverride(toString, objToString);

            PocoType = TypeBuilder.CreateType();

            // Set the ToStringCallback

            var firstInst = PocoType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]);

            var setThunk = firstInst.GetType().GetField("__ToStringThunk", BindingFlags.NonPublic | BindingFlags.Static);

            setThunk.SetValue(firstInst, ToStringFunc);
        }
Ejemplo n.º 35
0
        public static IConditional Compile(AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index)
        {
            TypeBuilder typeBuilder = assembly.DefineType(
                "__conditional" + index,
                TypeAttributes.Public,
                typeof(object)
                );

            #region Constructor
            {
                ConstructorBuilder ctor = typeBuilder.DefineConstructor(
                    MethodAttributes.Public,
                    CallingConventions.Standard,
                    Type.EmptyTypes
                    );

                ILGenerator il = ctor.GetILGenerator();

                // : base()
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));

                for (int i = 0; i < conditions.Length; ++i)
                {
                    conditions[i].Construct(typeBuilder, il, i);
                }

                // return;
                il.Emit(OpCodes.Ret);
            }
            #endregion

            #region IComparer
            typeBuilder.AddInterfaceImplementation(typeof(IConditional));

            MethodBuilder compareMethod;

            #region Compare
            {
                MethodEmitter emitter = new MethodEmitter(typeBuilder);

                emitter.Define(
                    /*  name  */ "Verify",
                    /*  attr  */ MethodAttributes.Public | MethodAttributes.Virtual,
                    /* return */ typeof(bool),
                    /* params */ new Type[] { typeof(object) });

                LocalBuilder obj = emitter.CreateLocal(objectType);
                LocalBuilder eq  = emitter.CreateLocal(typeof(bool));

                emitter.LoadArgument(1);
                emitter.CastAs(objectType);
                emitter.StoreLocal(obj);

                Label done = emitter.CreateLabel();

                for (int i = 0; i < conditions.Length; ++i)
                {
                    if (i > 0)
                    {
                        emitter.LoadLocal(eq);

                        emitter.BranchIfFalse(done);
                    }

                    emitter.LoadLocal(obj);

                    conditions[i].Compile(emitter);

                    emitter.StoreLocal(eq);
                }

                emitter.MarkLabel(done);

                emitter.LoadLocal(eq);

                emitter.Return();

                typeBuilder.DefineMethodOverride(
                    emitter.Method,
                    typeof(IConditional).GetMethod(
                        "Verify",
                        new Type[]
                {
                    typeof(object)
                }
                        )
                    );

                compareMethod = emitter.Method;
            }
            #endregion
            #endregion

            Type conditionalType = typeBuilder.CreateType();

            return((IConditional)Activator.CreateInstance(conditionalType));
        }
 /// <summary>
 /// Defines additional fields in the proxy type.
 /// </summary>
 /// <param name="typeBuilder">The type builder for the proxy.</param>
 /// <returns>The defined proxy fields.</returns>
 protected virtual FieldInfo[] DefineProxyFields(TypeBuilder typeBuilder)
 {
     return(new FieldInfo[0]);
 }
Ejemplo n.º 37
0
 /// <summary>
 /// Convenience method for creating static methods.
 ///
 /// Equivalent to calling to BuildMethod, but with MethodAttributes.Static set and CallingConventions.Standard.
 /// </summary>
 public static Emit BuildStaticMethod(Type returnType, Type[] parameterTypes, TypeBuilder type, string name, MethodAttributes attributes, bool allowUnverifiableCode = false, bool doVerify = true, bool strictBranchVerification = false)
 {
     return(BuildMethod(returnType, parameterTypes, type, name, attributes | MethodAttributes.Static, CallingConventions.Standard, allowUnverifiableCode, doVerify, strictBranchVerification));
 }
        public static Type Generate(string functionAssemblyName, string typeName, Collection <CustomAttributeBuilder> typeAttributes, ICollection <FunctionDescriptor> functions)
        {
            if (functions == null)
            {
                throw new ArgumentNullException(nameof(functions));
            }

            AssemblyName    assemblyName    = new AssemblyName(functionAssemblyName);
            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);

            ModuleBuilder mb = assemblyBuilder.DefineDynamicModule(assemblyName.Name);

            TypeBuilder tb = mb.DefineType(typeName, TypeAttributes.Public);

            if (typeAttributes != null)
            {
                foreach (CustomAttributeBuilder attributeBuilder in typeAttributes)
                {
                    tb.SetCustomAttribute(attributeBuilder);
                }
            }

            foreach (FunctionDescriptor function in functions)
            {
                if (function.Metadata.IsDirect())
                {
                    continue;
                }

                var retValue   = function.Parameters.Where(x => x.Name == ScriptConstants.SystemReturnParameterName).FirstOrDefault();
                var parameters = function.Parameters.Where(x => x != retValue).ToArray();

                MethodBuilder methodBuilder = tb.DefineMethod(function.Name, MethodAttributes.Public | MethodAttributes.Static);
                Type[]        types         = parameters.Select(p => p.Type).ToArray();
                methodBuilder.SetParameters(types);

                Type innerReturnType = null;

                if (retValue == null)
                {
                    methodBuilder.SetReturnType(typeof(Task));
                }
                else
                {
                    // It's critical to set the proper return type for the binder.
                    // The return parameters was added a MakeByRefType, so need to get the inner type.
                    innerReturnType = retValue.Type.GetElementType();

                    // Task<> derives from Task.
                    var actualReturnType = typeof(Task <>).MakeGenericType(innerReturnType);

                    methodBuilder.SetReturnType(actualReturnType);

                    ParameterBuilder parameterBuilder = methodBuilder.DefineParameter(0, ParameterAttributes.Retval, null);

                    if (retValue.CustomAttributes != null)
                    {
                        foreach (CustomAttributeBuilder attributeBuilder in retValue.CustomAttributes)
                        {
                            parameterBuilder.SetCustomAttribute(attributeBuilder);
                        }
                    }
                }

                if (function.CustomAttributes != null)
                {
                    foreach (CustomAttributeBuilder attributeBuilder in function.CustomAttributes)
                    {
                        methodBuilder.SetCustomAttribute(attributeBuilder);
                    }
                }

                for (int i = 0; i < parameters.Length; i++)
                {
                    ParameterDescriptor parameter        = parameters[i];
                    ParameterBuilder    parameterBuilder = methodBuilder.DefineParameter(i + 1, parameter.Attributes, parameter.Name);
                    if (parameter.CustomAttributes != null)
                    {
                        foreach (CustomAttributeBuilder attributeBuilder in parameter.CustomAttributes)
                        {
                            parameterBuilder.SetCustomAttribute(attributeBuilder);
                        }
                    }
                }

                _invokerMap[function.Name] = function.Invoker;

                MethodInfo invokeMethod = function.Invoker.GetType().GetMethod("Invoke");
                MethodInfo getInvoker   = typeof(FunctionGenerator).GetMethod("GetInvoker", BindingFlags.Static | BindingFlags.Public);

                ILGenerator il = methodBuilder.GetILGenerator();

                LocalBuilder argsLocal    = il.DeclareLocal(typeof(object[]));
                LocalBuilder invokerLocal = il.DeclareLocal(typeof(IFunctionInvoker));

                il.Emit(OpCodes.Nop);

                // declare an array for all parameter values
                il.Emit(OpCodes.Ldc_I4, parameters.Length);
                il.Emit(OpCodes.Newarr, typeof(object));
                il.Emit(OpCodes.Stloc, argsLocal);

                // copy each parameter into the arg array
                for (int i = 0; i < parameters.Length; i++)
                {
                    ParameterDescriptor parameter = parameters[i];

                    il.Emit(OpCodes.Ldloc, argsLocal);
                    il.Emit(OpCodes.Ldc_I4, i);
                    il.Emit(OpCodes.Ldarg, i);

                    // For Out and Ref types, need to do an indirection.
                    if (parameter.Type.IsByRef)
                    {
                        il.Emit(OpCodes.Ldind_Ref);
                    }

                    // Box value types
                    if (parameter.Type.IsValueType)
                    {
                        il.Emit(OpCodes.Box, parameter.Type);
                    }

                    il.Emit(OpCodes.Stelem_Ref);
                }

                // get the invoker instance
                il.Emit(OpCodes.Ldstr, function.Name);
                il.Emit(OpCodes.Call, getInvoker);
                il.Emit(OpCodes.Stloc, invokerLocal);

                // now call the invoker, passing in the args
                il.Emit(OpCodes.Ldloc, invokerLocal);
                il.Emit(OpCodes.Ldloc, argsLocal);
                il.Emit(OpCodes.Callvirt, invokeMethod); // pushes a Task<object>

                if (parameters.Any(p => p.Type.IsByRef))
                {
                    LocalBuilder taskLocal        = il.DeclareLocal(typeof(Task <object>));
                    LocalBuilder taskAwaiterLocal = il.DeclareLocal(typeof(TaskAwaiter <object>));

                    // We need to wait on the function's task if we have any out/ref
                    // parameters to ensure they have been populated before we copy them back

                    // Store the result into a local Task
                    // and load it onto the evaluation stack
                    il.Emit(OpCodes.Stloc, taskLocal);
                    il.Emit(OpCodes.Ldloc, taskLocal);

                    // Call "GetAwaiter" on the Task
                    il.Emit(OpCodes.Callvirt, typeof(Task <object>).GetMethod("GetAwaiter", Type.EmptyTypes));

                    // Call "GetResult", which will synchonously wait for the Task to complete
                    il.Emit(OpCodes.Stloc, taskAwaiterLocal);
                    il.Emit(OpCodes.Ldloca, taskAwaiterLocal);
                    il.Emit(OpCodes.Call, typeof(TaskAwaiter <object>).GetMethod("GetResult"));
                    il.Emit(OpCodes.Pop); // ignore GetResult();

                    // Copy back out and ref parameters
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        var param = parameters[i];
                        if (!param.Type.IsByRef)
                        {
                            continue;
                        }

                        il.Emit(OpCodes.Ldarg, i);

                        il.Emit(OpCodes.Ldloc, argsLocal);
                        il.Emit(OpCodes.Ldc_I4, i);
                        il.Emit(OpCodes.Ldelem_Ref);
                        il.Emit(OpCodes.Castclass, param.Type.GetElementType());

                        il.Emit(OpCodes.Stind_Ref);
                    }

                    il.Emit(OpCodes.Ldloc, taskLocal);
                }

                // Need to coerce.
                if (innerReturnType != null)
                {
                    var m  = typeof(FunctionGenerator).GetMethod("Coerce", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    var m2 = m.MakeGenericMethod(innerReturnType);
                    il.Emit(OpCodes.Call, m2);
                }

                il.Emit(OpCodes.Ret);
            }

            Type t = tb.CreateTypeInfo().AsType();

            return(t);
        }
Ejemplo n.º 39
0
 public override void GenerateMSIL(ILGenerator ilGenerator, TypeBuilder typeBuilder)
 {
     FirstPart.GenerateMSIL(ilGenerator, typeBuilder);
     SecondPart.GenerateMSIL(ilGenerator, typeBuilder);
 }
Ejemplo n.º 40
0
 public BuilderGenerator(TypeBuilder typeBuilder)
 {
     _typeBuilder = typeBuilder;
 }
Ejemplo n.º 41
0
        internal void AddToModule(ModuleBuilder module)
        {
            string typeName = (nextTypeId++).ToString();

            //
            //  Define a public class named "Property" in the assembly.
            //
            TypeBuilder myType =
                module.DefineType(typeName, TypeAttributes.Public);

            //
            // Mark the class as implementing IPropertyAccessor.
            //
            myType.AddInterfaceImplementation(typeof(IGetterSetter));

            // Add a constructor
            //ConstructorBuilder constructor = myType.DefineDefaultConstructor(MethodAttributes.Public);

            //
            // Define a method for the get operation.
            //
            Type[]        getParamTypes = new [] { typeof(object) };
            Type          getReturnType = typeof(object);
            MethodBuilder getMethod     =
                myType.DefineMethod("Get",
                                    MethodAttributes.Public | MethodAttributes.Virtual,
                                    getReturnType,
                                    getParamTypes);

            //
            // From the method, get an ILGenerator. This is used to
            // emit the IL that we want.
            //
            ILGenerator getIL = getMethod.GetILGenerator();


            //
            // Emit the IL.
            //
            var targetGetMethod = mProperty.GetGetMethod();

            if (targetGetMethod != null)
            {
                getIL.DeclareLocal(typeof(object));
                getIL.Emit(OpCodes.Ldarg_1);                                                    //Load the first argument
                //(target object)
                getIL.Emit(OpCodes.Castclass, mTargetType);                                     //Cast to the source type
                getIL.EmitCall(OpCodes.Call, targetGetMethod, null);                            //Get the property value
                if (targetGetMethod.ReturnType.IsValueType)
                {
                    getIL.Emit(OpCodes.Box, targetGetMethod.ReturnType);                        //Box if necessary
                }
                getIL.Emit(OpCodes.Stloc_0);                                                    //Store it
                getIL.Emit(OpCodes.Ldloc_0);
            }
            else
            {
                getIL.ThrowException(typeof(MissingMethodException));
            }

            getIL.Emit(OpCodes.Ret);


            //
            // Define a method for the set operation.
            //
            Type[]        setParamTypes = new [] { typeof(object), typeof(object) };
            Type          setReturnType = null;
            MethodBuilder setMethod     =
                myType.DefineMethod("Set",
                                    MethodAttributes.Public | MethodAttributes.Virtual,
                                    setReturnType,
                                    setParamTypes);

            //
            // From the method, get an ILGenerator. This is used to
            // emit the IL that we want.
            //
            ILGenerator setIL = setMethod.GetILGenerator();
            //
            // Emit the IL.
            //

            MethodInfo targetSetMethod = mProperty.GetSetMethod();

            if (targetSetMethod != null)
            {
                Type paramType = targetSetMethod.GetParameters()[0].ParameterType;

                setIL.DeclareLocal(paramType);
                setIL.Emit(OpCodes.Ldarg_1);                                                            //Load the first argument
                //(target object)

                setIL.Emit(OpCodes.Castclass, mTargetType);                     //Cast to the source type

                setIL.Emit(OpCodes.Ldarg_2);                                    //Load the second argument
                //(value object)

                if (paramType.IsValueType)
                {
                    setIL.Emit(OpCodes.Unbox, paramType);                                       //Unbox it
                    if (typesHashes[paramType] != null)                                         //and load
                    {
                        OpCode load = (OpCode)typesHashes[paramType];
                        setIL.Emit(load);
                    }
                    else
                    {
                        setIL.Emit(OpCodes.Ldobj, paramType);
                    }
                }
                else
                {
                    setIL.Emit(OpCodes.Castclass, paramType);                                   //Cast class
                }

                setIL.EmitCall(OpCodes.Callvirt,
                               targetSetMethod, null);                                                          //Set the property value
            }
            else
            {
                setIL.ThrowException(typeof(MissingMethodException));
            }

            setIL.Emit(OpCodes.Ret);

            //
            // Load the type
            //
            myType.CreateType();


            mEmittedPropertyAccessor = module.Assembly.CreateInstance(typeName) as IGetterSetter;
            if (mEmittedPropertyAccessor == null)
            {
                throw new Exception("Unable to create property accessor.");
            }
        }
Ejemplo n.º 42
0
        static void DefineMethods(TypeBuilder typeBuilder, Type interfaceType, MethodDefinition[] definitions, ConstructorInfo emptyCtor)
        {
            var filedHolderType = typeof(MagicOnionClientBase);
            var baseType        = typeof(MagicOnionClientBase <>).MakeGenericType(interfaceType);
            var hostField       = filedHolderType.GetField("host", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            var optionField     = filedHolderType.GetField("option", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            var invokerField    = filedHolderType.GetField("callInvoker", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            var resolverField   = filedHolderType.GetField("resolver", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            var filtersField    = filedHolderType.GetField("filters", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            // Clone
            {
                var method = typeBuilder.DefineMethod("Clone", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
                                                      typeof(MagicOnionClientBase <>).MakeGenericType(interfaceType),
                                                      Type.EmptyTypes);
                var il = method.GetILGenerator();

                il.Emit(OpCodes.Newobj, emptyCtor);

                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, hostField);
                il.Emit(OpCodes.Stfld, hostField);

                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, optionField);
                il.Emit(OpCodes.Stfld, optionField);

                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, invokerField);
                il.Emit(OpCodes.Stfld, invokerField);

                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, resolverField);
                il.Emit(OpCodes.Stfld, resolverField);

                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, filtersField);
                il.Emit(OpCodes.Stfld, filtersField);

                il.Emit(OpCodes.Ret);
            }
            // Overrides
            {
                // TSelf WithOption(CallOptions option)
                {
                    var method = typeBuilder.DefineMethod("WithOptions", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
                                                          interfaceType,
                                                          new[] { typeof(CallOptions) });
                    var il = method.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Call, baseType.GetMethod("WithOptions", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
                    il.Emit(OpCodes.Ret);
                }
                // TSelf WithHeaders(Metadata headers);
                {
                    var method = typeBuilder.DefineMethod("WithHeaders", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
                                                          interfaceType,
                                                          new[] { typeof(Metadata) });
                    var il = method.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Call, baseType.GetMethod("WithHeaders", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
                    il.Emit(OpCodes.Ret);
                }
                // TSelf WithDeadline(DateTime deadline);
                {
                    var method = typeBuilder.DefineMethod("WithDeadline", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
                                                          interfaceType,
                                                          new[] { typeof(DateTime) });
                    var il = method.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Call, baseType.GetMethod("WithDeadline", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
                    il.Emit(OpCodes.Ret);
                }
                // TSelf WithCancellationToken(CancellationToken cancellationToken);
                {
                    var method = typeBuilder.DefineMethod("WithCancellationToken", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
                                                          interfaceType,
                                                          new[] { typeof(CancellationToken) });
                    var il = method.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Call, baseType.GetMethod("WithCancellationToken", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
                    il.Emit(OpCodes.Ret);
                }
                // TSelf WithHost(string host);
                {
                    var method = typeBuilder.DefineMethod("WithHost", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
                                                          interfaceType,
                                                          new[] { typeof(string) });
                    var il = method.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Call, baseType.GetMethod("WithHost", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
                    il.Emit(OpCodes.Ret);
                }
            }
            // Proxy Methods
            for (int i = 0; i < definitions.Length; i++)
            {
                var def        = definitions[i];
                var parameters = def.MethodInfo.GetParameters().Select(x => x.ParameterType).ToArray();

                var method = typeBuilder.DefineMethod(def.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
                                                      def.MethodInfo.ReturnType,
                                                      parameters);
                var il = method.GetILGenerator();

                switch (def.MethodType)
                {
                case MethodType.Unary:
                {
                    // base.InvokeAsync<TRequest, TResponse>/InvokeTaskAsync(string path, TRequest request, Func<RequestContext, ResponseContext> requestMethod)

                    // this.
                    il.Emit(OpCodes.Ldarg_0);

                    // path
                    il.Emit(OpCodes.Ldstr, def.Path);

                    // create request
                    for (int j = 0; j < parameters.Length; j++)
                    {
                        il.Emit(OpCodes.Ldarg, j + 1);
                    }
                    if (parameters.Length == 0)
                    {
                        // use empty byte[0]
                        il.Emit(OpCodes.Ldsfld, nilBytes);
                    }
                    else if (parameters.Length == 1)
                    {
                        // already loaded parameter.
                    }
                    else
                    {
                        // call new DynamicArgumentTuple<T>
                        il.Emit(OpCodes.Newobj, def.RequestType.GetConstructors()[0]);
                    }

                    // requestMethod
                    il.Emit(OpCodes.Ldsfld, def.UnaryRequestDelegate);

                    // InvokeAsync/InvokeTaskAsync
                    var invokeMethod = def.ResponseIsTask
                                ? baseType.GetMethod("InvokeTaskAsync", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance)
                                : baseType.GetMethod("InvokeAsync", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance);
                    invokeMethod = invokeMethod.MakeGenericMethod(def.RequestType, def.ResponseType);
                    il.Emit(OpCodes.Callvirt, invokeMethod);
                }

                break;

                case MethodType.ServerStreaming:
                {
                    il.DeclareLocal(typeof(byte[]));         // request
                    il.DeclareLocal(typeof(AsyncServerStreamingCall <byte[]>));

                    // create request
                    for (int j = 0; j < parameters.Length; j++)
                    {
                        il.Emit(OpCodes.Ldarg, j + 1);
                    }
                    if (parameters.Length == 0)
                    {
                        // use empty byte[0]
                        il.Emit(OpCodes.Ldsfld, nilBytes);
                    }
                    else if (parameters.Length == 1)
                    {
                        // already loaded parameter.
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, resolverField);
                        il.Emit(OpCodes.Call, callMessagePackSerialize.MakeGenericMethod(def.RequestType));
                    }
                    else
                    {
                        // call new DynamicArgumentTuple<T>
                        il.Emit(OpCodes.Newobj, def.RequestType.GetConstructors()[0]);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, resolverField);
                        il.Emit(OpCodes.Call, callMessagePackSerialize.MakeGenericMethod(def.RequestType));
                    }
                    il.Emit(OpCodes.Stloc_0);

                    // create ***Result
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, invokerField);
                    il.Emit(OpCodes.Ldsfld, def.FieldMethod);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, hostField);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, optionField);
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Callvirt, typeof(CallInvoker).GetMethod("AsyncServerStreamingCall").MakeGenericMethod(typeof(byte[]), typeof(byte[])));
                    il.Emit(OpCodes.Stloc_1);

                    // create return result
                    il.Emit(OpCodes.Ldloc_1);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, resolverField);
                    var resultType = typeof(ServerStreamingResult <>).MakeGenericType(def.ResponseType);
                    il.Emit(OpCodes.Newobj, resultType.GetConstructors()[0]);
                    if (def.ResponseIsTask)
                    {
                        il.Emit(OpCodes.Call, typeof(Task).GetMethod("FromResult").MakeGenericMethod(resultType));
                    }
                }
                break;

                case MethodType.ClientStreaming:
                case MethodType.DuplexStreaming:
                    if (def.MethodType == MethodType.ClientStreaming)
                    {
                        il.DeclareLocal(typeof(AsyncClientStreamingCall <byte[], byte[]>));    // callResult
                    }
                    else
                    {
                        il.DeclareLocal(typeof(AsyncDuplexStreamingCall <byte[], byte[]>));    // callResult
                    }

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, invokerField);
                    il.Emit(OpCodes.Ldsfld, def.FieldMethod);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, hostField);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, optionField);
                    if (def.MethodType == MethodType.ClientStreaming)
                    {
                        il.Emit(OpCodes.Callvirt, typeof(CallInvoker).GetMethod("AsyncClientStreamingCall").MakeGenericMethod(typeof(byte[]), typeof(byte[])));
                    }
                    else
                    {
                        il.Emit(OpCodes.Callvirt, typeof(CallInvoker).GetMethod("AsyncDuplexStreamingCall").MakeGenericMethod(typeof(byte[]), typeof(byte[])));
                    }
                    il.Emit(OpCodes.Stloc_0);

                    // create return result
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, resolverField);
                    Type resultType2;
                    if (def.MethodType == MethodType.ClientStreaming)
                    {
                        resultType2 = typeof(ClientStreamingResult <,>).MakeGenericType(def.RequestType, def.ResponseType);
                        il.Emit(OpCodes.Newobj, resultType2.GetConstructors().OrderBy(x => x.GetParameters().Length).Last());
                    }
                    else
                    {
                        resultType2 = typeof(DuplexStreamingResult <,>).MakeGenericType(def.RequestType, def.ResponseType);
                        il.Emit(OpCodes.Newobj, resultType2.GetConstructors()[0]);
                    }

                    if (def.ResponseIsTask)
                    {
                        il.Emit(OpCodes.Call, typeof(Task).GetMethod("FromResult").MakeGenericMethod(resultType2));
                    }
                    break;

                default:
                    throw new InvalidOperationException("Not supported method type:" + def.MethodType);
                }

                il.Emit(OpCodes.Ret);
            }
        }
Ejemplo n.º 43
0
        static TypeAccessor CreateNew(Type type, bool allowNonPublicAccessors)
        {
#if !NO_DYNAMIC
            if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type))
            {
                return(DynamicAccessor.Singleton);
            }
#endif

            PropertyInfo[]           props   = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            FieldInfo[]              fields  = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
            Dictionary <string, int> map     = new Dictionary <string, int>();
            List <MemberInfo>        members = new List <MemberInfo>(props.Length + fields.Length);
            int i = 0;
            foreach (var prop in props)
            {
                if (!map.ContainsKey(prop.Name) && prop.GetIndexParameters().Length == 0)
                {
                    map.Add(prop.Name, i++);
                    members.Add(prop);
                }
            }
            foreach (var field in fields)
            {
                if (!map.ContainsKey(field.Name))
                {
                    map.Add(field.Name, i++); members.Add(field);
                }
            }

            ConstructorInfo ctor = null;
            if (_IsClass(type) && !_IsAbstract(type))
            {
                ctor = type.GetConstructor(TypeHelpers.EmptyTypes);
            }
            ILGenerator il;
            if (!IsFullyPublic(type, props, allowNonPublicAccessors))
            {
                DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(int), typeof(object) }, type, true),
                              dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(int), typeof(object), typeof(object) }, type, true);
                WriteMapImpl(dynGetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, true);
                WriteMapImpl(dynSetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, false);
                DynamicMethod dynCtor = null;
                if (ctor != null)
                {
                    dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), TypeHelpers.EmptyTypes, type, true);
                    il      = dynCtor.GetILGenerator();
                    il.Emit(OpCodes.Newobj, ctor);
                    il.Emit(OpCodes.Ret);
                }
                return(new DelegateAccessor(
                           map,
                           (Func <int, object, object>)dynGetter.CreateDelegate(typeof(Func <int, object, object>)),
                           (Action <int, object, object>)dynSetter.CreateDelegate(typeof(Action <int, object, object>)),
                           dynCtor == null ? null : (Func <object>)dynCtor.CreateDelegate(typeof(Func <object>)), type));
            }

            // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders
            if (assembly == null)
            {
                AssemblyName name = new AssemblyName("FastMember_dynamic");
#if COREFX
                assembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
#else
                assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
#endif
                module = assembly.DefineDynamicModule(name.Name);
            }
#if COREFX
            TypeAttributes attribs = typeof(TypeAccessor).GetTypeInfo().Attributes;
#else
            TypeAttributes attribs = typeof(TypeAccessor).Attributes;
#endif
            TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + GetNextCounterValue(),
                                               (attribs | TypeAttributes.Sealed | TypeAttributes.Public) & ~(TypeAttributes.Abstract | TypeAttributes.NotPublic), typeof(RuntimeTypeAccessor));

            il = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] {
                typeof(Dictionary <string, int>)
            }).GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            FieldBuilder mapField = tb.DefineField("_map", typeof(Dictionary <string, int>), FieldAttributes.InitOnly | FieldAttributes.Private);
            il.Emit(OpCodes.Stfld, mapField);
            il.Emit(OpCodes.Ret);


            PropertyInfo  indexer = typeof(TypeAccessor).GetProperty("Item");
            MethodInfo    baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod();
            MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) });
            il = body.GetILGenerator();
            WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, true);
            tb.DefineMethodOverride(body, baseGetter);

            body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) });
            il   = body.GetILGenerator();
            WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, false);
            tb.DefineMethodOverride(body, baseSetter);

            MethodInfo baseMethod;
            if (ctor != null)
            {
                baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod();
                body       = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, TypeHelpers.EmptyTypes);
                il         = body.GetILGenerator();
                il.Emit(OpCodes.Ldc_I4_1);
                il.Emit(OpCodes.Ret);
                tb.DefineMethodOverride(body, baseMethod);

                baseMethod = typeof(TypeAccessor).GetMethod("CreateNew");
                body       = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, TypeHelpers.EmptyTypes);
                il         = body.GetILGenerator();
                il.Emit(OpCodes.Newobj, ctor);
                il.Emit(OpCodes.Ret);
                tb.DefineMethodOverride(body, baseMethod);
            }

            baseMethod = typeof(RuntimeTypeAccessor).GetProperty("Type", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true);
            body       = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.ReturnType, TypeHelpers.EmptyTypes);
            il         = body.GetILGenerator();
            il.Emit(OpCodes.Ldtoken, type);
            il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
            il.Emit(OpCodes.Ret);
            tb.DefineMethodOverride(body, baseMethod);

            var accessor = (TypeAccessor)Activator.CreateInstance(_CreateType(tb), map);
            return(accessor);
        }
Ejemplo n.º 44
0
        protected override MethodEmitter BuildProxiedMethodBody(
            MethodEmitter emitter,
            ClassEmitter @class,
            INamingScope namingScope
            )
        {
            var invocationType = invocation;

            var genericArguments = Type.EmptyTypes;

            var constructor = invocation.GetConstructors()[0];

            IExpression proxiedMethodTokenExpression;

            if (MethodToOverride.IsGenericMethod)
            {
                // Not in the cache: generic method
                genericArguments             = emitter.MethodBuilder.GetGenericArguments();
                proxiedMethodTokenExpression = new MethodTokenExpression(
                    MethodToOverride.MakeGenericMethod(genericArguments)
                    );

                if (invocationType.IsGenericTypeDefinition)
                {
                    // bind generic method arguments to invocation's type arguments
                    invocationType = invocationType.MakeGenericType(genericArguments);
                    constructor    = TypeBuilder.GetConstructor(invocationType, constructor);
                }
            }
            else
            {
                var proxiedMethodToken = @class.CreateStaticField(
                    namingScope.GetUniqueName("token_" + MethodToOverride.Name),
                    typeof(MethodInfo)
                    );
                @class.ClassConstructor.CodeBuilder.AddStatement(
                    new AssignStatement(
                        proxiedMethodToken,
                        new MethodTokenExpression(MethodToOverride)
                        )
                    );

                proxiedMethodTokenExpression = proxiedMethodToken;
            }

            var methodInterceptors = SetMethodInterceptors(
                @class,
                namingScope,
                emitter,
                proxiedMethodTokenExpression
                );

            var dereferencedArguments = IndirectReference.WrapIfByRef(emitter.Arguments);
            var hasByRefArguments     = HasByRefArguments(emitter.Arguments);

            var arguments = GetCtorArguments(
                @class,
                proxiedMethodTokenExpression,
                dereferencedArguments,
                methodInterceptors
                );
            var ctorArguments = ModifyArguments(@class, arguments);

            var invocationLocal = emitter.CodeBuilder.DeclareLocal(invocationType);

            emitter.CodeBuilder.AddStatement(
                new AssignStatement(
                    invocationLocal,
                    new NewInstanceExpression(constructor, ctorArguments)
                    )
                );

            if (MethodToOverride.ContainsGenericParameters)
            {
                EmitLoadGenricMethodArguments(
                    emitter,
                    MethodToOverride.MakeGenericMethod(genericArguments),
                    invocationLocal
                    );
            }

            if (hasByRefArguments)
            {
                emitter.CodeBuilder.AddStatement(new TryStatement());
            }

            var proceed = new MethodInvocationExpression(
                invocationLocal,
                InvocationMethods.Proceed
                );

            emitter.CodeBuilder.AddStatement(proceed);

            if (hasByRefArguments)
            {
                emitter.CodeBuilder.AddStatement(new FinallyStatement());
            }

            GeneratorUtil.CopyOutAndRefParameters(
                dereferencedArguments,
                invocationLocal,
                MethodToOverride,
                emitter
                );

            if (hasByRefArguments)
            {
                emitter.CodeBuilder.AddStatement(new EndExceptionBlockStatement());
            }

            if (MethodToOverride.ReturnType != typeof(void))
            {
                var getRetVal = new MethodInvocationExpression(
                    invocationLocal,
                    InvocationMethods.GetReturnValue
                    );

                // Emit code to ensure a value type return type is not null, otherwise the cast will cause a null-deref
                if (emitter.ReturnType.IsValueType && !emitter.ReturnType.IsNullableType())
                {
                    LocalReference returnValue = emitter.CodeBuilder.DeclareLocal(typeof(object));
                    emitter.CodeBuilder.AddStatement(new AssignStatement(returnValue, getRetVal));

                    emitter.CodeBuilder.AddStatement(
                        new IfNullExpression(
                            returnValue,
                            new ThrowStatement(
                                typeof(InvalidOperationException),
                                "Interceptors failed to set a return value, or swallowed the exception thrown by the target"
                                )
                            )
                        );
                }

                // Emit code to return with cast from ReturnValue
                emitter.CodeBuilder.AddStatement(
                    new ReturnStatement(new ConvertExpression(emitter.ReturnType, getRetVal))
                    );
            }
            else
            {
                emitter.CodeBuilder.AddStatement(new ReturnStatement());
            }

            return(emitter);
        }
Ejemplo n.º 45
0
        /*
         * Generates an overriden implementation of method inside myType that delegates
         * to a function in a Lua table with the same name, if the function exists. If it
         * doesn't the method calls the base method (or does nothing, in case of interface
         * implementations).
         */
        private void GenerateMethod(TypeBuilder myType, MethodInfo method, MethodAttributes attributes, int methodIndex,
                                    FieldInfo luaTableField, FieldInfo returnTypesField, bool generateBase, out Type[] returnTypes)
        {
            var paramInfo       = method.GetParameters();
            var paramTypes      = new Type[paramInfo.Length];
            var returnTypesList = new List <Type>();

            // Counts out and ref parameters, for later use,
            // and creates the list of return types
            int nOutParams       = 0;
            int nOutAndRefParams = 0;
            var returnType       = method.ReturnType;

            returnTypesList.Add(returnType);

            for (int i = 0; i < paramTypes.Length; i++)
            {
                paramTypes[i] = paramInfo[i].ParameterType;
                if (!paramInfo[i].IsIn && paramInfo[i].IsOut)
                {
                    nOutParams++;
                }

                if (paramTypes[i].IsByRef)
                {
                    returnTypesList.Add(paramTypes[i].GetElementType());
                    nOutAndRefParams++;
                }
            }

            int[] refArgs = new int[nOutAndRefParams];
            returnTypes = returnTypesList.ToArray();

            // Generates a version of the method that calls the base implementation
            // directly, for use by the base field of the table
            if (generateBase)
            {
                var baseMethod = myType.DefineMethod("__luaInterface_base_" + method.Name,
                                                     MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.HideBySig,
                                                     returnType, paramTypes);
                ILGenerator generatorBase = baseMethod.GetILGenerator();
                generatorBase.Emit(OpCodes.Ldarg_0);

                for (int i = 0; i < paramTypes.Length; i++)
                {
                    generatorBase.Emit(OpCodes.Ldarg, i + 1);
                }

                generatorBase.Emit(OpCodes.Call, method);

                if (returnType == typeof(void))
                {
                    generatorBase.Emit(OpCodes.Pop);
                }

                generatorBase.Emit(OpCodes.Ret);
            }

            // Defines the method
            var methodImpl = myType.DefineMethod(method.Name, attributes, returnType, paramTypes);

            // If it's an implementation of an interface tells what method it
            // is overriding
            if (myType.BaseType.Equals(typeof(object)))
            {
                myType.DefineMethodOverride(methodImpl, method);
            }

            ILGenerator generator = methodImpl.GetILGenerator();

            generator.DeclareLocal(typeof(object[])); // original arguments
            generator.DeclareLocal(typeof(object[])); // with out-only arguments removed
            generator.DeclareLocal(typeof(int[]));    // indexes of out and ref arguments

            if (!(returnType == typeof(void)))        // return value
            {
                generator.DeclareLocal(returnType);
            }
            else
            {
                generator.DeclareLocal(typeof(object));
            }

            // Initializes local variables
            generator.Emit(OpCodes.Ldc_I4, paramTypes.Length);
            generator.Emit(OpCodes.Newarr, typeof(object));
            generator.Emit(OpCodes.Stloc_0);
            generator.Emit(OpCodes.Ldc_I4, paramTypes.Length - nOutParams + 1);
            generator.Emit(OpCodes.Newarr, typeof(object));
            generator.Emit(OpCodes.Stloc_1);
            generator.Emit(OpCodes.Ldc_I4, nOutAndRefParams);
            generator.Emit(OpCodes.Newarr, typeof(int));
            generator.Emit(OpCodes.Stloc_2);
            generator.Emit(OpCodes.Ldloc_1);
            generator.Emit(OpCodes.Ldc_I4_0);
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldfld, luaTableField);
            generator.Emit(OpCodes.Stelem_Ref);

            // Stores the arguments into the local variables, as needed
            for (int iArgs = 0, iInArgs = 1, iOutArgs = 0; iArgs < paramTypes.Length; iArgs++)
            {
                generator.Emit(OpCodes.Ldloc_0);
                generator.Emit(OpCodes.Ldc_I4, iArgs);
                generator.Emit(OpCodes.Ldarg, iArgs + 1);

                if (paramTypes[iArgs].IsByRef)
                {
                    if (paramTypes[iArgs].GetElementType().IsValueType)
                    {
                        generator.Emit(OpCodes.Ldobj, paramTypes[iArgs].GetElementType());
                        generator.Emit(OpCodes.Box, paramTypes[iArgs].GetElementType());
                    }
                    else
                    {
                        generator.Emit(OpCodes.Ldind_Ref);
                    }
                }
                else
                {
                    if (paramTypes[iArgs].IsValueType)
                    {
                        generator.Emit(OpCodes.Box, paramTypes[iArgs]);
                    }
                }

                generator.Emit(OpCodes.Stelem_Ref);

                if (paramTypes[iArgs].IsByRef)
                {
                    generator.Emit(OpCodes.Ldloc_2);
                    generator.Emit(OpCodes.Ldc_I4, iOutArgs);
                    generator.Emit(OpCodes.Ldc_I4, iArgs);
                    generator.Emit(OpCodes.Stelem_I4);
                    refArgs[iOutArgs] = iArgs;
                    iOutArgs++;
                }

                if (paramInfo[iArgs].IsIn || (!paramInfo[iArgs].IsOut))
                {
                    generator.Emit(OpCodes.Ldloc_1);
                    generator.Emit(OpCodes.Ldc_I4, iInArgs);
                    generator.Emit(OpCodes.Ldarg, iArgs + 1);

                    if (paramTypes[iArgs].IsByRef)
                    {
                        if (paramTypes[iArgs].GetElementType().IsValueType)
                        {
                            generator.Emit(OpCodes.Ldobj, paramTypes[iArgs].GetElementType());
                            generator.Emit(OpCodes.Box, paramTypes[iArgs].GetElementType());
                        }
                        else
                        {
                            generator.Emit(OpCodes.Ldind_Ref);
                        }
                    }
                    else
                    {
                        if (paramTypes[iArgs].IsValueType)
                        {
                            generator.Emit(OpCodes.Box, paramTypes[iArgs]);
                        }
                    }

                    generator.Emit(OpCodes.Stelem_Ref);
                    iInArgs++;
                }
            }

            // Gets the function the method will delegate to by calling
            // the getTableFunction method of class LuaClassHelper
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldfld, luaTableField);
            generator.Emit(OpCodes.Ldstr, method.Name);
            generator.Emit(OpCodes.Call, classHelper.GetMethod("GetTableFunction"));
            var lab1 = generator.DefineLabel();

            generator.Emit(OpCodes.Dup);
            generator.Emit(OpCodes.Brtrue_S, lab1);
            // Function does not exist, call base method
            generator.Emit(OpCodes.Pop);

            if (!method.IsAbstract)
            {
                generator.Emit(OpCodes.Ldarg_0);

                for (int i = 0; i < paramTypes.Length; i++)
                {
                    generator.Emit(OpCodes.Ldarg, i + 1);
                }

                generator.Emit(OpCodes.Call, method);

                if (returnType == typeof(void))
                {
                    generator.Emit(OpCodes.Pop);
                }

                generator.Emit(OpCodes.Ret);
                generator.Emit(OpCodes.Ldnull);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }

            var lab2 = generator.DefineLabel();

            generator.Emit(OpCodes.Br_S, lab2);
            generator.MarkLabel(lab1);
            // Function exists, call using method callFunction of LuaClassHelper
            generator.Emit(OpCodes.Ldloc_0);
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldfld, returnTypesField);
            generator.Emit(OpCodes.Ldc_I4, methodIndex);
            generator.Emit(OpCodes.Ldelem_Ref);
            generator.Emit(OpCodes.Ldloc_1);
            generator.Emit(OpCodes.Ldloc_2);
            generator.Emit(OpCodes.Call, classHelper.GetMethod("CallFunction"));
            generator.MarkLabel(lab2);

            // Stores the function return value
            if (returnType == typeof(void))
            {
                generator.Emit(OpCodes.Pop);
                generator.Emit(OpCodes.Ldnull);
            }
            else if (returnType.IsValueType)
            {
                generator.Emit(OpCodes.Unbox, returnType);
                generator.Emit(OpCodes.Ldobj, returnType);
            }
            else
            {
                generator.Emit(OpCodes.Castclass, returnType);
            }

            generator.Emit(OpCodes.Stloc_3);

            // Sets return values of out and ref parameters
            for (int i = 0; i < refArgs.Length; i++)
            {
                generator.Emit(OpCodes.Ldarg, refArgs[i] + 1);
                generator.Emit(OpCodes.Ldloc_0);
                generator.Emit(OpCodes.Ldc_I4, refArgs[i]);
                generator.Emit(OpCodes.Ldelem_Ref);

                if (paramTypes[refArgs[i]].GetElementType().IsValueType)
                {
                    generator.Emit(OpCodes.Unbox, paramTypes[refArgs[i]].GetElementType());
                    generator.Emit(OpCodes.Ldobj, paramTypes[refArgs[i]].GetElementType());
                    generator.Emit(OpCodes.Stobj, paramTypes[refArgs[i]].GetElementType());
                }
                else
                {
                    generator.Emit(OpCodes.Castclass, paramTypes[refArgs[i]].GetElementType());
                    generator.Emit(OpCodes.Stind_Ref);
                }
            }

            // Returns
            if (!(returnType == typeof(void)))
            {
                generator.Emit(OpCodes.Ldloc_3);
            }

            generator.Emit(OpCodes.Ret);
        }
Ejemplo n.º 46
0
 public ClassEmitter(TypeBuilder typeBuilder)
     : base(typeBuilder)
 {
 }
    public static void Main()
    {
        // Create an assembly.
        AssemblyName myAssemblyName = new AssemblyName();

        myAssemblyName.Name = "SampleAssembly";

        AssemblyBuilder myAssembly =
            Thread.GetDomain().DefineDynamicAssembly(myAssemblyName,
                                                     AssemblyBuilderAccess.RunAndSave);

        // Create a module. For a single-file assembly the module
        // name is usually the same as the assembly name.
        ModuleBuilder myModule =
            myAssembly.DefineDynamicModule(myAssemblyName.Name,
                                           myAssemblyName.Name + ".dll", true);

        // Define a public class 'Example'.
        TypeBuilder myTypeBuilder =
            myModule.DefineType("Example", TypeAttributes.Public);

        // Create the 'Function1' public method, which takes an integer
        // and returns a string.
        MethodBuilder myMethod = myTypeBuilder.DefineMethod("Function1",
                                                            MethodAttributes.Public | MethodAttributes.Static,
                                                            typeof(String), new Type[] { typeof(int) });

        // Generate IL for 'Function1'. The function body demonstrates
        // assigning an argument to a local variable, assigning a
        // constant string to a local variable, and putting the contents
        // of local variables on the stack.
        ILGenerator myMethodIL = myMethod.GetILGenerator();

        // <Snippet2>
        // Create local variables named myString and myInt.
        LocalBuilder myLB1 = myMethodIL.DeclareLocal(typeof(string));

        myLB1.SetLocalSymInfo("myString");
        Console.WriteLine("local 'myString' type is: {0}", myLB1.LocalType);

        LocalBuilder myLB2 = myMethodIL.DeclareLocal(typeof(int));

        myLB2.SetLocalSymInfo("myInt", 1, 2);
        Console.WriteLine("local 'myInt' type is: {0}", myLB2.LocalType);
        // </Snippet2>

        // Store the function argument in myInt.
        myMethodIL.Emit(OpCodes.Ldarg_0);
        myMethodIL.Emit(OpCodes.Stloc_1);

        // Store a literal value in myString, and return the value.
        myMethodIL.Emit(OpCodes.Ldstr, "string value");
        myMethodIL.Emit(OpCodes.Stloc_0);
        myMethodIL.Emit(OpCodes.Ldloc_0);
        myMethodIL.Emit(OpCodes.Ret);

        // Create "Example" class.
        Type myType1 = myTypeBuilder.CreateType();

        Console.WriteLine("'Example' is created.");

        myAssembly.Save(myAssemblyName.Name + ".dll");
        Console.WriteLine("'{0}' is created.", myAssemblyName.Name + ".dll");

        // Invoke 'Function1' method of 'Example', passing the value 42.
        Object myObject2 = myType1.InvokeMember("Function1",
                                                BindingFlags.InvokeMethod, null, null, new Object[] { 42 });

        Console.WriteLine("Example.Function1 returned: {0}", myObject2);
    }
Ejemplo n.º 48
0
        private static bool TryCreatePropertyDescriptor(ref PropertyDescriptor descriptor)
        {
            try
            {
                PropertyInfo property = descriptor.ComponentType.GetProperty(descriptor.Name);
                if (property == null)
                {
                    return(false);
                }

                lock (properties)
                {
                    PropertyDescriptor foundBuiltAlready;
                    if (properties.TryGetValue(property, out foundBuiltAlready))
                    {
                        descriptor = foundBuiltAlready;
                        return(true);
                    }

                    string      name = "_c" + Interlocked.Increment(ref counter).ToString();
                    TypeBuilder tb   = moduleBuilder.DefineType(name, TypeAttributes.Sealed | TypeAttributes.NotPublic | TypeAttributes.Class | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoClass | TypeAttributes.Public, typeof(ChainingPropertyDescriptor));

                    // ctor calls base
                    ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[] { typeof(PropertyDescriptor) });
                    ILGenerator        il = cb.GetILGenerator();
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Call, typeof(ChainingPropertyDescriptor).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(PropertyDescriptor) }, null));
                    il.Emit(OpCodes.Ret);

                    MethodBuilder mb;
                    MethodInfo    baseMethod;

                    if (property.CanRead)
                    {
                        // obtain the implementation that we want to override
                        baseMethod = typeof(ChainingPropertyDescriptor).GetMethod("GetValue");

                        // create a new method that accepts an object and returns an object (as per the base)
                        mb = tb.DefineMethod(baseMethod.Name,
                                             MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final,
                                             baseMethod.CallingConvention, baseMethod.ReturnType, new Type[] { typeof(object) });

                        // start writing IL into the method
                        il = mb.GetILGenerator();
                        if (property.DeclaringType.IsValueType)
                        {
                            // upbox the object argument into our known (instance) struct type
                            LocalBuilder lb = il.DeclareLocal(property.DeclaringType);
                            il.Emit(OpCodes.Ldarg_1);
                            il.Emit(OpCodes.Unbox_Any, property.DeclaringType);
                            il.Emit(OpCodes.Stloc_0);
                            il.Emit(OpCodes.Ldloca_S, lb);
                        }
                        else
                        {
                            // cast the object argument into our known class type
                            il.Emit(OpCodes.Ldarg_1);
                            il.Emit(OpCodes.Castclass, property.DeclaringType);
                        }

                        // call the "get" method
                        il.Emit(OpCodes.Callvirt, property.GetGetMethod());

                        if (property.PropertyType.IsValueType)
                        {
                            // box it from the known (value) struct type
                            il.Emit(OpCodes.Box, property.PropertyType);
                        }

                        // return the value
                        il.Emit(OpCodes.Ret);
                        // signal that this method should override the base
                        tb.DefineMethodOverride(mb, baseMethod);
                    }

                    bool supportsChangeEvents = descriptor.SupportsChangeEvents, isReadOnly = descriptor.IsReadOnly;

                    // override SupportsChangeEvents
                    baseMethod = typeof(ChainingPropertyDescriptor).GetProperty("SupportsChangeEvents").GetGetMethod();
                    mb         = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, Type.EmptyTypes);
                    il         = mb.GetILGenerator();

                    if (supportsChangeEvents)
                    {
                        il.Emit(OpCodes.Ldc_I4_1);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldc_I4_0);
                    }

                    il.Emit(OpCodes.Ret);
                    tb.DefineMethodOverride(mb, baseMethod);

                    // override IsReadOnly
                    baseMethod = typeof(ChainingPropertyDescriptor).GetProperty("IsReadOnly").GetGetMethod();
                    mb         = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, Type.EmptyTypes);
                    il         = mb.GetILGenerator();

                    if (isReadOnly)
                    {
                        il.Emit(OpCodes.Ldc_I4_1);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldc_I4_0);
                    }

                    il.Emit(OpCodes.Ret);
                    tb.DefineMethodOverride(mb, baseMethod);

                    /*  REMOVED: PropertyType, ComponentType; actually *adds* time overriding these
                     * // override PropertyType
                     * baseMethod = typeof(ChainingPropertyDescriptor).GetProperty("PropertyType").GetGetMethod();
                     * mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, Type.EmptyTypes);
                     * il = mb.GetILGenerator();
                     * il.Emit(OpCodes.Ldtoken, descriptor.PropertyType);
                     * il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
                     * il.Emit(OpCodes.Ret);
                     * tb.DefineMethodOverride(mb, baseMethod);
                     *
                     * // override ComponentType
                     * baseMethod = typeof(ChainingPropertyDescriptor).GetProperty("ComponentType").GetGetMethod();
                     * mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, Type.EmptyTypes);
                     * il = mb.GetILGenerator();
                     * il.Emit(OpCodes.Ldtoken, descriptor.ComponentType);
                     * il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
                     * il.Emit(OpCodes.Ret);
                     * tb.DefineMethodOverride(mb, baseMethod);
                     */

                    // for classes, implement write (would be lost in unbox for structs)
                    if (!property.DeclaringType.IsValueType)
                    {
                        if (!isReadOnly && property.CanWrite)
                        {
                            // override set method
                            baseMethod = typeof(ChainingPropertyDescriptor).GetMethod("SetValue");
                            mb         = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, baseMethod.CallingConvention, baseMethod.ReturnType, new Type[] { typeof(object), typeof(object) });
                            il         = mb.GetILGenerator();
                            il.Emit(OpCodes.Ldarg_1);
                            il.Emit(OpCodes.Castclass, property.DeclaringType);
                            il.Emit(OpCodes.Ldarg_2);

                            if (property.PropertyType.IsValueType)
                            {
                                il.Emit(OpCodes.Unbox_Any, property.PropertyType);
                            }
                            else
                            {
                                il.Emit(OpCodes.Castclass, property.PropertyType);
                            }

                            il.Emit(OpCodes.Callvirt, property.GetSetMethod());
                            il.Emit(OpCodes.Ret);
                            tb.DefineMethodOverride(mb, baseMethod);
                        }

                        if (supportsChangeEvents)
                        {
                            EventInfo ei = property.DeclaringType.GetEvent(property.Name + "Changed");
                            if (ei != null)
                            {
                                baseMethod = typeof(ChainingPropertyDescriptor).GetMethod("AddValueChanged");
                                mb         = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, new Type[] { typeof(object), typeof(EventHandler) });
                                il         = mb.GetILGenerator();
                                il.Emit(OpCodes.Ldarg_1);
                                il.Emit(OpCodes.Castclass, property.DeclaringType);
                                il.Emit(OpCodes.Ldarg_2);
                                il.Emit(OpCodes.Callvirt, ei.GetAddMethod());
                                il.Emit(OpCodes.Ret);
                                tb.DefineMethodOverride(mb, baseMethod);

                                baseMethod = typeof(ChainingPropertyDescriptor).GetMethod("RemoveValueChanged");
                                mb         = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, new Type[] { typeof(object), typeof(EventHandler) });
                                il         = mb.GetILGenerator();
                                il.Emit(OpCodes.Ldarg_1);
                                il.Emit(OpCodes.Castclass, property.DeclaringType);
                                il.Emit(OpCodes.Ldarg_2);
                                il.Emit(OpCodes.Callvirt, ei.GetRemoveMethod());
                                il.Emit(OpCodes.Ret);
                                tb.DefineMethodOverride(mb, baseMethod);
                            }
                        }
                    }

                    PropertyDescriptor newDesc = tb.CreateType().GetConstructor(new Type[] { typeof(PropertyDescriptor) })
                                                 .Invoke(new object[] { descriptor }) as PropertyDescriptor;

                    if (newDesc == null)
                    {
                        return(false);
                    }

                    descriptor = newDesc;
                    properties.Add(property, descriptor);

                    return(true);
                }
            }
            catch
            {
                return(false);
            }
        }
 /// <summary>
 /// Creates a method builder for building an implementation of a native calling method.
 /// </summary>
 /// <param name="typeBuilder">The type builder to create the method in.</param>
 /// <param name="context">The IL generation context.</param>
 /// <returns>Create created method builder.</returns>
 protected abstract MethodBuilder CreateMethodBuilder(TypeBuilder typeBuilder, NativeIlGenContext context);
Ejemplo n.º 50
0
        public void Acquire(TypeBuilder typeBuilder, ILGenerator il, string fieldName)
        {
            if (m_Value is string)
            {
                string toParse = (string)m_Value;

                if (!m_Type.IsValueType && toParse == "null")
                {
                    m_Value = null;
                }
                else if (m_Type == typeof(string))
                {
                    if (toParse == @"@""null""")
                    {
                        toParse = "null";
                    }

                    m_Value = toParse;
                }
                else if (m_Type.IsEnum)
                {
                    m_Value = Enum.Parse(m_Type, toParse, true);
                }
                else
                {
                    MethodInfo parseMethod = null;
                    object[]   parseArgs   = null;

                    MethodInfo parseNumber = m_Type.GetMethod(
                        "Parse",
                        BindingFlags.Public | BindingFlags.Static,
                        null,
                        new Type[] { typeof(string), typeof(NumberStyles) },
                        null
                        );

                    if (parseNumber != null)
                    {
                        NumberStyles style = NumberStyles.Integer;

                        if (Insensitive.StartsWith(toParse, "0x"))
                        {
                            style   = NumberStyles.HexNumber;
                            toParse = toParse.Substring(2);
                        }

                        parseMethod = parseNumber;
                        parseArgs   = new object[] { toParse, style };
                    }
                    else
                    {
                        MethodInfo parseGeneral = m_Type.GetMethod(
                            "Parse",
                            BindingFlags.Public | BindingFlags.Static,
                            null,
                            new Type[] { typeof(string) },
                            null
                            );

                        parseMethod = parseGeneral;
                        parseArgs   = new object[] { toParse };
                    }

                    if (parseMethod != null)
                    {
                        m_Value = parseMethod.Invoke(null, parseArgs);

                        if (!m_Type.IsPrimitive)
                        {
                            m_Field = typeBuilder.DefineField(
                                fieldName,
                                m_Type,
                                FieldAttributes.Private | FieldAttributes.InitOnly
                                );

                            il.Emit(OpCodes.Ldarg_0);

                            il.Emit(OpCodes.Ldstr, toParse);

                            if (parseArgs.Length == 2)                               // dirty evil hack :-(
                            {
                                il.Emit(OpCodes.Ldc_I4, (int)parseArgs[1]);
                            }

                            il.Emit(OpCodes.Call, parseMethod);
                            il.Emit(OpCodes.Stfld, m_Field);
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException(
                                  String.Format(
                                      "Unable to convert string \"{0}\" into type '{1}'.",
                                      m_Value,
                                      m_Type
                                      )
                                  );
                    }
                }
            }
        }
Ejemplo n.º 51
0
        private void GenerateNestedType(ref GeneratorContext ctx, MethodInfo method, MethodInfo methodImpl)
        {
            int idx;

            lock (indexLock)
            {
                idx = index++;
            }

            TypeBuilder builder = ctx.Module.DefineType($"<>c__CacheDelegate_{method.Name}_{idx}",
                                                        TypeAttributes.Class |
                                                        TypeAttributes.NotPublic |
                                                        TypeAttributes.AnsiClass |
                                                        TypeAttributes.AutoClass |
                                                        TypeAttributes.Sealed |
                                                        TypeAttributes.BeforeFieldInit);

            builder.SetCustomAttribute(new CustomAttributeBuilder(
                                           typeof(CompilerGeneratedAttribute)
#if NETSTANDARD1_6
                                           .GetTypeInfo()
#endif
                                           .GetConstructor(Type.EmptyTypes),
                                           new object[0]));

            // add generic parameters
            GenericTypeParameterBuilder[] genPar = null;
            if (method.IsGenericMethod)
            {
                genPar = builder.DefineGenericParameters(ctx.GenericParameterNames);
                for (int i = 0; i < ctx.GenericParameterNames.Length; i++)
                {
                    genPar[i].SetGenericParameterAttributes(ctx.GenericArguments[i]
#if NETSTANDARD1_6
                                                            .GetTypeInfo()
#endif
                                                            .GenericParameterAttributes);
                    genPar[i].SetInterfaceConstraints(ctx.GenericArguments[i]
#if NETSTANDARD1_6
                                                      .GetTypeInfo()
#endif
                                                      .GetGenericParameterConstraints());
                }
            }

            //FieldBuilder asyncState = null;
            //FieldBuilder asyncBuilder = null;
            //if (isAsync)
            //{
            //	asyncState = nested.DefineField("<>1__state", typeof(int), FieldAttributes.Public);
            //	asyncBuilder = nested.DefineField("<>t__builder",
            //		typeof(AsyncTaskMethodBuilder<>).MakeGenericType(method.ReturnType),
            //		FieldAttributes.Public);
            //}

            #region Generate nested fields and key array

            List <string> parameters = method.GetParameters()
                                       .Where(o => o.GetCustomAttribute <CacheIgnoreAttribute>() == null)
                                       .Select(o => o.Name).ToList();
            parameters = methodImpl.GetParameters()
                         .Where(o => o.GetCustomAttribute <CacheIgnoreAttribute>() == null)
                         .Where(o => parameters.Contains(o.Name))
                         .Select(o => o.Name).ToList();

            foreach (ParameterInfo par in method.GetParameters())
            {
                FieldBuilder field = null;
#if !NETSTANDARD1_6
                if (genPar != null)
                {
                    GenericTypeParameterBuilder b = genPar.SingleOrDefault(o => o.Name == par.ParameterType.Name);
                    if (b != null)
                    {
                        field = builder.DefineField(par.Name, b, FieldAttributes.Public);
                    }
                }
#else
#endif
                //if (field == null)
                field = builder.DefineField(par.Name, par.ParameterType, FieldAttributes.Public);

                ctx.NestedFields.Add(field);
                if (parameters.Contains(field.Name))
                {
                    ctx.NestedKeyFields.Add(field);
                }
            }

            #endregion

            ctx.NestedMethod = builder.DefineMethod($"<{method.Name}>b__0",
                                                    MethodAttributes.Assembly |
                                                    MethodAttributes.HideBySig,
                                                    method.ReturnType, new[] { ctx.ServiceBase });

            #region Delegate code

            ParameterBuilder parBuilder = ctx.NestedMethod.DefineParameter(1, ParameterAttributes.None, "svc");
            ILGenerator      il         = ctx.NestedMethod.GetILGenerator();
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Callvirt, NonCachedMethod(ctx.ServiceBase));
            foreach (FieldBuilder item in ctx.NestedFields)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, item);
            }
            il.Emit(OpCodes.Callvirt, methodImpl);
            il.Emit(OpCodes.Ret);

            builder.DefineDefaultConstructor(MethodAttributes.Public);

            Type result = builder.CreateTypeInfo().AsType();

            if (result
#if NETSTANDARD1_6
                .GetTypeInfo()
#endif
                .IsGenericTypeDefinition)
            {
                result.MakeGenericType(method.GetGenericArguments());
            }

            ctx.NestedType = result;

            #endregion
        }
Ejemplo n.º 52
0
 void ICondition.Construct(TypeBuilder typeBuilder, ILGenerator il, int index)
 {
 }
Ejemplo n.º 53
0
        public MethodInfo GetMethod(Function f)
        {
            MethodInfo result;
            if (_methods.TryGetValue(f, out result))
                return result;

            var method = f as Method;

            if (method != null && method.IsGenericParameterization)
            {
                var md = GetMethod(method.GenericDefinition);

                var targs = new Type[method.GenericArguments.Length];
                for (int i = 0; i < targs.Length; i++)
                    targs[i] = GetType(method.GenericArguments[i]);

                result = md.MakeGenericMethod(targs);

                _methods.Add(f, result);
                return result;
            }

            var type = GetType(f.DeclaringType);

            if (type.IsTypeBuilder())
            {
                if (f != f.MasterDefinition) // Should always be true
                    result = TypeBuilder.GetMethod(type, GetMethod(f.MasterDefinition));
            }
            else if (f is Cast)
            {
                var returnType = GetType(f.ReturnType);
                var operandType = GetType(f.Parameters[0].Type);

                foreach (var mi in type.GetMethods(_memberFlags))
                {
                    var paramList = mi.GetParameters();

                    if (mi.Name != "op_Explicit" && mi.Name != "op_Implicit" ||
                        paramList.Length != 1 ||
                        paramList[0].ParameterType != operandType ||
                        mi.ReturnType != returnType)
                        continue;

                    result = mi;
                    break;
                }
            }
            else if (method != null && method.IsGenericDefinition)
            {
                foreach (var mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
                {
                    if (!mi.IsGenericMethodDefinition ||
                        mi.Name != method.UnoName)
                        continue;

                    var paramList = mi.GetParameters();
                    if (paramList.Length != method.Parameters.Length)
                        continue;

                    var typeParams = mi.GetGenericMethodDefinition().GetGenericArguments();
                    if (typeParams.Length != method.GenericParameters.Length)
                        continue;

                    // TODO: Avoid copying types
                    var oldTypes = new Dictionary<DataType, Type>();
                    foreach (var e in _types)
                        oldTypes.Add(e.Key, e.Value);

                    for (int i = 0; i < typeParams.Length; i++)
                        _types[method.GenericParameters[i]] = typeParams[i];

                    if (GetType(method.ReturnType) == mi.ReturnType && ParameterTypesEquals(mi.GetParameters(), GetParameterTypes(method.Parameters)))
                    {
                        result = mi;
                        break;
                    }

                    // Not found - reset types
                    _types.Clear();
                    foreach (var e in oldTypes)
                        _types.Add(e.Key, e.Value);
                }
            }
            else
            {
                var name = f.UnoName;

                if (type == System_String)
                    switch (name)
                    {
                        case "get_Item":
                            name = "get_Chars";
                            break;
                        case "op_Addition":
                            name = "Concat";
                            break;
                    }

                var paramTypes = GetParameterTypes(f.Parameters);

                try
                {
                    result = type.GetMethod(name, _memberFlags, _binder, paramTypes, null);

                    if (result == null && method != null)
                    {
                        if (method.ImplementedMethod != null)
                            TryGetImplementedMethod(type, method.ImplementedMethod.Name, paramTypes, out result);
                        else
                            TryGetInterfaceMethod(type, name, paramTypes, out result);
                    }
                }
                catch (ArgumentException e)
                {
                    ThrowPrebuiltSignatureException(e, f, f.Parameters, paramTypes);
                }
            }

            if (result == null)
                throw new FatalException(f.Source, ErrorCode.E0000, ".NET method not resolved: " + f + " [flags: " + f.Stats + "]");

            _methods.Add(f, result);
            return result;
        }
Ejemplo n.º 54
0
 public override void Construct(TypeBuilder typeBuilder, ILGenerator il, int index)
 {
     m_Value.Acquire(typeBuilder, il, "v" + index);
 }
Ejemplo n.º 55
0
        public static void OrElse_NoMethod_TrueOperatorIncorrectMethod_ThrowsArgumentException(TypeBuilder builder, Type returnType, Type[] parameterTypes)
        {
            MethodBuilder opTrue = builder.DefineMethod("op_True", MethodAttributes.SpecialName | MethodAttributes.Static, returnType, parameterTypes);

            opTrue.GetILGenerator().Emit(OpCodes.Ret);

            MethodBuilder opFalse = builder.DefineMethod("op_False", MethodAttributes.SpecialName | MethodAttributes.Static, typeof(bool), new Type[] { builder.AsType() });

            opFalse.GetILGenerator().Emit(OpCodes.Ret);

            MethodBuilder method = builder.DefineMethod("op_BitwiseOr", MethodAttributes.Public | MethodAttributes.Static, builder.AsType(), new Type[] { builder.AsType(), builder.AsType() });

            method.GetILGenerator().Emit(OpCodes.Ret);

            TypeInfo createdType = builder.CreateTypeInfo();
            object   obj         = Activator.CreateInstance(createdType.AsType());

            Assert.Throws <ArgumentException>(null, () => Expression.OrElse(Expression.Constant(obj), Expression.Constant(obj)));
        }
Ejemplo n.º 56
0
 public abstract void Construct(TypeBuilder typeBuilder, ILGenerator il, int index);
Ejemplo n.º 57
0
        private unsafe static void OverrideDynamicInvokeImpl(TypeBuilder delegateBuilder, MethodInfo invokeMethod, Type[] parameterTypes, Type resultType)
        {
            var dynamicInvokeMethodBuilder = delegateBuilder.DefineMethod(
                "DynamicInvokeImpl",
                MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                CallingConventions.Standard,
                typeof(object),
                new Type[] { typeof(object[]) });

            var iLGen = dynamicInvokeMethodBuilder.GetILGenerator();

            iLGen.LoadArgument(0);

            for (int i = 0; i < parameterTypes.Length; i++)
            {
                var item = parameterTypes[i];

                iLGen.LoadArgument(1);
                iLGen.LoadConstant(i);

                if (item.IsByRef)
                {
                    item = item.GetElementType();

                    iLGen.LoadReferenceElement();
                    iLGen.CastClass(item);

                    if (item.IsValueType)
                    {
                        iLGen.LoadConstant(sizeof(IntPtr));
                        iLGen.Add();

                        continue;
                    }

                    iLGen.Pop();
                    iLGen.LoadArgument(1);
                    iLGen.LoadConstant(i);
                    iLGen.LoadElementAddress(typeof(object));

                    continue;
                }

                iLGen.LoadReferenceElement();
                iLGen.CastClass(item);

                if (item.IsValueType)
                {
                    iLGen.UnboxAny(item);
                }
            }

            iLGen.Call(invokeMethod);

            if (resultType == typeof(void))
            {
                iLGen.LoadNull();
            }
            else if (resultType.IsValueType)
            {
                iLGen.Box(resultType);
            }

            iLGen.Return();
        }
Ejemplo n.º 58
0
        private unsafe static void ImplObjectInterface(TypeBuilder delegateBuilder, MethodInfo invokeMethod, Type[] parameterTypes, Type resultType)
        {
            bool isAllEqualObject = true;

            foreach (var item in parameterTypes)
            {
                if (item != typeof(object))
                {
                    isAllEqualObject = false;

                    break;
                }
            }

            if (isAllEqualObject)
            {
                return;
            }

            Type[] objectTypes = new Type[parameterTypes.Length];

            for (int i = 0; i < objectTypes.Length; i++)
            {
                objectTypes[i] = typeof(object);
            }

            Type interfaceType;

            if (resultType == typeof(void))
            {
                if (parameterTypes.Length >= ActionInterfaces.Length)
                {
                    return;
                }

                interfaceType = ActionInterfaces[parameterTypes.Length];

                if (interfaceType.IsGenericTypeDefinition)
                {
                    interfaceType = interfaceType.MakeGenericType(objectTypes);
                }
            }
            else
            {
                if (parameterTypes.Length >= FuncInterfaces.Length)
                {
                    return;
                }

                interfaceType = FuncInterfaces[parameterTypes.Length];

                if (interfaceType.IsGenericTypeDefinition)
                {
                    var genericTypes = objectTypes;

                    Array.Resize(ref genericTypes, objectTypes.Length + 1);

                    genericTypes[objectTypes.Length] = typeof(object);

                    interfaceType = interfaceType.MakeGenericType(genericTypes);
                }
            }

            delegateBuilder.AddInterfaceImplementation(interfaceType);

            var interfaceInvoke = interfaceType.GetMethod("Invoke");

            var invokeBuilder = delegateBuilder.DefineMethod(
                "InvokeImpl",
                MethodAttributes.Public | MethodAttributes.Virtual,
                CallingConventions.Standard,
                interfaceInvoke.ReturnType,
                objectTypes);

            var iLGen = invokeBuilder.GetILGenerator();

            iLGen.LoadArgument(0);

            for (int i = 0; i < parameterTypes.Length; ++i)
            {
                var item = parameterTypes[i];

                iLGen.LoadArgument(i + 1);

                if (item.IsByRef)
                {
                    item = typeof(IntPtr);
                }

                iLGen.CastClass(item);

                if (item.IsValueType)
                {
                    iLGen.UnboxAny(item);
                }
            }

            iLGen.Call(invokeMethod);

            if (resultType.IsValueType)
            {
                iLGen.Box(resultType);
            }

            iLGen.Return();

            delegateBuilder.DefineMethodOverride(invokeBuilder, interfaceInvoke);
        }
Ejemplo n.º 59
0
        static void DefineUnaryRequestDelegate(ILGenerator staticContructorGenerator, TypeBuilder typeBuilder, Type interfaceType, MethodDefinition definition)
        {
            // static ResponseContext _Method(RequestContext context);
            MethodBuilder method;
            {
                method = typeBuilder.DefineMethod("_" + definition.MethodInfo.Name, MethodAttributes.Private | MethodAttributes.Static,
                                                  typeof(ResponseContext),
                                                  new[] { typeof(RequestContext) });
                var il = method.GetILGenerator();

                // CreateResponseContext<TRequest, TResponse>(Context, Method);
                var createMethod = typeof(MagicOnionClientBase)
                                   .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
                                   .Where(x => x.Name == "CreateResponseContext")
                                   .OrderByDescending(x => x.GetGenericArguments().Length)
                                   .First()
                                   .MakeGenericMethod(definition.RequestType, definition.ResponseType);

                il.Emit(OpCodes.Ldarg_0);                        // context
                il.Emit(OpCodes.Ldsfld, definition.FieldMethod); // method
                il.Emit(OpCodes.Call, createMethod);
                il.Emit(OpCodes.Ret);
            }

            // static readonly Func<RequestContext, ResposneContext> methodDelegate = _Method;
            {
                definition.UnaryRequestDelegate = typeBuilder.DefineField(definition.MethodInfo.Name + "Delegate", typeof(Func <RequestContext, ResponseContext>), FieldAttributes.Private | FieldAttributes.Static);

                var il = staticContructorGenerator;
                il.Emit(OpCodes.Ldnull);
                il.Emit(OpCodes.Ldftn, method);
                il.Emit(OpCodes.Newobj, typeof(Func <RequestContext, ResponseContext>).GetConstructors()[0]);
                il.Emit(OpCodes.Stsfld, definition.UnaryRequestDelegate);
            }
        }
Ejemplo n.º 60
0
        private static void ImplInstanceDynamicImpl(TypeBuilder delegateBuilder, MethodInfo invokeMethod, Type[] parameterTypes, Type resultType)
        {
            if (!(parameterTypes.Length != 0 &&                                                  // Must one or more Parameters.
                  (parameterTypes[0].IsClass || parameterTypes[0].IsInterface ||                 // First Parameter Is Class Or Interface.
                   (parameterTypes[0].IsByRef && parameterTypes[0].GetElementType().IsValueType) // Or First Parameter Is ValueType Ref.
                  )))
            {
                return;
            }

            GetParametersTypes(Method_IInstanceDynamicInvoker_Invoke, out var invokerParameterTypes, out var invokerReturnType, true);

            delegateBuilder.AddInterfaceImplementation(Type_IInstanceDynamicInvoker);

            var dynamicInvokeMethodBuilder = delegateBuilder.DefineMethod(
                "DynamicInvokeImpl",
                MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                CallingConventions.Standard,
                invokerReturnType,
                invokerParameterTypes);

            var iLGen = dynamicInvokeMethodBuilder.GetILGenerator();

            iLGen.LoadArgument(0);
            iLGen.LoadArgument(1);

            for (int i = 1; i < parameterTypes.Length; i++)
            {
                var item = parameterTypes[i];

                iLGen.LoadArgument(2);
                iLGen.LoadConstant(i - 1);

                iLGen.LoadReferenceElement();

                if (item.IsByRef)
                {
                    item = item.GetElementType();

                    iLGen.CastClass(item);

                    if (item.IsValueType)
                    {
                        iLGen.Call(Method_GetStructRef);

                        continue;
                    }

                    iLGen.Pop();
                    iLGen.LoadArgument(2);
                    iLGen.LoadConstant(i - 1);
                    iLGen.LoadElementAddress(typeof(object));

                    continue;
                }

                if (item.IsValueType)
                {
                    iLGen.UnboxAny(item);
                }
            }

            iLGen.Call(invokeMethod);

            if (resultType == typeof(void))
            {
                iLGen.LoadNull();
            }
            else if (resultType.IsValueType)
            {
                iLGen.Box(resultType);
            }

            iLGen.Return();


            delegateBuilder.DefineMethodOverride(dynamicInvokeMethodBuilder, Method_IInstanceDynamicInvoker_Invoke);
        }