Example #1
0
		internal ViewLocator(IApp app) {
			viewMap = new Dictionary<Type, IList<IView>>();
			foreach (var type in typeof(IView).Assembly.GetTypes()) {
				if (!type.IsAbstract && typeof(IView).IsAssignableFrom(type)) {
					var baseType = type.BaseType;

					if (baseType != null && baseType.IsGenericType &&
					    baseType.GetGenericTypeDefinition() == typeof(ViewBase<>)) {
						var view = (IView)Activator.CreateInstance(type);
						type.GetProperty("App").SetValue(view, app, null);

						var modelType = baseType.GetGenericArguments()[0];
						viewMap.AddListEntry(modelType, view);
					}
				}
			}
		}
Example #2
0
        private void Override(Dictionary<VTableSignature, List<VTableSlot>> slotDict, VTableSignature sig, VTableSlot slot, MethodDef target)
        {
            List<VTableSlot> slotList = slotDict[sig];
            VTableSlot targetSlot = slotList.Single(baseSlot => baseSlot.MethodDef == target);

            if (slot.MethodDef.IsReuseSlot || targetSlot.MethodDef.DeclaringType.IsInterface)
                slot.Override(targetSlot);
            slotList.Remove(targetSlot);

            if (!slot.MethodDef.IsFinal) {
                slotDict.AddListEntry(slot.Signature, slot);
                Slots.Add(slot);
            }
            else
                Finals.Add(slot);
        }
Example #3
0
 private void Inherit(VTable parent, Dictionary<VTableSignature, List<VTableSlot>> slotDict)
 {
     foreach (VTableSlot slot in parent.Slots) {
         List<VTableSlot> slotList;
         if (slotDict.TryGetValue(slot.Signature, out slotList)) {
             if (slotList.Count > 0) {
                 if (slotList.All(baseSlot => baseSlot.MethodDef.DeclaringType.IsInterface)) {
                     // Base slot is interface method => add together
                     if (!slotList.Any(baseSlot =>
                                       baseSlot.Signature == slot.Signature &&
                                       new SigComparer().Equals(baseSlot.DeclaringType, slot.DeclaringType))) {
                         slotList.Add(slot);
                         Slots.Add(slot);
                     }
                 }
                 else
                     throw new UnreachableException();
             }
             else {
                 slotList.Add(slot);
                 Slots.Add(slot);
             }
         }
         else {
             slotDict.AddListEntry(slot.Signature, slot);
             Slots.Add(slot);
         }
     }
 }
Example #4
0
            public Trace(CilBody body, bool hasReturnValue)
            {
                RefCount = new Dictionary<uint, int>();
                BrRefs = new Dictionary<uint, List<Instruction>>();
                BeforeStack = new Dictionary<uint, int>();
                AfterStack = new Dictionary<uint, int>();

                body.UpdateInstructionOffsets();

                foreach (ExceptionHandler eh in body.ExceptionHandlers) {
                    BeforeStack[eh.TryStart.Offset] = 0;
                    BeforeStack[eh.HandlerStart.Offset] = (eh.HandlerType != ExceptionHandlerType.Finally ? 1 : 0);
                    if (eh.FilterStart != null)
                        BeforeStack[eh.FilterStart.Offset] = 1;
                }

                int currentStack = 0;
                for (int i = 0; i < body.Instructions.Count; i++) {
                    var instr = body.Instructions[i];

                    if (BeforeStack.ContainsKey(instr.Offset))
                        currentStack = BeforeStack[instr.Offset];

                    BeforeStack[instr.Offset] = currentStack;
                    instr.UpdateStack(ref currentStack, hasReturnValue);
                    AfterStack[instr.Offset] = currentStack;

                    uint offset;
                    switch (instr.OpCode.FlowControl) {
                        case FlowControl.Branch:
                            offset = ((Instruction)instr.Operand).Offset;
                            if (!BeforeStack.ContainsKey(offset))
                                BeforeStack[offset] = currentStack;

                            Increment(RefCount, offset);
                            BrRefs.AddListEntry(offset, instr);

                            currentStack = 0;
                            continue;
                        case FlowControl.Call:
                            if (instr.OpCode.Code == Code.Jmp)
                                currentStack = 0;
                            break;
                        case FlowControl.Cond_Branch:
                            if (instr.OpCode.Code == Code.Switch) {
                                foreach (Instruction target in (Instruction[])instr.Operand) {
                                    if (!BeforeStack.ContainsKey(target.Offset))
                                        BeforeStack[target.Offset] = currentStack;

                                    Increment(RefCount, target.Offset);
                                    BrRefs.AddListEntry(target.Offset, instr);
                                }
                            }
                            else {
                                offset = ((Instruction)instr.Operand).Offset;
                                if (!BeforeStack.ContainsKey(offset))
                                    BeforeStack[offset] = currentStack;

                                Increment(RefCount, offset);
                                BrRefs.AddListEntry(offset, instr);
                            }
                            break;
                        case FlowControl.Meta:
                        case FlowControl.Next:
                        case FlowControl.Break:
                            break;
                        case FlowControl.Return:
                        case FlowControl.Throw:
                            continue;
                        default:
                            throw new UnreachableException();
                    }

                    if (i + 1 < body.Instructions.Count) {
                        offset = body.Instructions[i + 1].Offset;
                        Increment(RefCount, offset);
                    }
                }
            }
Example #5
0
		/// <summary>
		///     Perform the actual tracing.
		/// </summary>
		/// <returns>This instance.</returns>
		/// <exception cref="InvalidMethodException">Bad method body.</exception>
		internal MethodTrace Trace() {
			CilBody body = method.Body;
			method.Body.UpdateInstructionOffsets();
			Instructions = method.Body.Instructions.ToArray();

			offset2index = new Dictionary<uint, int>();
			var beforeDepths = new int[body.Instructions.Count];
			var afterDepths = new int[body.Instructions.Count];
			fromInstrs = new Dictionary<int, List<Instruction>>();

			IList<Instruction> instrs = body.Instructions;
			for (int i = 0; i < instrs.Count; i++) {
				offset2index.Add(instrs[i].Offset, i);
				beforeDepths[i] = int.MinValue;
			}

			foreach (ExceptionHandler eh in body.ExceptionHandlers) {
				beforeDepths[offset2index[eh.TryStart.Offset]] = 0;
				beforeDepths[offset2index[eh.HandlerStart.Offset]] = (eh.HandlerType != ExceptionHandlerType.Finally ? 1 : 0);
				if (eh.FilterStart != null)
					beforeDepths[offset2index[eh.FilterStart.Offset]] = 1;
			}

			// Just do a simple forward scan to build the stack depth map
			int currentStack = 0;
			for (int i = 0; i < instrs.Count; i++) {
				Instruction instr = instrs[i];

				if (beforeDepths[i] != int.MinValue) // Already set due to being target of a branch / beginning of EHs.
					currentStack = beforeDepths[i];

				beforeDepths[i] = currentStack;
				instr.UpdateStack(ref currentStack);
				afterDepths[i] = currentStack;

				switch (instr.OpCode.FlowControl) {
					case FlowControl.Branch:
						int index = offset2index[((Instruction)instr.Operand).Offset];
						if (beforeDepths[index] == int.MinValue)
							beforeDepths[index] = currentStack;
						fromInstrs.AddListEntry(offset2index[((Instruction)instr.Operand).Offset], instr);
						currentStack = 0;
						break;
					case FlowControl.Break:
						break;
					case FlowControl.Call:
						if (instr.OpCode.Code == Code.Jmp)
							currentStack = 0;
						break;
					case FlowControl.Cond_Branch:
						if (instr.OpCode.Code == Code.Switch) {
							foreach (Instruction target in (Instruction[])instr.Operand) {
								int targetIndex = offset2index[target.Offset];
								if (beforeDepths[targetIndex] == int.MinValue)
									beforeDepths[targetIndex] = currentStack;
								fromInstrs.AddListEntry(offset2index[target.Offset], instr);
							}
						}
						else {
							int targetIndex = offset2index[((Instruction)instr.Operand).Offset];
							if (beforeDepths[targetIndex] == int.MinValue)
								beforeDepths[targetIndex] = currentStack;
							fromInstrs.AddListEntry(offset2index[((Instruction)instr.Operand).Offset], instr);
						}
						break;
					case FlowControl.Meta:
						break;
					case FlowControl.Next:
						break;
					case FlowControl.Return:
						break;
					case FlowControl.Throw:
						break;
					default:
						throw new UnreachableException();
				}
			}

			foreach (int stackDepth in beforeDepths)
				if (stackDepth == int.MinValue)
					throw new InvalidMethodException("Bad method body.");

			foreach (int stackDepth in afterDepths)
				if (stackDepth == int.MinValue)
					throw new InvalidMethodException("Bad method body.");

			BeforeStackDepths = beforeDepths;
			AfterStackDepths = afterDepths;

			return this;
		}
Example #6
0
        private void PopulateReferences(BamlDocument document)
        {
            var clrNs = new Dictionary<string, List<Tuple<AssemblyDef, string>>>();

            assemblyRefs.Clear();
            foreach (AssemblyInfoRecord rec in document.OfType<AssemblyInfoRecord>()) {
                AssemblyDef assembly = context.Resolver.ResolveThrow(rec.AssemblyFullName, module);
                assemblyRefs.Add(rec.AssemblyId, assembly);

                if (!context.Modules.Any(m => m.Assembly == assembly))
                    continue;

                foreach (CustomAttribute attr in assembly.CustomAttributes.FindAll("System.Windows.Markup.XmlnsDefinitionAttribute")) {
                    clrNs.AddListEntry(
                        (UTF8String)attr.ConstructorArguments[0].Value,
                        Tuple.Create(assembly, (string)(UTF8String)attr.ConstructorArguments[1].Value));
                }
            }

            xmlnsCtx = new XmlNsContext(document, assemblyRefs);

            typeRefs.Clear();
            foreach (TypeInfoRecord rec in document.OfType<TypeInfoRecord>()) {
                AssemblyDef assembly;
                var asmId = (short)(rec.AssemblyId & 0xfff);
                if (asmId == -1)
                    assembly = things.FrameworkAssembly;
                else
                    assembly = assemblyRefs[(ushort)asmId];

                // WPF uses Assembly.GetType to load it, so if no assembly specified in the TypeSig, it must be in current assembly.
                AssemblyDef assemblyRef = module.Assembly == assembly ?
                                              null : context.Resolver.ResolveThrow(module.GetAssemblyRefs().Single(r => r.FullName == assembly.FullName), module);

                TypeSig typeSig = TypeNameParser.ParseAsTypeSigReflectionThrow(module, rec.TypeFullName, new DummyAssemblyRefFinder(assemblyRef));
                typeRefs[rec.TypeId] = typeSig;

                AddTypeSigReference(typeSig, new BAMLTypeReference(typeSig, rec));
            }

            attrRefs.Clear();
            foreach (AttributeInfoRecord rec in document.OfType<AttributeInfoRecord>()) {
                TypeSig declType;
                if (typeRefs.TryGetValue(rec.OwnerTypeId, out declType)) {
                    TypeDef type = declType.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                    attrRefs[rec.AttributeId] = AnalyzeAttributeReference(type, rec);
                }
                else {
                    Debug.Assert((short)rec.OwnerTypeId < 0);
                    TypeDef declTypeDef = things.Types((KnownTypes)(-(short)rec.OwnerTypeId));
                    attrRefs[rec.AttributeId] = AnalyzeAttributeReference(declTypeDef, rec);
                }
            }

            strings.Clear();
            foreach (StringInfoRecord rec in document.OfType<StringInfoRecord>()) {
                strings[rec.StringId] = rec;
            }

            foreach (PIMappingRecord rec in document.OfType<PIMappingRecord>()) {
                var asmId = (short)(rec.AssemblyId & 0xfff);
                AssemblyDef assembly;
                if (asmId == -1)
                    assembly = things.FrameworkAssembly;
                else
                    assembly = assemblyRefs[(ushort)asmId];

                Tuple<AssemblyDef, string> scope = Tuple.Create(assembly, rec.ClrNamespace);
                clrNs.AddListEntry(rec.XmlNamespace, scope);
            }

            xmlns.Clear();
            foreach (XmlnsPropertyRecord rec in document.OfType<XmlnsPropertyRecord>()) {
                List<Tuple<AssemblyDef, string>> clrMap;
                if (clrNs.TryGetValue(rec.XmlNamespace, out clrMap)) {
                    xmlns[rec.Prefix] = clrMap;
                    foreach (var scope in clrMap)
                        xmlnsCtx.AddNsMap(scope, rec.Prefix);
                }
            }
        }