Пример #1
0
        public void Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen, bool swallowResult)
        {
            int firstCast = -1;

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

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

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

            _method.Emit(context, codeGen, swallowResult);
        }
Пример #2
0
            public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
            {
                var next       = codeGen.DefineLabel();
                var scopeField = context.RuntimeContext.ContextType.Fields.First(f =>
                                                                                 f.Name == AvaloniaXamlIlLanguage.ContextNameScopeFieldName);

                using (var local = codeGen.LocalsPool.GetLocal(_types.StyledElement))
                {
                    codeGen
                    .Isinst(_types.StyledElement)
                    .Dup()
                    .Stloc(local.Local)
                    .Brfalse(next)
                    .Ldloc(local.Local)
                    .Ldloc(context.ContextLocal)
                    .Ldfld(scopeField)
                    .EmitCall(_types.NameScopeSetNameScope, true)
                    .MarkLabel(next)
                    .Ldloc(context.ContextLocal)
                    .Ldfld(scopeField)
                    .EmitCall(_types.INameScopeComplete, true);
                }

                return(XamlIlNodeEmitResult.Void(1));
            }
Пример #3
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            if (!(node is XamlIlAstNewClrObjectNode n))
            {
                return(null);
            }

            var type = n.Type.GetClrType();
            var ctor = n.Constructor ?? type.FindConstructor();

            if (ctor == null)
            {
                throw new XamlIlLoadException("Unable to find default constructor and no non-default one is specified",
                                              n);
            }

            for (var c = 0; c < n.Arguments.Count; c++)
            {
                context.Emit(n.Arguments[c], codeGen, ctor.Parameters[c]);
            }

            var gen = codeGen
                      .Emit(OpCodes.Newobj, ctor);


            return(XamlIlNodeEmitResult.Type(0, type));
        }
            public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
            {
                var exts           = context.Configuration.TypeSystem.GetType("Avalonia.Controls.NameScopeExtensions");
                var findNameScope  = exts.FindMethod(m => m.Name == "FindNameScope");
                var registerMethod = findNameScope.ReturnType.FindMethod(m => m.Name == "Register");

                using (var targetLoc = context.GetLocal(context.Configuration.WellKnownTypes.Object))
                    using (var nameScopeLoc = context.GetLocal(findNameScope.ReturnType))
                    {
                        var exit = codeGen.DefineLabel();
                        codeGen
                        // var target = {pop}
                        .Stloc(targetLoc.Local)
                        // var scope = target.FindNameScope()
                        .Ldloc(targetLoc.Local)
                        .Castclass(findNameScope.Parameters[0])
                        .EmitCall(findNameScope)
                        .Stloc(nameScopeLoc.Local)
                        // if({scope} != null) goto call;
                        .Ldloc(nameScopeLoc.Local)
                        .Brfalse(exit)
                        .Ldloc(nameScopeLoc.Local);
                        context.Emit(Value, codeGen, Value.Type.GetClrType());
                        codeGen
                        .Ldloc(targetLoc.Local)
                        .EmitCall(registerMethod)
                        .MarkLabel(exit);
                    }
                return(XamlIlNodeEmitResult.Void(1));
            }
Пример #5
0
        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            var so          = context.Configuration.WellKnownTypes.Object;
            var isp         = context.Configuration.TypeMappings.ServiceProvider;
            var subType     = context.CreateSubType("XamlIlClosure_" + Guid.NewGuid(), so);
            var buildMethod = subType.DefineMethod(so, new[]
            {
                isp
            }, "Build", true, true, false);

            CompileBuilder(new XamlIlEmitContext(buildMethod.Generator, context.Configuration,
                                                 context.RuntimeContext, buildMethod.Generator.DefineLocal(context.RuntimeContext.ContextType),
                                                 (s, type) => subType.DefineSubType(type, s, false), context.Emitters));

            var funcType = Type.GetClrType();

            codeGen
            .Ldnull()
            .Ldftn(buildMethod)
            .Newobj(funcType.Constructors.FirstOrDefault(ct =>
                                                         ct.Parameters.Count == 2 && ct.Parameters[0].Equals(context.Configuration.WellKnownTypes.Object)));

            // Allow to save values from the parent context, pass own service provider, etc, etc
            if (context.Configuration.TypeMappings.DeferredContentExecutorCustomization != null)
            {
                codeGen
                .Ldloc(context.ContextLocal)
                .EmitCall(context.Configuration.TypeMappings.DeferredContentExecutorCustomization);
            }

            subType.CreateType();
            return(XamlIlNodeEmitResult.Type(0, funcType));
        }
Пример #6
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlCodeGen codeGen)
        {
            if (!(node is XamlIlAstNewClrObjectNode n))
            {
                return(null);
            }
            var type = n.Type.GetClrType();

            var argTypes = n.Arguments.Select(a => a.Type.GetClrType()).ToList();
            var ctor     = type.FindConstructor(argTypes);

            if (ctor == null)
            {
                throw new XamlIlLoadException(
                          $"Unable to find public constructor for type {type.GetFqn()}({string.Join(", ", argTypes.Select(at => at.GetFqn()))})",
                          n);
            }

            for (var c = 0; c < n.Arguments.Count; c++)
            {
                var ctorArg = n.Arguments[c];
                context.Emit(ctorArg, codeGen, ctor.Parameters[c]);
            }

            var gen = codeGen.Generator
                      .Emit(OpCodes.Newobj, ctor);


            return(XamlIlNodeEmitResult.Type(type));
        }
        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);
        }
Пример #8
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     // Discard the stack value we are "supposed" to manipulate
     codeGen.Pop();
     context.Emit(Imperative, codeGen, null);
     return(XamlIlNodeEmitResult.Void(1));
 }
        protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            var name = _type.ToString();

            EmitCall(context, codeGen,
                     m => m.Name == name && m.Parameters.Count == 1);
        }
Пример #10
0
        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            var type   = TargetType.GetClrType();
            var member = ResolveMember(type);

            if (member is IXamlIlProperty prop)
            {
                codeGen.Emit(OpCodes.Call, prop.Getter);
                return(XamlIlNodeEmitResult.Type(0, prop.Getter.ReturnType));
            }
            else if (member is IXamlIlField field)
            {
                if (field.IsLiteral)
                {
                    TypeSystemHelpers.EmitFieldLiteral(field, codeGen);
                }
                else
                {
                    codeGen.Emit(OpCodes.Ldsfld, field);
                }
                return(XamlIlNodeEmitResult.Type(0, field.FieldType));
            }
            else
            {
                throw new XamlIlLoadException(
                          $"Unable to resolve {Member} as static field, property, constant or enum value", this);
            }
        }
        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"));
        }
Пример #12
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     codeGen
     .Ldloc(context.ContextLocal)
     .Ldfld(context.RuntimeContext.RootObjectField);
     return(XamlIlNodeEmitResult.Type(0, Type.GetClrType()));
 }
Пример #13
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlCodeGen codeGen)
        {
            if (!(node is XamlIlInstanceMethodCallBaseNode mc))
            {
                return(null);
            }
            for (var c = 0; c < mc.Arguments.Count; c++)
            {
                context.Emit(mc.Arguments[c], codeGen, mc.Method.Parameters[c]);
            }
            codeGen.Generator.Emit(mc.Method.IsStatic ? OpCodes.Call : OpCodes.Callvirt, mc.Method);

            var isVoid = mc.Method.ReturnType.Equals(context.Configuration.WellKnownTypes.Void);

            if (mc is XamlIlInstanceNoReturnMethodCallNode && !isVoid)
            {
                codeGen.Generator.Emit(OpCodes.Pop);
            }
            if (mc is XamlIlStaticReturnMethodCallNode && isVoid)
            {
                throw new XamlIlLoadException(
                          $"XamlIlStaticReturnMethodCallNode expects a value while {mc.Method.Name} returns void", node);
            }

            return(isVoid ? XamlIlNodeEmitResult.Void : XamlIlNodeEmitResult.Type(mc.Method.ReturnType));
        }
        protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            codeGen.Ldstr(String);
            var name = _type.ToString();

            EmitCall(context, codeGen,
                     m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].FullName == "System.String");
        }
Пример #15
0
        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            var rv = context.Emit(Value, codeGen, Local.Type);

            codeGen.Emit(OpCodes.Dup);
            context.StLocal(Local, codeGen);
            return(XamlIlNodeEmitResult.Type(0, rv.ReturnType));
        }
        protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            var name = Concrete ? "OfType" : "Is";

            codeGen.Ldtype(TargetType);
            EmitCall(context, codeGen,
                     m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].FullName == "System.Type");
        }
Пример #17
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     if (!XamlIlAvaloniaPropertyHelper.Emit(context, codeGen, Property))
     {
         throw new XamlIlLoadException(Property.Name + " is not an AvaloniaProperty", this);
     }
     return(XamlIlNodeEmitResult.Type(0, Type.GetClrType()));
 }
        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));
        }
 public virtual XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     if (Previous != null)
     {
         context.Emit(Previous, codeGen, Type.GetClrType());
     }
     DoEmit(context, codeGen);
     return(XamlIlNodeEmitResult.Type(0, Type.GetClrType()));
 }
Пример #20
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     context.Emit(Value, codeGen, Method.DeclaringType);
     codeGen
     .Ldftn(Method)
     .Newobj(DelegateType.Constructors.FirstOrDefault(ct =>
                                                      ct.Parameters.Count == 2 && ct.Parameters[0].Equals(context.Configuration.WellKnownTypes.Object)));
     return(XamlIlNodeEmitResult.Type(0, DelegateType));
 }
Пример #21
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            if (!(node is XamlIlPropertyAssignmentNode an))
                return null;
            var callOp = an.Property.Setter.IsStatic ? OpCodes.Call : OpCodes.Callvirt;
            context.Emit(an.Value, codeGen, an.Property.Setter.Parameters.Last());
            codeGen.Emit(callOp, an.Property.Setter);

            return XamlIlNodeEmitResult.Void(1);
        }
Пример #22
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));
        }
Пример #23
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));
        }
Пример #24
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlCodeGen codeGen)
        {
            if (!(node is XamlIlPropertyValueManipulationNode pvm))
            {
                return(null);
            }
            codeGen.Generator.Emit(pvm.Property.Getter.IsStatic ? OpCodes.Call : OpCodes.Callvirt,
                                   pvm.Property.Getter);
            context.Emit(pvm.Manipulation, codeGen, null);

            return(XamlIlNodeEmitResult.Void);
        }
Пример #25
0
 public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     if (!(node is XamlIlAstTextNode text))
     {
         return(null);
     }
     if (!text.Type.GetClrType().Equals(context.Configuration.WellKnownTypes.String))
     {
         throw new XamlIlLoadException("Text node type wasn't resolved to well-known System.String", node);
     }
     codeGen.Emit(OpCodes.Ldstr, text.Text);
     return(XamlIlNodeEmitResult.Type(0, text.Type.GetClrType()));
 }
Пример #26
0
        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlCodeGen codeGen)
        {
            var type   = TargetType.GetClrType();
            var member = ResolveMember(type);

            if (member is IXamlIlProperty prop)
            {
                codeGen.Generator.Emit(OpCodes.Call, prop.Getter);
                return(XamlIlNodeEmitResult.Type(prop.Getter.ReturnType));
            }
            else if (member is IXamlIlField field)
            {
                if (field.IsLiteral)
                {
                    var ftype = field.FieldType.IsEnum ? field.FieldType.GetEnumUnderlyingType() : field.FieldType;

                    if (ftype.Name == "UInt64" || ftype.Name == "Int64")
                    {
                        codeGen.Generator.Emit(OpCodes.Ldc_I8,
                                               TypeSystemHelpers.ConvertLiteralToLong(field.GetLiteralValue()));
                    }
                    else if (ftype.Name == "Double")
                    {
                        codeGen.Generator.Emit(OpCodes.Ldc_R8, (double)field.GetLiteralValue());
                    }
                    else if (ftype.Name == "Single")
                    {
                        codeGen.Generator.Emit(OpCodes.Ldc_R4, (float)field.GetLiteralValue());
                    }
                    else if (ftype.Name == "String")
                    {
                        codeGen.Generator.Emit(OpCodes.Ldstr, (string)field.GetLiteralValue());
                    }
                    else
                    {
                        codeGen.Generator.Emit(OpCodes.Ldc_I4,
                                               TypeSystemHelpers.ConvertLiteralToInt(field.GetLiteralValue()));
                    }
                }
                else
                {
                    codeGen.Generator.Emit(OpCodes.Ldsfld, field);
                }
                return(XamlIlNodeEmitResult.Type(field.FieldType));
            }
            else
            {
                throw new XamlIlLoadException(
                          $"Unable to resolve {Member} as static field, property, constant or enum value", this);
            }
        }
Пример #27
0
        public static bool Emit(XamlIlEmitContext context, IXamlIlEmitter emitter, IXamlIlProperty property)
        {
            var type  = (property.Getter ?? property.Setter).DeclaringType;
            var name  = property.Name + "Property";
            var found = type.Fields.FirstOrDefault(f => f.IsStatic && f.Name == name);

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

            emitter.Ldsfld(found);
            return(true);
        }
 protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     if (!XamlIlAvaloniaPropertyHelper.Emit(context, codeGen, Property))
     {
         throw new XamlIlLoadException(
                   $"{Property.Name} of {(Property.Setter ?? Property.Getter).DeclaringType.GetFqn()} doesn't seem to be an AvaloniaProperty",
                   this);
     }
     context.Emit(Value, codeGen, context.Configuration.WellKnownTypes.Object);
     EmitCall(context, codeGen,
              m => m.Name == "PropertyEquals" &&
              m.Parameters.Count == 3 &&
              m.Parameters[1].FullName == "Avalonia.AvaloniaProperty" &&
              m.Parameters[2].Equals(context.Configuration.WellKnownTypes.Object));
 }
Пример #29
0
        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            context.Emit(Value, codeGen, context.Configuration.WellKnownTypes.Object);
            var t = Type.GetClrType();

            if (t.IsValueType)
            {
                codeGen.Unbox_Any(t);
            }
            else
            {
                codeGen.Castclass(t);
            }
            return(XamlIlNodeEmitResult.Type(0, t));
        }
Пример #30
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            if (!(node is XamlIlValueWithManipulationNode vwm))
            {
                return(null);
            }
            var created = context.Emit(vwm.Value, codeGen, vwm.Type.GetClrType());

            if (vwm.Manipulation != null &&
                !(vwm.Manipulation is XamlIlManipulationGroupNode grp && grp.Children.Count == 0))
            {
                codeGen.Emit(OpCodes.Dup);
                context.Emit(vwm.Manipulation, codeGen, null);
            }
            return(XamlIlNodeEmitResult.Type(0, created.ReturnType));
        }