Example #1
0
 public override void EmitWithArguments(
     XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context,
     IXamlILEmitter emitter,
     IReadOnlyList <IXamlAstValueNode> arguments)
 {
     emitter.Ldsfld(AvaloniaProperty);
     context.Emit(arguments[1], emitter, Parameters[1]);
     context.Emit(arguments[0], emitter, Parameters[0]);
     EmitSetStyledPropertyValue(emitter);
 }
Example #2
0
        public void Emit(XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> 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 <XamlLocalsPool.PooledLocal>();
                for (var c = ParametersWithThis.Count - 1; c >= firstCast; c--)
                {
                    codeGen.Castclass(_method.ParametersWithThis[c]);
                    if (c > firstCast)
                    {
                        var l = context.GetLocalOfType(_method.ParametersWithThis[c]);
                        codeGen.Stloc(l.Local);
                        locals.Push(l);
                    }
                }

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

            context.Emit(_method, codeGen, swallowResult);
        }
                public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
                {
                    if (node is RobustNameScopeRegistrationXamlIlNode registration)
                    {
                        var scopeField = context.RuntimeContext.ContextType.Fields.First(f =>
                                                                                         f.Name == XamlCompiler.ContextNameScopeFieldName);
                        var namescopeRegisterFunction = context.Configuration.TypeSystem
                                                        .FindType("Robust.Client.UserInterface.XAML.NameScope").Methods
                                                        .First(m => m.Name == "Register");

                        using (var targetLoc = context.GetLocalOfType(context.Configuration.TypeSystem.FindType("Robust.Client.UserInterface.Control")))
                        {
                            codeGen
                            // var target = {pop}
                            .Stloc(targetLoc.Local)
                            // _context.NameScope.Register(Name, target)
                            .Ldloc(context.ContextLocal)
                            .Ldfld(scopeField);

                            context.Emit(registration.Name, codeGen, registration.Name.Type.GetClrType());

                            codeGen
                            .Ldloc(targetLoc.Local)
                            .EmitCall(namescopeRegisterFunction, true);
                        }

                        return(XamlILNodeEmitResult.Void(1));
                    }
                    return(default);
        public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
        {
            if (node is AvaloniaNameScopeRegistrationXamlIlNode registration)
            {
                var scopeField = context.RuntimeContext.ContextType.Fields.First(f =>
                                                                                 f.Name == AvaloniaXamlIlLanguage.ContextNameScopeFieldName);

                using (var targetLoc = context.GetLocalOfType(context.Configuration.WellKnownTypes.Object))
                {
                    codeGen
                    // var target = {pop}
                    .Stloc(targetLoc.Local)
                    // _context.NameScope.Register(Name, target)
                    .Ldloc(context.ContextLocal)
                    .Ldfld(scopeField);

                    context.Emit(registration.Name, codeGen, registration.Name.Type.GetClrType());

                    codeGen
                    .Ldloc(targetLoc.Local)
                    .EmitCall(context.GetAvaloniaTypes().INameScopeRegister, true);
                }

                return(XamlILNodeEmitResult.Void(1));
            }
            return(default);
        public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
        {
            if (!(node is XamlObjectInitializationNode 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 <XamlNeedsParentStackCache>().NeedsParentStack(node);

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

            using (codeGen.EmitObjectInitializationMarker(init.Type.FullName))
            {
                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));
        }
Example #6
0
        public XamlILNodeEmitResult Emit(XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
        {
            var rv = context.Emit(Value, codeGen, Local.Type);

            codeGen.Emit(OpCodes.Dup);
            var lcl = context.GetLocalForNode(Local, codeGen, throwOnUninitialized: false);

            codeGen.Stloc(lcl);
            return(XamlILNodeEmitResult.Type(0, rv.ReturnType));
        }
            public void EmitWithArguments(
                XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context,
                IXamlILEmitter emitter,
                IReadOnlyList <IXamlAstValueNode> arguments)
            {
                emitter.EmitCall(_getter);

                for (var i = 0; i < arguments.Count; ++i)
                {
                    context.Emit(arguments[i], emitter, Parameters[i]);
                }

                emitter.EmitCall(_adder, true);
            }
        public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
        {
            if (!(node is XamlPropertyAssignmentNode an))
            {
                return(null);
            }

            var setters = ValidateAndGetSetters(an);

            for (var c = 0; c < an.Values.Count - 1; c++)
            {
                context.Emit(an.Values[c], codeGen, an.Values[c].Type.GetClrType());
            }

            var value = an.Values.Last();

            var isValueType = value.Type.GetClrType().IsValueType;

            // If there is only one available setter or if value is a value type, always use the first one
            if (setters.Count == 1 || isValueType)
            {
                var setter = an.PossibleSetters.First();

                using (codeGen.EmitSetPropertyMarker(setter))
                {
                    context.Emit(value, codeGen, setter.Parameters.Last());
                    context.Emit(setter, codeGen);
                }
            }
            else
            {
                var        checkedTypes = new List <IXamlType>();
                var        exit         = codeGen.DefineLabel();
                IXamlLabel next         = null;
                var        hadJumps     = false;
                context.Emit(value, codeGen, value.Type.GetClrType());

                foreach (var setter in setters)
                {
                    var type = setter.Parameters.Last();

                    // We have already checked this type or its base type
                    if (checkedTypes.Any(ch => ch.IsAssignableFrom(type)))
                    {
                        continue;
                    }

                    if (next != null)
                    {
                        codeGen.MarkLabel(next);
                        next = null;
                    }

                    IXamlLabel Next() => next ?? (next = codeGen.DefineLabel());

                    var checkNext = false;
                    if (setter.BinderParameters.AllowRuntimeNull)
                    {
                        checkedTypes.Add(type);
                    }
                    else
                    {
                        // Check for null; Also don't add this type to the list of checked ones because of the null check
                        codeGen
                        .Dup()
                        .Brfalse(Next());
                        checkNext = true;
                    }

                    // Only do dynamic checks if we know that type is not assignable by downcast
                    if (!type.IsAssignableFrom(value.Type.GetClrType()))
                    {
                        codeGen
                        .Dup()
                        .Isinst(type)
                        .Brfalse(Next());
                        checkNext = true;
                    }

                    if (checkNext)
                    {
                        hadJumps = true;
                    }

                    ILEmitHelpers.EmitConvert(context, codeGen, value, value.Type.GetClrType(), type);
                    context.Emit(setter, codeGen);
                    if (hadJumps)
                    {
                        codeGen.Br(exit);
                    }

                    if (!checkNext)
                    {
                        break;
                    }
                }

                if (next != null)
                {
                    codeGen.MarkLabel(next);

                    if (setters.Any(x => !x.BinderParameters.AllowRuntimeNull))
                    {
                        next = codeGen.DefineLabel();
                        codeGen
                        .Dup()
                        .Brtrue(next)
                        .Newobj(context.Configuration.TypeSystem.GetType("System.NullReferenceException")
                                .FindConstructor())
                        .Throw();
                        codeGen.MarkLabel(next);
                    }

                    codeGen
                    .Newobj(context.Configuration.TypeSystem.GetType("System.InvalidCastException")
                            .FindConstructor())
                    .Throw();
                }

                codeGen.MarkLabel(exit);
            }

            return(XamlILNodeEmitResult.Void(1));
        }