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); } }
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)); }
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(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(XamlIlEmitContext context, IXamlIlEmitter codeGen) { // Discard the stack value we are "supposed" to manipulate codeGen.Pop(); context.Emit(Imperative, codeGen, null); 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(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)); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { codeGen .Ldloc(context.ContextLocal) .Ldfld(context.RuntimeContext.RootObjectField); return(XamlIlNodeEmitResult.Type(0, Type.GetClrType())); }
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(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)); }
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 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 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(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, 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 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)); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { var type = Value.GetClrType(); var method = _systemType.Methods.FirstOrDefault(m => m.Name == "GetTypeFromHandle" && m.Parameters.Count == 1 && m.Parameters[0].Name == "RuntimeTypeHandle"); if (method == null) { throw new XamlIlTypeSystemException( $"Unable to find GetTypeFromHandle(RuntimeTypeHandle) on {_systemType.GetFqn()}"); } codeGen .Emit(OpCodes.Ldtoken, type) .Emit(OpCodes.Call, method); return(XamlIlNodeEmitResult.Type(0, _systemType)); }
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)); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (Constant is string) { codeGen.Emit(OpCodes.Ldstr, (string)Constant); } else if (Constant is long || Constant is ulong) { codeGen.Emit(OpCodes.Ldc_I8, TypeSystemHelpers.ConvertLiteralToLong(Constant)); } else if (Constant is float f) { codeGen.Emit(OpCodes.Ldc_R4, f); } else if (Constant is double d) { codeGen.Emit(OpCodes.Ldc_R8, d); } else { codeGen.Emit(OpCodes.Ldc_I4, TypeSystemHelpers.ConvertLiteralToInt(Constant)); } return(XamlIlNodeEmitResult.Type(0, Type.GetClrType())); }
public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (!(node is XamlIlManipulationGroupNode group)) { return(null); } if (group.Children.Count == 0) { codeGen.Emit(OpCodes.Pop); } else { for (var c = 0; c < group.Children.Count; c++) { if (c != group.Children.Count - 1) { codeGen.Emit(OpCodes.Dup); } context.Emit(group.Children[c], codeGen, null); } } return(XamlIlNodeEmitResult.Void(1)); }
public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (!(node is XamlIlMethodCallBaseNode mc)) { return(null); } bool thisArgFromArgs = node is XamlIlStaticOrTargetedReturnMethodCallNode; bool expectsVoid = node is XamlIlNoReturnMethodCallNode; for (var c = 0; c < mc.Arguments.Count; c++) { var off = thisArgFromArgs ? 0 : 1; var expectedType = mc.Method.ParametersWithThis[c + off]; context.Emit(mc.Arguments[c], codeGen, expectedType); } mc.Method.Emit(context, codeGen, expectsVoid); var isVoid = mc.Method.ReturnType.Equals(context.Configuration.WellKnownTypes.Void); if (!expectsVoid && isVoid) { throw new XamlIlLoadException( $"XamlIlStaticReturnMethodCallNode expects a value while {mc.Method.Name} returns void", node); } var consumed = thisArgFromArgs ? 0 : 1; return(isVoid || expectsVoid ? XamlIlNodeEmitResult.Void(consumed) : XamlIlNodeEmitResult.Type(consumed, mc.Method.ReturnType)); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { context.Emit(Value, codeGen, Value.Type.GetClrType()); context.Emit(Manipulation, codeGen, null); return(XamlIlNodeEmitResult.Void(0)); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { codeGen.Emit(OpCodes.Ldnull); return(XamlIlNodeEmitResult.Type(0, XamlIlPseudoType.Null)); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { codeGen.Ldloc(context.ContextLocal); return(XamlIlNodeEmitResult.Type(0, Type.GetClrType())); }
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) { context.LdLocal(this, codeGen); return(XamlIlNodeEmitResult.Type(0, Type)); }