Beispiel #1
0
        private Emit(CallingConventions callConvention, Type returnType, Type[] parameterTypes, bool allowUnverifiable, bool doVerify, bool strictBranchVerification)
        {
            CallingConventions = callConvention;

            AllowsUnverifiableCIL = allowUnverifiable;

            IsVerifying = doVerify;
            UsesStrictBranchVerification = strictBranchVerification;

            ReturnType     = TypeOnStack.Get(returnType);
            ParameterTypes = parameterTypes;

            IL = new BufferedILGenerator <DelegateType>();

            Trackers = new LinqList <VerifiableTracker>();

            AllLocals = new LinqList <Local>();

            UnusedLocals   = new LinqHashSet <Local>();
            UnusedLabels   = new LinqHashSet <Label>();
            UnmarkedLabels = new LinqHashSet <Label>();

            Branches = new LinqList <SigilTuple <OpCode, Label, int> >();
            Marks    = new LinqDictionary <Label, int>();
            Returns  = new LinqList <int>();
            Throws   = new LinqList <int>();

            BranchPatches = new LinqDictionary <int, SigilTuple <Label, UpdateOpCodeDelegate, OpCode> >();

            CurrentExceptionBlock = new Stack <ExceptionBlock>();

            TryBlocks     = new LinqDictionary <ExceptionBlock, SigilTuple <int, int> >();
            CatchBlocks   = new LinqDictionary <CatchBlock, SigilTuple <int, int> >();
            FinallyBlocks = new LinqDictionary <FinallyBlock, SigilTuple <int, int> >();

            ReadonlyPatches = new LinqList <SigilTuple <int, TypeOnStack> >();

            Shorthand = new EmitShorthand <DelegateType>(this);

            FreedLocals = new LinqList <Local>();

            CurrentLocals = new LinqDictionary <string, Local>();
            Locals        = new LocalLookup(CurrentLocals);

            CurrentLabels = new LinqDictionary <string, Label>();
            Labels        = new LabelLookup(CurrentLabels);

            ElidableCasts = new LinqList <int>();

            TypesProducedAtIndex = new LinqDictionary <int, LinqList <TypeOnStack> >();

            var start = DefineLabel("__start");

            CurrentVerifiers = IsVerifying ? new RollingVerifier(start, UsesStrictBranchVerification) : new RollingVerifierWithoutVerification(start);
            MarkLabel(start);
        }
Beispiel #2
0
        public RollingVerifier(Label beginAt, bool strictBranchVerification)
        {
            UsesStrictBranchVerification = strictBranchVerification;

            RestoreOnMark = new LinqDictionary<Label, LinqList<VerifiableTracker>>();
            RestoreStacksOnMark = new LinqDictionary<Label, LinqList<LinqStack<LinqList<TypeOnStack>>>>();
            VerifyFromLabel = new LinqDictionary<Label, LinqList<VerifiableTracker>>();

            StacksAtLabels = new LinqDictionary<Label, SigilTuple<bool, LinqStack<LinqList<TypeOnStack>>>>();
            ExpectedStacksAtLabels = new LinqDictionary<Label, LinqList<SigilTuple<bool, LinqStack<LinqList<TypeOnStack>>>>>();

            MustBeEmptyWhenBranchedTo = new LinqHashSet<Label>();

            EmptyCurrentScope();
            
            Add(new VerifiableTracker(beginAt), new LinqStack<LinqList<TypeOnStack>>());
        }
Beispiel #3
0
        private void ValidateDelegateType(Type delegateType)
        {
            var baseTypes = new LinqHashSet <Type>();

            baseTypes.Add(delegateType);
            var bType = TypeHelpers.GetBaseType(delegateType);

            while (bType != null)
            {
                baseTypes.Add(bType);
                bType = TypeHelpers.GetBaseType(bType);
            }

            if (!baseTypes.Contains(typeof(Delegate)))
            {
                throw new ArgumentException("delegateType must be a delegate, found " + delegateType.FullName);
            }

            var invoke     = delegateType.GetMethod("Invoke");
            var returnType = invoke.ReturnType;

            if (returnType != ReturnType)
            {
                throw new ArgumentException("Expected delegateType to return " + ReturnType + ", found " + returnType);
            }

            var parameterTypes = invoke.GetParameters();

            if (parameterTypes.Length != ParameterTypes.Length)
            {
                throw new ArgumentException("Expected delegateType to take " + ParameterTypes.Length + " parameters, found " + parameterTypes.Length);
            }

            for (var i = 0; i < parameterTypes.Length; i++)
            {
                var actualType   = parameterTypes[i].ParameterType;
                var expectedType = ParameterTypes[i];

                if (actualType != expectedType)
                {
                    throw new ArgumentException("Expected delegateType's parameter at index " + i + " to be a " + expectedType + ", found " + actualType);
                }
            }
        }
Beispiel #4
0
        private static void ValidateNewParameters <CheckDelegateType>()
        {
            var delType = typeof(CheckDelegateType);

            var baseTypes = new LinqHashSet <Type>();

            baseTypes.Add(delType);
            var bType = delType.BaseType;

            while (bType != null)
            {
                baseTypes.Add(bType);
                bType = bType.BaseType;
            }

            if (!baseTypes.Contains(typeof(Delegate)))
            {
                throw new ArgumentException("DelegateType must be a delegate, found " + delType.FullName);
            }
        }
Beispiel #5
0
        private static void ValidateNewParameters <CheckDelegateType>()
        {
            var delType = typeof(CheckDelegateType);

            var baseTypes = new LinqHashSet <Type>();

            baseTypes.Add(delType);
#if NETSTANDARD
            var bType = delType.GetTypeInfo().BaseType;
#else
            var bType = delType.BaseType;
#endif
            while (bType != null)
            {
                baseTypes.Add(bType);
                bType = TypeHelpers.GetBaseType(bType);
            }

            if (!baseTypes.Contains(typeof(Delegate)))
            {
                throw new ArgumentException("DelegateType must be a delegate, found " + delType.FullName);
            }
        }
        private static void UpdateStack(LinqStack<LinqList<TypeOnStack>> stack, InstructionAndTransitions wrapped, bool isBaseless)
        {
            var legal = wrapped.Transitions;
            var instr = wrapped.Instruction;

            var legalSize = 0;

            legal.Each(
                t =>
                {
                    legalSize += t.PushedToStack.Length;

                    if (t.Before != null) t.Before(stack, isBaseless);
                }
            );

            if (legal.Any(l => LinqAlternative.Any(l.PoppedFromStack, u => u == TypeOnStack.Get<PopAllType>())))
            {
                if (instr.HasValue)
                {
                    for (var i = 0; i < stack.Count; i++)
                    {
                        var ix = stack.Count - i - 1;
                        stack.ElementAt(i).Each(y => y.Mark(wrapped, ix));
                    }
                }

                stack.Clear();
            }
            else
            {
                var toPop = legal.First().PoppedCount;

                for (var j = 0; j < toPop && stack.Count > 0; j++)
                {
                    var popped = stack.Pop();

                    if (instr.HasValue)
                    {
                        var ix = toPop - j - 1;
                        popped.Each(y => y.Mark(wrapped, ix));
                    }
                }
            }

            var toPush = new LinqList<TypeOnStack>(legalSize);
            var pushed = new LinqHashSet<TypeOnStack>();
            for(var i = 0; i < legal.Count; i++)
            {
                foreach (var p in legal[i].PushedToStack)
                {
                    if (pushed.Contains(p)) continue;

                    toPush.Add(p);
                    pushed.Add(p);
                }
            }

            if (toPush.Count > 0)
            {
                stack.Push(toPush);
            }
        }