Пример #1
1
        public static MethodBuilder DefineMethod(this TypeBuilder typeBuilder, MethodInfo method, MethodAttributes? attributes = null, ParameterInfo[] parameters = null)
        {
            Type[] parametersTypes = null;
            MethodBuilder methodBuilder = null;

            parameters = parameters ?? method.GetParameters();
            parametersTypes = parameters.ToArray(parameter => parameter.ParameterType);
            attributes = attributes ?? method.Attributes & ~MethodAttributes.Abstract;
            methodBuilder = typeBuilder.DefineMethod(method.Name, attributes.Value, method.ReturnType, parametersTypes);

            parameters.ForEach(1, (parameter, i) => {
                var parameterBuilder = methodBuilder.DefineParameter(i, parameter.Attributes, parameter.Name);

                if (parameter.IsDefined<ParamArrayAttribute>()) {
                    parameterBuilder.SetCustomAttribute<ParamArrayAttribute>();
                }
                else if (parameter.IsOut) {
                    parameterBuilder.SetCustomAttribute<OutAttribute>();
                }
                else if (parameter.IsOptional) {
                    parameterBuilder.SetCustomAttribute<OptionalAttribute>()
                                    .SetConstant(parameter.DefaultValue);
                }
            });

            return methodBuilder;
        }
 public NonTargetedMethodMetadata(MethodInfo method)
     : base(method)
 {
     _methodAttributes = method.Attributes;
     _methodAttributes &= ~MethodAttributes.Abstract;
     _methodAttributes &= ~MethodAttributes.NewSlot;
 }
Пример #3
0
 public EventKey( TypeKey typeKey, string type, string name, MethodAttributes addMethodAttributes)
 {
     this.typeKey = typeKey;
     this.type = type;
     this.name = name;
     this.addMethodAttributes = addMethodAttributes;
 }
        public static MethodDefinition AddPropertyGetter(
            PropertyDefinition property
            , MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual
            , FieldDefinition backingField = null)
        {
            if (backingField == null)
            {
                // TODO: Try and find existing friendly named backingFields first.
                backingField = AddPropertyBackingField(property);
            }

            var methodName = "get_" + property.Name;
            var getter = new MethodDefinition(methodName, methodAttributes, property.PropertyType)
            {
                IsGetter = true,
                Body = {InitLocals = true},
            };

            getter.Body.Variables.Add(new VariableDefinition(property.PropertyType));

            var returnStart = Instruction.Create(OpCodes.Ldloc_0);
            getter.Body.Instructions.Append(
                Instruction.Create(OpCodes.Ldarg_0),
                Instruction.Create(OpCodes.Ldfld, backingField),
                Instruction.Create(OpCodes.Stloc_0),
                Instruction.Create(OpCodes.Br_S, returnStart),
                returnStart,
                Instruction.Create(OpCodes.Ret)
                );        
                
            property.GetMethod = getter;
            property.DeclaringType.Methods.Add(getter);
            return getter;
        }
Пример #5
0
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="typeBuilder">Type builder</param>
 /// <param name="attributes">Attributes for the constructor (public, private, etc.)</param>
 /// <param name="parameters">Parameter types for the constructor</param>
 /// <param name="callingConventions">Calling convention for the constructor</param>
 public ConstructorBuilder(TypeBuilder typeBuilder, MethodAttributes attributes,
                           IEnumerable<Type> parameters, CallingConventions callingConventions)
 {
     if (typeBuilder == null)
         throw new ArgumentNullException("typeBuilder");
     Type = typeBuilder;
     Attributes = attributes;
     Parameters = new List<ParameterBuilder>();
     Parameters.Add(new ParameterBuilder(null, 0));
     if (parameters != null)
     {
         int x = 1;
         foreach (var parameterType in parameters)
         {
             Parameters.Add(new ParameterBuilder(parameterType, x));
             ++x;
         }
     }
     CallingConventions = callingConventions;
     Builder = Type.Builder.DefineConstructor(attributes, callingConventions,
                                              (parameters != null && parameters.Count() > 0)
                                                  ? parameters.ToArray()
                                                  : System.Type.EmptyTypes);
     Generator = Builder.GetILGenerator();
 }
Пример #6
0
    private void CheckSupport(EventDefinition eventInfo, MethodAttributes methodAttributes)
    {
      EventAttributes eventAttributes = eventInfo.Attributes;

      string warningTemplate = "Event '" + name + "' has unsupported attribute: '{0}'.";

      // in order to reduce output we warn only about important attributes which are not currently
      // supported:

      // EventDefinition properties

      // EventAttributes
      //if ((eventAttributes & EventAttributes.RTSpecialName) != 0) { Logger.Warning(warningTemplate, "RTSpecialName"); }
      //if ((eventAttributes & EventAttributes.SpecialName) != 0) { Logger.Warning(warningTemplate, "SpecialName"); }

      // MethodAttributes
      //if ((methodAttributes & MethodAttributes.CheckAccessOnOverride) != 0) { Logger.Warning(warningTemplate, "CheckAccessOnOverride"); }
      //if ((methodAttributes & MethodAttributes.FamANDAssem) != 0) { Logger.Warning(warningTemplate, "FamANDAssem"); }
      // TODO: support this: if ((methodAttributes & MethodAttributes.HasSecurity) != 0) { Logger.Warning(warningTemplate, "HasSecurity"); }
      //if ((methodAttributes & MethodAttributes.HideBySig) != 0) { Logger.Warning(warningTemplate, "HideBySig"); }
      //if ((methodAttributes & MethodAttributes.NewSlot) != 0) { Logger.Warning(warningTemplate, "NewSlot"); }
      // TODO: support this: if ((methodAttributes & MethodAttributes.PinvokeImpl) != 0) { Logger.Warning(warningTemplate, "PinvokeImpl"); }
      //if ((methodAttributes & MethodAttributes.PrivateScope) != 0) { Logger.Warning(warningTemplate, "PrivateScope"); }
      // TODO: support this: if ((methodAttributes & MethodAttributes.RequireSecObject) != 0) { Logger.Warning(warningTemplate, "RequiresSecObject"); }
      //if ((methodAttributes & MethodAttributes.ReuseSlot) != 0) { Logger.Warning(warningTemplate, "ReuseSlot"); }
      //if ((methodAttributes & MethodAttributes.RTSpecialName) != 0) { Logger.Warning(warningTemplate, "RTSpecialName"); }
      //if ((methodAttributes & MethodAttributes.SpecialName) != 0) { Logger.Warning(warningTemplate, "SpecialName"); }
      // TODO: support this: if ((methodAttributes & MethodAttributes.UnmanagedExport) != 0) { Logger.Warning(warningTemplate, "UnmanagedExport"); }
    }
 public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
 {
     _Name = Name;
     _DeclaringType = DeclaringType;
     _ReturnType = ReturnType;
     _MethodAttributes = MethodAttributes;
 }
 public MethodBuilder(TypeBuilder TypeBuilder, string Name,
     MethodAttributes Attributes, IEnumerable<Type> Parameters, Type ReturnType)
     : base()
 {
     Contract.Requires<ArgumentNullException>(TypeBuilder!=null,"TypeBuilder");
     Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(Name),"Name");
     this.Name = Name;
     this.Type = TypeBuilder;
     this.Attributes = Attributes;
     this.ReturnType = (ReturnType == null) ? typeof(void) : ReturnType;
     this.Parameters = new List<ParameterBuilder>();
     this.Parameters.Add(new ParameterBuilder(null, 0));
     if (Parameters != null)
     {
         int x = 1;
         if (Name.StartsWith("set_", StringComparison.InvariantCulture))
             x = -1;
         foreach (Type ParameterType in Parameters)
         {
             this.Parameters.Add(new ParameterBuilder(ParameterType, x));
             ++x;
         }
     }
     Builder = Type.Builder.DefineMethod(Name, Attributes, ReturnType,
         (Parameters != null && Parameters.Count() > 0) ? Parameters.ToArray() : System.Type.EmptyTypes);
     Generator = Builder.GetILGenerator();
 }
Пример #9
0
 public MethodDefinition(string name, MethodAttributes attributes, TypeReference returnType)
     : base(name, returnType)
 {
     this.attributes = (ushort) attributes;
     this.HasThis = !this.IsStatic;
     this.token = new MetadataToken (TokenType.Method);
 }
Пример #10
0
#pragma warning restore 169, 414

		internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt)
		{
			this.name = name;
			this.attrs = attributes;
			this.call_conv = callingConvention;
			this.rtype = returnType;
			this.returnModReq = returnModReq;
			this.returnModOpt = returnModOpt;
			this.paramModReq = paramModReq;
			this.paramModOpt = paramModOpt;
			// The MSDN docs does not specify this, but the MS MethodBuilder
			// appends a HasThis flag if the method is not static
			if ((attributes & MethodAttributes.Static) == 0)
 				this.call_conv |= CallingConventions.HasThis;
			if (parameterTypes != null) {
				for (int i = 0; i < parameterTypes.Length; ++i)
					if (parameterTypes [i] == null)
						throw new ArgumentException ("Elements of the parameterTypes array cannot be null", "parameterTypes");

				this.parameters = new Type [parameterTypes.Length];
				System.Array.Copy (parameterTypes, this.parameters, parameterTypes.Length);
			}
			type = tb;
			table_idx = get_next_table_index (this, 0x06, true);

			((ModuleBuilder)tb.Module).RegisterToken (this, GetToken ().Token);
		}
Пример #11
0
 public PropertyKey( TypeKey typeKey, PropertyDefinition prop )
 {
     this.typeKey = typeKey;
     this.type = prop.PropertyType.FullName;
     this.name = prop.Name;
     this.getterMethodAttributes = prop.GetMethod != null ? prop.GetMethod.Attributes : 0;
 }
Пример #12
0
 public MethodBuilder(TypeBuilder typeBuilder, string name,
                      MethodAttributes attributes, IEnumerable<Type> parameters, Type returnType)
 {
     if (typeBuilder == null)
         throw new ArgumentNullException("typeBuilder");
     if (string.IsNullOrEmpty(name))
         throw new ArgumentNullException("name");
     Name = name;
     Type = typeBuilder;
     Attributes = attributes;
     ReturnType = (returnType == null) ? typeof (void) : returnType;
     Parameters = new List<ParameterBuilder>();
     Parameters.Add(new ParameterBuilder(null, 0));
     if (parameters != null)
     {
         int x = 1;
         if (name.StartsWith("set_", StringComparison.InvariantCulture))
             x = -1;
         foreach (var parameterType in parameters)
         {
             Parameters.Add(new ParameterBuilder(parameterType, x));
             ++x;
         }
     }
     Builder = Type.Builder.DefineMethod(name, attributes, returnType,
                                         (parameters != null && parameters.Count() > 0)
                                             ? parameters.ToArray()
                                             : System.Type.EmptyTypes);
     Generator = Builder.GetILGenerator();
 }
Пример #13
0
        /// <summary>
        /// Defines a constructor.
        /// </summary>
        /// <param name="typeBuilder">The type builder.</param>
        /// <param name="methodAttributes">The method attributes.</param>
        /// <param name="callingConvention">The calling convention.</param>
        /// <param name="parameterTypes">The parameter types.</param>
        /// <param name="parameterNames">The parameter names.</param>
        /// <returns>The constructor builder.</returns>
        public static ConstructorBuilder DefineConstructor(this TypeBuilder typeBuilder,
                                                           MethodAttributes methodAttributes,
                                                           CallingConventions callingConvention,
                                                           Type[] parameterTypes,
                                                           string[] parameterNames)
        {
            if (typeBuilder == null)
                throw new ArgumentNullException("typeBuilder");

            if (parameterTypes == null)
                throw new ArgumentNullException("parameterTypes");

            if (parameterNames == null)
                throw new ArgumentNullException("parameterNames");

            if (parameterTypes.Length != parameterNames.Length)
                throw new ArgumentException(Resources.NumberOfParameterTypesAndNamesMustBeEqual);

            // Define constructor.
            var constructorBuilder = typeBuilder.DefineConstructor(
                methodAttributes,
                callingConvention,
                parameterTypes);

            // Define constructor parameters.
            constructorBuilder.DefineParameters(parameterNames);

            return constructorBuilder;
        }
 public void GetILGenerator_ReturnsNonNull(MethodAttributes attributes)
 {
     TypeBuilder type = Helpers.DynamicType(TypeAttributes.NotPublic);
     ConstructorBuilder constructor = type.DefineConstructor(attributes, CallingConventions.Standard, new Type[0]);
     Assert.NotNull(constructor.GetILGenerator());
     Assert.NotNull(constructor.GetILGenerator(s_randomInt));
 }
        private object[] ExecutePosTest(
                            CustomAttributeBuilder customAttrBuilder,
                            MethodAttributes getMethodAttr,
                            Type returnType,
                            Type[] paramTypes,
                            BindingFlags bindingAttr)
        {
            TypeBuilder myTypeBuilder = GetTypeBuilder(TypeAttributes.Class | TypeAttributes.Public);

            PropertyBuilder myPropertyBuilder = myTypeBuilder.DefineProperty(DynamicPropertyName,
                                                                             PropertyAttributes.HasDefault,
                                                                             returnType, null);
            myPropertyBuilder.SetCustomAttribute(customAttrBuilder);
            // Define the "get" accessor method for DynamicPropertyName
            MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod(DynamicMethodName,
                                                                       getMethodAttr, returnType, paramTypes);
            ILGenerator methodILGenerator = myMethodBuilder.GetILGenerator();
            methodILGenerator.Emit(OpCodes.Ldarg_0);
            methodILGenerator.Emit(OpCodes.Ret);

            // Map the 'get' method created above to our PropertyBuilder
            myPropertyBuilder.SetGetMethod(myMethodBuilder);

            Type myType = myTypeBuilder.CreateTypeInfo().AsType();

            PropertyInfo myProperty = myType.GetProperty(DynamicPropertyName, bindingAttr);
            return myProperty.GetCustomAttributes(false).Select(a => (object)a).ToArray();
        }
Пример #16
0
        public void DefineConstructor(MethodAttributes attributes, Type[] parameterTypes, CallingConventions callingConvention)
        {
            TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public);

            FieldBuilder fieldBuilderA = type.DefineField("TestField", typeof(int), FieldAttributes.Private);
            FieldBuilder fieldBuilderB = type.DefineField("TestField", typeof(int), FieldAttributes.Private);

            ConstructorBuilder constructor = type.DefineConstructor(attributes, callingConvention, parameterTypes);
            ILGenerator ctorIlGenerator = constructor.GetILGenerator();
            if (parameterTypes.Length != 0)
            {
                // Calling base class constructor
                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[0]));

                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Ldarg_1);
                ctorIlGenerator.Emit(OpCodes.Stfld, fieldBuilderA);

                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Ldarg_2);
                ctorIlGenerator.Emit(OpCodes.Stfld, fieldBuilderB);
            }
            ctorIlGenerator.Emit(OpCodes.Ret);
            Helpers.VerifyConstructor(constructor, type, attributes, callingConvention, parameterTypes);
        }
Пример #17
0
        public ILGenerator CreateFunction(TypeBuilder a_TypeBuilder, string a_Name, MethodAttributes a_MethodAttributes, Type a_ReturnType, Type[] a_Parameters)
        {
            MethodBuilder methodBuilder = a_TypeBuilder.DefineMethod(a_Name, a_MethodAttributes, a_ReturnType, a_Parameters);
            ILGenerator ilGenerator = methodBuilder.GetILGenerator();

            return ilGenerator;
        }
 internal FunctionObject(string name, ParameterDeclaration[] parameter_declarations, TypeExpression return_type_expr, Block body, FunctionScope own_scope, ScriptObject enclosing_scope, Context funcContext, MethodAttributes attributes, CustomAttributeList customAttributes, bool isMethod) : base(body.Globals.globalObject.originalFunction.originalPrototype, name, parameter_declarations.Length)
 {
     this.parameter_declarations = parameter_declarations;
     int length = parameter_declarations.Length;
     this.formal_parameters = new string[length];
     for (int i = 0; i < length; i++)
     {
         this.formal_parameters[i] = parameter_declarations[i].identifier;
     }
     this.argumentsSlotNumber = 0;
     this.return_type_expr = return_type_expr;
     if (this.return_type_expr != null)
     {
         own_scope.AddReturnValueField();
     }
     this.body = body;
     this.method = null;
     this.parameterInfos = null;
     this.funcContext = funcContext;
     this.own_scope = own_scope;
     this.own_scope.owner = this;
     if ((!(enclosing_scope is ActivationObject) || !((ActivationObject) enclosing_scope).fast) && !isMethod)
     {
         this.argumentsSlotNumber = this.own_scope.GetNextSlotNumber();
         JSLocalField field = (JSLocalField) this.own_scope.AddNewField("arguments", null, FieldAttributes.PrivateScope);
         field.type = new TypeExpression(new ConstantWrapper(Typeob.Object, funcContext));
         field.isDefined = true;
         this.hasArgumentsObject = true;
     }
     else
     {
         this.hasArgumentsObject = false;
     }
     this.implementedIface = null;
     this.implementedIfaceMethod = null;
     this.isMethod = isMethod;
     this.isExpandoMethod = (customAttributes != null) && customAttributes.ContainsExpandoAttribute();
     this.isStatic = this.own_scope.isStatic = (attributes & MethodAttributes.Static) != MethodAttributes.PrivateScope;
     this.suppressIL = false;
     this.noVersionSafeAttributeSpecified = true;
     this.fields = this.own_scope.GetLocalFields();
     this.enclosing_scope = enclosing_scope;
     this.must_save_stack_locals = false;
     this.text = null;
     this.mb = null;
     this.cb = null;
     this.attributes = attributes;
     if (!this.isStatic)
     {
         this.attributes |= MethodAttributes.HideBySig;
     }
     this.globals = body.Globals;
     this.superConstructor = null;
     this.superConstructorCall = null;
     this.customAttributes = customAttributes;
     base.noExpando = false;
     this.clsCompliance = CLSComplianceSpec.NotAttributed;
     this.engineLocal = null;
     this.partiallyEvaluated = false;
 }
        public void PosTest1()
        {
            int i = 0;
            MethodAttributes[] attributes = new MethodAttributes[] {
                MethodAttributes.Assembly,
                MethodAttributes.CheckAccessOnOverride,
                MethodAttributes.FamANDAssem,
                MethodAttributes.Family,
                MethodAttributes.FamORAssem,
                MethodAttributes.Final,
                MethodAttributes.HasSecurity,
                MethodAttributes.HideBySig,
                MethodAttributes.MemberAccessMask,
                MethodAttributes.NewSlot,
                MethodAttributes.Private,
                MethodAttributes.PrivateScope,
                MethodAttributes.Public,
                MethodAttributes.RequireSecObject,
                MethodAttributes.ReuseSlot,
                MethodAttributes.RTSpecialName,
                MethodAttributes.SpecialName,
                MethodAttributes.Static,
                MethodAttributes.UnmanagedExport,
                MethodAttributes.Virtual,
                MethodAttributes.VtableLayoutMask
            };

            for (; i < attributes.Length; ++i)
            {
                ILGenerator generator =
                    CreateConstructorBuilder("PosTest1_Type" + i, attributes[i]).GetILGenerator();
                Assert.NotNull(generator);
            }
        }
Пример #20
0
	    internal EventGen(TypeGen owner, string name, Type type, MethodAttributes mthAttr)
		{
			_owner = owner;
			Name = name;
			_type = type;
			_attrs = mthAttr;
		}
 internal FunctionObject(Type t, string name, string method_name, string[] formal_parameters, JSLocalField[] fields, bool must_save_stack_locals, bool hasArgumentsObject, string text, VsaEngine engine) : base(engine.Globals.globalObject.originalFunction.originalPrototype, name, formal_parameters.Length)
 {
     base.engine = engine;
     this.formal_parameters = formal_parameters;
     this.argumentsSlotNumber = 0;
     this.body = null;
     this.method = TypeReflector.GetTypeReflectorFor(Globals.TypeRefs.ToReferenceContext(t)).GetMethod(method_name, BindingFlags.Public | BindingFlags.Static);
     this.parameterInfos = this.method.GetParameters();
     if (!Microsoft.JScript.CustomAttribute.IsDefined(this.method, typeof(JSFunctionAttribute), false))
     {
         this.isMethod = true;
     }
     else
     {
         JSFunctionAttributeEnum attributeValue = ((JSFunctionAttribute) Microsoft.JScript.CustomAttribute.GetCustomAttributes(this.method, typeof(JSFunctionAttribute), false)[0]).attributeValue;
         this.isExpandoMethod = (attributeValue & JSFunctionAttributeEnum.IsExpandoMethod) != JSFunctionAttributeEnum.None;
     }
     this.funcContext = null;
     this.own_scope = null;
     this.fields = fields;
     this.must_save_stack_locals = must_save_stack_locals;
     this.hasArgumentsObject = hasArgumentsObject;
     this.text = text;
     this.attributes = MethodAttributes.Public;
     this.globals = engine.Globals;
     this.superConstructor = null;
     this.superConstructorCall = null;
     this.enclosing_scope = this.globals.ScopeStack.Peek();
     base.noExpando = false;
     this.clsCompliance = CLSComplianceSpec.NotAttributed;
 }
Пример #22
0
 internal PropertyGen(TypeGen owner, MethodAttributes attrs, Type type, string name)
 {
     this.owner = owner;
     this.attrs = attrs;
     this.type = type;
     this.name = name;
 }
Пример #23
0
        internal void StartMethod(string name, Type returns, Type[] parameters, MethodAttributes methodAttributes)
        {
            var before = "";
            var firstArgIdx = 1;
            if (methodAttributes.HasFlag(MethodAttributes.Public)) before += "public ";
            if (methodAttributes.HasFlag(MethodAttributes.Static))
            {
                firstArgIdx = 0;
                before += "static ";
            }
            if (methodAttributes.HasFlag(MethodAttributes.Virtual)) before += "virtual ";

            switch (parameters.Length)
            {
                case 0:
                    WriteLine(String.Format("{2}{0} {1}()", returns.ToSimpleName(), name, before));
                    break;
                case 1:
                    WriteLine(String.Format("{2}{0} {1}({3} arg{4})", returns.ToSimpleName(), name, before, parameters[0].ToSimpleName(), firstArgIdx));
                    break;
                default:
                    WriteLine(String.Format("{2}{0} {1}(", returns.ToSimpleName(), name, before));
                    Indent++;
                    int idx = 0;
                    foreach (var par in parameters)
                    {
                        WriteLine(
                            $"{par.ToSimpleName()} arg{idx + firstArgIdx}{(idx + 1 == parameters.Length ? ')' : ',')}");
                        idx++;
                    }
                    Indent--;
                    break;
            }
            OpenScope();
        }
Пример #24
0
 public ConstructorBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes)
 {
     var cb = _typeBuilder.DefineConstructor(attributes, callingConvention, parameterTypes);
     _members.Add(cb);
     _paramsByMember.Add(cb, parameterTypes);
     return cb;
 }
Пример #25
0
        public void DefineConstructor(MethodAttributes methodAttributes, Type[] parameterTypes, CallingConventions callingConvention, BindingFlags bindingFlags)
        {
            TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public);

            FieldBuilder fieldBuilderA = type.DefineField("TestField", typeof(int), FieldAttributes.Private);
            FieldBuilder fieldBuilderB = type.DefineField("TestField", typeof(int), FieldAttributes.Private);

            ConstructorBuilder ctorBuilder = type.DefineConstructor(methodAttributes, callingConvention, parameterTypes);
            ILGenerator ctorIlGenerator = ctorBuilder.GetILGenerator();

            if (parameterTypes.Length != 0)
            {
                //Calling base class constructor
                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[0]));

                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Ldarg_1);
                ctorIlGenerator.Emit(OpCodes.Stfld, fieldBuilderA);

                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Ldarg_2);
                ctorIlGenerator.Emit(OpCodes.Stfld, fieldBuilderB);
            }

            ctorIlGenerator.Emit(OpCodes.Ret);

            Type createdType = type.CreateTypeInfo().AsType();
            Assert.NotNull(createdType.GetConstructors(bindingFlags).FirstOrDefault());
        }
 public MethodDefinitionProjection(MethodDefinition method, MethodDefinitionTreatment treatment)
 {
     Attributes = method.Attributes;
     ImplAttributes = method.ImplAttributes;
     Name = method.Name;
     Treatment = treatment;
 }
Пример #27
0
        /// <summary>	
        /// 	타입의 생성자를 생성합니다. 
        /// </summary>
        /// <param name="methodAttributes">	생성자 메서드인 .ctor 의 메서드 특성입니다. </param>
        /// <param name="callingConventions">	메서드의 유효한 호출 규칙입니다. </param>
        /// <param name="parameterCriteriaMetadataInfos">	매개 변수의 표준적인 메타데이터 정보입니다. </param>
        /// <returns>	
        /// 	생성자를 생성할 때 사용하는 <see cref="ConstructorBuilder"/> 객체를 반환합니다. 
        /// </returns>
        public ConstructorBuilder CreateConstructor(MethodAttributes methodAttributes, CallingConventions callingConventions, IEnumerable<ParameterCriteriaMetadataInfo> parameterCriteriaMetadataInfos)
        {
            if (isStaticMethod(methodAttributes))
            {
                methodAttributes = MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Private | MethodAttributes.HideBySig;
                callingConventions = CallingConventions.Standard;
            }
            else
            {
                callingConventions = CallingConventions.HasThis;
            }

            var constructorBuilder = this.TypeBuilder.DefineConstructor(methodAttributes, callingConventions, parameterCriteriaMetadataInfos.Select( o => o.Type).ToArray());

            int iSeqence = 0;
            foreach (var parameter in parameterCriteriaMetadataInfos)
            {
                iSeqence++;
                constructorBuilder.DefineParameter(iSeqence, parameter.ParameterAttribute, parameter.Name);
            }

            var il = constructorBuilder.GetILGenerator();

            if (isStaticMethod(methodAttributes))	// 정적 생성자는 Object 개체 파생이 아니므로 Object 생성을 하지 않음
            {
                il.Emit(OpCodes.Nop);
            }
            else
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Call, this.TypeBuilder.BaseType.GetConstructors()[0]);
            }

            return constructorBuilder;
        }
Пример #28
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="TypeBuilder">Type builder</param>
 /// <param name="Name">Name of the method</param>
 /// <param name="Attributes">Attributes for the method (public, private, etc.)</param>
 /// <param name="Parameters">Parameter types for the method</param>
 /// <param name="ReturnType">Return type for the method</param>
 public MethodBuilder(TypeBuilder TypeBuilder, string Name,
     MethodAttributes Attributes, List<Type> Parameters, Type ReturnType)
     : base()
 {
     if (TypeBuilder == null)
         throw new ArgumentNullException("TypeBuilder");
     if (string.IsNullOrEmpty(Name))
         throw new ArgumentNullException("Name");
     this.Name = Name;
     this.Type = TypeBuilder;
     this.Attributes = Attributes;
     this.ReturnType = (ReturnType == null) ? typeof(void) : ReturnType;
     this.Parameters = new List<ParameterBuilder>();
     this.Parameters.Add(new ParameterBuilder(null, 0));
     if (Parameters != null)
     {
         int x = 1;
         if (Name.StartsWith("set_"))
             x = -1;
         foreach (Type ParameterType in Parameters)
         {
             this.Parameters.Add(new ParameterBuilder(ParameterType, x));
             ++x;
         }
     }
     Commands = new List<ICommand>();
     Builder = Type.Builder.DefineMethod(Name, Attributes, ReturnType,
         (Parameters != null && Parameters.Count > 0) ? Parameters.ToArray() : System.Type.EmptyTypes);
     Generator = Builder.GetILGenerator();
 }
Пример #29
0
 public MethodBuilder DefineMethod(string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
 {
     var mb = _typeBuilder.DefineMethod(name, attributes, returnType, parameterTypes);
     _members.Add(mb);
     _paramsByMember.Add(mb, parameterTypes);
     return mb;
 }
Пример #30
0
 public void DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
 {
     bool defaultReturnTypeAndParameters = returnType == null && parameterTypes == null;
     if (callingConvention == CallingConventions.Standard)
     {
         if (defaultReturnTypeAndParameters)
         {
             // Use DefineMethod(string, MethodAttributes)
             TypeBuilder type1 = Helpers.DynamicType(TypeAttributes.Public);
             MethodBuilder method1 = type1.DefineMethod(name, attributes);
             VerifyMethod(type1, method1, name, attributes, callingConvention, returnType, parameterTypes);
         }
         // Use DefineMethod(string, MethodAttributes, Type, Type[])
         TypeBuilder type2 = Helpers.DynamicType(TypeAttributes.Public);
         MethodBuilder method2 = type2.DefineMethod(name, attributes, returnType, parameterTypes);
         VerifyMethod(type2, method2, name, attributes, callingConvention, returnType, parameterTypes);
     }
     if (defaultReturnTypeAndParameters)
     {
         // Use DefineMethod(string, MethodAttributes, CallingConventions)
         TypeBuilder type3 = Helpers.DynamicType(TypeAttributes.Public);
         MethodBuilder method3 = type3.DefineMethod(name, attributes, callingConvention);
         VerifyMethod(type3, method3, name, attributes, callingConvention, returnType, parameterTypes);
     }
     // Use DefineMethod(string, MethodAttributes, CallingConventions, Type, Type[])
     TypeBuilder type4 = Helpers.DynamicType(TypeAttributes.Public);
     MethodBuilder method4 = type4.DefineMethod(name, attributes, callingConvention, returnType, parameterTypes);
     VerifyMethod(type4, method4, name, attributes, callingConvention, returnType, parameterTypes);
 }
Пример #31
0
        private void Init(string name,
                          MethodAttributes attributes,
                          CallingConventions callingConvention,
                          Type?returnType,
                          Type[]?signature,
                          Type?owner,
                          Module?m,
                          bool skipVisibility,
                          bool transparentMethod)
        {
            ArgumentNullException.ThrowIfNull(name);

            CheckConsistency(attributes, callingConvention);

            // check and store the signature
            if (signature != null)
            {
                m_parameterTypes = new RuntimeType[signature.Length];
                for (int i = 0; i < signature.Length; i++)
                {
                    if (signature[i] == null)
                    {
                        throw new ArgumentException(SR.Arg_InvalidTypeInSignature);
                    }
                    m_parameterTypes[i] = (signature[i].UnderlyingSystemType as RuntimeType) !;
                    if (m_parameterTypes[i] == null || m_parameterTypes[i] == typeof(void))
                    {
                        throw new ArgumentException(SR.Arg_InvalidTypeInSignature);
                    }
                }
            }
            else
            {
                m_parameterTypes = Array.Empty <RuntimeType>();
            }

            // check and store the return value
            m_returnType = (returnType == null) ? (RuntimeType)typeof(void) : (returnType.UnderlyingSystemType as RuntimeType) !;
            if (m_returnType == null)
            {
                throw new NotSupportedException(SR.Arg_InvalidTypeInRetType);
            }

            if (transparentMethod)
            {
                Debug.Assert(owner == null && m == null, "owner and m cannot be set for transparent methods");
                m_module = GetDynamicMethodsModule();
                if (skipVisibility)
                {
                    m_restrictedSkipVisibility = true;
                }
            }
            else
            {
                Debug.Assert(m != null || owner != null, "Constructor should ensure that either m or owner is set");
                Debug.Assert(m == null || !m.Equals(s_anonymouslyHostedDynamicMethodsModule), "The user cannot explicitly use this assembly");
                Debug.Assert(m == null || owner == null, "m and owner cannot both be set");

                if (m != null)
                {
                    m_module = m.ModuleHandle.GetRuntimeModule(); // this returns the underlying module for all RuntimeModule and ModuleBuilder objects.
                }
                else
                {
                    RuntimeType?rtOwner = null;
                    if (owner != null)
                    {
                        rtOwner = owner.UnderlyingSystemType as RuntimeType;
                    }

                    if (rtOwner != null)
                    {
                        if (rtOwner.HasElementType || rtOwner.ContainsGenericParameters ||
                            rtOwner.IsGenericParameter || rtOwner.IsInterface)
                        {
                            throw new ArgumentException(SR.Argument_InvalidTypeForDynamicMethod);
                        }

                        m_typeOwner = rtOwner;
                        m_module    = rtOwner.GetRuntimeModule();
                    }
                }

                m_skipVisibility = skipVisibility;
            }

            // initialize remaining fields
            m_ilGenerator  = null;
            m_fInitLocals  = true;
            m_methodHandle = null;
            m_dynMethod    = new RTDynamicMethod(this, name, attributes, callingConvention);
        }
Пример #32
0
        /// <summary>
        /// Creates a method builder from an existing method info
        /// </summary>
        /// <param name="typeBuilder"></param>
        /// <param name="methodInfo"></param>
        /// <param name="attributes"></param>
        /// <returns></returns>
        public static MethodBuilder CreateMethod(this TypeBuilder typeBuilder, MethodInfo methodInfo, MethodAttributes attributes = MethodAttributes.Public)
        {
            Type[] parameterTypes = methodInfo.GetParameters().ToArray(p => p.ParameterType);

            MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, attributes, methodInfo.ReturnType, parameterTypes);

            return(methodBuilder);
        }
Пример #33
0
 public MethodDefinition(string name, MethodAttributes attrs, TypeReference returnType) :
     this(name, attrs)
 {
     this.ReturnType.ReturnType = returnType;
 }
 public MethodEmitter CreateMethod(string name, MethodAttributes attrs, Type returnType,
                                   params ArgumentReference[] argumentReferences)
 {
     Type[] argumentTypes = ArgumentsUtil.InitializeAndConvert(argumentReferences);
     return(CreateMethod(name, attrs, returnType, argumentTypes));
 }
Пример #35
0
 public Method(MetadataReader r, MethodHandle h, MethodAttributes f)
 {
     _reader = r;
     _handle = h;
     _flags  = f;
 }
Пример #36
0
        private Type EmitHelperClass(string HandlerName, EventInfo Info)
        {
            if (helperModule == null)
            {
                AssemblyName myAsmName = new AssemblyName();
                myAsmName.Name = assemblyName + "DynamicAssembly";
                asmBuilder     = Thread.GetDomain().DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
                helperModule   = asmBuilder.DefineDynamicModule(assemblyName + "DynamicModule", true);
            }

            //////////////////////////////////////////////////////////////////////////
            // Define Type
            //////////////////////////////////////////////////////////////////////////
            TypeBuilder helperTypeBld = helperModule.DefineType(HandlerName + "Helper", TypeAttributes.Public);

            // Define fields
            FieldBuilder typeField   = helperTypeBld.DefineField("eventType", typeof(Type), FieldAttributes.Private);
            FieldBuilder eventField  = helperTypeBld.DefineField("CommonEvent", typeof(GenericEventHandlerDelegate), FieldAttributes.Private);
            EventBuilder commonEvent = helperTypeBld.DefineEvent("CommonEvent", EventAttributes.None, typeof(GenericEventHandlerDelegate));

            //////////////////////////////////////////////////////////////////////////
            // Build Constructor
            //////////////////////////////////////////////////////////////////////////
            Type            objType = Type.GetType("System.Object");
            ConstructorInfo objCtor = objType.GetConstructor(new Type[0]);

            // Build constructor with arguments (Type)
            Type[]             ctorParams = new Type[] { typeof(EventInfo) };
            ConstructorBuilder ctor       = helperTypeBld.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctorParams);

            // Call constructor of base class
            ILGenerator ctorIL = ctor.GetILGenerator();

            ctorIL.Emit(OpCodes.Ldarg_0);
            ctorIL.Emit(OpCodes.Call, objCtor);

            // store first argument to typeField
            ctorIL.Emit(OpCodes.Ldarg_0);
            ctorIL.Emit(OpCodes.Ldarg_1);
            ctorIL.Emit(OpCodes.Stfld, typeField);

            // return
            ctorIL.Emit(OpCodes.Ret);
            // Now constructor is finished!

            //////////////////////////////////////////////////////////////////////////
            // Build customized event handler
            //////////////////////////////////////////////////////////////////////////
            string     eventName = Info.Name;
            Type       ehType    = Info.EventHandlerType;
            MethodInfo mi        = ehType.GetMethod("Invoke");

            ParameterInfo[] eventParams = mi.GetParameters();

            // Build the type list of the parameter
            int paramCount = eventParams.Length;

            Type[] invokeParams = new Type[paramCount];
            for (int i = 0; i < paramCount; i++)
            {
                invokeParams[i] = eventParams[i].ParameterType;
            }

            string           methodName = "CustomEventHandler";
            MethodAttributes attr       = MethodAttributes.Public | MethodAttributes.HideBySig;
            MethodBuilder    invokeMthd = helperTypeBld.DefineMethod(methodName, attr, typeof(void), invokeParams);

            // A ILGenerator can now be spawned, attached to the MethodBuilder.
            ILGenerator ilGen = invokeMthd.GetILGenerator();

            // Create Label before return
            Label endOfMethod = ilGen.DefineLabel();

            // Create a local variable of type 'string', and call it 'args'
            LocalBuilder localObj = ilGen.DeclareLocal(typeof(object[]));

            localObj.SetLocalSymInfo("args");             // Provide name for the debugger.

            // create object array of proper length
            ilGen.Emit(OpCodes.Ldc_I4, paramCount);
            ilGen.Emit(OpCodes.Newarr, typeof(object));
            ilGen.Emit(OpCodes.Stloc_0);

            // Now put all arguments in the object array
            for (int i = 0; i < paramCount; i++)
            {
                byte i1b = Convert.ToByte(i + 1);
                ilGen.Emit(OpCodes.Ldloc_0);
                ilGen.Emit(OpCodes.Ldc_I4, i);
                ilGen.Emit(OpCodes.Ldarg_S, i1b);

                // Is argument value type?
                if (invokeParams[i].IsValueType)
                {
                    // Box the value type
                    ilGen.Emit(OpCodes.Box, invokeParams[i]);
                }
                // Put the argument in the object array
                ilGen.Emit(OpCodes.Stelem_Ref);
            }

            // raise common event
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldfld, eventField);
            ilGen.Emit(OpCodes.Brfalse_S, endOfMethod);
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldfld, eventField);
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldfld, typeField);
            ilGen.Emit(OpCodes.Ldloc_0);
            MethodInfo raiseEventMethod = typeof(GenericEventHandlerDelegate).GetMethod("Invoke", BindingFlags.Public | BindingFlags.Instance);

            if (raiseEventMethod == null)
            {
                throw new ApplicationException("CommonEventHandlerDlg:Invoke not found");
            }
            ilGen.Emit(OpCodes.Callvirt, raiseEventMethod);

            // return
            ilGen.MarkLabel(endOfMethod);
            ilGen.Emit(OpCodes.Ret);

            //////////////////////////////////////////////////////////////////////////
            // add_CommonEvent
            //////////////////////////////////////////////////////////////////////////
            methodName      = "add_CommonEvent";
            attr            = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
            invokeParams    = new Type[1];
            invokeParams[0] = typeof(GenericEventHandlerDelegate);
            MethodBuilder addMethod = helperTypeBld.DefineMethod(methodName, attr, typeof(void), invokeParams);

            ilGen = addMethod.GetILGenerator();

            // define code
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldfld, eventField);
            ilGen.Emit(OpCodes.Ldarg_1);

            Type[]     combineTypes = new Type[] { typeof(Delegate), typeof(Delegate) };
            MethodInfo combineMtd   = typeof(Delegate).GetMethod("Combine", combineTypes);

            if (combineMtd == null)
            {
                throw new ApplicationException("Delegate:Combine not found");
            }
            ilGen.Emit(OpCodes.Call, combineMtd);
            ilGen.Emit(OpCodes.Castclass, typeof(GenericEventHandlerDelegate));
            ilGen.Emit(OpCodes.Stfld, eventField);
            ilGen.Emit(OpCodes.Ret);

            // Set add method
            commonEvent.SetAddOnMethod(addMethod);

            //////////////////////////////////////////////////////////////////////////
            // remove_CommonEvent
            //////////////////////////////////////////////////////////////////////////
            methodName      = "remove_CommonEvent";
            attr            = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
            invokeParams    = new Type[1];
            invokeParams[0] = typeof(GenericEventHandlerDelegate);
            MethodBuilder removeMethod = helperTypeBld.DefineMethod(methodName, attr, typeof(void), invokeParams);

            ilGen = removeMethod.GetILGenerator();

            // define code
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldfld, eventField);
            ilGen.Emit(OpCodes.Ldarg_1);

            MethodInfo removeMtd = typeof(Delegate).GetMethod("Remove", combineTypes);

            if (removeMtd == null)
            {
                throw new ApplicationException("Delegate:Remove not found");
            }
            ilGen.Emit(OpCodes.Call, removeMtd);
            ilGen.Emit(OpCodes.Castclass, typeof(GenericEventHandlerDelegate));
            ilGen.Emit(OpCodes.Stfld, eventField);
            ilGen.Emit(OpCodes.Ret);

            // Set remove method
            commonEvent.SetRemoveOnMethod(removeMethod);

            //////////////////////////////////////////////////////////////////////////
            // Now event handler is finished!
            //////////////////////////////////////////////////////////////////////////
            return(helperTypeBld.CreateType());
        }
 public CompletionItem GetCompletion() => MethodAttributes.GetFunctionCompletion(this);
    public static void Main()
    {
        // An assembly consists of one or more modules, each of which
        // contains zero or more types. This code creates a single-module
        // assembly, the most common case. The module contains one type,
        // named "MyDynamicType", that has a private field, a property
        // that gets and sets the private field, constructors that
        // initialize the private field, and a method that multiplies
        // a user-supplied number by the private field value and returns
        // the result. In C# the type might look like this:

        /*
         * public class MyDynamicType
         * {
         *  private int m_number;
         *
         *  public MyDynamicType() : this(42) {}
         *  public MyDynamicType(int initNumber)
         *  {
         *
         *      m_number = initNumber;
         *  }
         *
         *  public int Number
         *  {
         *      get { return m_number; }
         *      set { m_number = value; }
         *  }
         *
         *  public int MyMethod(int multiplier)
         *  {
         *      return m_number * multiplier;
         *  }
         * }
         */

        AssemblyName    aName = new AssemblyName("DynamicAssemblyExample");
        AssemblyBuilder ab    =
            AssemblyBuilder.DefineDynamicAssembly(
                aName,
                AssemblyBuilderAccess.RunAndSave);

        // For a single-module assembly, the module name is usually
        // the assembly name plus an extension.
        ModuleBuilder mb =
            ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");

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

        // Add a private field of type int (Int32).
        FieldBuilder fbNumber = tb.DefineField(
            "m_number",
            typeof(int),
            FieldAttributes.Private);

        // Define a constructor that takes an integer argument and
        // stores it in the private field.
        Type[]             parameterTypes = { typeof(int) };
        ConstructorBuilder ctor1          = tb.DefineConstructor(
            MethodAttributes.Public,
            CallingConventions.Standard,
            parameterTypes);

        ILGenerator ctor1IL = ctor1.GetILGenerator();

        // For a constructor, argument zero is a reference to the new
        // instance. Push it on the stack before calling the base
        // class constructor. Specify the default constructor of the
        // base class (System.Object) by passing an empty array of
        // types (Type.EmptyTypes) to GetConstructor.

        //  ldarg.0
        //  call      instance void [mscorlib]System.Object::.ctor()
        //  ldarg.0
        //  ldarg.1
        //  stfld     int32 MyDynamicType1::m_number
        //  ret

        ctor1IL.Emit(OpCodes.Ldarg_0);
        ctor1IL.Emit(OpCodes.Call,
                     typeof(object).GetConstructor(Type.EmptyTypes));
        // Push the instance on the stack before pushing the argument
        // that is to be assigned to the private field m_number.
        ctor1IL.Emit(OpCodes.Ldarg_0);
        ctor1IL.Emit(OpCodes.Ldarg_1);
        ctor1IL.Emit(OpCodes.Stfld, fbNumber);
        ctor1IL.Emit(OpCodes.Ret);

        // Define a default constructor that supplies a default value
        // for the private field. For parameter types, pass the empty
        // array of types or pass null.
        ConstructorBuilder ctor0 = tb.DefineConstructor(
            MethodAttributes.Public,
            CallingConventions.Standard,
            Type.EmptyTypes);

        //  ldarg.0
        //  ldc.i4.s   42
        //  call      instance void MyDynamicType1::.ctor(int32)
        //  ret

        ILGenerator ctor0IL = ctor0.GetILGenerator();

        // For a constructor, argument zero is a reference to the new
        // instance. Push it on the stack before pushing the default
        // value on the stack, then call constructor ctor1.
        ctor0IL.Emit(OpCodes.Ldarg_0);
        ctor0IL.Emit(OpCodes.Ldc_I4_S, 42);
        ctor0IL.Emit(OpCodes.Call, ctor1);
        ctor0IL.Emit(OpCodes.Ret);

        // Define a property named Number that gets and sets the private
        // field.
        //
        // The last argument of DefineProperty is null, because the
        // property has no parameters. (If you don't specify null, you must
        // specify an array of Type objects. For a parameterless property,
        // use the built-in array with no elements: Type.EmptyTypes)
        PropertyBuilder pbNumber = tb.DefineProperty(
            "Number",
            PropertyAttributes.HasDefault,
            typeof(int),
            null);

        // The property "set" and property "get" methods require a special
        // set of attributes.
        MethodAttributes getSetAttr = MethodAttributes.Public |
                                      MethodAttributes.SpecialName | MethodAttributes.HideBySig;

        // Define the "get" accessor method for Number. The method returns
        // an integer and has no arguments. (Note that null could be
        // used instead of Types.EmptyTypes)
        MethodBuilder mbNumberGetAccessor = tb.DefineMethod(
            "get_Number",
            getSetAttr,
            typeof(int),
            Type.EmptyTypes);

        ILGenerator numberGetIL = mbNumberGetAccessor.GetILGenerator();

        // For an instance property, argument zero is the instance. Load the
        // instance, then load the private field and return, leaving the
        // field value on the stack.
        numberGetIL.Emit(OpCodes.Ldarg_0);
        numberGetIL.Emit(OpCodes.Ldfld, fbNumber);
        numberGetIL.Emit(OpCodes.Ret);

        // Define the "set" accessor method for Number, which has no return
        // type and takes one argument of type int (Int32).
        MethodBuilder mbNumberSetAccessor = tb.DefineMethod(
            "set_Number",
            getSetAttr,
            null,
            new Type[] { typeof(int) });

        ILGenerator numberSetIL = mbNumberSetAccessor.GetILGenerator();

        // Load the instance and then the numeric argument, then store the
        // argument in the field.
        numberSetIL.Emit(OpCodes.Ldarg_0);
        numberSetIL.Emit(OpCodes.Ldarg_1);
        numberSetIL.Emit(OpCodes.Stfld, fbNumber);
        numberSetIL.Emit(OpCodes.Ret);

        // Last, map the "get" and "set" accessor methods to the
        // PropertyBuilder. The property is now complete.
        pbNumber.SetGetMethod(mbNumberGetAccessor);
        pbNumber.SetSetMethod(mbNumberSetAccessor);

        // Define a method that accepts an integer argument and returnsF
        // the product of that integer and the private field m_number. This
        // time, the array of parameter types is created on the fly.
        MethodBuilder meth = tb.DefineMethod(
            "MyMethod",
            MethodAttributes.Public,
            typeof(int),
            new Type[] { typeof(int) });

        ILGenerator methIL = meth.GetILGenerator();

        // To retrieve the private instance field, load the instance it
        // belongs to (argument zero). After loading the field, load the
        // argument one and then multiply. Return from the method with
        // the return value (the product of the two numbers) on the
        // execution stack.
        methIL.Emit(OpCodes.Ldarg_0);
        methIL.Emit(OpCodes.Ldfld, fbNumber);
        methIL.Emit(OpCodes.Ldarg_1);
        methIL.Emit(OpCodes.Mul);
        methIL.Emit(OpCodes.Ret);

        // Finish the type.
        Type t = tb.CreateType();

        // The following line saves the single-module assembly. This
        // requires AssemblyBuilderAccess to include Save. You can now
        // type "ildasm MyDynamicAsm.dll" at the command prompt, and
        // examine the assembly. You can also write a program that has
        // a reference to the assembly, and use the MyDynamicType type.
        //

        String assemblyName = aName.Name + ".dll";

        Console.WriteLine("Creating " + assemblyName);
        ab.Save(assemblyName);

        // Because AssemblyBuilderAccess includes Run, the code can be
        // executed immediately. Start by getting reflection objects for
        // the method and the property.
        MethodInfo   mi = t.GetMethod("MyMethod");
        PropertyInfo pi = t.GetProperty("Number");

        // Create an instance of MyDynamicType using the default
        // constructor.
        object o1 = Activator.CreateInstance(t);

        // Display the value of the property, then change it to 127 and
        // display it again. Use null to indicate that the property
        // has no index.
        Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null));
        pi.SetValue(o1, 127, null);
        Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null));

        // Call MyMethod, passing 22, and display the return value, 22
        // times 127. Arguments must be passed as an array, even when
        // there is only one.
        object[] arguments = { 22 };
        Console.WriteLine("o1.MyMethod(22): {0}",
                          mi.Invoke(o1, arguments));

        // Create an instance of MyDynamicType using the constructor
        // that specifies m_Number. The constructor is identified by
        // matching the types in the argument array. In this case,
        // the argument array is created on the fly. Display the
        // property value.
        object o2 = Activator.CreateInstance(t,
                                             new object[] { 5280 });

        Console.WriteLine("o2.Number: {0}", pi.GetValue(o2, null));
    }
Пример #39
0
        private static void CreateAutoImplementedProperty(TypeBuilder builder, string propertyName, Type propertyType)
        {
            const string PrivateFieldPrefix = "m_";
            const string GetterPrefix       = "get_";
            const string SetterPrefix       = "set_";

            // Generate the field.
            FieldBuilder fieldBuilder = builder.DefineField(
                string.Concat(
                    PrivateFieldPrefix, propertyName),
                propertyType,
                FieldAttributes.Private);

            // Generate the property
            PropertyBuilder propertyBuilder = builder.DefineProperty(
                propertyName,
                System.Reflection.PropertyAttributes.HasDefault,
                propertyType, null);

            // Property getter and setter attributes.
            MethodAttributes propertyMethodAttributes = MethodAttributes.Public
                                                        | MethodAttributes.SpecialName
                                                        | MethodAttributes.HideBySig;

            // Define the getter method.
            MethodBuilder getterMethod = builder.DefineMethod(
                string.Concat(
                    GetterPrefix, propertyName),
                propertyMethodAttributes,
                propertyType,
                Type.EmptyTypes);

            // Emit the IL code.
            // ldarg.0
            // ldfld,_field
            // ret
            ILGenerator getterILCode = getterMethod.GetILGenerator();

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

            // Define the setter method.
            MethodBuilder setterMethod = builder.DefineMethod(
                string.Concat(SetterPrefix, propertyName),
                propertyMethodAttributes,
                null,
                new Type[] { propertyType });

            // Emit the IL code.
            // ldarg.0
            // ldarg.1
            // stfld,_field
            // ret
            ILGenerator setterILCode = setterMethod.GetILGenerator();

            setterILCode.Emit(OpCodes.Ldarg_0);
            setterILCode.Emit(OpCodes.Ldarg_1);
            setterILCode.Emit(OpCodes.Stfld, fieldBuilder);
            setterILCode.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getterMethod);
            propertyBuilder.SetSetMethod(setterMethod);
        }
Пример #40
0
        /// <summary>
        /// Adds a forwarding method to the proxy based on the passed <see cref="MethodInfo"/>, using the passed <see cref="MethodAttributes"/>.
        /// </summary>
        /// <remarks>
        /// Note that this works for interface methods only, if the <see cref="MethodInfo"/> comes from the interface, not the
        /// type implementing the interface.
        /// </remarks>
        public IMethodEmitter AddForwardingMethodFromClassOrInterfaceMethodInfoCopy(MethodInfo methodInfo, MethodAttributes methodAttributes)
        {
            ArgumentUtility.CheckNotNull("methodInfo", methodInfo);

            IMethodEmitter methodEmitter;

            if (methodInfo.DeclaringType.IsInterface)
            {
                methodEmitter = _classEmitter.CreateMethodOverrideOrInterfaceImplementation(
                    methodInfo, true, methodAttributes & MethodAttributes.MemberAccessMask);
            }
            else
            {
                // Note: Masking the attributes with MethodAttributes.MemberAccessMask below, would remove
                // desired attributes such as Final, Virtual and HideBySig.
                methodEmitter = _classEmitter.CreateMethod(methodInfo.Name, methodAttributes, methodInfo);
            }

            ImplementForwardingMethod(methodInfo, methodEmitter);

            // TODO: Test return type
            return(methodEmitter);
        }
Пример #41
0
        /// <summary>
        /// Creates and returns a MethodBuilder
        /// </summary>
        internal static MethodBuilder CompileLambda(LambdaExpression lambda, TypeBuilder type, MethodAttributes attributes, bool emitDebugSymbols)
        {
            // 1. Create signature
            List <Type>   types;
            List <string> names;
            string        lambdaName;
            Type          returnType;

            ComputeSignature(lambda, out types, out names, out lambdaName, out returnType);

            // 2. Bind lambda
            AnalyzedTree tree = AnalyzeLambda(ref lambda);

            // 3. Create lambda compiler
            LambdaCompiler c = CreateStaticCompiler(
                tree,
                lambda,
                type,
                lambda.Name ?? "lambda_method", // don't use generated name
                attributes,
                returnType,
                types,
                names,
                false, // dynamicMethod
                emitDebugSymbols
                );

            // 4. Emit
            c.EmitLambdaBody(null);

            return((MethodBuilder)c._method);
        }
 public MethodEmitter CreateMethod(string name, MethodAttributes attrs, Type returnType)
 {
     return(CreateMethod(name, attrs, returnType, Type.EmptyTypes));
 }
Пример #43
0
        /// <summary>
        /// 生成代理类型的接口实现方法
        /// </summary>
        /// <param name="builder">类型生成器</param>
        /// <param name="apiMethods">接口方法集合</param>
        /// <param name="fieldInterceptor">拦截器字段</param>
        /// <param name="fieldApiMethods">接口方法集合字段</param>
        private static void BuildMethods(TypeBuilder builder, MethodInfo[] apiMethods, FieldBuilder fieldInterceptor, FieldBuilder fieldApiMethods)
        {
            const MethodAttributes implementAttribute = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot | MethodAttributes.HideBySig;

            for (var i = 0; i < apiMethods.Length; i++)
            {
                var apiMethod      = apiMethods[i];
                var apiParameters  = apiMethod.GetParameters();
                var parameterTypes = apiParameters.Select(p => p.ParameterType).ToArray();

                var iL = builder
                         .DefineMethod(apiMethod.Name, implementAttribute, CallingConventions.Standard, apiMethod.ReturnType, parameterTypes)
                         .GetILGenerator();

                // this.interceptor
                iL.Emit(OpCodes.Ldarg_0);
                iL.Emit(OpCodes.Ldfld, fieldInterceptor);

                // 加载target参数
                iL.Emit(OpCodes.Ldarg_0);

                // 加载method参数 this.apiMethods[i]
                iL.Emit(OpCodes.Ldarg_0);
                iL.Emit(OpCodes.Ldfld, fieldApiMethods);
                iL.Emit(OpCodes.Ldc_I4, i);
                iL.Emit(OpCodes.Ldelem_Ref);

                // var parameters = new object[parameters.Length]
                var parameters = iL.DeclareLocal(typeof(object[]));
                iL.Emit(OpCodes.Ldc_I4, apiParameters.Length);
                iL.Emit(OpCodes.Newarr, typeof(object));
                iL.Emit(OpCodes.Stloc, parameters);

                for (var j = 0; j < apiParameters.Length; j++)
                {
                    iL.Emit(OpCodes.Ldloc, parameters);
                    iL.Emit(OpCodes.Ldc_I4, j);
                    iL.Emit(OpCodes.Ldarg, j + 1);

                    var parameterType = parameterTypes[j];
                    if (parameterType.GetTypeInfo().IsValueType || parameterType.IsGenericParameter)
                    {
                        iL.Emit(OpCodes.Box, parameterType);
                    }
                    iL.Emit(OpCodes.Stelem_Ref);
                }

                // 加载parameters参数
                iL.Emit(OpCodes.Ldloc, parameters);

                // Intercep(this, method, parameters)
                iL.Emit(OpCodes.Callvirt, interceptMethod);

                if (apiMethod.ReturnType == typeof(void))
                {
                    iL.Emit(OpCodes.Pop);
                }

                iL.Emit(OpCodes.Castclass, apiMethod.ReturnType);
                iL.Emit(OpCodes.Ret);
            }
        }
Пример #44
0
 private MethodAttributes ModifyAccessorAttributesForExplicitInterfaceProperty(MethodAttributes attributes)
 {
     return(attributes & ~MethodAttributes.Public | MethodAttributes.Private);
 }
Пример #45
0
        private static bool CanAccessMember(this MetadataType currentType, TypeDesc targetType, MethodAttributes memberVisibility, TypeDesc instance)
        {
            if (instance == null)
            {
                instance = currentType;
            }

            // Check access to class defining member
            if (!currentType.CanAccess(targetType))
            {
                return(false);
            }

            var targetTypeDef = (MetadataType)targetType.GetTypeDefinition();

            if (memberVisibility == MethodAttributes.Public)
            {
                return(true);
            }

            // This is module-scope checking, to support C++ file & function statics.
            if (memberVisibility == MethodAttributes.PrivateScope)
            {
                return(currentType.Module == targetTypeDef.Module);
            }

            if (memberVisibility == MethodAttributes.Assembly)
            {
                return(currentType.Module == targetTypeDef.Module || targetTypeDef.Module.GrantsFriendAccessTo(currentType.Module));
            }

            if (memberVisibility == MethodAttributes.FamANDAssem)
            {
                if (currentType.Module != targetTypeDef.Module && !targetTypeDef.Module.GrantsFriendAccessTo(currentType.Module))
                {
                    return(false);
                }
            }

            // Nested classes can access all members of their parent class.
            do
            {
                // Classes have access to all of their own members
                if (currentType == targetTypeDef)
                {
                    return(true);
                }

                switch (memberVisibility)
                {
                case MethodAttributes.FamORAssem:
                    if (currentType.Module == targetTypeDef.Module || targetTypeDef.Module.GrantsFriendAccessTo(currentType.Module))
                    {
                        return(true);
                    }

                    // Check if current class is subclass of target
                    if (CanAccessFamily(currentType, targetTypeDef, instance))
                    {
                        return(true);
                    }
                    break;

                case MethodAttributes.Family:
                case MethodAttributes.FamANDAssem:
                    // Assembly acces was already checked earlier, so only need to check family access
                    if (CanAccessFamily(currentType, targetTypeDef, instance))
                    {
                        return(true);
                    }
                    break;

                case MethodAttributes.Private:
                    break;     // Already handled by loop

                default:
                    Debug.Assert(false);
                    break;
                }

                var containingType = currentType.ContainingType;
                if (containingType != null)
                {
                    currentType = (MetadataType)containingType.GetTypeDefinition();
                }
                else
                {
                    currentType = null;
                }
            } while (currentType != null);

            return(false);
        }
Пример #46
0
        internal MethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention,
                               Type?returnType, Type[]?returnTypeRequiredCustomModifiers, Type[]?returnTypeOptionalCustomModifiers,
                               Type[]?parameterTypes, Type[][]?parameterTypeRequiredCustomModifiers, Type[][]?parameterTypeOptionalCustomModifiers,
                               ModuleBuilder mod, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TypeBuilder type)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (name.Length == 0)
            {
                throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
            }

            if (name[0] == '\0')
            {
                throw new ArgumentException(SR.Argument_IllegalName, nameof(name));
            }

            if (mod == null)
            {
                throw new ArgumentNullException(nameof(mod));
            }

            if (parameterTypes != null)
            {
                foreach (Type t in parameterTypes)
                {
                    if (t == null)
                    {
                        throw new ArgumentNullException(nameof(parameterTypes));
                    }
                }
            }

            m_strName        = name;
            m_module         = mod;
            m_containingType = type;
            m_returnType     = returnType ?? typeof(void);

            if ((attributes & MethodAttributes.Static) == 0)
            {
                // turn on the has this calling convention
                callingConvention |= CallingConventions.HasThis;
            }
            else if ((attributes & MethodAttributes.Virtual) != 0)
            {
                // A method can't be both static and virtual
                throw new ArgumentException(SR.Arg_NoStaticVirtual);
            }

#if !FEATURE_DEFAULT_INTERFACES
            if ((attributes & MethodAttributes.SpecialName) != MethodAttributes.SpecialName)
            {
                if ((type.Attributes & TypeAttributes.Interface) == TypeAttributes.Interface)
                {
                    // methods on interface have to be abstract + virtual except special name methods such as type initializer
                    if ((attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) !=
                        (MethodAttributes.Abstract | MethodAttributes.Virtual) &&
                        (attributes & MethodAttributes.Static) == 0)
                    {
                        throw new ArgumentException(SR.Argument_BadAttributeOnInterfaceMethod);
                    }
                }
            }
#endif

            m_callingConvention = callingConvention;

            if (parameterTypes != null)
            {
                m_parameterTypes = new Type[parameterTypes.Length];
                Array.Copy(parameterTypes, m_parameterTypes, parameterTypes.Length);
            }
            else
            {
                m_parameterTypes = null;
            }

            m_returnTypeRequiredCustomModifiers    = returnTypeRequiredCustomModifiers;
            m_returnTypeOptionalCustomModifiers    = returnTypeOptionalCustomModifiers;
            m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers;
            m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;

            // m_signature = SignatureHelper.GetMethodSigHelper(mod, callingConvention,
            //                returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
            //                parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);

            m_iAttributes = attributes;
            m_bIsBaked    = false;
            m_fInitLocals = true;

            m_localSymInfo = new LocalSymInfo();
            m_ubBody       = null;
            m_ilGenerator  = null;

            // Default is managed IL. Manged IL has bit flag 0x0020 set off
            m_dwMethodImplFlags = MethodImplAttributes.IL;
        }
Пример #47
0
        public static MethodAttributes MethodAttr(Modifiers mod_flags)
        {
            MethodAttributes ma = MethodAttributes.HideBySig;

            switch (mod_flags & Modifiers.AccessibilityMask)
            {
            case Modifiers.PUBLIC:
                ma |= MethodAttributes.Public;
                break;

            case Modifiers.PRIVATE:
                ma |= MethodAttributes.Private;
                break;

            case Modifiers.PROTECTED | Modifiers.INTERNAL:
                ma |= MethodAttributes.FamORAssem;
                break;

            case Modifiers.PROTECTED:
                ma |= MethodAttributes.Family;
                break;

            case Modifiers.INTERNAL:
                ma |= MethodAttributes.Assembly;
                break;

            default:
                throw new NotImplementedException(mod_flags.ToString());
            }

            if ((mod_flags & Modifiers.STATIC) != 0)
            {
                ma |= MethodAttributes.Static;
            }
            if ((mod_flags & Modifiers.ABSTRACT) != 0)
            {
                ma |= MethodAttributes.Abstract | MethodAttributes.Virtual;
            }
            if ((mod_flags & Modifiers.SEALED) != 0)
            {
                ma |= MethodAttributes.Final;
            }

            if ((mod_flags & Modifiers.VIRTUAL) != 0)
            {
                ma |= MethodAttributes.Virtual;
            }

            if ((mod_flags & Modifiers.OVERRIDE) != 0)
            {
                ma |= MethodAttributes.Virtual;
            }
            else
            {
                if ((ma & MethodAttributes.Virtual) != 0)
                {
                    ma |= MethodAttributes.NewSlot;
                }
            }

            return(ma);
        }
Пример #48
0
 /// <summary>
 /// Is the given visibility value set?
 /// </summary>
 private bool IsVisibility(MethodAttributes value)
 {
     return(((Attributes) & MethodAttributes.MemberAccessMask) == value);
 }
Пример #49
0
 internal static CodeMethod DefineMethod(CodeClass cls, string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
 {
     return(new CodeMethod(cls, name, attributes, returnType, parameterTypes));
 }
Пример #50
0
        private Type GetObjectType(List <string> vars)
        {
            AssemblyName assemblyName = new AssemblyName();

            assemblyName.Name = "tmpAssembly";
            AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder   module          = assemblyBuilder.DefineDynamicModule("tmpModule");

            // create a new type builder
            TypeBuilder typeBuilder = module.DefineType("TmpClass", TypeAttributes.Public | TypeAttributes.Class);

            //For tracking and fixing duplicate property names. Duplicate properties cant be declared in an assembly(class)
            List <string> varlist = new List <string>();
            int           counter = 1;

            foreach (string var in vars)
            {
                Type   type         = typeof(string);
                string propertyName = var.Replace(".", "");

                #region Duplicate property fixing logic
                if (varlist.Contains(propertyName))
                {
                    propertyName = propertyName + counter.ToString();
                    counter++;
                }
                varlist.Add(propertyName);
                #endregion

                // Generate a private field
                FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
                // Generate a public property
                PropertyBuilder property =
                    typeBuilder.DefineProperty(propertyName,
                                               PropertyAttributes.None,
                                               type,
                                               new Type[] { type });

                // The property set and property get methods require a special set of attributes:

                MethodAttributes GetSetAttr =
                    MethodAttributes.Public |
                    MethodAttributes.HideBySig;

                // Define the "get" accessor method for current private field.
                MethodBuilder currGetPropMthdBldr =
                    typeBuilder.DefineMethod("get_value",
                                             GetSetAttr,
                                             type,
                                             Type.EmptyTypes);

                // Intermediate Language stuff...
                ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
                currGetIL.Emit(OpCodes.Ldarg_0);
                currGetIL.Emit(OpCodes.Ldfld, field);
                currGetIL.Emit(OpCodes.Ret);

                // Define the "set" accessor method for current private field.
                MethodBuilder currSetPropMthdBldr =
                    typeBuilder.DefineMethod("set_value",
                                             GetSetAttr,
                                             null,
                                             new Type[] { type });

                // Again some Intermediate Language stuff...
                ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
                currSetIL.Emit(OpCodes.Ldarg_0);
                currSetIL.Emit(OpCodes.Ldarg_1);
                currSetIL.Emit(OpCodes.Stfld, field);
                currSetIL.Emit(OpCodes.Ret);

                // Last, we must map the two methods created above to our PropertyBuilder to
                // their corresponding behaviors, "get" and "set" respectively.
                property.SetGetMethod(currGetPropMthdBldr);
                property.SetSetMethod(currSetPropMthdBldr);
            }
            Type generetedType = typeBuilder.CreateType();
            return(generetedType);
        }
Пример #51
0
        public CompiledMethod(CompiledClass parent, string name, BracketFragment parameterBlock, BracketFragment codeBlock, TypeFragment retType, bool isPublic)
        {
            Name           = name;
            Parent         = parent;
            CodeBlock      = codeBlock;
            Script         = Parent.Script;
            ParameterBlock = parameterBlock;

            Type returnType = null;

            if (retType != null)
            {
                returnType = retType.FindType(Script);
                if (returnType == null)
                {
                    Error("Type '" + retType.Value + "' was not found.");
                }
            }
            string           methodName = Name;
            MethodAttributes attrib     = isPublic?MethodAttributes.Public:MethodAttributes.Private;

            if (methodName == "new")
            {
                methodName = ".ctor";
                attrib    |= MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
            }
            // Does the parent base type define this method?
            // If so, use it's name.
            Type baseType = Parent.Builder.BaseType;

            // Parse the parameter set right away:
            ParseParameters();

            MethodInfo mInfo = Types.GetOverload(baseType.GetMethods(), Name, ParameterTypes, true);

            if (mInfo != null)
            {
                methodName = mInfo.Name;
                attrib    |= MethodAttributes.Virtual | MethodAttributes.HideBySig;         //|MethodAttributes.NewSlot;
            }

            bool isVoid = Types.IsVoid(returnType);

            if (isVoid)
            {
                returnType = typeof(void);
            }

            Builder = Parent.Builder.DefineMethod(
                methodName,
                attrib,
                returnType,
                null
                );

            ApplyParameters();

            ILStream    = new NitroIL(Builder.GetILGenerator());
            EndOfMethod = ILStream.DefineLabel();
            if (!isVoid)
            {
                ReturnBay = ILStream.DeclareLocal(returnType);
            }
        }
Пример #52
0
 public static CodeMethod DefineConstructor(CodeClass cls, MethodAttributes attributes, Type[] parameterTypes)
 {
     return(new CodeMethod(cls, attributes, parameterTypes));
 }
Пример #53
0
 public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)
 {
     return(DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet));
 }
Пример #54
0
        private static ConstructorInfo FromBinary(
            Reader reader,
            System.Type instanceContainer,
            System.Type exportContainer,
            IEnumerable <RuntimeImport> imports
            )
        {
            if (reader.ReadUInt32() != Module.Magic)
            {
                throw new ModuleLoadException("File preamble magic value is incorrect.", 0);
            }

            switch (reader.ReadUInt32())
            {
            case 0x1:                     //First release
            case 0xd:                     //Final pre-release, binary format is identical with first release.
                break;

            default:
                throw new ModuleLoadException("Unsupported version, only version 0x1 and 0xd are accepted.", 4);
            }

            uint memoryPagesMinimum = 0;
            uint memoryPagesMaximum = 0;

            Signature[] signatures         = null;
            Signature[] functionSignatures = null;
            KeyValuePair <string, uint>[] exportedFunctions = null;
            var previousSection = Section.None;

            var module = AssemblyBuilder.DefineDynamicAssembly(
                new AssemblyName("CompiledWebAssembly"),
                AssemblyBuilderAccess.RunAndCollect
                )
                         .DefineDynamicModule("CompiledWebAssembly")
            ;

            const TypeAttributes classAttributes =
                TypeAttributes.Public |
                TypeAttributes.Class |
                TypeAttributes.BeforeFieldInit
            ;

            const MethodAttributes constructorAttributes =
                MethodAttributes.Public |
                MethodAttributes.HideBySig |
                MethodAttributes.SpecialName |
                MethodAttributes.RTSpecialName
            ;

            const MethodAttributes internalFunctionAttributes =
                MethodAttributes.Assembly |
                MethodAttributes.Static |
                MethodAttributes.HideBySig
            ;

            const MethodAttributes exportedFunctionAttributes =
                MethodAttributes.Public |
                MethodAttributes.Virtual |
                MethodAttributes.Final |
                MethodAttributes.HideBySig
            ;

            var          exportsBuilder = module.DefineType("CompiledExports", classAttributes, exportContainer);
            FieldBuilder memory         = null;

            ILGenerator instanceConstructorIL;
            {
                var instanceConstructor = exportsBuilder.DefineConstructor(constructorAttributes, CallingConventions.Standard, System.Type.EmptyTypes);
                instanceConstructorIL = instanceConstructor.GetILGenerator();
                {
                    var usableConstructor = exportContainer.GetTypeInfo().DeclaredConstructors.FirstOrDefault(c => c.GetParameters().Length == 0);
                    if (usableConstructor != null)
                    {
                        instanceConstructorIL.Emit(OpCodes.Ldarg_0);
                        instanceConstructorIL.Emit(OpCodes.Call, usableConstructor);
                    }
                }
            }

            var exports           = exportsBuilder.AsType();
            var importedFunctions = 0;

            MethodInfo[]       internalFunctions = null;
            Indirect[]         functionElements  = null;
            GlobalInfo[]       globalGetters     = null;
            GlobalInfo[]       globalSetters     = null;
            CompilationContext context           = null;
            MethodInfo         startFunction     = null;

            while (reader.TryReadVarUInt7(out var id))             //At points where TryRead is used, the stream can safely end.
            {
                var payloadLength = reader.ReadVarUInt32();
                if (id != 0 && (Section)id < previousSection)
                {
                    throw new ModuleLoadException($"Sections out of order; section {(Section)id} encounterd after {previousSection}.", reader.Offset);
                }

                switch ((Section)id)
                {
                case Section.None:
                {
                    var preNameOffset = reader.Offset;
                    reader.ReadString(reader.ReadVarUInt32());                                         //Name
                    reader.ReadBytes(payloadLength - checked ((uint)(reader.Offset - preNameOffset))); //Content
                }
                break;

                case Section.Type:
                {
                    signatures = new Signature[reader.ReadVarUInt32()];

                    for (var i = 0; i < signatures.Length; i++)
                    {
                        signatures[i] = new Signature(reader, (uint)i);
                    }
                }
                break;

                case Section.Import:
                {
                    if (imports == null)
                    {
                        imports = Enumerable.Empty <RuntimeImport>();
                    }

                    var importsByName = imports.ToDictionary(import => new Tuple <string, string>(import.ModuleName, import.FieldName));

                    var count           = reader.ReadVarUInt32();
                    var functionImports = new List <MethodInfo>(checked ((int)count));

                    for (var i = 0; i < count; i++)
                    {
                        var moduleName = reader.ReadString(reader.ReadVarUInt32());
                        var fieldName  = reader.ReadString(reader.ReadVarUInt32());

                        if (!importsByName.TryGetValue(new Tuple <string, string>(moduleName, fieldName), out var import))
                        {
                            throw new CompilerException($"Import not found for {moduleName}::{fieldName}.");
                        }

                        var kind = (ExternalKind)reader.ReadByte();

                        switch (kind)
                        {
                        case ExternalKind.Function:
                            var typeIndex = reader.ReadVarUInt32();
                            if (!(import is FunctionImport functionImport))
                            {
                                throw new CompilerException($"{moduleName}::{fieldName} is expected to be a function, but provided import was not.");
                            }

                            if (!signatures[typeIndex].Equals(functionImport.Type))
                            {
                                throw new CompilerException($"{moduleName}::{fieldName} did not match the required type signature.");
                            }

                            functionImports.Add(functionImport.Method);
                            break;

                        case ExternalKind.Table:
                        case ExternalKind.Memory:
                        case ExternalKind.Global:
                            throw new ModuleLoadException($"Imported external kind of {kind} is not currently supported.", reader.Offset);

                        default:
                            throw new ModuleLoadException($"Imported external kind of {kind} is not recognized.", reader.Offset);
                        }
                    }

                    importedFunctions = functionImports.Count;
                    internalFunctions = functionImports.ToArray();
                }
                break;

                case Section.Function:
                {
                    functionSignatures = new Signature[reader.ReadVarUInt32()];
                    var importedFunctionCount = internalFunctions == null ? 0 : internalFunctions.Length;
                    if (importedFunctionCount != 0)
                    {
                        Array.Resize(ref internalFunctions, checked (importedFunctionCount + functionSignatures.Length));
                    }
                    else
                    {
                        internalFunctions = new MethodInfo[functionSignatures.Length];
                    }

                    for (var i = 0; i < functionSignatures.Length; i++)
                    {
                        var signature = functionSignatures[i] = signatures[reader.ReadVarUInt32()];
                        var parms     = signature.ParameterTypes.Concat(new[] { exports }).ToArray();
                        internalFunctions[importedFunctionCount + i] = exportsBuilder.DefineMethod(
                            $"👻 {i}",
                            internalFunctionAttributes,
                            CallingConventions.Standard,
                            signature.ReturnTypes.FirstOrDefault(),
                            parms
                            );
                    }
                }
                break;

                case Section.Table:
                {
                    var count = reader.ReadVarUInt32();
                    for (var i = 0; i < count; i++)
                    {
                        var elementType = (ElementType)reader.ReadVarInt7();
                        switch (elementType)
                        {
                        default:
                            throw new ModuleLoadException($"Element type {elementType} not supported.", reader.Offset);

                        case ElementType.AnyFunction:
                            var setFlags = (ResizableLimits.Flags)reader.ReadVarUInt32();
                            functionElements = new Indirect[reader.ReadVarUInt32()];
                            if ((setFlags & ResizableLimits.Flags.Maximum) != 0)
                            {
                                reader.ReadVarUInt32();                                                         //Not used.
                            }
                            break;
                        }
                    }
                }
                break;

                case Section.Memory:
                {
                    var count = reader.ReadVarUInt32();
                    if (count > 1)
                    {
                        throw new ModuleLoadException("Multiple memory values are not supported.", reader.Offset);
                    }

                    var setFlags = (ResizableLimits.Flags)reader.ReadVarUInt32();
                    memoryPagesMinimum = reader.ReadVarUInt32();
                    if ((setFlags & ResizableLimits.Flags.Maximum) != 0)
                    {
                        memoryPagesMaximum = Math.Min(reader.ReadVarUInt32(), uint.MaxValue / Memory.PageSize);
                    }
                    else
                    {
                        memoryPagesMaximum = uint.MaxValue / Memory.PageSize;
                    }

                    memory = exportsBuilder.DefineField("☣ Memory", typeof(Runtime.UnmanagedMemory), FieldAttributes.Private | FieldAttributes.InitOnly);

                    instanceConstructorIL.Emit(OpCodes.Ldarg_0);
                    Instructions.Int32Constant.Emit(instanceConstructorIL, (int)memoryPagesMinimum);
                    Instructions.Int32Constant.Emit(instanceConstructorIL, (int)memoryPagesMaximum);
                    instanceConstructorIL.Emit(OpCodes.Newobj, typeof(uint?).GetTypeInfo().DeclaredConstructors.Where(info =>
                        {
                            var parms = info.GetParameters();
                            return(parms.Length == 1 && parms[0].ParameterType == typeof(uint));
                        }).First());
                    instanceConstructorIL.Emit(OpCodes.Newobj, typeof(Runtime.UnmanagedMemory).GetTypeInfo().DeclaredConstructors.Where(info =>
                        {
                            var parms = info.GetParameters();
                            return(parms.Length == 2 && parms[0].ParameterType == typeof(uint) && parms[1].ParameterType == typeof(uint?));
                        }).First());
                    instanceConstructorIL.Emit(OpCodes.Stfld, memory);

                    exportsBuilder.AddInterfaceImplementation(typeof(IDisposable));

                    var dispose = exportsBuilder.DefineMethod(
                        "Dispose",
                        MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                        CallingConventions.HasThis,
                        typeof(void),
                        System.Type.EmptyTypes
                        );

                    var disposeIL = dispose.GetILGenerator();
                    disposeIL.Emit(OpCodes.Ldarg_0);
                    disposeIL.Emit(OpCodes.Ldfld, memory);
                    disposeIL.Emit(OpCodes.Call, typeof(Runtime.UnmanagedMemory)
                                   .GetTypeInfo()
                                   .DeclaredMethods
                                   .Where(info =>
                                          info.ReturnType == typeof(void) &&
                                          info.GetParameters().Length == 0 &&
                                          info.Name == nameof(Runtime.UnmanagedMemory.Dispose))
                                   .First());
                    disposeIL.Emit(OpCodes.Ret);
                }
                break;

                case Section.Global:
                {
                    var count = reader.ReadVarUInt32();
                    globalGetters = new GlobalInfo[count];
                    globalSetters = new GlobalInfo[count];

                    context = new CompilationContext(
                        exportsBuilder,
                        memory,
                        functionSignatures,
                        internalFunctions,
                        signatures,
                        functionElements,
                        module,
                        globalGetters,
                        globalSetters
                        );

                    var emptySignature = Signature.Empty;

                    for (var i = 0; i < globalGetters.Length; i++)
                    {
                        var contentType = (ValueType)reader.ReadVarInt7();
                        var isMutable   = reader.ReadVarUInt1() == 1;

                        var getter = exportsBuilder.DefineMethod(
                            $"🌍 Get {i}",
                            internalFunctionAttributes,
                            CallingConventions.Standard,
                            contentType.ToSystemType(),
                            isMutable ? new[] { exports } : null
                            );

                        globalGetters[i] = new GlobalInfo(contentType, isMutable, getter);

                        var il = getter.GetILGenerator();
                        var getterSignature = new Signature(contentType);

                        if (isMutable == false)
                        {
                            context.Reset(
                                il,
                                getterSignature,
                                getterSignature.RawParameterTypes
                                );

                            foreach (var instruction in Instruction.ParseInitializerExpression(reader))
                            {
                                instruction.Compile(context);
                                context.Previous = instruction.OpCode;
                            }
                        }
                        else                                         //Mutable
                        {
                            var field = exportsBuilder.DefineField(
                                $"🌍 {i}",
                                contentType.ToSystemType(),
                                FieldAttributes.Private | (isMutable ? 0 : FieldAttributes.InitOnly)
                                );

                            il.Emit(OpCodes.Ldarg_0);
                            il.Emit(OpCodes.Ldfld, field);
                            il.Emit(OpCodes.Ret);

                            var setter = exportsBuilder.DefineMethod(
                                $"🌍 Set {i}",
                                internalFunctionAttributes,
                                CallingConventions.Standard,
                                typeof(void),
                                new[] { contentType.ToSystemType(), exports }
                                );

                            il = setter.GetILGenerator();
                            il.Emit(OpCodes.Ldarg_1);
                            il.Emit(OpCodes.Ldarg_0);
                            il.Emit(OpCodes.Stfld, field);
                            il.Emit(OpCodes.Ret);

                            globalSetters[i] = new GlobalInfo(contentType, isMutable, setter);

                            context.Reset(
                                instanceConstructorIL,
                                emptySignature,
                                emptySignature.RawParameterTypes
                                );

                            context.EmitLoadThis();
                            var ended = false;

                            foreach (var instruction in Instruction.ParseInitializerExpression(reader))
                            {
                                if (ended)
                                {
                                    throw new CompilerException("Only a single End is allowed within an initializer expression.");
                                }

                                if (instruction.OpCode == OpCode.End)
                                {
                                    context.Emit(OpCodes.Stfld, field);
                                    ended = true;
                                    continue;
                                }

                                instruction.Compile(context);
                                context.Previous = instruction.OpCode;
                            }
                        }
                    }
                }
                break;

                case Section.Export:
                {
                    const MethodAttributes exportedPropertyAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual | MethodAttributes.Final;
                    var totalExports = reader.ReadVarUInt32();
                    var xFunctions   = new List <KeyValuePair <string, uint> >((int)Math.Min(int.MaxValue, totalExports));

                    for (var i = 0; i < totalExports; i++)
                    {
                        var name = reader.ReadString(reader.ReadVarUInt32());

                        var kind  = (ExternalKind)reader.ReadByte();
                        var index = reader.ReadVarUInt32();
                        switch (kind)
                        {
                        case ExternalKind.Function:
                            xFunctions.Add(new KeyValuePair <string, uint>(name, index));
                            break;

                        case ExternalKind.Table:
                            throw new NotSupportedException($"Unsupported export kind {kind}.");

                        case ExternalKind.Memory:
                            if (index != 0)
                            {
                                throw new ModuleLoadException($"Exported memory must be of index 0, found {index}.", reader.Offset);
                            }
                            if (memory == null)
                            {
                                throw new CompilerException("Cannot export linear memory when linear memory is not defined.");
                            }

                            {
                                var memoryGetter = exportsBuilder.DefineMethod("get_" + name,
                                                                               exportedPropertyAttributes,
                                                                               CallingConventions.HasThis,
                                                                               typeof(Runtime.UnmanagedMemory),
                                                                               System.Type.EmptyTypes
                                                                               );
                                var getterIL = memoryGetter.GetILGenerator();
                                getterIL.Emit(OpCodes.Ldarg_0);
                                getterIL.Emit(OpCodes.Ldfld, memory);
                                getterIL.Emit(OpCodes.Ret);

                                exportsBuilder.DefineProperty(name, PropertyAttributes.None, typeof(Runtime.UnmanagedMemory), System.Type.EmptyTypes)
                                .SetGetMethod(memoryGetter);
                            }
                            break;

                        case ExternalKind.Global:
                            if (index >= globalGetters.Length)
                            {
                                throw new ModuleLoadException($"Exported global index of {index} is greater than the number of globals {globalGetters.Length}.", reader.Offset);
                            }

                            {
                                var getter     = globalGetters[i];
                                var setter     = globalSetters[i];
                                var property   = exportsBuilder.DefineProperty(name, PropertyAttributes.None, getter.Type.ToSystemType(), System.Type.EmptyTypes);
                                var wrappedGet = exportsBuilder.DefineMethod("get_" + name,
                                                                             exportedPropertyAttributes,
                                                                             CallingConventions.HasThis,
                                                                             getter.Type.ToSystemType(),
                                                                             System.Type.EmptyTypes
                                                                             );

                                var wrappedGetIL = wrappedGet.GetILGenerator();
                                if (getter.IsMutable)
                                {
                                    wrappedGetIL.Emit(OpCodes.Ldarg_0);
                                }
                                wrappedGetIL.Emit(OpCodes.Call, getter.Builder);
                                wrappedGetIL.Emit(OpCodes.Ret);
                                property.SetGetMethod(wrappedGet);

                                if (setter != null)
                                {
                                    var wrappedSet = exportsBuilder.DefineMethod("set_" + name,
                                                                                 exportedPropertyAttributes,
                                                                                 CallingConventions.HasThis,
                                                                                 null,
                                                                                 new [] { getter.Type.ToSystemType() }
                                                                                 );

                                    var wrappedSetIL = wrappedSet.GetILGenerator();
                                    wrappedSetIL.Emit(OpCodes.Ldarg_1);
                                    wrappedSetIL.Emit(OpCodes.Ldarg_0);
                                    wrappedSetIL.Emit(OpCodes.Call, setter.Builder);
                                    wrappedSetIL.Emit(OpCodes.Ret);

                                    property.SetSetMethod(wrappedSet);
                                }
                            }
                            break;

                        default:
                            throw new NotSupportedException($"Unrecognized export kind {kind}.");
                        }
                    }

                    exportedFunctions = xFunctions.ToArray();
                }
                break;

                case Section.Start:
                {
                    var preReadOffset = reader.Offset;
                    var startIndex    = reader.ReadVarInt32();
                    if (startIndex >= internalFunctions.Length)
                    {
                        throw new ModuleLoadException($"Start function of index {startIndex} exceeds available functions of {internalFunctions.Length}", preReadOffset);
                    }

                    startFunction = internalFunctions[startIndex];
                }
                break;

                case Section.Element:
                {
                    if (functionElements == null)
                    {
                        throw new ModuleLoadException("Element section found without an associated table section.", reader.Offset);
                    }

                    var count = reader.ReadVarUInt32();
                    for (var i = 0; i < count; i++)
                    {
                        var index = reader.ReadVarUInt32();
                        if (index != 0)
                        {
                            throw new ModuleLoadException($"Index value of anything other than 0 is not supported, {index} found.", reader.Offset);
                        }

                        {
                            var initializer = Instruction.ParseInitializerExpression(reader).ToArray();
                            if (initializer.Length != 2 || !(initializer[0] is Instructions.Int32Constant c) || c.Value != 0 || !(initializer[1] is Instructions.End))
                            {
                                throw new ModuleLoadException("Initializer expression support for the Element section is limited to a single Int32 constant of 0 followed by end.", reader.Offset);
                            }
                        }

                        var elements = reader.ReadVarUInt32();
                        if (elements != functionElements.Length)
                        {
                            throw new ModuleLoadException($"Element count {elements} does not match the indication provided by the earlier table {functionElements.Length}.", reader.Offset);
                        }

                        for (var j = 0; j < functionElements.Length; j++)
                        {
                            var functionIndex = reader.ReadVarUInt32();
                            functionElements[j] = new Indirect(
                                functionSignatures[functionIndex].TypeIndex,
                                (MethodBuilder)internalFunctions[importedFunctions + functionIndex]
                                );
                        }
                    }
                }
                break;

                case Section.Code:
                {
                    var functionBodies = reader.ReadVarUInt32();

                    if (functionBodies > 0 && functionSignatures == null)
                    {
                        throw new ModuleLoadException("Code section is invalid when Function section is missing.", reader.Offset);
                    }
                    if (functionBodies != functionSignatures.Length)
                    {
                        throw new ModuleLoadException($"Code section has {functionBodies} functions described but {functionSignatures.Length} were expected.", reader.Offset);
                    }

                    if (context == null)                                     //Might have been created by the Global section, if present.
                    {
                        context = new CompilationContext(
                            exportsBuilder,
                            memory,
                            functionSignatures,
                            internalFunctions,
                            signatures,
                            functionElements,
                            module,
                            globalGetters,
                            globalSetters
                            );
                    }

                    for (var functionBodyIndex = 0; functionBodyIndex < functionBodies; functionBodyIndex++)
                    {
                        var signature      = functionSignatures[functionBodyIndex];
                        var byteLength     = reader.ReadVarUInt32();
                        var startingOffset = reader.Offset;

                        var locals = new Local[reader.ReadVarUInt32()];
                        for (var localIndex = 0; localIndex < locals.Length; localIndex++)
                        {
                            locals[localIndex] = new Local(reader);
                        }

                        var il = ((MethodBuilder)internalFunctions[importedFunctions + functionBodyIndex]).GetILGenerator();

                        context.Reset(
                            il,
                            signature,
                            signature.RawParameterTypes.Concat(
                                locals
                                .SelectMany(local => Enumerable.Range(0, checked ((int)local.Count)).Select(_ => local.Type))
                                ).ToArray()
                            );

                        foreach (var local in locals.SelectMany(local => Enumerable.Range(0, checked ((int)local.Count)).Select(_ => local.Type)))
                        {
                            il.DeclareLocal(local.ToSystemType());
                        }

                        foreach (var instruction in Instruction.Parse(reader))
                        {
                            instruction.Compile(context);
                            context.Previous = instruction.OpCode;
                        }

                        if (reader.Offset - startingOffset != byteLength)
                        {
                            throw new ModuleLoadException($"Instruction sequence reader ended after readering {reader.Offset - startingOffset} characters, expected {byteLength}.", reader.Offset);
                        }
                    }
                }
                break;

                case Section.Data:
                {
                    if (memory == null)
                    {
                        throw new ModuleLoadException("Data section cannot be used unless a memory section is defined.", reader.Offset);
                    }

                    var count = reader.ReadVarUInt32();

                    if (context == null)                                     //Would only be null if there is no Global or Code section, but have to check.
                    {
                        context = new CompilationContext(
                            exportsBuilder,
                            memory,
                            new Signature[0],
                            new MethodInfo[0],
                            new Signature[0],
                            functionElements,
                            module,
                            globalGetters,
                            globalSetters
                            );
                    }

                    context.Reset(
                        instanceConstructorIL,
                        Signature.Empty,
                        Signature.Empty.RawParameterTypes
                        );
                    var block = new Instructions.Block(BlockType.Int32);

                    var address = instanceConstructorIL.DeclareLocal(typeof(uint));

                    for (var i = 0; i < count; i++)
                    {
                        var startingOffset = reader.Offset;
                        {
                            var index = reader.ReadVarUInt32();
                            if (index != 0)
                            {
                                throw new ModuleLoadException($"Data index must be 0, found {index}.", startingOffset);
                            }
                        }

                        block.Compile(context);                                         //Prevents "end" instruction of the initializer expression from becoming a return.
                        foreach (var instruction in Instruction.ParseInitializerExpression(reader))
                        {
                            instruction.Compile(context);
                            context.Previous = instruction.OpCode;
                        }
                        context.Stack.Pop();
                        instanceConstructorIL.Emit(OpCodes.Stloc, address);

                        var data = reader.ReadBytes(reader.ReadVarUInt32());

                        //Ensure sufficient memory is allocated, error if max is exceeded.
                        instanceConstructorIL.Emit(OpCodes.Ldloc, address);
                        instanceConstructorIL.Emit(OpCodes.Ldc_I4, data.Length);
                        instanceConstructorIL.Emit(OpCodes.Add_Ovf_Un);

                        instanceConstructorIL.Emit(OpCodes.Ldarg_0);

                        instanceConstructorIL.Emit(OpCodes.Call, context[HelperMethod.RangeCheck8, Instructions.MemoryImmediateInstruction.CreateRangeCheck]);
                        instanceConstructorIL.Emit(OpCodes.Pop);

                        if (data.Length > 0x3f0000)                                         //Limitation of DefineInitializedData, can be corrected by splitting the data.
                        {
                            throw new NotSupportedException($"Data segment {i} is length {data.Length}, exceeding the current implementation limit of 4128768.");
                        }

                        var field = exportsBuilder.DefineInitializedData($"☣ Data {i}", data, FieldAttributes.Assembly | FieldAttributes.InitOnly);

                        instanceConstructorIL.Emit(OpCodes.Ldarg_0);
                        instanceConstructorIL.Emit(OpCodes.Ldfld, memory);
                        instanceConstructorIL.Emit(OpCodes.Call, Runtime.UnmanagedMemory.StartGetter);
                        instanceConstructorIL.Emit(OpCodes.Ldloc, address);
                        instanceConstructorIL.Emit(OpCodes.Conv_I);
                        instanceConstructorIL.Emit(OpCodes.Add_Ovf_Un);

                        instanceConstructorIL.Emit(OpCodes.Ldsflda, field);

                        instanceConstructorIL.Emit(OpCodes.Ldc_I4, data.Length);

                        instanceConstructorIL.Emit(OpCodes.Cpblk);
                    }
                }
                break;

                default:
                    throw new ModuleLoadException($"Unrecognized section type {(Section)id}.", reader.Offset);
                }

                previousSection = (Section)id;
            }

            if (exportedFunctions != null)
            {
                for (var i = 0; i < exportedFunctions.Length; i++)
                {
                    var exported  = exportedFunctions[i];
                    var signature = functionSignatures[exported.Value - importedFunctions];

                    var method = exportsBuilder.DefineMethod(
                        exported.Key,
                        exportedFunctionAttributes,
                        CallingConventions.HasThis,
                        signature.ReturnTypes.FirstOrDefault(),
                        signature.ParameterTypes
                        );

                    var il = method.GetILGenerator();
                    for (var parm = 0; parm < signature.ParameterTypes.Length; parm++)
                    {
                        il.Emit(OpCodes.Ldarg, parm + 1);
                    }

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Call, internalFunctions[exported.Value]);
                    il.Emit(OpCodes.Ret);
                }
            }

            if (startFunction != null)
            {
                instanceConstructorIL.Emit(OpCodes.Ldarg_0);
                instanceConstructorIL.Emit(OpCodes.Call, startFunction);
            }

            instanceConstructorIL.Emit(OpCodes.Ret);             //Finish the constructor.
            var exportInfo = exportsBuilder.CreateTypeInfo();

            TypeInfo instance;

            {
                var instanceBuilder     = module.DefineType("CompiledInstance", classAttributes, instanceContainer);
                var instanceConstructor = instanceBuilder.DefineConstructor(constructorAttributes, CallingConventions.Standard, null);
                var il = instanceConstructor.GetILGenerator();
                var memoryAllocated = checked (memoryPagesMaximum * Memory.PageSize);

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Newobj, exportInfo.DeclaredConstructors.First());
                il.Emit(OpCodes.Call, instanceContainer
                        .GetTypeInfo()
                        .DeclaredConstructors
                        .First(info => info.GetParameters()
                               .FirstOrDefault()
                               ?.ParameterType == exportContainer
                               )
                        );
                il.Emit(OpCodes.Ret);

                instance = instanceBuilder.CreateTypeInfo();
            }

            module.CreateGlobalFunctions();
            return(instance.DeclaredConstructors.First());
        }
Пример #55
0
 private bool HasFlag(MethodAttributes flag)
 {
     // flag must be exactly one bit
     Debug.Assert(flag != 0 && ((ushort)flag & ((ushort)flag - 1)) == 0);
     return(((ushort)flag & _flags) != 0);
 }
        static Type EnsureDelegateType(BuildContext context, MethodInfo method)
        {
            // The delegate should be defined as inner type of context.TypeBuilder.
            // It's possible, but we can not define and use newly defined type as Emit target in its owner type.
            // To solve this problem, we should create a top level delegate and make sure its name is unique.
            //
            var delegateName = context.TypeBuilder.TypeBuilder.FullName + "$" + method.Name + "$Delegate";
            var delegateType = context.GetItem <Type>(delegateName);

            if (delegateType == null)
            {
                var pi         = method.GetParameters();
                var parameters = new Type[pi.Length];

                for (var i = 0; i < pi.Length; i++)
                {
                    parameters[i] = pi[i].ParameterType;
                }

                const MethodImplAttributes mia = MethodImplAttributes.Runtime | MethodImplAttributes.Managed;
                const MethodAttributes     ma  = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual;

                Debug.Assert(context.AssemblyBuilder != null, "context.AssemblyBuilder != null");

                var delegateBuilder = context.AssemblyBuilder.DefineType(delegateName,
                                                                         TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass,
                                                                         typeof(MulticastDelegate));

                // Create constructor
                //
                var ctorBuilder = delegateBuilder.DefineConstructor(
                    MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName, CallingConventions.Standard,
                    typeof(object), typeof(IntPtr));
                ctorBuilder.ConstructorBuilder.SetImplementationFlags(mia);

                // Define the BeginInvoke method for the delegate
                //
                var beginParameters = new Type[parameters.Length + 2];

                Array.Copy(parameters, 0, beginParameters, 0, parameters.Length);
                beginParameters[parameters.Length]     = typeof(AsyncCallback);
                beginParameters[parameters.Length + 1] = typeof(object);

                var methodBuilder = delegateBuilder.DefineMethod("BeginInvoke", ma, typeof(IAsyncResult), beginParameters);

                methodBuilder.MethodBuilder.SetImplementationFlags(mia);

                // Define the EndInvoke method for the delegate
                //
                methodBuilder = delegateBuilder.DefineMethod("EndInvoke", ma, method.ReturnType, typeof(IAsyncResult));
                methodBuilder.MethodBuilder.SetImplementationFlags(mia);

                // Define the Invoke method for the delegate
                //
                methodBuilder = delegateBuilder.DefineMethod("Invoke", ma, method.ReturnType, parameters);
                methodBuilder.MethodBuilder.SetImplementationFlags(mia);

                context.Items.Add(delegateName, delegateType = delegateBuilder.Create());
            }

            return(delegateType);
        }
Пример #57
0
 public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
 {
     this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, securityAction, permissionSet);
     this.attributes |= MethodAttributes.HasSecurity;
 }
Пример #58
0
 public void __SetAttributes(MethodAttributes attributes)
 {
     this.attributes = attributes;
 }
Пример #59
0
 public DynamicMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) : this(name, attributes, callingConvention, returnType, parameterTypes, null, m, skipVisibility, false)
 {
 }
Пример #60
0
        public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention,
                                                 Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
                                                 Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
                                                 CallingConvention nativeCallConv, CharSet nativeCharSet)
        {
            MethodBuilder mb = DefineMethod(name, attributes | MethodAttributes.PinvokeImpl, callingConvention,
                                            returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
                                            parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);

            mb.SetDllImportPseudoCustomAttribute(dllName, entryName, nativeCallConv, nativeCharSet, null, null, null, null, null);
            return(mb);
        }