public IXamlIlLabel DefineLabel() { var label = _inner.DefineLabel(); _unmarkedLabels.Add(label, null);//, Environment.StackTrace); return(label); }
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 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 IXamlIlLabel DefineLabel() { var label = _inner.DefineLabel(); _labels[label] = new LabelInfo(); return(label); }
public XamlIlNodeEmitResult Emit(IXamlIlAstNode node, XamlIlEmitContext context, IXamlIlEmitter codeGen) { if (!(node is XamlIlPropertyAssignmentNode 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(); context.Emit(value, codeGen, setter.Parameters.Last()); setter.Emit(codeGen); } else { var checkedTypes = new List <IXamlIlType>(); IXamlIlLabel exit = codeGen.DefineLabel(); IXamlIlLabel 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; } IXamlIlLabel 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; } TypeSystemHelpers.EmitConvert(context, codeGen, value, value.Type.GetClrType(), type); setter.Emit(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)); }