public IXamlILEmitter MarkLabel(IXamlLabel label)
 {
     if (_labels.TryGetValue(label, out var info))
     {
         info.Offset = Instructions.Count;
     }
     _inner.MarkLabel(label);
     return(this);
 }
 public IXamlILEmitter MarkLabel(IXamlLabel label)
 {
     if (!_unmarkedLabels.Remove(label))
     {
         throw new InvalidOperationException("Attempt to mark undeclared label");
     }
     _inner.MarkLabel(label);
     _labelsToMarkOnNextInstruction.Add(label);
     return(this);
 }
Exemplo n.º 3
0
 public static IXamlILEmitter Ble(this IXamlILEmitter emitter, IXamlLabel label)
 => emitter.Emit(OpCodes.Ble, label);
Exemplo n.º 4
0
 public IXamlILEmitter Emit(OpCode code, IXamlLabel label)
 {
     _ilg.Emit(code, ((SreLabel)label).Label);
     return(this);
 }
Exemplo n.º 5
0
 public IXamlILEmitter MarkLabel(IXamlLabel label)
 {
     _ilg.MarkLabel(((SreLabel)label).Label);
     return(this);
 }
 public IXamlILEmitter Emit(OpCode code, IXamlLabel label)
 {
     Record(code, label);
     _inner.Emit(code, label);
     return(this);
 }
Exemplo n.º 7
0
 public IXamlILEmitter Emit(SreOpCode code, IXamlLabel label)
 => Emit(((CecilLabel)label).CreateInstruction(Dic[code]));
Exemplo n.º 8
0
 public IXamlILEmitter MarkLabel(IXamlLabel label)
 {
     _markedLabels.Add((CecilLabel)label);
     return(this);
 }
        public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
        {
            if (!(node is XamlPropertyAssignmentNode 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();

                using (codeGen.EmitSetPropertyMarker(setter))
                {
                    context.Emit(value, codeGen, setter.Parameters.Last());
                    context.Emit(setter, codeGen);
                }
            }
            else
            {
                var        checkedTypes = new List <IXamlType>();
                var        exit         = codeGen.DefineLabel();
                IXamlLabel 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;
                    }

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

                    ILEmitHelpers.EmitConvert(context, codeGen, value, value.Type.GetClrType(), type);
                    context.Emit(setter, 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));
        }