protected void EmitCall(XamlIlEmitContext context, IXamlIlEmitter codeGen, Func <IXamlIlMethod, bool> method)
        {
            var selectors = context.Configuration.TypeSystem.GetType("Avalonia.Styling.Selectors");
            var found     = selectors.FindMethod(m => m.IsStatic && m.Parameters.Count > 0 && method(m));

            codeGen.EmitCall(found);
        }
        protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            if (_selectors.Count == 0)
            {
                throw new XamlIlLoadException("Invalid selector count", this);
            }
            if (_selectors.Count == 1)
            {
                _selectors[0].Emit(context, codeGen);
                return;
            }
            var listType = context.Configuration.TypeSystem.FindType("System.Collections.Generic.List`1")
                           .MakeGenericType(base.Type.GetClrType());
            var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType());

            codeGen
            .Newobj(listType.FindConstructor());
            foreach (var s in _selectors)
            {
                codeGen.Dup();
                context.Emit(s, codeGen, Type.GetClrType());
                codeGen.EmitCall(add, true);
            }

            EmitCall(context, codeGen,
                     m => m.Name == "Or" && m.Parameters.Count == 1 && m.Parameters[0].Name.StartsWith("IReadOnlyList"));
        }
 public void Emit(IXamlIlEmitter codegen)
 {
     if (_type.IsValueType)
     {
         codegen.Box(_type);
     }
     codegen.EmitCall(_method, true);
 }
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            if (!(node is XamlIlObjectInitializationNode init))
            {
                return(null);
            }
            var supportInitType    = context.Configuration.TypeMappings.SupportInitialize;
            var supportsInitialize = supportInitType != null &&
                                     context.Configuration.TypeMappings.SupportInitialize
                                     .IsAssignableFrom(init.Type);

            if (supportsInitialize)
            {
                codeGen
                // We need a copy for/EndInit
                .Emit(OpCodes.Dup);
                if (!init.SkipBeginInit)
                {
                    codeGen
                    .Emit(OpCodes.Dup)
                    .EmitCall(supportInitType.FindMethod(m => m.Name == "BeginInit"));
                }
            }


            var addToParentStack = context.RuntimeContext.ParentListField != null &&
                                   !init.Type.IsValueType &&
                                   context.GetOrCreateItem <XamlIlNeedsParentStackCache>().NeedsParentStack(node);

            if (addToParentStack)
            {
                using (var local = context.GetLocal(init.Type))
                    codeGen
                    .Stloc(local.Local)
                    .Ldloc(context.ContextLocal)
                    .Ldloc(local.Local)
                    .EmitCall(context.RuntimeContext.PushParentMethod)
                    .Ldloc(local.Local);
            }

            context.Emit(init.Manipulation, codeGen, null);

            if (addToParentStack)
            {
                codeGen
                .Ldloc(context.ContextLocal)
                .EmitCall(context.RuntimeContext.PopParentMethod, true);
            }

            if (supportsInitialize)
            {
                codeGen
                .EmitCall(supportInitType.FindMethod(m => m.Name == "EndInit"));
            }


            return(XamlIlNodeEmitResult.Void(1));
        }
예제 #5
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter ilgen)
        {
            if (!(node is XamlIlMarkupExtensionNode me))
            {
                return(null);
            }
            XamlIlNeedsParentStackCache.Verify(context, node);

            var prop = context.ParentNodes().OfType <XamlIlPropertyAssignmentNode>().FirstOrDefault();

            var needProvideValueTarget = me.ProvideValue.Parameters.Count != 0 &&
                                         context.RuntimeContext.PropertyTargetObject != null &&
                                         prop != null;

            void EmitPropertyDescriptor()
            {
                if (context.Configuration.TypeMappings.ProvideValueTargetPropertyEmitter
                    ?.Invoke(context, ilgen, prop.Property) == true)
                {
                    return;
                }
                ilgen.Ldstr(prop.Property.Name);
            }

            context.Emit(me.Value, ilgen, me.Value.Type.GetClrType());

            if (me.ProvideValue.Parameters.Count > 0)
            {
                ilgen
                .Emit(OpCodes.Ldloc, context.ContextLocal);
            }

            if (needProvideValueTarget)
            {
                ilgen
                .Ldloc(context.ContextLocal);
                EmitPropertyDescriptor();
                ilgen
                .Stfld(context.RuntimeContext.PropertyTargetProperty);
            }

            ilgen.EmitCall(me.ProvideValue);

            if (needProvideValueTarget)
            {
                ilgen
                .Ldloc(context.ContextLocal)
                .Ldnull()
                .Stfld(context.RuntimeContext.PropertyTargetProperty);
            }



            return(XamlIlNodeEmitResult.Type(0, me.ProvideValue.ReturnType));
        }
예제 #6
0
 public override void Emit(IXamlIlEmitter emitter)
 {
     using (var bloc = emitter.LocalsPool.GetLocal(Types.IBinding))
         emitter
         .Stloc(bloc.Local)
         .Ldsfld(AvaloniaProperty)
         .Ldloc(bloc.Local)
         // TODO: provide anchor?
         .Ldnull();
     emitter.EmitCall(Types.AvaloniaObjectBindMethod, true);
 }
예제 #7
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            if (!(node is XamlIlPropertyValueManipulationNode pvm))
            {
                return(null);
            }
            codeGen.EmitCall(pvm.Property.Getter);
            context.Emit(pvm.Manipulation, codeGen, null);

            return(XamlIlNodeEmitResult.Void(1));
        }
            public void Emit(IXamlIlEmitter emitter)
            {
                var locals = new Stack <XamlIlLocalsPool.PooledLocal>();

                // Save all "setter" parameters
                for (var c = Parameters.Count - 1; c >= 0; c--)
                {
                    var loc = emitter.LocalsPool.GetLocal(Parameters[c]);
                    locals.Push(loc);
                    emitter.Stloc(loc.Local);
                }

                emitter.EmitCall(_getter);
                while (locals.Count > 0)
                {
                    using (var loc = locals.Pop())
                        emitter.Ldloc(loc.Local);
                }
                emitter.EmitCall(_adder, true);
            }
예제 #9
0
        public void EmitCall(IXamlIlEmitter codeGen)
        {
            int firstCast = -1;

            for (var c = Parameters.Count - 1; c >= 0; c--)
            {
                if (!_baseParametersWithThis[c].Equals(Parameters[c]))
                {
                    firstCast = c;
                }
            }

            if (firstCast != -1)
            {
                var locals = new Stack <XamlIlLocalsPool.PooledLocal>();
                for (var c = Parameters.Count - 1; c >= firstCast; c--)
                {
                    codeGen.Castclass(_baseParametersWithThis[c]);
                    if (c > firstCast)
                    {
                        var l = codeGen.LocalsPool.GetLocal(_baseParametersWithThis[c]);
                        codeGen.Stloc(l.Local);
                        locals.Push(l);
                    }
                }

                while (locals.Count != 0)
                {
                    using (var l = locals.Pop())
                    {
                        codeGen.Ldloc(l.Local);
                        l.Dispose();
                    }
                }
            }

            codeGen.EmitCall(_method);
        }
예제 #10
0
파일: Clr.cs 프로젝트: cm4ker/XamlIl
 public void Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen, bool swallowResult)
 {
     codeGen.EmitCall(_method, swallowResult);
 }
예제 #11
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            if (!(node is XamlIlObjectInitializationNode init))
            {
                return(null);
            }
            var supportInitType    = context.Configuration.TypeMappings.SupportInitialize;
            var supportsInitialize = supportInitType != null &&
                                     context.Configuration.TypeMappings.SupportInitialize
                                     .IsAssignableFrom(init.Type);

            if (supportsInitialize)
            {
                codeGen
                // We need a copy for/EndInit
                .Emit(OpCodes.Dup);
                if (!init.SkipBeginInit)
                {
                    codeGen
                    .Emit(OpCodes.Dup)
                    .EmitCall(supportInitType.FindMethod(m => m.Name == "BeginInit"));
                }
            }

            IXamlIlType objectListType   = null;
            var         addToParentStack = context.RuntimeContext.ParentListField != null &&
                                           !init.Type.IsValueType &&
                                           context.GetOrCreateItem <XamlIlNeedsParentStackCache>().NeedsParentStack(node);

            if (addToParentStack)
            {
                objectListType = context.Configuration.TypeSystem.GetType("System.Collections.Generic.List`1")
                                 .MakeGenericType(new[] { context.Configuration.WellKnownTypes.Object });

                using (var local = context.GetLocal(init.Type))
                    codeGen
                    .Stloc(local.Local)
                    .Ldloc(context.ContextLocal).Ldfld(context.RuntimeContext.ParentListField)
                    .Ldloc(local.Local)
                    .EmitCall(objectListType.FindMethod("Add", context.Configuration.WellKnownTypes.Void,
                                                        false, context.Configuration.WellKnownTypes.Object))
                    .Ldloc(local.Local);
            }

            context.Emit(init.Manipulation, codeGen, null);

            if (addToParentStack)
            {
                codeGen
                .Ldloc(context.ContextLocal).Ldfld(context.RuntimeContext.ParentListField)
                .Ldloc(context.ContextLocal).Ldfld(context.RuntimeContext.ParentListField)
                .EmitCall(objectListType.FindMethod(m => m.Name == "get_Count"))
                .Ldc_I4(1).Emit(OpCodes.Sub)
                .EmitCall(objectListType.FindMethod(m => m.Name == "RemoveAt"));
            }

            if (supportsInitialize)
            {
                codeGen
                .EmitCall(supportInitType.FindMethod(m => m.Name == "EndInit"));
            }


            return(XamlIlNodeEmitResult.Void(1));
        }
예제 #12
0
 public void Emit(IXamlIlEmitter codegen)
 {
     codegen.EmitCall(_method, true);
 }