public void Emit(IXamlIlEmitter emitter) { var so = _parent._config.WellKnownTypes.Object; var method = _parent._avaloniaObject .FindMethod(m => m.IsPublic && !m.IsStatic && m.Name == "SetValue" && m.Parameters.Count == 3 && m.Parameters[0].Equals(_parent._avaloniaPropertyType) && m.Parameters[1].Equals(so) && m.Parameters[2].IsEnum ); if (method == null) { throw new XamlIlTypeSystemException( "Unable to find SetValue(AvaloniaProperty, object, BindingPriority) on AvaloniaObject"); } using (var loc = emitter.LocalsPool.GetLocal(_parent.PropertyType)) emitter .Stloc(loc.Local) .Ldsfld(_parent._field) .Ldloc(loc.Local); if (_parent.PropertyType.IsValueType) { emitter.Box(_parent.PropertyType); } emitter .Ldc_I4(0) .EmitCall(method); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { var exts = context.Configuration.TypeSystem.GetType("Avalonia.Controls.NameScopeExtensions"); var findNameScope = exts.FindMethod(m => m.Name == "FindNameScope"); var registerMethod = findNameScope.ReturnType.FindMethod(m => m.Name == "Register"); using (var targetLoc = context.GetLocal(context.Configuration.WellKnownTypes.Object)) using (var nameScopeLoc = context.GetLocal(findNameScope.ReturnType)) { var exit = codeGen.DefineLabel(); codeGen // var target = {pop} .Stloc(targetLoc.Local) // var scope = target.FindNameScope() .Ldloc(targetLoc.Local) .Castclass(findNameScope.Parameters[0]) .EmitCall(findNameScope) .Stloc(nameScopeLoc.Local) // if({scope} != null) goto call; .Ldloc(nameScopeLoc.Local) .Brfalse(exit) .Ldloc(nameScopeLoc.Local); context.Emit(Value, codeGen, Value.Type.GetClrType()); codeGen .Ldloc(targetLoc.Local) .EmitCall(registerMethod) .MarkLabel(exit); } return(XamlIlNodeEmitResult.Void(1)); }
public void Emit(XamlIlEmitContext 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 <XamlIlEmitContext.PooledLocal>(); for (var c = ParametersWithThis.Count - 1; c >= firstCast; c--) { codeGen.Castclass(ParametersWithThis[c]); if (c > firstCast) { var l = context.GetLocal(ParametersWithThis[c]); codeGen.Stloc(l.Local); locals.Push(l); } } while (locals.Count != 0) { using (var l = locals.Pop()) codeGen.Ldloc(l.Local); } } _method.Emit(context, codeGen, swallowResult); }
public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (!(node is XamlIlObjectInitializationNode 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 <XamlIlNeedsParentStackCache>().NeedsParentStack(node); if (addToParentStack) { using (var local = context.GetLocal(init.Type)) codeGen .Stloc(local.Local) .Ldloc(context.ContextLocal) .Ldloc(local.Local) .EmitCall(context.RuntimeContext.PushParentMethod) .Ldloc(local.Local); } 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 override void Emit(IXamlIlEmitter emitter) { using (var bloc = emitter.LocalsPool.GetLocal(Types.IBinding)) emitter .Stloc(bloc.Local) .Ldsfld(AvaloniaProperty) .Ldloc(bloc.Local) // TODO: provide anchor? .Ldnull(); emitter.EmitCall(Types.AvaloniaObjectBindMethod, 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); }
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(); }
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); }
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)); }
private XamlIlNodeEmitResult EmitCore(IXamlIlAstNode value, IXamlIlEmitter codeGen, IXamlIlType expectedType) { CheckingIlEmitter parent = null; CheckingIlEmitter checkedEmitter = null; if (EnableIlVerification) { parent = codeGen as CheckingIlEmitter; parent?.Pause(); checkedEmitter = new CheckingIlEmitter(codeGen); } #if XAMLIL_DEBUG var res = EmitNode(value, checkedEmitter); #else XamlIlNodeEmitResult res; try { res = EmitNode(value, checkedEmitter ?? codeGen); } catch (Exception e) when(!(e is XmlException)) { throw new XamlIlLoadException( "Internal compiler error while emitting node " + value + ":\n" + e, value); } #endif if (EnableIlVerification) { var expectedBalance = res.ProducedItems - res.ConsumedItems; var checkResult = checkedEmitter.Check(res.ProducedItems - res.ConsumedItems, false); if (checkResult != null) { throw new XamlIlLoadException($"Error during IL verification: {checkResult}\n{checkedEmitter}\n", value); } parent?.Resume(); parent?.ExplicitStack(expectedBalance); } var returnedType = res.ReturnType; if (returnedType != null || expectedType != null) { if (returnedType != null && expectedType == null) { throw new XamlIlLoadException( $"Emit of node {value} resulted in {returnedType.GetFqn()} while caller expected void", value); } if (expectedType != null && returnedType == null) { throw new XamlIlLoadException( $"Emit of node {value} resulted in void while caller expected {expectedType.GetFqn()}", value); } if (!returnedType.Equals(expectedType)) { XamlIlLocalsPool.PooledLocal local = null; // ReSharper disable once ExpressionIsAlwaysNull // Value is assigned inside the closure in certain conditions TypeSystemHelpers.EmitConvert(this, value, returnedType, expectedType, ldaddr => { if (ldaddr && returnedType.IsValueType) { // We need to store the value to a temporary variable, since *address* // is required (probably for method call on the value type) local = GetLocal(returnedType); codeGen .Stloc(local.Local) .Ldloca(local.Local); } // Otherwise do nothing, value is already at the top of the stack return(codeGen); }); local?.Dispose(); } } return(res); }
public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (!(node is XamlIlObjectInitializationNode 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")); } } IXamlIlType objectListType = null; var addToParentStack = context.RuntimeContext.ParentListField != null && !init.Type.IsValueType && context.GetOrCreateItem <XamlIlNeedsParentStackCache>().NeedsParentStack(node); if (addToParentStack) { objectListType = context.Configuration.TypeSystem.GetType("System.Collections.Generic.List`1") .MakeGenericType(new[] { context.Configuration.WellKnownTypes.Object }); using (var local = context.GetLocal(init.Type)) codeGen .Stloc(local.Local) .Ldloc(context.ContextLocal).Ldfld(context.RuntimeContext.ParentListField) .Ldloc(local.Local) .EmitCall(objectListType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, context.Configuration.WellKnownTypes.Object)) .Ldloc(local.Local); } context.Emit(init.Manipulation, codeGen, null); if (addToParentStack) { codeGen .Ldloc(context.ContextLocal).Ldfld(context.RuntimeContext.ParentListField) .Ldloc(context.ContextLocal).Ldfld(context.RuntimeContext.ParentListField) .EmitCall(objectListType.FindMethod(m => m.Name == "get_Count")) .Ldc_I4(1).Emit(OpCodes.Sub) .EmitCall(objectListType.FindMethod(m => m.Name == "RemoveAt")); } if (supportsInitialize) { codeGen .EmitCall(supportInitType.FindMethod(m => m.Name == "EndInit")); } return(XamlIlNodeEmitResult.Void(1)); }