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(XamlIlEmitContext context, IXamlIlEmitter codeGen) { var next = codeGen.DefineLabel(); var scopeField = context.RuntimeContext.ContextType.Fields.First(f => f.Name == AvaloniaXamlIlLanguage.ContextNameScopeFieldName); using (var local = codeGen.LocalsPool.GetLocal(_types.StyledElement)) { codeGen .Isinst(_types.StyledElement) .Dup() .Stloc(local.Local) .Brfalse(next) .Ldloc(local.Local) .Ldloc(context.ContextLocal) .Ldfld(scopeField) .EmitCall(_types.NameScopeSetNameScope, true) .MarkLabel(next) .Ldloc(context.ContextLocal) .Ldfld(scopeField) .EmitCall(_types.INameScopeComplete, true); } return(XamlIlNodeEmitResult.Void(1)); }
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)); }
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 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)); }
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)); }
protected void EmitCall(XamlIlEmitContext context, IXamlIlEmitter codeGen, Func <IXamlIlMethod, bool> method) { var selectors = context.Configuration.TypeSystem.GetType("Avalonia.Styling.Selectors"); var found = selectors.FindMethod(m => m.IsStatic && m.Parameters.Count > 0 && method(m)); codeGen.EmitCall(found); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { // Discard the stack value we are "supposed" to manipulate codeGen.Pop(); context.Emit(Imperative, codeGen, null); return(XamlIlNodeEmitResult.Void(1)); }
protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { var name = _type.ToString(); EmitCall(context, codeGen, m => m.Name == name && m.Parameters.Count == 1); }
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); } }
protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (_selectors.Count == 0) { throw new XamlIlLoadException("Invalid selector count", this); } if (_selectors.Count == 1) { _selectors[0].Emit(context, codeGen); return; } var listType = context.Configuration.TypeSystem.FindType("System.Collections.Generic.List`1") .MakeGenericType(base.Type.GetClrType()); var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType()); codeGen .Newobj(listType.FindConstructor()); foreach (var s in _selectors) { codeGen.Dup(); context.Emit(s, codeGen, Type.GetClrType()); codeGen.EmitCall(add, true); } EmitCall(context, codeGen, m => m.Name == "Or" && m.Parameters.Count == 1 && m.Parameters[0].Name.StartsWith("IReadOnlyList")); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { codeGen .Ldloc(context.ContextLocal) .Ldfld(context.RuntimeContext.RootObjectField); return(XamlIlNodeEmitResult.Type(0, Type.GetClrType())); }
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)); }
protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { codeGen.Ldstr(String); var name = _type.ToString(); EmitCall(context, codeGen, m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].FullName == "System.String"); }
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)); }
protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { var name = Concrete ? "OfType" : "Is"; codeGen.Ldtype(TargetType); EmitCall(context, codeGen, m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].FullName == "System.Type"); }
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())); }
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 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())); }
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)); }
public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (!(node is XamlIlPropertyAssignmentNode an)) return null; var callOp = an.Property.Setter.IsStatic ? OpCodes.Call : OpCodes.Callvirt; context.Emit(an.Value, codeGen, an.Property.Setter.Parameters.Last()); codeGen.Emit(callOp, an.Property.Setter); return XamlIlNodeEmitResult.Void(1); }
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)); }
public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (!(node is XamlIlPropertyValueManipulationNode pvm)) { return(null); } codeGen.EmitCall(pvm.Property.Getter); context.Emit(pvm.Manipulation, codeGen, null); return(XamlIlNodeEmitResult.Void(1)); }
public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlCodeGen codeGen) { if (!(node is XamlIlPropertyValueManipulationNode pvm)) { return(null); } codeGen.Generator.Emit(pvm.Property.Getter.IsStatic ? OpCodes.Call : OpCodes.Callvirt, pvm.Property.Getter); context.Emit(pvm.Manipulation, codeGen, null); return(XamlIlNodeEmitResult.Void); }
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())); }
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); } }
public static bool Emit(XamlIlEmitContext context, IXamlIlEmitter emitter, IXamlIlProperty property) { var type = (property.Getter ?? property.Setter).DeclaringType; var name = property.Name + "Property"; var found = type.Fields.FirstOrDefault(f => f.IsStatic && f.Name == name); if (found == null) { return(false); } emitter.Ldsfld(found); return(true); }
protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (!XamlIlAvaloniaPropertyHelper.Emit(context, codeGen, Property)) { throw new XamlIlLoadException( $"{Property.Name} of {(Property.Setter ?? Property.Getter).DeclaringType.GetFqn()} doesn't seem to be an AvaloniaProperty", this); } context.Emit(Value, codeGen, context.Configuration.WellKnownTypes.Object); EmitCall(context, codeGen, m => m.Name == "PropertyEquals" && m.Parameters.Count == 3 && m.Parameters[1].FullName == "Avalonia.AvaloniaProperty" && m.Parameters[2].Equals(context.Configuration.WellKnownTypes.Object)); }
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)); }
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)); }