Пример #1
0
		public void Load( MethodEmitter method )
		{
			if ( m_Field != null )
			{
				method.LoadArgument( 0 );
				method.LoadField( m_Field );
			}
			else if ( m_Value == null )
			{
				method.LoadNull( m_Type );
			}
			else
			{
				if ( m_Value is int )
					method.Load( (int) m_Value );
				else if ( m_Value is long )
					method.Load( (long) m_Value );
				else if ( m_Value is float )
					method.Load( (float) m_Value );
				else if ( m_Value is double )
					method.Load( (double) m_Value );
				else if ( m_Value is char )
					method.Load( (char) m_Value );
				else if ( m_Value is bool )
					method.Load( (bool) m_Value );
				else if ( m_Value is string )
					method.Load( (string) m_Value );
				else if ( m_Value is Enum )
					method.Load( (Enum) m_Value );
				else
					throw new InvalidOperationException( "Unrecognized comparison value." );
			}
		}
		protected override void ImplementInvokeMethodOnTarget(AbstractTypeEmitter @class, ParameterInfo[] parameters, MethodEmitter invokeMethodOnTarget, MethodInfo callbackMethod, Reference targetField)
		{
			invokeMethodOnTarget.CodeBuilder.AddStatement(
				new ExpressionStatement(
					new MethodInvocationExpression(SelfReference.Self, InvocationMethods.EnsureValidTarget)));
			base.ImplementInvokeMethodOnTarget(@class, parameters, invokeMethodOnTarget, callbackMethod, targetField);
		}
Пример #3
0
 void ICondition.Compile(MethodEmitter emitter)
 {
     // The object was safely cast to be the conditionals type
     // If it's null, then the type cast didn't work...
     emitter.LoadNull();
     emitter.Compare(OpCodes.Ceq);
     emitter.LogicalNot();
 }
        private Reference GetDelegate(AbstractTypeEmitter invocation, MethodEmitter invokeMethodOnTarget)
        {
            var closedDelegateType   = delegateType.MakeGenericType(invocation.GenericTypeParams);
            var localReference       = invokeMethodOnTarget.CodeBuilder.DeclareLocal(closedDelegateType);
            var closedMethodOnTarget = method.MethodOnTarget.MakeGenericMethod(invocation.GenericTypeParams);
            var localTarget          = new ReferenceExpression(targetReference);

            invokeMethodOnTarget.CodeBuilder.AddStatement(
                SetDelegate(localReference, localTarget, closedDelegateType, closedMethodOnTarget));
            return(localReference);
        }
Пример #5
0
        private Reference GetDelegate(AbstractTypeEmitter invocation, MethodEmitter invokeMethodOnTarget)
        {
            var genericTypeParameters = invocation.GenericTypeParams.AsTypeArray();
            var closedDelegateType    = delegateType.MakeGenericType(genericTypeParameters);
            var localReference        = invokeMethodOnTarget.CodeBuilder.DeclareLocal(closedDelegateType);
            var closedMethodOnTarget  = method.MethodOnTarget.MakeGenericMethod(genericTypeParameters);

            invokeMethodOnTarget.CodeBuilder.AddStatement(
                SetDelegate(localReference, targetReference, closedDelegateType, closedMethodOnTarget));
            return(localReference);
        }
        public MethodInvocationExpression GetCallbackMethodInvocation(
            AbstractTypeEmitter invocation,
            IExpression[] args,
            Reference targetField,
            MethodEmitter invokeMethodOnTarget
            )
        {
            var @delegate = GetDelegate(invocation, invokeMethodOnTarget);

            return(new MethodInvocationExpression(@delegate, GetCallbackMethod(), args));
        }
Пример #7
0
        protected void ImplementProxyTargetAccessor(ClassEmitter emitter, FieldReference interceptorsField)
        {
            MethodEmitter dynProxyGetTarget = emitter.CreateMethod("DynProxyGetTarget", typeof(object));

            dynProxyGetTarget.CodeBuilder.AddStatement(
                new ReturnStatement(new ConvertExpression(typeof(object), targetType, GetTargetReferenceExpression(emitter))));

            MethodEmitter getInterceptors = emitter.CreateMethod("GetInterceptors", typeof(IInterceptor[]));

            getInterceptors.CodeBuilder.AddStatement(
                new ReturnStatement(interceptorsField));
        }
Пример #8
0
 internal CodeBlock(ClassGenerator clazz, MethodEmitter emitter, params Parameter[] parameters)
 {
     this.Clazz             = clazz;
     this._emitter          = emitter;
     this._parent           = null;
     this._continuableBlock = false;
     LocalVariables.createNew(clazz.Handle(), "this");
     foreach (Parameter parameter in parameters)
     {
         LocalVariables.createNew(parameter.Type(), parameter.Name());
     }
 }
        public MethodInvocationExpression GetCallbackMethodInvocation(
            AbstractTypeEmitter invocation,
            IExpression[] args,
            Reference targetField,
            MethodEmitter invokeMethodOnTarget
            )
        {
            var allArgs   = GetAllArgs(args, targetField);
            var @delegate = (Reference)invocation.GetField("delegate");

            return(new MethodInvocationExpression(@delegate, GetCallbackMethod(), allArgs));
        }
        public void StaticMethodArguments()
        {
            ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "Foo", typeof(List <object>),
                                                    Type.EmptyTypes);
            MethodEmitter methodEmitter = emitter.CreateMethod("StaticMethod", MethodAttributes.Public | MethodAttributes.Static,
                                                               typeof(string), typeof(string));

            methodEmitter.CodeBuilder.AddStatement(new ReturnStatement(methodEmitter.Arguments[0]));
            Type t = emitter.BuildType();

            Assert.AreEqual("five", t.GetMethod("StaticMethod").Invoke(null, new object[] { "five" }));
        }
Пример #11
0
    /// <summary>
    /// Creates a reference to a parameter used in a custom attribute.
    /// </summary>
    /// <param name="emitter">The emitter.</param>
    /// <param name="attribute">The attribute.</param>
    /// <param name="arg">The argument.</param>
    public void CreateAttributeParameter(MethodEmitter emitter, CustomAttribute attribute, CustomAttributeArgument arg)
    {
        var il = emitter.GetIL();

        if (arg.Value == null)
        {
            il.Emit(Codes.Null);
            return;
        }

        var type = arg.Type;

        if (type.IsArray)
        {
            var elements = (arg.Value as IEnumerable).Cast <CustomAttributeArgument>().ToArray();

            il.Emit(Codes.Int(elements.Length));
            il.Emit(Codes.CreateArray(type.GetElementType()));

            if (elements.Length == 0)
            {
                return;
            }

            il.Emit(Codes.Duplicate);

            for (int i = 0, count = elements.Length; i < count; i++)
            {
                il.Emit(Codes.Int(i));

                if (elements[i].Value == null)
                {
                    il.Emit(Codes.Null);
                    il.Emit(Codes.StoreArray);
                }
                else
                {
                    il.Emit(Codes.Load(elements[i].Value));
                    il.Emit(Codes.StoreArray);
                }

                if (i + 1 < count)
                {
                    il.Emit(Codes.Duplicate);
                }
            }
        }
        else
        {
            il.Emit(Codes.Load(arg.Value));
        }
    }
Пример #12
0
    /// <summary>
    /// Create an attribute variable for a property definition.
    /// </summary>
    /// <param name="property">The property.</param>
    /// <param name="get">The getter method.</param>
    /// <param name="set">The setter method.</param>
    /// <param name="attribute">The attribute.</param>
    /// <param name="field">The optional field reference which was routed.</param>
    /// <returns></returns>
    public Variable[] CreateAttribute(PropertyEmitter property, MethodEmitter get, MethodEmitter set, CustomAttribute attribute, MemberReference field)
    {
        var method = get ?? set;
        var sta    = method.Target.IsStatic;

        var options = attribute.GetAttribute(Context.Finder.CompilationOptionsAttribute);
        var scope   = options.GetProperty("Scope", notFound: AttributeScopeSingleton);

        if (sta)
        {
            if (scope == AttributeScopeInstanced)
            {
                scope = AttributeScopeSingleton;
            }
            else if (scope == AttributeScopeMultiInstanced)
            {
                scope = AttributeScopeMultiSingleton;
            }
        }

        var hasGet = attribute.HasInterface(Context.Finder.IPropertyGetInterceptor);
        var hasSet = attribute.HasInterface(Context.Finder.IPropertySetInterceptor);

        switch (scope)
        {
        case AttributeScopeAdhoc:
            var adhocGet = hasGet && get != null?CreateAttributeAdhoc(get, attribute, property.Target) : null;

            var adhocSet = hasSet && set != null?CreateAttributeAdhoc(set, attribute, property.Target) : null;

            return(new[] { adhocGet, adhocSet });

        case AttributeScopeInstanced:
            var instanced = CreateAttributeInstanced(property.Parent, attribute, field ?? property.Target);
            return(new[] { hasGet?instanced : null, hasSet ? instanced : null });

        case AttributeScopeMultiInstanced:
            var multi = CreateAttributeMultiInstanced(property.Parent, attribute, field ?? property.Target);
            return(new[] { hasGet?multi : null, hasSet ? multi : null });

        case AttributeScopeSingleton:
            var singleton = CreateAttributeSingleton(property.Parent, attribute, field ?? property.Target);
            return(new[] { hasGet?singleton : null, hasSet ? singleton : null });

        case AttributeScopeMultiSingleton:
            var multiSingleton = CreateAttributeMultiSingleton(property.Parent, attribute, field ?? property.Target);
            return(new[] { hasGet?multiSingleton : null, hasSet ? multiSingleton : null });

        default:
            throw new NotSupportedException($"Cannot create attribute '{attribute.AttributeType.FullName}' with scope '{scope}'");
        }
    }
        public void InstanceMethodArguments()
        {
            ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "Foo", typeof(List <object>),
                                                    Type.EmptyTypes);
            MethodEmitter methodEmitter = emitter.CreateMethod("InstanceMethod", MethodAttributes.Public,
                                                               typeof(string), typeof(string));

            methodEmitter.CodeBuilder.AddStatement(new ReturnStatement(methodEmitter.Arguments[0]));
            Type   t        = emitter.BuildType();
            object instance = Activator.CreateInstance(t);

            Assert.AreEqual("six", t.GetMethod("InstanceMethod").Invoke(instance, new object[] { "six" }));
        }
Пример #14
0
 private void InitOutParameters(MethodEmitter emitter, ParameterInfo[] parameters)
 {
     for (var index = 0; index < parameters.Length; index++)
     {
         var parameter = parameters[index];
         if (parameter.IsOut)
         {
             emitter.CodeBuilder.AddStatement(
                 new AssignArgumentStatement(new ArgumentReference(parameter.ParameterType, index + 1),
                                             new DefaultValueExpression(parameter.ParameterType)));
         }
     }
 }
        protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class,
                                                                INamingScope namingScope)
        {
            var targetReference = getTargetReference(@class, MethodToOverride);

            emitter.CodeBuilder.AddStatement(
                new IfNullExpression(
                    targetReference,
                    IfNull(emitter.ReturnType),
                    IfNotNull(targetReference)));

            return(emitter);
        }
Пример #16
0
 public override void Close()
 {
     EndBlock();
     if (_parent != null)
     {
         _parent._emitter = _emitter;
     }
     else
     {
         _emitter.done();
     }
     this._emitter = InvalidState.BlockClosed;
 }
Пример #17
0
 public void Load(MethodEmitter method)
 {
     if (m_Field != null)
     {
         method.LoadArgument(0);
         method.LoadField(m_Field);
     }
     else if (m_Value == null)
     {
         method.LoadNull(m_Type);
     }
     else
     {
         if (m_Value is int i)
         {
             method.Load(i);
         }
         else if (m_Value is long lValue)
         {
             method.Load(lValue);
         }
         else if (m_Value is float fValue)
         {
             method.Load(fValue);
         }
         else if (m_Value is double dValue)
         {
             method.Load(dValue);
         }
         else if (m_Value is char cValue)
         {
             method.Load(cValue);
         }
         else if (m_Value is bool bValue)
         {
             method.Load(bValue);
         }
         else if (m_Value is string sValue)
         {
             method.Load(sValue);
         }
         else if (m_Value is Enum eValue)
         {
             method.Load(eValue);
         }
         else
         {
             throw new InvalidOperationException("Unrecognized comparison value.");
         }
     }
 }
Пример #18
0
 public void Load(MethodEmitter method)
 {
     if (Field != null)
     {
         method.LoadArgument(0);
         method.LoadField(Field);
     }
     else if (Value == null)
     {
         method.LoadNull(Type);
     }
     else
     {
         if (Value is int i)
         {
             method.Load(i);
         }
         else if (Value is long l)
         {
             method.Load(l);
         }
         else if (Value is float f)
         {
             method.Load(f);
         }
         else if (Value is double d)
         {
             method.Load(d);
         }
         else if (Value is char c)
         {
             method.Load(c);
         }
         else if (Value is bool b)
         {
             method.Load(b);
         }
         else if (Value is string s)
         {
             method.Load(s);
         }
         else if (Value is Enum e)
         {
             method.Load(e);
         }
         else
         {
             throw new InvalidOperationException("Unrecognized comparison value.");
         }
     }
 }
Пример #19
0
 public void Load(MethodEmitter method)
 {
     if (m_Field != null)
     {
         method.LoadArgument(0);
         method.LoadField(m_Field);
     }
     else if (m_Value == null)
     {
         method.LoadNull(m_Type);
     }
     else
     {
         if (m_Value is int)
         {
             method.Load((int)m_Value);
         }
         else if (m_Value is long)
         {
             method.Load((long)m_Value);
         }
         else if (m_Value is float)
         {
             method.Load((float)m_Value);
         }
         else if (m_Value is double)
         {
             method.Load((double)m_Value);
         }
         else if (m_Value is char)
         {
             method.Load((char)m_Value);
         }
         else if (m_Value is bool)
         {
             method.Load((bool)m_Value);
         }
         else if (m_Value is string)
         {
             method.Load((string)m_Value);
         }
         else if (m_Value is Enum)
         {
             method.Load((Enum)m_Value);
         }
         else
         {
             throw new InvalidOperationException("Unrecognized comparison value.");
         }
     }
 }
Пример #20
0
        public void TestCanEmit_InstancePropertyInitializer()
        {
            var stringType = assemblyEmitter.TypeSystem.String;
            var voidType   = assemblyEmitter.TypeSystem.Void;

            var initializer  = new LiteralNode(stringType, "aaa");
            var backingField = new FieldDefinition("testProperty_backingField", FieldAttributes.Private, stringType);

            var setter = new MethodEmitter(typeEmitter, "set_testProperty", voidType, MethodAttributes.Public);
            var value  = new ParameterDefinition("value", ParameterAttributes.None, stringType);

            var setterBody = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand = new FieldNode()
                        {
                            ObjectInstance = new ThisNode()
                            {
                                ExpressionReturnType = backingField.DeclaringType
                            },
                            Field = backingField
                        },
                        RightOperand = new ParameterNode(value)
                    }
                }
            };

            setter.AddArgument(value);
            setter.ParseTree(setterBody);

            var property = new PropertyDefinition("testProperty", PropertyAttributes.None, stringType);

            property.SetMethod = (MethodDefinition)setter.Get();

            typeEmitter.AddField(backingField);
            typeEmitter.AddProperty(property, initializer);

            var loadFieldExpression = new FieldNode()
            {
                ObjectInstance = ConstructTypeEmitterInstance(),
                Field          = backingField
            };

            GenerateBodyToOutputExpression(loadFieldExpression);
            ExpectedOutput = "aaa";
            AssertSuccessByExecution();
        }
Пример #21
0
        public CustomMethodEmitter(CustomClassEmitter declaringType, string name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNull("attributes", attributes);
            ArgumentUtility.CheckNotNull("methodToUseAsATemplate", methodToUseAsATemplate);

            MethodEmitter innerEmitter = declaringType.InnerEmitter.CreateMethod(name, attributes, methodToUseAsATemplate);

            _innerEmitter   = innerEmitter;
            _declaringType  = declaringType;
            _name           = name;
            _parameterTypes = _innerEmitter.Arguments.Select(a => a.Type).ToArray();
        }
        public void TestCanEmit_FunctionAssignmentToFunctorWithoutArgs()
        {
            var voidType = assemblyEmitter.TypeSystem.Void;

            var targetMethod = new MethodEmitter(typeEmitter, "TargetMethod", voidType);

            targetMethod.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    CallConsoleWriteLine(new LiteralNode(assemblyEmitter.TypeSystem.String, "TargetMethod was called"))
                }
            });

            var functorType = AssemblyRegistry.GetFunctorType(assemblyEmitter, targetMethod.Get());
            var field       = new FieldDefinition("myFunction", FieldAttributes.Public, functorType);

            var initializer = new FunctionNode()
            {
                Method         = targetMethod.Get(),
                ObjectInstance = new ThisNode()
                {
                    ExpressionReturnType = typeEmitter.Get(assemblyEmitter)
                },
                ExpressionReturnType = functorType
            };

            typeEmitter.AddField(field);
            typeEmitter.AddFieldInitializer(field, initializer);

            BodyCodeBlock = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new MethodCallNode()
                    {
                        ExpressionReturnType = voidType,
                        Function             = new FieldNode()
                        {
                            Field          = field,
                            ObjectInstance = ConstructTypeEmitterInstance()
                        },
                        Args = new IExpressionNode[0]
                    }
                }
            };

            ExpectedOutput = "TargetMethod was called";
            AssertSuccessByExecution();
        }
Пример #23
0
    /// <summary>
    /// Weaves all types which are candidates for method interception.
    /// </summary>
    public void WeaveMethodInterceptors()
    {
        var candidates = Context.Candidates.FindTypeByMethodInterceptors();

        foreach (var item in candidates)
        {
            var weaver = new TypeEmitter(Context.Module, item.Type, Context);

            foreach (var method in item.Methods)
            {
                var inner = new MethodEmitter(weaver, method.Method);
                WeaveMethodInterceptors(inner, method);
            }
        }
    }
Пример #24
0
        protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope)
        {
            var targetReference = getTargetReference(@class, MethodToOverride);
            var arguments       = ArgumentsUtil.ConvertToArgumentReferenceExpression(MethodToOverride.GetParameters());

            emitter.CodeBuilder.AddStatement(new ReturnStatement(
                                                 new MethodInvocationExpression(
                                                     targetReference,
                                                     MethodToOverride,
                                                     arguments)
            {
                VirtualCall = true
            }));
            return(emitter);
        }
Пример #25
0
    /// <summary>
    /// Creates a reference to a property used in a custom attribute.
    /// </summary>
    /// <param name="emitter">The emitter.</param>
    /// <param name="attribute">The attribute.</param>
    /// <param name="field">The attribute variable.</param>
    /// <param name="property">The property.</param>
    public void CreateAttributeProperty(MethodEmitter emitter, CustomAttribute attribute, Variable field, Mono.Cecil.CustomAttributeNamedArgument property)
    {
        var il     = emitter.GetIL();
        var member = field.Type.Resolve().Properties.FirstOrDefault(p => p.Name == property.Name)?.SetMethod;

        if (member == null)
        {
            throw new MissingMemberException($"Cannot resolve property {property.Name} of {attribute.AttributeType.Name} as there is no setter");
        }

        il.Emit(Codes.ThisIf(field));
        il.Emit(Codes.Load(field));
        CreateAttributeParameter(emitter, attribute, property.Argument);
        il.Emit(Codes.Invoke(member.Import()));
    }
Пример #26
0
        protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope)
        {
            InitOutParameters(emitter, MethodToOverride.GetParameters());

            if (emitter.ReturnType == typeof(void))
            {
                emitter.CodeBuilder.AddStatement(new ReturnStatement());
            }
            else
            {
                emitter.CodeBuilder.AddStatement(new ReturnStatement(new DefaultValueExpression(emitter.ReturnType)));
            }

            return(emitter);
        }
Пример #27
0
        public CustomMethodEmitter(CustomClassEmitter declaringType, string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNull("attributes", attributes);
            ArgumentUtility.CheckNotNull("returnType", returnType);
            ArgumentUtility.CheckNotNull("parameterTypes", parameterTypes);

            MethodEmitter innerEmitter = declaringType.InnerEmitter.CreateMethod(name, attributes, returnType, parameterTypes);

            _innerEmitter   = innerEmitter;
            _declaringType  = declaringType;
            _name           = name;
            _parameterTypes = parameterTypes;
        }
        public void TestCanEmit_FunctionAssignmentToDelegate()
        {
            var voidType = assemblyEmitter.TypeSystem.Void;

            var targetMethod = new MethodEmitter(typeEmitter, "TargetMethod", voidType, MethodAttributes.Private | MethodAttributes.Static);

            targetMethod.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    CallConsoleWriteLine(new LiteralNode(assemblyEmitter.TypeSystem.String, "Inside target method"))
                }
            });

            var declaringType = (TypeDefinition)typeEmitter.Get(assemblyEmitter);
            var delegateType  = DelegateEmitter.Create(assemblyEmitter, "MyDelegate", declaringType, voidType, new TypeReference[0]);

            declaringType.NestedTypes.Add(delegateType);

            var delegateField = new FieldDefinition("myDelegate", FieldAttributes.Public | FieldAttributes.Static, delegateType);

            typeEmitter.AddField(delegateField);

            BodyCodeBlock = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new FieldNode(delegateField),
                        RightOperand = new FunctionNode()
                        {
                            ExpressionReturnType = delegateType,
                            Method = targetMethod.Get()
                        }
                    },
                    new MethodCallNode()
                    {
                        ExpressionReturnType = voidType,
                        Function             = new FieldNode(delegateField),
                        Args = new IExpressionNode[0]
                    }
                }
            };

            ExpectedOutput = "Inside target method";
            AssertSuccessByExecution();
        }
Пример #29
0
    /// <summary>
    /// Create an attribute variable for a method definition.
    /// </summary>
    /// <param name="method">The method.</param>
    /// <param name="attribute">The attribute.</param>
    /// <param name="member">The optional parameter member.</param>
    /// <returns></returns>
    public Variable CreateAttribute(MethodEmitter method, CustomAttribute attribute)
    {
        var options = attribute.GetAttribute(Context.Finder.CompilationOptionsAttribute);
        var scope   = options != null?options.GetProperty("Scope", notFound : AttributeScopeSingleton) : AttributeScopeSingleton;

        if (scope == AttributeScopeInstanced && attribute.HasConstructorArguments)
        {
            scope = AttributeScopeMultiInstanced;
        }

        switch (scope)
        {
        case AttributeScopeInstanced:
            if (method.Target.IsStatic)
            {
                scope = AttributeScopeSingleton;
            }
            break;

        case AttributeScopeMultiInstanced:
            if (method.Target.IsStatic)
            {
                scope = AttributeScopeMultiSingleton;
            }
            break;
        }

        switch (scope)
        {
        case AttributeScopeAdhoc:
            return(CreateAttributeAdhoc(method, attribute, method.Target));

        case AttributeScopeInstanced:
            return(CreateAttributeInstanced(method.Parent, attribute, method.Target));

        case AttributeScopeMultiInstanced:
            return(CreateAttributeMultiInstanced(method.Parent, attribute, method.Target));

        case AttributeScopeSingleton:
            return(CreateAttributeSingleton(method.Parent, attribute, method.Target));

        case AttributeScopeMultiSingleton:
            return(CreateAttributeMultiSingleton(method.Parent, attribute, method.Target));

        default:
            throw new NotSupportedException($"Cannot create attribute '{attribute.AttributeType.FullName}' with scope {scope}");
        }
    }
Пример #30
0
 protected virtual void AddAddValueInvocation(
     ArgumentReference serializationInfo,
     MethodEmitter getObjectData,
     FieldReference field
     )
 {
     getObjectData.CodeBuilder.AddStatement(
         new MethodInvocationExpression(
             serializationInfo,
             SerializationInfoMethods.AddValue_Object,
             new LiteralStringExpression(field.Reference.Name),
             field
             )
         );
     return;
 }
        private void ParseHeader(Modifiers mods, IAbstractSyntaxTree lexerNode, string methodName)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.Type);
            var point   = Parser.GetSequencePoint(lexerNode);
            var builder = new TypeNode.TypeBuilder(Parent);
            int count   = lexerNode.Children.Count;
            var paramz  = ParseParams(Parser, lexerNode.Children[count - 1]);

            for (int i = 0; i < count - 1; i++)
            {
                builder.Append(lexerNode.Children[i]);
            }

            MethodReturnType = builder.Type;
            emitter          = new MethodEmitter(GetClass().TypeEmitter, methodName, MethodReturnType, AttributesFromModifiers(Parser.GetSequencePoint(lexerNode), mods));

            foreach (var p in paramz)
            {
                var param = ParseParameter(Parent, p.Type, p.Name);
                if (param.ParameterType.IsVoid())
                {
                    ErrorCode.IllegalMethodParam.ReportAndThrow(point, "Illegal method parameter type void");
                }
                if (symbols.ContainsKey(param.Name))
                {
                    ErrorCode.ParamAlreadyDeclared.ReportAndThrow(point, "Parameter with name {0} is already declared", param.Name);
                }
                emitter.AddArgument(param);
                symbols.Add(param.Name, param);
            }
            ParamTypes = symbols.Values.Select(p => p.ParameterType);

            if (mods.HasFlag(Modifiers.Entry))
            {
                if (MethodReturnType != Parser.Int32 && MethodReturnType != Parser.UInt32 && MethodReturnType != Parser.Void)
                {
                    InvalidEntryReturn(SequencePoint, MethodReturnType);
                }
                emitter.SetAsEntryPoint();

                if (!ValidParametersForMain(ParamTypes))
                {
                    InvalidEntryParams(point, ParamTypes);
                }
            }
        }
Пример #32
0
        /// <summary>
        /// Defines a new runtime method.
        /// </summary>
        /// <param name="returnType">The return type.</param>
        /// <param name="parameterTypes">All parameter types.</param>
        /// <param name="methodEmitter">The method emitter.</param>
        /// <returns>The acquired scoped lock.</returns>
        public ScopedLock DefineRuntimeMethod(
            Type returnType,
            Type[] parameterTypes,
            out MethodEmitter methodEmitter)
        {
            var scopedLock = new ScopedLock(this);

            methodEmitter = new MethodEmitter(
                new DynamicMethod(
                    LauncherMethodName,
                    returnType,
                    parameterTypes,
                    moduleBuilder,
                    true));

            return(scopedLock);
        }
Пример #33
0
        /// <summary>
        /// Gets or creates the <c>add</c> method emitter.
        /// </summary>
        /// <returns></returns>
        public MethodEmitter GetAdd()
        {
            if (add != null)
            {
                return(add);
            }

            var attributes = MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final;
            var method     = new MethodDefinition($"add_{Target.Name}", attributes, Parent.Context.Module.TypeSystem.Void);

            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, Target.EventType.Import()));
            Target.AddMethod = method;
            Parent.Target.Methods.Add(method);
            Parent.Context.AddCompilerGenerated(method);

            return(add = new MethodEmitter(Parent, method));
        }
Пример #34
0
		public abstract void Compile( MethodEmitter emitter );
Пример #35
0
        public static IComparer Compile(AssemblyEmitter assembly, Type objectType, Property[] props)
        {
            TypeBuilder typeBuilder = assembly.DefineType(
                "__distinct",
                TypeAttributes.Public,
                typeof(object));

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

                ILGenerator il = ctor.GetILGenerator();

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

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

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

            MethodBuilder compareMethod;

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

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

                LocalBuilder a = emitter.CreateLocal(objectType);
                LocalBuilder b = emitter.CreateLocal(objectType);

                LocalBuilder v = emitter.CreateLocal(typeof(int));

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

                emitter.LoadArgument(2);
                emitter.CastAs(objectType);
                emitter.StoreLocal(b);

                emitter.Load(0);
                emitter.StoreLocal(v);

                Label end = emitter.CreateLabel();

                for (int i = 0; i < props.Length; ++i)
                {
                    if (i > 0)
                    {
                        emitter.LoadLocal(v);
                        emitter.BranchIfTrue(end); // if ( v != 0 ) return v;
                    }

                    Property prop = props[i];

                    emitter.LoadLocal(a);
                    emitter.Chain(prop);

                    bool couldCompare =
                        emitter.CompareTo(1, delegate()
                        {
                            emitter.LoadLocal(b);
                            emitter.Chain(prop);
                        });

                    if (!couldCompare)
                        throw new InvalidOperationException("Property is not comparable.");

                    emitter.StoreLocal(v);
                }

                emitter.MarkLabel(end);

                emitter.LoadLocal(v);
                emitter.Return();

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

                compareMethod = emitter.Method;
            }
            #endregion
            #endregion

            #region IEqualityComparer
            typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<object>));

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

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

                emitter.Generator.Emit(OpCodes.Ldarg_0);
                emitter.Generator.Emit(OpCodes.Ldarg_1);
                emitter.Generator.Emit(OpCodes.Ldarg_2);

                emitter.Generator.Emit(OpCodes.Call, compareMethod);

                emitter.Generator.Emit(OpCodes.Ldc_I4_0);

                emitter.Generator.Emit(OpCodes.Ceq);

                emitter.Generator.Emit(OpCodes.Ret);

                typeBuilder.DefineMethodOverride(
                    emitter.Method,
                    typeof(IEqualityComparer<object>).GetMethod(
                        "Equals",
                        new Type[]
                        {
                            typeof(object),
                            typeof(object)
                        }));
            }
            #endregion

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

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

                LocalBuilder obj = emitter.CreateLocal(objectType);

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

                for (int i = 0; i < props.Length; ++i)
                {
                    Property prop = props[i];

                    emitter.LoadLocal(obj);
                    emitter.Chain(prop);

                    Type active = emitter.Active;

                    MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes);

                    if (getHashCode == null)
                        getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes);

                    if (active != typeof(int))
                    {
                        if (!active.IsValueType)
                        {
                            LocalBuilder value = emitter.AcquireTemp(active);

                            Label valueNotNull = emitter.CreateLabel();
                            Label done = emitter.CreateLabel();

                            emitter.StoreLocal(value);
                            emitter.LoadLocal(value);

                            emitter.BranchIfTrue(valueNotNull);

                            emitter.Load(0);
                            emitter.Pop(typeof(int));

                            emitter.Branch(done);

                            emitter.MarkLabel(valueNotNull);

                            emitter.LoadLocal(value);
                            emitter.Call(getHashCode);

                            emitter.ReleaseTemp(value);

                            emitter.MarkLabel(done);
                        }
                        else
                        {
                            emitter.Call(getHashCode);
                        }
                    }

                    if (i > 0)
                        emitter.Xor();
                }

                emitter.Return();

                typeBuilder.DefineMethodOverride(
                    emitter.Method,
                    typeof(IEqualityComparer<object>).GetMethod(
                        "GetHashCode",
                        new Type[]
                        {
                            typeof(object)
                        }));
            }
            #endregion
            #endregion

            Type comparerType = typeBuilder.CreateType();

            return (IComparer)Activator.CreateInstance(comparerType);
        }
 public override void EmitMethod(MethodInfo methodInfo)
 {
     var emitter = new MethodEmitter(TypeBuilder, ImplField);
     emitter.Emit(methodInfo);
 }
Пример #37
0
        public static IComparer Compile(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders)
        {
            TypeBuilder typeBuilder = assembly.DefineType(
                "__sort",
                TypeAttributes.Public,
                typeof(object));

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

                ILGenerator il = ctor.GetILGenerator();

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

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

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

            MethodBuilder compareMethod;

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

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

                LocalBuilder a = emitter.CreateLocal(objectType);
                LocalBuilder b = emitter.CreateLocal(objectType);

                LocalBuilder v = emitter.CreateLocal(typeof(int));

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

                emitter.LoadArgument(2);
                emitter.CastAs(objectType);
                emitter.StoreLocal(b);

                emitter.Load(0);
                emitter.StoreLocal(v);

                Label end = emitter.CreateLabel();

                for (int i = 0; i < orders.Length; ++i)
                {
                    if (i > 0)
                    {
                        emitter.LoadLocal(v);
                        emitter.BranchIfTrue(end); // if ( v != 0 ) return v;
                    }

                    OrderInfo orderInfo = orders[i];

                    Property prop = orderInfo.Property;
                    int sign = orderInfo.Sign;

                    emitter.LoadLocal(a);
                    emitter.Chain(prop);

                    bool couldCompare =
                        emitter.CompareTo(sign, delegate()
                        {
                            emitter.LoadLocal(b);
                            emitter.Chain(prop);
                        });

                    if (!couldCompare)
                        throw new InvalidOperationException("Property is not comparable.");

                    emitter.StoreLocal(v);
                }

                emitter.MarkLabel(end);

                emitter.LoadLocal(v);
                emitter.Return();

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

                compareMethod = emitter.Method;
            }
            #endregion
            #endregion

            Type comparerType = typeBuilder.CreateType();

            return (IComparer)Activator.CreateInstance(comparerType);
        }
Пример #38
0
		public MethodInvocationExpression(Reference owner, MethodEmitter method, params Expression[] args) :
			this(owner, method.MethodBuilder, args)
		{
		}
Пример #39
0
		public MethodInvocationExpression(MethodEmitter method, params Expression[] args) :
			this(SelfReference.Self, method.MethodBuilder, args)
		{
		}
Пример #40
0
		public override void Compile( MethodEmitter emitter )
		{
			bool inverse = false;

			string methodName;

			switch ( m_Operator )
			{
				case StringOperator.Equal:
					methodName = "Equals";
					break;

				case StringOperator.NotEqual:
					methodName = "Equals";
					inverse = true;
					break;

				case StringOperator.Contains:
					methodName = "Contains";
					break;

				case StringOperator.StartsWith:
					methodName = "StartsWith";
					break;

				case StringOperator.EndsWith:
					methodName = "EndsWith";
					break;

				default:
					throw new InvalidOperationException( "Invalid string comparison operator." );
			}

			if ( m_IgnoreCase || methodName == "Equals" )
			{
				Type type = ( m_IgnoreCase ? typeof( Insensitive ) : typeof( String ) );

				emitter.BeginCall(
					type.GetMethod(
						methodName,
						BindingFlags.Public | BindingFlags.Static,
						null,
						new Type[]
						{
							typeof( string ),
							typeof( string )
						},
						null
					)
				);

				emitter.Chain( m_Property );
				m_Value.Load( emitter );

				emitter.FinishCall();
			}
			else
			{
				Label notNull = emitter.CreateLabel();
				Label moveOn = emitter.CreateLabel();

				LocalBuilder temp = emitter.AcquireTemp( m_Property.Type );

				emitter.Chain( m_Property );

				emitter.StoreLocal( temp );
				emitter.LoadLocal( temp );

				emitter.BranchIfTrue( notNull );

				emitter.Load( false );
				emitter.Pop();
				emitter.Branch( moveOn );

				emitter.MarkLabel( notNull );
				emitter.LoadLocal( temp );

				emitter.BeginCall(
					typeof( string ).GetMethod(
						methodName,
						BindingFlags.Public | BindingFlags.Instance,
						null,
						new Type[]
						{
							typeof( string )
						},
						null
					)
				);

				m_Value.Load( emitter );

				emitter.FinishCall();

				emitter.MarkLabel( moveOn );
			}

			if ( m_Not != inverse )
				emitter.LogicalNot();
		}
Пример #41
0
		public override void Compile( MethodEmitter emitter )
		{
			emitter.Chain( m_Property );

			bool inverse = false;

			bool couldCompare =
			emitter.CompareTo( 1, delegate()
			{
				m_Value.Load( emitter );
			} );

			if ( couldCompare )
			{
				emitter.Load( 0 );

				switch ( m_Operator )
				{
					case ComparisonOperator.Equal:
						emitter.Compare( OpCodes.Ceq );
						break;

					case ComparisonOperator.NotEqual:
						emitter.Compare( OpCodes.Ceq );
						inverse = true;
						break;

					case ComparisonOperator.Greater:
						emitter.Compare( OpCodes.Cgt );
						break;

					case ComparisonOperator.GreaterEqual:
						emitter.Compare( OpCodes.Clt );
						inverse = true;
						break;

					case ComparisonOperator.Lesser:
						emitter.Compare( OpCodes.Clt );
						break;

					case ComparisonOperator.LesserEqual:
						emitter.Compare( OpCodes.Cgt );
						inverse = true;
						break;

					default:
						throw new InvalidOperationException( "Invalid comparison operator." );
				}
			}
			else
			{
				// This type is -not- comparable
				// We can only support == and != operations

				m_Value.Load( emitter );

				switch ( m_Operator )
				{
					case ComparisonOperator.Equal:
						emitter.Compare( OpCodes.Ceq );
						break;

					case ComparisonOperator.NotEqual:
						emitter.Compare( OpCodes.Ceq );
						inverse = true;
						break;

					case ComparisonOperator.Greater:
					case ComparisonOperator.GreaterEqual:
					case ComparisonOperator.Lesser:
					case ComparisonOperator.LesserEqual:
						throw new InvalidOperationException( "Property does not support relational comparisons." );

					default:
						throw new InvalidOperationException( "Invalid operator." );
				}
			}

			if ( m_Not != inverse )
				emitter.LogicalNot();
		}
Пример #42
0
		public static IConditional Compile( AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index )
		{
			TypeBuilder typeBuilder = assembly.DefineType(
					"__conditional" + index,
					TypeAttributes.Public,
					typeof( object )
				);

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

				ILGenerator il = ctor.GetILGenerator();

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

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

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

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

			MethodBuilder compareMethod;

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

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

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

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

				Label done = emitter.CreateLabel();

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

						emitter.BranchIfFalse( done );
					}

					emitter.LoadLocal( obj );

					conditions[i].Compile( emitter );

					emitter.StoreLocal( eq );
				}

				emitter.MarkLabel( done );

				emitter.LoadLocal( eq );

				emitter.Return();

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

				compareMethod = emitter.Method;
			}
			#endregion
			#endregion

			Type conditionalType = typeBuilder.CreateType();

			return (IConditional) Activator.CreateInstance( conditionalType );
		}