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