Esempio n. 1
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));
        }
Esempio n. 2
0
File: Clr.cs Progetto: cm4ker/XamlIl
        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));
        }
Esempio n. 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));
        }
Esempio n. 4
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);
            }
        }
Esempio n. 5
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));
        }
Esempio n. 6
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     codeGen
     .Ldloc(context.ContextLocal)
     .Ldfld(context.RuntimeContext.RootObjectField);
     return(XamlIlNodeEmitResult.Type(0, Type.GetClrType()));
 }
Esempio n. 7
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()));
 }
Esempio n. 8
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));
        }
 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()));
 }
Esempio n. 10
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));
 }
Esempio n. 11
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));
        }
Esempio n. 12
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()));
 }
Esempio n. 13
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);
            }
        }
Esempio n. 14
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));
        }
Esempio n. 15
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));
        }
Esempio n. 16
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));
        }
Esempio n. 17
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));
        }
Esempio n. 18
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()));
 }
Esempio n. 19
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     codeGen.Ldsfld(_field);
     return(XamlIlNodeEmitResult.Type(0, _field.FieldType));
 }
Esempio n. 20
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     context.LdLocal(this, codeGen);
     return(XamlIlNodeEmitResult.Type(0, Type));
 }
Esempio n. 21
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     codeGen.Ldloc(context.ContextLocal);
     return(XamlIlNodeEmitResult.Type(0, Type.GetClrType()));
 }
Esempio n. 22
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlCodeGen codeGen)
 {
     codeGen.Generator.Emit(OpCodes.Ldnull);
     return(XamlIlNodeEmitResult.Type(XamlIlPseudoType.Null));
 }
Esempio n. 23
0
 public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
 {
     codeGen.Emit(OpCodes.Ldnull);
     return(XamlIlNodeEmitResult.Type(0, XamlIlPseudoType.Null));
 }