Exemple #1
0
 public static IXamlIlEmitter Ldsfld(this IXamlIlEmitter emitter, IXamlIlField field)
 => emitter.Emit(OpCodes.Ldsfld, field);
Exemple #2
0
 public static IXamlIlEmitter LdThisFld(this IXamlIlEmitter emitter, IXamlIlField field)
 => emitter.Ldarg_0().Emit(OpCodes.Ldfld, field);
Exemple #3
0
        private XamlIlContext(IXamlIlTypeBuilder builder,
                              IXamlIlTypeSystem typeSystem, XamlIlLanguageTypeMappings mappings,
                              IXamlIlType rootType, IEnumerable <IXamlIlField> staticProviders, string baseUri)
        {
            RootObjectField             = builder.DefineField(rootType, "RootObject", true, false);
            _parentServiceProviderField = builder.DefineField(mappings.ServiceProvider, "_sp", false, false);
            if (mappings.InnerServiceProviderFactoryMethod != null)
            {
                _innerServiceProviderField = builder.DefineField(mappings.ServiceProvider, "_innerSp", false, false);
            }
            var so         = typeSystem.GetType("System.Object");
            var systemType = typeSystem.GetType("System.Type");
            var getServiceInterfaceMethod = mappings.ServiceProvider.FindMethod("GetService", so, false, systemType);

            var ownServices   = new List <IXamlIlType>();
            var ctorCallbacks = new List <Action <IXamlIlEmitter> >();

            if (mappings.RootObjectProvider != null)
            {
                builder.AddInterfaceImplementation(mappings.RootObjectProvider);
                var rootGen = ImplementInterfacePropertyGetter(builder, mappings.RootObjectProvider, "RootObject")
                              .Generator;
                var tryParent          = rootGen.DefineLabel();
                var fail               = rootGen.DefineLabel();
                var parentRootProvider = rootGen.DefineLocal(mappings.RootObjectProvider);
                rootGen
                // if(RootObject!=null) return RootObject;
                .LdThisFld(RootObjectField)
                .Brfalse(tryParent)
                .LdThisFld(RootObjectField)
                .Ret()
                // if(_sp == null) goto fail;
                .MarkLabel(tryParent)
                .LdThisFld(_parentServiceProviderField)
                .Brfalse(fail)
                // parentProv =  (IRootObjectProvider)_sp.GetService(typeof(IRootObjectProvider));
                .LdThisFld(_parentServiceProviderField)
                .Ldtype(mappings.RootObjectProvider)
                .EmitCall(getServiceInterfaceMethod)
                .Castclass(mappings.RootObjectProvider)
                .Stloc(parentRootProvider)
                // if(parentProv == null) goto fail;
                .Ldloc(parentRootProvider)
                .Brfalse(fail)
                // return parentProv.Root;
                .Ldloc(parentRootProvider)
                .EmitCall(mappings.RootObjectProvider.FindMethod(m => m.Name == "get_RootObject"))
                .Ret()
                // fail:
                .MarkLabel(fail)
                .Ldnull()
                .Ret();

                ownServices.Add(mappings.RootObjectProvider);
            }

            if (mappings.ParentStackProvider != null)
            {
                builder.AddInterfaceImplementation(mappings.ParentStackProvider);
                var objectListType = typeSystem.GetType("System.Collections.Generic.List`1")
                                     .MakeGenericType(new[] { typeSystem.GetType("System.Object") });
                ParentListField = builder.DefineField(objectListType, "ParentsStack", true, false);

                var enumerator = EmitParentEnumerable(typeSystem, builder, mappings);
                CreateCallbacks.Add(enumerator.createCallback);
                _parentStackEnumerableField = builder.DefineField(
                    typeSystem.GetType("System.Collections.Generic.IEnumerable`1").MakeGenericType(new[] { so }),
                    "_parentStackEnumerable", false, false);

                ImplementInterfacePropertyGetter(builder, mappings.ParentStackProvider, "Parents")
                .Generator.LdThisFld(_parentStackEnumerableField).Ret();

                ctorCallbacks.Add(g => g
                                  .Emit(OpCodes.Ldarg_0)
                                  .Emit(OpCodes.Newobj, objectListType.FindConstructor(new List <IXamlIlType>()))
                                  .Emit(OpCodes.Stfld, ParentListField)
                                  .Emit(OpCodes.Ldarg_0)
                                  .Emit(OpCodes.Ldarg_0)
                                  .Emit(OpCodes.Newobj, enumerator.ctor)
                                  .Emit(OpCodes.Stfld, _parentStackEnumerableField));
                ownServices.Add(mappings.ParentStackProvider);
            }

            ownServices.Add(EmitTypeDescriptorContextStub(typeSystem, builder, mappings));

            if (mappings.ProvideValueTarget != null)
            {
                builder.AddInterfaceImplementation(mappings.ProvideValueTarget);
                PropertyTargetObject   = builder.DefineField(so, "ProvideTargetObject", true, false);
                PropertyTargetProperty = builder.DefineField(so, "ProvideTargetProperty", true, false);
                ImplementInterfacePropertyGetter(builder, mappings.ProvideValueTarget, "TargetObject")
                .Generator.LdThisFld(PropertyTargetObject).Ret();
                ImplementInterfacePropertyGetter(builder, mappings.ProvideValueTarget, "TargetProperty")
                .Generator.LdThisFld(PropertyTargetProperty).Ret();
                ownServices.Add(mappings.ProvideValueTarget);
            }

            if (mappings.UriContextProvider != null)
            {
                var systemUri = typeSystem.GetType("System.Uri");
                var cached    = builder.DefineField(systemUri, "_baseUri", false, false);
                builder.AddInterfaceImplementation(mappings.UriContextProvider);
                var getter = builder.DefineMethod(systemUri, new IXamlIlType[0], "get_BaseUri", true, false, true);
                var setter = builder.DefineMethod(typeSystem.GetType("System.Void"), new[] { systemUri },
                                                  "set_BaseUri", true, false, true);


                var noCache = getter.Generator.DefineLabel();
                getter.Generator
                .LdThisFld(cached)
                .Brfalse(noCache)
                .LdThisFld(cached)
                .Ret()
                .MarkLabel(noCache)
                .Ldarg_0()
                .Ldstr(baseUri)
                .Newobj(systemUri.FindConstructor(new List <IXamlIlType>
                {
                    typeSystem.GetType("System.String")
                }))
                .Stfld(cached)
                .LdThisFld(cached)
                .Ret();

                setter.Generator
                .Ldarg_0()
                .Ldarg(1)
                .Stfld(cached)
                .Ret();
                builder.DefineProperty(systemUri, "BaseUri", setter, getter);


                ownServices.Add(mappings.UriContextProvider);
            }

            builder.AddInterfaceImplementation(mappings.ServiceProvider);
            var getServiceMethod = builder.DefineMethod(so,
                                                        new[] { systemType },
                                                        "GetService", true, false, true);

            ownServices = ownServices.Where(s => s != null).ToList();


            if (_innerServiceProviderField != null)
            {
                var next        = getServiceMethod.Generator.DefineLabel();
                var innerResult = getServiceMethod.Generator.DefineLocal(so);
                getServiceMethod.Generator
                //if(_inner == null) goto next;
                .LdThisFld(_innerServiceProviderField)
                .Brfalse(next)
                // var innerRes = _inner.GetService(type);
                .LdThisFld(_innerServiceProviderField)
                .Ldarg(1)
                .EmitCall(getServiceInterfaceMethod)
                .Stloc(innerResult)
                // if(innerRes == null) goto next;
                .Ldloc(innerResult)
                .Brfalse(next)
                // return innerRes
                .Ldloc(innerResult)
                .Ret()
                .MarkLabel(next);
            }
            var compare = systemType.FindMethod("Equals", typeSystem.GetType("System.Boolean"),
                                                false, systemType);
            var fromHandle = systemType.Methods.First(m => m.Name == "GetTypeFromHandle");

            if (ownServices.Count != 0)
            {
                for (var c = 0; c < ownServices.Count; c++)
                {
                    var next = getServiceMethod.Generator.DefineLabel();
                    getServiceMethod.Generator
                    .Emit(OpCodes.Ldtoken, ownServices[c])
                    .Emit(OpCodes.Call, fromHandle)
                    .Emit(OpCodes.Ldarg_1)
                    .Emit(OpCodes.Callvirt, compare)
                    .Emit(OpCodes.Brfalse, next)
                    .Emit(OpCodes.Ldarg_0)
                    .Emit(OpCodes.Ret)
                    .MarkLabel(next);
                }
            }

            if (staticProviders != null)
            {
                foreach (var sprov in staticProviders)
                {
                    var next = getServiceMethod.Generator.DefineLabel();
                    getServiceMethod.Generator
                    .Ldtoken(sprov.FieldType)
                    .EmitCall(fromHandle)
                    .Ldarg(1)
                    .EmitCall(compare)
                    .Brfalse(next)
                    .Ldsfld(sprov)
                    .Ret()
                    .MarkLabel(next);
                }
            }

            var noParentProvider = getServiceMethod.Generator.DefineLabel();

            getServiceMethod.Generator
            .LdThisFld(_parentServiceProviderField)
            .Brfalse(noParentProvider)
            .LdThisFld(_parentServiceProviderField)
            .Ldarg(1)
            .EmitCall(getServiceInterfaceMethod)
            .Emit(OpCodes.Ret)
            .MarkLabel(noParentProvider)
            .Ldnull()
            .Ret();

            var ctor = builder.DefineConstructor(false, mappings.ServiceProvider);

            ctor.Generator
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Call, so.Constructors.First())
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Ldarg_1)
            .Emit(OpCodes.Stfld, _parentServiceProviderField);
            foreach (var feature in ctorCallbacks)
            {
                feature(ctor.Generator);
            }

            // We are calling this last to ensure that our own services are ready
            if (_innerServiceProviderField != null)
            {
                ctor.Generator
                // _innerSp = InnerServiceProviderFactory(this)
                .Ldarg_0()
                .Ldarg_0()
                .EmitCall(mappings.InnerServiceProviderFactoryMethod)
                .Stfld(_innerServiceProviderField);
            }

            ctor.Generator.Emit(OpCodes.Ret);

            Constructor = ctor;
            CreateCallbacks.Add(() => { ContextType = builder.CreateType(); });
            ContextType = builder;
        }
Exemple #4
0
 public IXamlIlEmitter Emit(OpCode code, IXamlIlField field)
 {
     Track(code, field);
     _inner.Emit(code, field);
     return(this);
 }
Exemple #5
0
 public bool Equals(IXamlIlField other) => other is CecilField cf && cf.Field == Field;
Exemple #6
0
 public IXamlIlEmitter Emit(SreOpCode code, IXamlIlField field)
 {
     return(Emit(Instruction.Create(Dic[code], Import(((CecilField)field).Field))));
 }
Exemple #7
0
 public IXamlIlEmitter Emit(OpCode code, IXamlIlField field)
 {
     _ilg.Emit(code, ((SreField)field).Field);
     return(this);
 }
Exemple #8
0
 public bool Equals(IXamlIlField other) => ((SreField)other)?.Field.Equals(Field) == true;
Exemple #9
0
 public static XamlIlConstantNode GetLiteralFieldConstantNode(IXamlIlField field, IXamlIlLineInfo info)
 => new XamlIlConstantNode(info, field.FieldType, GetLiteralFieldConstantValue(field));
Exemple #10
0
 public UnsetValueSetter(AvaloniaXamlIlWellKnownTypes types, IXamlIlType declaringType, IXamlIlField avaloniaProperty)
     : base(types, declaringType, avaloniaProperty)
 {
     Parameters = new[] { types.UnsetValueType };
 }
Exemple #11
0
 public BindingSetter(AvaloniaXamlIlWellKnownTypes types,
                      IXamlIlType declaringType,
                      IXamlIlField avaloniaProperty) : base(types, declaringType, avaloniaProperty)
 {
     Parameters = new[] { types.IBinding };
 }