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); }
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)); }
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)); }