private static void EmitNameScopeField(XamlIlLanguageTypeMappings mappings,
                                               IXamlIlTypeSystem typeSystem,
                                               IXamlIlTypeBuilder typebuilder, IXamlIlEmitter constructor)
        {
            var nameScopeType = typeSystem.FindType("Avalonia.Controls.INameScope");
            var field         = typebuilder.DefineField(nameScopeType,
                                                        ContextNameScopeFieldName, true, false);

            constructor
            .Ldarg_0()
            .Ldarg(1)
            .Ldtype(nameScopeType)
            .EmitCall(mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature("GetService",
                                                                                       typeSystem.FindType("System.Object"), typeSystem.FindType("System.Type"))))
            .Stfld(field);
        }
示例#2
0
        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            var res                = context.Emit(Value, codeGen, Value.Type.GetClrType());
            var supportInitType    = context.Configuration.TypeMappings.SupportInitialize;
            var supportsInitialize = supportInitType != null &&
                                     context.Configuration.TypeMappings.SupportInitialize
                                     .IsAssignableFrom(Value.Type.GetClrType());

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

            return(res);
        }
示例#3
0
        public static IXamlIlEmitter EmitCall(this IXamlIlEmitter emitter, IXamlIlMethod method, bool swallowResult = false)
        {
            if (method is IXamlIlCustomEmitMethod custom)
            {
                custom.EmitCall(emitter);
            }
            else
            {
                emitter.Emit(method.IsStatic ? OpCodes.Call : OpCodes.Callvirt, method);
            }

            if (swallowResult && !(method.ReturnType.Namespace == "System" && method.ReturnType.Name == "Void"))
            {
                emitter.Pop();
            }
            return(emitter);
        }
示例#4
0
        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            var type   = Value.GetClrType();
            var method = _systemType.Methods.FirstOrDefault(m =>
                                                            m.Name == "GetTypeFromHandle" && m.Parameters.Count == 1 &&
                                                            m.Parameters[0].Name == "RuntimeTypeHandle");

            if (method == null)
            {
                throw new XamlIlTypeSystemException(
                          $"Unable to find GetTypeFromHandle(RuntimeTypeHandle) on {_systemType.GetFqn()}");
            }
            codeGen
            .Emit(OpCodes.Ldtoken, type)
            .Emit(OpCodes.Call, method);
            return(XamlIlNodeEmitResult.Type(0, _systemType));
        }
示例#5
0
        /// <summary>
        ///         /// T Build(IServiceProvider sp);
        /// </summary>


        XamlIlEmitContext InitCodeGen(Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType,
                                      IXamlIlEmitter codeGen, XamlIlContext context, bool needContextLocal)
        {
            IXamlIlLocal contextLocal = null;

            if (needContextLocal)
            {
                contextLocal = codeGen.DefineLocal(context.ContextType);
                codeGen
                .Emit(OpCodes.Ldarg_0)
                .Emit(OpCodes.Newobj, context.Constructor)
                .Emit(OpCodes.Stloc, contextLocal);
            }

            var emitContext = new XamlIlEmitContext(codeGen, _configuration, context, contextLocal, createSubType, Emitters);

            return(emitContext);
        }
示例#6
0
        void CompileBuild(IXamlIlAstValueNode rootInstance, Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType,
                          IXamlIlEmitter codeGen, XamlIlContext context, IXamlIlMethod compiledPopulate)
        {
            var needContextLocal = !(rootInstance is XamlIlAstNewClrObjectNode newObj && newObj.Arguments.Count == 0);
            var emitContext      = InitCodeGen(createSubType, codeGen, context, needContextLocal);


            var rv = codeGen.DefineLocal(rootInstance.Type.GetClrType());

            emitContext.Emit(rootInstance, codeGen, rootInstance.Type.GetClrType());
            codeGen
            .Emit(OpCodes.Stloc, rv)
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Ldloc, rv)
            .Emit(OpCodes.Call, compiledPopulate)
            .Emit(OpCodes.Ldloc, rv)
            .Emit(OpCodes.Ret);
        }
示例#7
0
        public static bool Emit(XamlIlEmitContext context, IXamlIlEmitter emitter, XamlIlAstClrProperty property)
        {
            if (property is IXamlIlAvaloniaProperty ap)
            {
                emitter.Ldsfld(ap.AvaloniaProperty);
                return(true);
            }
            var type  = property.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);
        }
            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 XamlIlNodeEmitResult Emit(IXamlIlAstNode value, IXamlIlEmitter codeGen, IXamlIlType expectedType)
        {
            XamlIlNodeEmitResult res = null;

            if (_currentNode != null)
            {
                PushParent(_currentNode);
                _currentNode = value;
                res          = EmitCore(value, codeGen, expectedType);
                _currentNode = PopParent();
            }
            else
            {
                _currentNode = value;
                res          = EmitCore(value, codeGen, expectedType);
                _currentNode = null;
            }

            return(res);
        }
示例#10
0
        public static void EmitConvert(XamlIlEmitContext context, IXamlIlEmitter ilgen, IXamlIlLineInfo node,
                                       IXamlIlType what,
                                       IXamlIlType to)
        {
            XamlIlLocalsPool.PooledLocal local = null;

            EmitConvert(context, node, what, to, lda =>
            {
                if (!lda)
                {
                    return(ilgen);
                }
                local = ilgen.LocalsPool.GetLocal(what);
                ilgen
                .Stloc(local.Local)
                .Ldloca(local.Local);
                return(ilgen);
            });
            local?.Dispose();
        }
示例#11
0
                public void EmitCall(IXamlIlEmitter emitter)
                {
                    var method = Parent._avaloniaObject
                                 .FindMethod(m => m.IsPublic && !m.IsStatic && m.Name == "GetValue"
                                             &&
                                             m.Parameters.Count == 1 &&
                                             m.Parameters[0].Equals(Parent._avaloniaPropertyType));

                    if (method == null)
                    {
                        throw new XamlIlTypeSystemException(
                                  "Unable to find T GetValue<T>(AvaloniaProperty<T>) on AvaloniaObject");
                    }
                    emitter
                    .Ldsfld(Parent._field)
                    .EmitCall(method);
                    if (Parent.PropertyType.IsValueType)
                    {
                        emitter.Unbox_Any(Parent.PropertyType);
                    }
                }
示例#12
0
        XamlIlEmitContext InitCodeGen(
            IFileSource file,
            Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType,
            IXamlIlEmitter codeGen, XamlIlContext context, bool needContextLocal)
        {
            IXamlIlLocal contextLocal = null;

            if (needContextLocal)
            {
                contextLocal = codeGen.DefineLocal(context.ContextType);
                // Pass IService provider as the first argument to context factory
                codeGen
                .Emit(OpCodes.Ldarg_0);
                context.Factory(codeGen);
                codeGen.Emit(OpCodes.Stloc, contextLocal);
            }

            var emitContext = new XamlIlEmitContext(codeGen, _configuration, context, contextLocal, createSubType, file, Emitters);

            return(emitContext);
        }
示例#13
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);
        }
示例#14
0
        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            var scopeField = context.RuntimeContext.ContextType.Fields.First(f =>
                                                                             f.Name == AvaloniaXamlIlLanguage.ContextNameScopeFieldName);

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

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

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

            return(XamlIlNodeEmitResult.Void(1));
        }
示例#15
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     if (Constant is string)
     {
         codeGen.Emit(OpCodes.Ldstr, (string)Constant);
     }
     else if (Constant is long || Constant is ulong)
     {
         codeGen.Emit(OpCodes.Ldc_I8, TypeSystemHelpers.ConvertLiteralToLong(Constant));
     }
     else if (Constant is float f)
     {
         codeGen.Emit(OpCodes.Ldc_R4, f);
     }
     else if (Constant is double d)
     {
         codeGen.Emit(OpCodes.Ldc_R8, d);
     }
     else
     {
         codeGen.Emit(OpCodes.Ldc_I4, TypeSystemHelpers.ConvertLiteralToInt(Constant));
     }
     return(XamlIlNodeEmitResult.Type(0, Type.GetClrType()));
 }
 protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     context.Emit(Argument, codeGen, Type.GetClrType());
     EmitCall(context, codeGen,
              m => m.Name == "Not" && m.Parameters.Count == 2 && m.Parameters[1].Equals(Type.GetClrType()));
 }
 protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen) => codeGen.Ldnull();
 protected abstract void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen);
示例#19
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));
        }
示例#20
0
        public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen)
        {
            if (!(node is XamlIlMethodCallBaseNode mc))
            {
                return(null);
            }

            bool thisArgFromArgs = node is XamlIlStaticOrTargetedReturnMethodCallNode;
            bool expectsVoid     = node is XamlIlNoReturnMethodCallNode;


            for (var c = 0; c < mc.Arguments.Count; c++)
            {
                var off          = thisArgFromArgs ? 0 : 1;
                var expectedType = mc.Method.ParametersWithThis[c + off];
                context.Emit(mc.Arguments[c], codeGen, expectedType);
            }



            mc.Method.Emit(context, codeGen, expectsVoid);

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

            if (!expectsVoid && isVoid)
            {
                throw new XamlIlLoadException(
                          $"XamlIlStaticReturnMethodCallNode expects a value while {mc.Method.Name} returns void", node);
            }

            var consumed = thisArgFromArgs ? 0 : 1;

            return(isVoid || expectsVoid
                ? XamlIlNodeEmitResult.Void(consumed)
                : XamlIlNodeEmitResult.Type(consumed, mc.Method.ReturnType));
        }
示例#21
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));
        }
示例#22
0
 public static IXamlIlEmitter Pop(this IXamlIlEmitter emitter)
 => emitter.Emit(OpCodes.Pop);
示例#23
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     context.LdLocal(this, codeGen);
     return(XamlIlNodeEmitResult.Type(0, Type));
 }
示例#24
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     XamlIlNeedsParentStackCache.Verify(context, this);
     return(context.Emit(Value, codeGen, Value.Type.GetClrType()));
 }
示例#25
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     codeGen.Ldloc(context.ContextLocal);
     return(XamlIlNodeEmitResult.Type(0, Type.GetClrType()));
 }
示例#26
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     context.Emit(Value, codeGen, Value.Type.GetClrType());
     context.Emit(Manipulation, codeGen, null);
     return(XamlIlNodeEmitResult.Void(0));
 }
示例#27
0
 public static IXamlIlEmitter Ldtoken(this IXamlIlEmitter emitter, IXamlIlMethod method)
 => emitter.Emit(OpCodes.Ldtoken, method);
示例#28
0
 public abstract void Emit(IXamlIlEmitter codegen);
示例#29
0
 public static IXamlIlEmitter Ldtoken(this IXamlIlEmitter emitter, IXamlIlType type)
 => emitter.Emit(OpCodes.Ldtoken, type);
示例#30
0
 public static IXamlIlEmitter Dup(this IXamlIlEmitter emitter)
 => emitter.Emit(OpCodes.Dup);