Exemplo n.º 1
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));
        }
Exemplo n.º 5
0
 public static void EmitConvert(XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlLineInfo node, IXamlType what,
                                IXamlType to, Func <bool, IXamlILEmitter> ld)
 {
     if (what.Equals(to))
     {
         ld(false);
     }
     else if (what == XamlPseudoType.Null)
     {
         if (to.IsValueType)
         {
             if (to.GenericTypeDefinition?.Equals(context.Configuration.WellKnownTypes.NullableT) == true)
             {
                 using (var loc = context.GetLocalOfType(to))
                     ld(false)
                     .Pop()
                     .Ldloca(loc.Local)
                     .Emit(OpCodes.Initobj, to)
                     .Ldloc(loc.Local);
             }
             else
             {
                 throw new XamlLoadException("Unable to convert {x:Null} to " + to.GetFqn(), node);
             }
         }
         else
         {
             ld(false);
         }
     }
     else if (what.IsValueType && to.IsValueType)
     {
         if (to.IsNullableOf(what))
         {
             ld(false).Emit(OpCodes.Newobj,
                            to.Constructors.First(c =>
                                                  c.Parameters.Count == 1 && c.Parameters[0].Equals(what)));
         }
         else if (what.IsNullableOf(what))
         {
             ld(true)
             .EmitCall(what.FindMethod(m => m.Name == "get_Value"));
         }
         else
         {
             throw new XamlLoadException(
                       $"Don't know how to convert value type {what.GetFullName()} to value type {to.GetFullName()}",
                       node);
         }
     }
     else if (!to.IsValueType && what.IsValueType)
     {
         if (!to.IsAssignableFrom(what))
         {
             throw new XamlLoadException(
                       $"Don't know how to convert value type {what.GetFullName()} to reference type {to.GetFullName()}",
                       node);
         }
         ld(false).Box(what);
     }
     else if (to.IsValueType && !what.IsValueType)
     {
         if (!(what.Namespace == "System" && what.Name == "Object"))
         {
             throw new XamlLoadException(
                       $"Don't know how to convert reference type {what.GetFullName()} to value type {to.GetFullName()}",
                       node);
         }
         ld(false).Unbox_Any(to);
     }
     else
     {
         if (to.IsAssignableFrom(what))
         {
             // Downcast, always safe
             ld(false);
         }
         else if (what.IsInterface || what.IsAssignableFrom(to))
         {
             // Upcast or cast from interface, might throw InvalidCastException
             ld(false).Emit(OpCodes.Castclass, to);
         }
         else
         {
             // Types are completely unrelated, e. g. string to List<int> conversion attempt
             throw new XamlLoadException(
                       $"Don't know how to convert reference type {what.GetFullName()} to reference type {to.GetFullName()}",
                       node);
         }
     }
 }