private void ImportLdToken(int token) { object obj = _methodIL.GetObject(token); if (obj is TypeDesc) { var type = (TypeDesc)obj; if (type.IsRuntimeDeterminedSubtype) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, type), "ldtoken"); } else { if (ConstructedEETypeNode.CreationAllowed(type)) { _dependencies.Add(_factory.ConstructedTypeSymbol(type), "ldtoken"); } else { _dependencies.Add(_factory.NecessaryTypeSymbol(type), "ldtoken"); } } // If this is a ldtoken Type / GetValueInternal sequence, we're done. BasicBlock nextBasicBlock = _basicBlocks[_currentOffset]; if (nextBasicBlock == null) { if ((ILOpcode)_ilBytes[_currentOffset] == ILOpcode.call) { int methodToken = ReadILTokenAt(_currentOffset + 1); var method = (MethodDesc)_methodIL.GetObject(methodToken); if (IsRuntimeTypeHandleGetValueInternal(method)) { // Codegen expands this and doesn't do the normal ldtoken. return; } } } _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeTypeHandle), "ldtoken"); } else if (obj is MethodDesc) { var method = (MethodDesc)obj; if (method.IsRuntimeDeterminedExactMethod) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodHandle, method), "ldtoken"); } else { _dependencies.Add(_factory.RuntimeMethodHandle(method), "ldtoken"); } _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeMethodHandle), "ldtoken"); } else { Debug.Assert(obj is FieldDesc); // First check if this is a ldtoken Field / InitializeArray sequence. BasicBlock nextBasicBlock = _basicBlocks[_currentOffset]; if (nextBasicBlock == null) { if ((ILOpcode)_ilBytes[_currentOffset] == ILOpcode.call) { int methodToken = ReadILTokenAt(_currentOffset + 1); var method = (MethodDesc)_methodIL.GetObject(methodToken); if (IsRuntimeHelpersInitializeArray(method)) { // Codegen expands this and doesn't do the normal ldtoken. return; } } } var field = (FieldDesc)obj; if (field.OwningType.IsRuntimeDeterminedSubtype) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.FieldHandle, field), "ldtoken"); } else { _dependencies.Add(_factory.RuntimeFieldHandle(field), "ldtoken"); } _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeFieldHandle), "ldtoken"); } }
// Todo: This is looking up the hierarchy to DefType and ParameterizedType. It should really // call a virtual or an outside type to handle those parts internal bool RetrieveRuntimeTypeHandleIfPossible() { TypeDesc type = this; if (!type.RuntimeTypeHandle.IsNull()) { return(true); } TypeBuilderState state = GetTypeBuilderStateIfExist(); if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle) { return(false); } if (type is DefType) { DefType typeAsDefType = (DefType)type; TypeDesc typeDefinition = typeAsDefType.GetTypeDefinition(); RuntimeTypeHandle typeDefHandle = typeDefinition.RuntimeTypeHandle; if (typeDefHandle.IsNull()) { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING NativeFormat.NativeFormatType mdType = typeDefinition as NativeFormat.NativeFormatType; if (mdType != null) { // Look up the runtime type handle in the module metadata if (TypeLoaderEnvironment.Instance.TryGetNamedTypeForMetadata(new QTypeDefinition(mdType.MetadataReader, mdType.Handle), out typeDefHandle)) { typeDefinition.SetRuntimeTypeHandleUnsafe(typeDefHandle); } } #endif #if ECMA_METADATA_SUPPORT Ecma.EcmaType ecmaType = typeDefinition as Ecma.EcmaType; if (ecmaType != null) { // Look up the runtime type handle in the module metadata if (TypeLoaderEnvironment.Instance.TryGetNamedTypeForMetadata(new QTypeDefinition(ecmaType.MetadataReader, ecmaType.Handle), out typeDefHandle)) { typeDefinition.SetRuntimeTypeHandleUnsafe(typeDefHandle); } } #endif } if (!typeDefHandle.IsNull()) { Instantiation instantiation = typeAsDefType.Instantiation; if ((instantiation.Length > 0) && !typeAsDefType.IsGenericDefinition) { // Generic type. First make sure we have type handles for the arguments, then check // the instantiation. bool argumentsRegistered = true; bool arrayArgumentsFound = false; for (int i = 0; i < instantiation.Length; i++) { if (!instantiation[i].RetrieveRuntimeTypeHandleIfPossible()) { argumentsRegistered = false; arrayArgumentsFound = arrayArgumentsFound || (instantiation[i] is ArrayType); } } RuntimeTypeHandle rtth; // If at least one of the arguments is not known to the runtime, we take a slower // path to compare the current type we need a handle for to the list of generic // types statically available, by loading them as DefTypes and doing a DefType comparaison if ((argumentsRegistered && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.HandleBasedGenericTypeLookup(typeAsDefType), out rtth)) || (arrayArgumentsFound && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.DefTypeBasedGenericTypeLookup(typeAsDefType), out rtth))) { typeAsDefType.SetRuntimeTypeHandleUnsafe(rtth); return(true); } } else { // Nongeneric, or generic type def types are just the type handle of the type definition as found above type.SetRuntimeTypeHandleUnsafe(typeDefHandle); return(true); } } } else if (type is ParameterizedType) { ParameterizedType typeAsParameterType = (ParameterizedType)type; if (typeAsParameterType.ParameterType.RetrieveRuntimeTypeHandleIfPossible()) { RuntimeTypeHandle rtth; if ((type is ArrayType && (TypeLoaderEnvironment.Instance.TryGetArrayTypeForElementType_LookupOnly(typeAsParameterType.ParameterType.RuntimeTypeHandle, type.IsMdArray, type.IsMdArray ? ((ArrayType)type).Rank : -1, out rtth) || TypeLoaderEnvironment.Instance.TryGetArrayTypeHandleForNonDynamicArrayTypeFromTemplateTable(type as ArrayType, out rtth))) || (type is PointerType && TypeSystemContext.PointerTypesCache.TryGetValue(typeAsParameterType.ParameterType.RuntimeTypeHandle, out rtth))) { typeAsParameterType.SetRuntimeTypeHandleUnsafe(rtth); return(true); } else if (type is ByRefType) { // Byref types don't have any associated type handles, so return success at this point // since we were able to resolve the typehandle of the element type return(true); } } } else if (type is SignatureVariable) { // SignatureVariables do not have RuntimeTypeHandles } else { Debug.Assert(false); } // Make a note on the type build state that we have attempted to retrieve RuntimeTypeHandle but there is not one GetOrCreateTypeBuilderState().AttemptedAndFailedToRetrieveTypeHandle = true; return(false); }
private void ImportCall(ILOpcode opcode, int token) { // Strip runtime determined characteristics off of the method (because that's how RyuJIT operates) var runtimeDeterminedMethod = (MethodDesc)_methodIL.GetObject(token); MethodDesc method = runtimeDeterminedMethod; if (runtimeDeterminedMethod.IsRuntimeDeterminedExactMethod) { method = runtimeDeterminedMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); } if (method.IsRawPInvoke()) { // Raw P/invokes don't have any dependencies. return; } string reason = null; switch (opcode) { case ILOpcode.newobj: reason = "newobj"; break; case ILOpcode.call: reason = "call"; break; case ILOpcode.callvirt: reason = "callvirt"; break; case ILOpcode.ldftn: reason = "ldftn"; break; case ILOpcode.ldvirtftn: reason = "ldvirtftn"; break; default: Debug.Assert(false); break; } if (opcode == ILOpcode.newobj) { TypeDesc owningType = runtimeDeterminedMethod.OwningType; if (owningType.IsString) { // String .ctor handled specially below } else if (owningType.IsGCPointer) { if (owningType.IsRuntimeDeterminedSubtype) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, owningType), reason); } else { _dependencies.Add(_factory.ConstructedTypeSymbol(owningType), reason); } if (owningType.IsMdArray) { _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.NewMultiDimArr_NonVarArg), reason); return; } else { _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.NewObject), reason); } } if (owningType.IsDelegate) { // If this is a verifiable delegate construction sequence, the previous instruction is a ldftn/ldvirtftn if (_previousInstructionOffset >= 0 && _ilBytes[_previousInstructionOffset] == (byte)ILOpcode.prefix1) { // TODO: for ldvirtftn we need to also check for the `dup` instruction, otherwise this is a normal newobj. ILOpcode previousOpcode = (ILOpcode)(0x100 + _ilBytes[_previousInstructionOffset + 1]); if (previousOpcode == ILOpcode.ldvirtftn || previousOpcode == ILOpcode.ldftn) { int delTargetToken = ReadILTokenAt(_previousInstructionOffset + 2); var delTargetMethod = (MethodDesc)_methodIL.GetObject(delTargetToken); TypeDesc canonDelegateType = method.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific); DelegateCreationInfo info = _compilation.GetDelegateCtor(canonDelegateType, delTargetMethod, previousOpcode == ILOpcode.ldvirtftn); if (info.NeedsRuntimeLookup) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.DelegateCtor, info), reason); } else { _dependencies.Add(_factory.ReadyToRunHelper(ReadyToRunHelperId.DelegateCtor, info), reason); } return; } } } } if (method.OwningType.IsDelegate && method.Name == "Invoke") { // TODO: might not want to do this if scanning for reflection. // This is expanded as an intrinsic, not a function call. return; } if (method.IsIntrinsic) { if (IsRuntimeHelpersInitializeArray(method)) { if (_previousInstructionOffset >= 0 && _ilBytes[_previousInstructionOffset] == (byte)ILOpcode.ldtoken) { return; } } if (IsRuntimeTypeHandleGetValueInternal(method)) { if (_previousInstructionOffset >= 0 && _ilBytes[_previousInstructionOffset] == (byte)ILOpcode.ldtoken) { return; } } if (IsActivatorDefaultConstructorOf(method)) { if (runtimeDeterminedMethod.IsRuntimeDeterminedExactMethod) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.DefaultConstructor, runtimeDeterminedMethod.Instantiation[0]), reason); } else { MethodDesc ctor = method.Instantiation[0].GetDefaultConstructor(); if (ctor == null) { MetadataType activatorType = _compilation.TypeSystemContext.SystemModule.GetKnownType("System", "Activator"); MetadataType classWithMissingCtor = activatorType.GetKnownNestedType("ClassWithMissingConstructor"); ctor = classWithMissingCtor.GetParameterlessConstructor(); } _dependencies.Add(_factory.CanonicalEntrypoint(ctor), reason); } return; } if (method.OwningType.IsByReferenceOfT && (method.IsConstructor || method.Name == "get_Value")) { return; } if (IsEETypePtrOf(method)) { if (runtimeDeterminedMethod.IsRuntimeDeterminedExactMethod) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, runtimeDeterminedMethod.Instantiation[0]), reason); } else { _dependencies.Add(_factory.ConstructedTypeSymbol(method.Instantiation[0]), reason); } return; } } TypeDesc exactType = method.OwningType; bool resolvedConstraint = false; bool forceUseRuntimeLookup = false; MethodDesc methodAfterConstraintResolution = method; if (_constrained != null) { // We have a "constrained." call. Try a partial resolve of the constraint call. Note that this // will not necessarily resolve the call exactly, since we might be compiling // shared generic code - it may just resolve it to a candidate suitable for // JIT compilation, and require a runtime lookup for the actual code pointer // to call. TypeDesc constrained = _constrained; if (constrained.IsRuntimeDeterminedSubtype) { constrained = constrained.ConvertToCanonForm(CanonicalFormKind.Specific); } MethodDesc directMethod = constrained.GetClosestDefType().TryResolveConstraintMethodApprox(method.OwningType, method, out forceUseRuntimeLookup); if (directMethod == null && constrained.IsEnum) { // Constrained calls to methods on enum methods resolve to System.Enum's methods. System.Enum is a reference // type though, so we would fail to resolve and box. We have a special path for those to avoid boxing. directMethod = _compilation.TypeSystemContext.TryResolveConstrainedEnumMethod(constrained, method); } if (directMethod != null) { // Either // 1. no constraint resolution at compile time (!directMethod) // OR 2. no code sharing lookup in call // OR 3. we have have resolved to an instantiating stub methodAfterConstraintResolution = directMethod; Debug.Assert(!methodAfterConstraintResolution.OwningType.IsInterface); resolvedConstraint = true; exactType = constrained; } else if (constrained.IsValueType) { // We'll need to box `this`. Note we use _constrained here, because the other one is canonical. AddBoxingDependencies(_constrained, reason); } } MethodDesc targetMethod = methodAfterConstraintResolution; bool exactContextNeedsRuntimeLookup; if (targetMethod.HasInstantiation) { exactContextNeedsRuntimeLookup = targetMethod.IsSharedByGenericInstantiations; } else { exactContextNeedsRuntimeLookup = exactType.IsCanonicalSubtype(CanonicalFormKind.Any); } // // Determine whether to perform direct call // bool directCall = false; if (targetMethod.Signature.IsStatic) { // Static methods are always direct calls directCall = true; } else if (targetMethod.OwningType.IsInterface) { // Force all interface calls to be interpreted as if they are virtual. directCall = false; } else if ((opcode != ILOpcode.callvirt && opcode != ILOpcode.ldvirtftn) || resolvedConstraint) { directCall = true; } else { if (!targetMethod.IsVirtual || targetMethod.IsFinal || targetMethod.OwningType.IsSealed()) { directCall = true; } } bool allowInstParam = opcode != ILOpcode.ldvirtftn && opcode != ILOpcode.ldftn; if (directCall && !allowInstParam && targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific).RequiresInstArg()) { // Needs a single address to call this method but the method needs a hidden argument. // We need a fat function pointer for this that captures both things. if (exactContextNeedsRuntimeLookup) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodEntry, runtimeDeterminedMethod), reason); } else { _dependencies.Add(_factory.FatFunctionPointer(runtimeDeterminedMethod), reason); } } else if (directCall) { bool referencingArrayAddressMethod = false; if (targetMethod.IsIntrinsic) { // If this is an intrinsic method with a callsite-specific expansion, this will replace // the method with a method the intrinsic expands into. If it's not the special intrinsic, // method stays unchanged. targetMethod = _compilation.ExpandIntrinsicForCallsite(targetMethod, _canonMethod); // Array address method requires special dependency tracking. referencingArrayAddressMethod = targetMethod.IsArrayAddressMethod(); } MethodDesc concreteMethod = targetMethod; targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); if (targetMethod.IsConstructor && targetMethod.OwningType.IsString) { _dependencies.Add(_factory.StringAllocator(targetMethod), reason); } else if (exactContextNeedsRuntimeLookup) { if (targetMethod.IsSharedByGenericInstantiations && !resolvedConstraint && !referencingArrayAddressMethod) { ISymbolNode instParam = null; if (targetMethod.RequiresInstMethodDescArg()) { instParam = GetGenericLookupHelper(ReadyToRunHelperId.MethodDictionary, runtimeDeterminedMethod); } else if (targetMethod.RequiresInstMethodTableArg()) { bool hasHiddenParameter = true; if (targetMethod.IsIntrinsic) { if (_factory.TypeSystemContext.IsSpecialUnboxingThunkTargetMethod(targetMethod)) { hasHiddenParameter = false; } } if (hasHiddenParameter) { instParam = GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, runtimeDeterminedMethod.OwningType); } } if (instParam != null) { _dependencies.Add(instParam, reason); } _dependencies.Add(_factory.RuntimeDeterminedMethod(runtimeDeterminedMethod), reason); } else { Debug.Assert(!forceUseRuntimeLookup); _dependencies.Add(_factory.MethodEntrypoint(targetMethod), reason); if (targetMethod.RequiresInstMethodTableArg() && resolvedConstraint) { if (_constrained.IsRuntimeDeterminedSubtype) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, _constrained), reason); } else { _dependencies.Add(_factory.ConstructedTypeSymbol(_constrained), reason); } } if (referencingArrayAddressMethod && !_isReadOnly) { // Address method is special - it expects an instantiation argument, unless a readonly prefix was applied. _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, runtimeDeterminedMethod.OwningType), reason); } } } else { ISymbolNode instParam = null; if (targetMethod.RequiresInstMethodDescArg()) { instParam = _compilation.NodeFactory.MethodGenericDictionary(concreteMethod); } else if (targetMethod.RequiresInstMethodTableArg() || (referencingArrayAddressMethod && !_isReadOnly)) { // Ask for a constructed type symbol because we need the vtable to get to the dictionary instParam = _compilation.NodeFactory.ConstructedTypeSymbol(concreteMethod.OwningType); } if (instParam != null) { _dependencies.Add(instParam, reason); if (!referencingArrayAddressMethod) { _dependencies.Add(_compilation.NodeFactory.ShadowConcreteMethod(concreteMethod), reason); } else { // We don't want array Address method to be modeled in the generic dependency analysis. // The method doesn't actually have runtime determined dependencies (won't do // any generic lookups). _dependencies.Add(_compilation.NodeFactory.MethodEntrypoint(targetMethod), reason); } } else if (targetMethod.AcquiresInstMethodTableFromThis()) { _dependencies.Add(_compilation.NodeFactory.ShadowConcreteMethod(concreteMethod), reason); } else { _dependencies.Add(_compilation.NodeFactory.MethodEntrypoint(targetMethod), reason); } } } else if (method.HasInstantiation) { // Generic virtual method call if (exactContextNeedsRuntimeLookup) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodHandle, runtimeDeterminedMethod), reason); } else { _dependencies.Add(_factory.RuntimeMethodHandle(runtimeDeterminedMethod), reason); } _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GVMLookupForSlot), reason); } else if (method.OwningType.IsInterface) { if (exactContextNeedsRuntimeLookup) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.VirtualDispatchCell, runtimeDeterminedMethod), reason); } else { _dependencies.Add(_factory.InterfaceDispatchCell(method), reason); } } else if (_compilation.HasFixedSlotVTable(method.OwningType)) { // No dependencies: virtual call through the vtable } else { MethodDesc slotDefiningMethod = targetMethod.IsNewSlot ? targetMethod : MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(targetMethod); _dependencies.Add(_factory.VirtualMethodUse(slotDefiningMethod), reason); } }
protected override void ComputeMetadata(NodeFactory factory, out byte[] metadataBlob, out List <MetadataMapping <MetadataType> > typeMappings, out List <MetadataMapping <MethodDesc> > methodMappings, out List <MetadataMapping <FieldDesc> > fieldMappings) { MetadataLoadedInfo loadedMetadata = _loadedMetadata.Value; metadataBlob = _metadataBlob; typeMappings = new List <MetadataMapping <MetadataType> >(); methodMappings = new List <MetadataMapping <MethodDesc> >(); fieldMappings = new List <MetadataMapping <FieldDesc> >(); Dictionary <MethodDesc, MethodDesc> canonicalToSpecificMethods = new Dictionary <MethodDesc, MethodDesc>(); // The handling of generic methods which are implemented by canonical code is interesting, the invoke map // needs to have a specific instantiation for each canonical bit of code. foreach (GenericDictionaryNode dictionaryNode in GetCompiledGenericDictionaries()) { MethodGenericDictionaryNode methodDictionary = dictionaryNode as MethodGenericDictionaryNode; if (methodDictionary == null) { continue; } MethodDesc method = methodDictionary.OwningMethod; Debug.Assert(method.HasInstantiation && !method.IsCanonicalMethod(CanonicalFormKind.Any)); MethodDesc canonicalMethod = method.GetCanonMethodTarget(CanonicalFormKind.Specific); if (canonicalToSpecificMethods.ContainsKey(canonicalMethod)) { // We only need to record 1 specific to canonical method mapping continue; } canonicalToSpecificMethods.Add(canonicalMethod, method); } // Generate type definition mappings foreach (var definition in _typeDefinitionsGenerated) { int token; if (loadedMetadata.AllTypeMappings.TryGetValue(definition, out token)) { typeMappings.Add(new MetadataMapping <MetadataType>(definition, token)); } } foreach (var method in GetCompiledMethods()) { if (!MethodCanBeInvokedViaReflection(factory, method)) { continue; } // If there is a possible canonical method, use that instead of a specific method (folds canonically equivalent methods away) if (method.GetCanonMethodTarget(CanonicalFormKind.Specific) != method) { continue; } int token; if (loadedMetadata.MethodMappings.TryGetValue(method.GetTypicalMethodDefinition(), out token)) { MethodDesc invokeMapMethod = GetInvokeMapMethodForMethod(canonicalToSpecificMethods, method); if (invokeMapMethod != null) { methodMappings.Add(new MetadataMapping <MethodDesc>(invokeMapMethod, token)); } } else if (!WillUseMetadataTokenToReferenceMethod(method) && _compilationModuleGroup.ContainsMethod(method.GetCanonMethodTarget(CanonicalFormKind.Specific))) { MethodDesc invokeMapMethod = GetInvokeMapMethodForMethod(canonicalToSpecificMethods, method); // For methods on types that are not in the current module, assume they must be reflectable // and generate a non-metadata backed invoke table entry // TODO, the above computation is overly generous with the set of methods that are placed into the method invoke map // It includes methods which are not reflectable at all. if (invokeMapMethod != null) { methodMappings.Add(new MetadataMapping <MethodDesc>(invokeMapMethod, 0)); } } } foreach (var eetypeGenerated in GetTypesWithEETypes()) { if (eetypeGenerated.IsGenericDefinition) { continue; } if (eetypeGenerated.HasInstantiation) { // Collapsing of field map entries based on canonicalization, to avoid redundant equivalent entries TypeDesc canonicalType = eetypeGenerated.ConvertToCanonForm(CanonicalFormKind.Specific); if (canonicalType != eetypeGenerated && TypeGeneratesEEType(canonicalType)) { continue; } } foreach (FieldDesc field in eetypeGenerated.GetFields()) { int token; if (loadedMetadata.FieldMappings.TryGetValue(field.GetTypicalFieldDefinition(), out token)) { fieldMappings.Add(new MetadataMapping <FieldDesc>(field, token)); } else if (!WillUseMetadataTokenToReferenceField(field)) { // TODO, the above computation is overly generous with the set of fields that are placed into the field invoke map // It includes fields which are not reflectable at all, and collapses static fields across generics // TODO! enable this. Disabled due to cross module import of statics is not yet implemented // fieldMappings.Add(new MetadataMapping<FieldDesc>(field, 0)); } } } }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { MetadataType type = (MetadataType)defType; if (type.IsGenericDefinition) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } // CLI - Partition 1, section 9.5 - Generic types shall not be marked explicitlayout. if (type.HasInstantiation && type.IsExplicitLayout) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadExplicitGeneric, type.GetTypeDefinition()); } // Count the number of instance fields in advance for convenience int numInstanceFields = 0; foreach (var field in type.GetFields()) { if (field.IsStatic) { continue; } TypeDesc fieldType = field.FieldType; // ByRef instance fields are not allowed. if (fieldType.IsByRef) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } // ByRef-like instance fields on non-byref-like types are not allowed. if (fieldType.IsByRefLike && !type.IsByRefLike) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } numInstanceFields++; } if (type.IsModuleType) { // This is a global type, it must not have instance fields. if (numInstanceFields > 0) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } // Global types do not do the rest of instance field layout. ComputedInstanceFieldLayout result = new ComputedInstanceFieldLayout(); result.Offsets = Array.Empty <FieldAndOffset>(); return(result); } // CLI - Partition 2, section 22.8 // A type has layout if it is marked SequentialLayout or ExplicitLayout. If any type within an inheritance chain has layout, // then so shall all its base classes, up to the one that descends immediately from System.ValueType (if it exists in the type’s // hierarchy); otherwise, from System.Object // Note: While the CLI isn't clearly worded, the layout needs to be the same for the entire chain. // If the current type isn't ValueType or System.Object and has a layout and the parent type isn't // ValueType or System.Object then the layout type attributes need to match if ((!type.IsValueType && !type.IsObject) && (type.IsSequentialLayout || type.IsExplicitLayout) && (!type.BaseType.IsValueType && !type.BaseType.IsObject)) { MetadataType baseType = type.MetadataBaseType; if (type.IsSequentialLayout != baseType.IsSequentialLayout || type.IsExplicitLayout != baseType.IsExplicitLayout) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); } } // Enum types must have a single instance field if (type.IsEnum && numInstanceFields != 1) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } if (type.IsPrimitive) { // Primitive types are special - they may have a single field of the same type // as the type itself. They do not do the rest of instance field layout. if (numInstanceFields > 1) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } SizeAndAlignment instanceByteSizeAndAlignment; var sizeAndAlignment = ComputeInstanceSize( type, type.Context.Target.GetWellKnownTypeSize(type), type.Context.Target.GetWellKnownTypeAlignment(type), out instanceByteSizeAndAlignment ); ComputedInstanceFieldLayout result = new ComputedInstanceFieldLayout { ByteCountUnaligned = instanceByteSizeAndAlignment.Size, ByteCountAlignment = instanceByteSizeAndAlignment.Alignment, FieldAlignment = sizeAndAlignment.Alignment, FieldSize = sizeAndAlignment.Size, }; if (numInstanceFields > 0) { FieldDesc instanceField = null; foreach (FieldDesc field in type.GetFields()) { if (!field.IsStatic) { Debug.Assert(instanceField == null, "Unexpected extra instance field"); instanceField = field; } } Debug.Assert(instanceField != null, "Null instance field"); result.Offsets = new FieldAndOffset[] { new FieldAndOffset(instanceField, LayoutInt.Zero) }; } else { result.Offsets = Array.Empty <FieldAndOffset>(); } return(result); } // If the type has layout, read its packing and size info // If the type has explicit layout, also read the field offset info if (type.IsExplicitLayout || type.IsSequentialLayout) { if (type.IsEnum) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); } var layoutMetadata = type.GetClassLayout(); // If packing is out of range or not a power of two, throw that the size is invalid int packing = layoutMetadata.PackingSize; if (packing < 0 || packing > 128 || ((packing & (packing - 1)) != 0)) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); } Debug.Assert(layoutMetadata.Offsets == null || layoutMetadata.Offsets.Length == numInstanceFields); } // At this point all special cases are handled and all inputs validated return(ComputeInstanceFieldLayout(type, numInstanceFields)); }
public static bool operator !=(StringIterator it1, StringIterator it2) { Debug.Assert(Object.ReferenceEquals(it1._string, it2._string)); return(it1._index != it2._index); }
public void Start(BaseEffect effect) { if (live_preview_enabled) { throw new InvalidOperationException("LivePreviewManager.Start() called while live preview is already enabled."); } // Create live preview surface. // Start rendering. // Listen for changes to effectConfiguration object, and restart render if needed. live_preview_enabled = true; apply_live_preview_flag = false; cancel_live_preview_flag = false; layer = PintaCore.Layers.CurrentLayer; this.effect = effect; //TODO Use the current tool layer instead. live_preview_surface = new Cairo.ImageSurface(Cairo.Format.Argb32, PintaCore.Workspace.ImageSize.Width, PintaCore.Workspace.ImageSize.Height); // Handle selection path. PintaCore.Tools.Commit(); selection_path = (PintaCore.Layers.ShowSelection) ? PintaCore.Workspace.ActiveDocument.Selection.SelectionPath : null; render_bounds = (selection_path != null) ? selection_path.GetBounds() : live_preview_surface.GetBounds(); render_bounds = PintaCore.Workspace.ClampToImageSize(render_bounds); history_item = new SimpleHistoryItem(effect.Icon, effect.Name); history_item.TakeSnapshotOfLayer(PintaCore.Layers.CurrentLayerIndex); // Paint the pre-effect layer surface into into the working surface. using (var ctx = new Cairo.Context(live_preview_surface)) { layer.Draw(ctx, layer.Surface, 1); } if (effect.EffectData != null) { effect.EffectData.PropertyChanged += EffectData_PropertyChanged; } if (Started != null) { Started(this, new LivePreviewStartedEventArgs()); } var settings = new AsyncEffectRenderer.Settings() { ThreadCount = PintaCore.System.RenderThreads, TileWidth = render_bounds.Width, TileHeight = 1, ThreadPriority = ThreadPriority.BelowNormal }; Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:ffff") + "Start Live preview."); renderer = new Renderer(this, settings); renderer.Start(effect, layer.Surface, live_preview_surface, render_bounds); if (effect.IsConfigurable) { if (!effect.LaunchConfiguration()) { PintaCore.Chrome.MainWindowBusy = true; Cancel(); } else { PintaCore.Chrome.MainWindowBusy = true; Apply(); } } else { PintaCore.Chrome.MainWindowBusy = true; Apply(); } }
public static bool IsStringBuilder(TypeSystemContext context, TypeDesc type) { Debug.Assert(type != null); return(type == GetStringBuilder(context, throwIfNotFound: false)); }
/// <summary> /// This is used to set base type for generic types without metadata /// </summary> public void SetBaseType(DefType baseType) { Debug.Assert(!_baseTypeCached || _baseType == baseType); _baseType = baseType; _baseTypeCached = true; }
protected override async Task <IImmutableList <Exception> > WriteMessagesAsync(IEnumerable <AtomicWrite> messages) { try { #if DEBUG _log.Debug("Entering method WriteMessagesAsync"); #endif var exceptions = ImmutableList <Exception> .Empty; using (var atomicWrites = messages.GetEnumerator()) { while (atomicWrites.MoveNext()) { Debug.Assert(atomicWrites.Current != null, "atomicWrites.Current != null"); var batch = new TableBatchOperation(); foreach (var currentMsg in atomicWrites.Current.Payload .AsInstanceOf <IImmutableList <IPersistentRepresentation> >()) { Debug.Assert(currentMsg != null, nameof(currentMsg) + " != null"); batch.Insert( new PersistentJournalEntry(currentMsg.PersistenceId, currentMsg.SequenceNr, _serialization.PersistentToBytes(currentMsg), currentMsg.Manifest)); } try { if (_log.IsDebugEnabled && _settings.VerboseLogging) { _log.Debug("Attempting to write batch of {0} messages to Azure storage", batch.Count); } var results = await Table.ExecuteBatchAsync(batch); if (_log.IsDebugEnabled && _settings.VerboseLogging) { foreach (var r in results) { _log.Debug("Azure table storage wrote entity [{0}] with status code [{1}]", r.Etag, r.HttpStatusCode); } } } catch (Exception ex) { exceptions = exceptions.Add(ex); } } } #if DEBUG _log.Debug("Leaving method WriteMessagesAsync"); foreach (var ex in exceptions) { _log.Error(ex, "recorded exception during write"); } #endif /* * Part of the Akka.Persistence design. * * Either return null or return an exception for each failed AtomicWrite. * * Either everything fails or everything succeeds is the idea I guess. */ return(exceptions.IsEmpty ? null : exceptions); } catch (Exception ex) { _log.Error(ex, "Error during WriteMessagesAsync"); throw; } }
private bool ComputeCanCompareValueTypeBits(MetadataType type) { Debug.Assert(type.IsValueType); if (type.ContainsGCPointers) { return(false); } if (type.IsGenericDefinition) { return(false); } OverlappingFieldTracker overlappingFieldTracker = new OverlappingFieldTracker(type); bool result = true; foreach (var field in type.GetFields()) { if (field.IsStatic) { continue; } if (!overlappingFieldTracker.TrackField(field)) { // This field overlaps with another field - can't compare memory result = false; break; } TypeDesc fieldType = field.FieldType; if (fieldType.IsPrimitive || fieldType.IsEnum || fieldType.IsPointer || fieldType.IsFunctionPointer) { TypeFlags category = fieldType.UnderlyingType.Category; if (category == TypeFlags.Single || category == TypeFlags.Double) { // Double/Single have weird behaviors around negative/positive zero result = false; break; } } else { // Would be a suprise if this wasn't a valuetype. We checked ContainsGCPointers above. Debug.Assert(fieldType.IsValueType); MethodDesc objectEqualsMethod = fieldType.Context._objectEqualsMethod; // If the field overrides Equals, we can't use the fast helper because we need to call the method. if (fieldType.FindVirtualFunctionTargetMethodOnObjectType(objectEqualsMethod).OwningType == fieldType) { result = false; break; } if (!_hashtable.GetOrCreateValue((MetadataType)fieldType).CanCompareValueTypeBits) { result = false; break; } } } // If there are gaps, we can't memcompare if (result && overlappingFieldTracker.HasGaps) { result = false; } return(result); }
/// <include file='doc\UserControl.uex' path='docs/doc[@for="UserControlControlBuilder.SetTagInnerText"]/*' /> /// <internalonly/> public override void SetTagInnerText(string text) { Debug.Assert(InDesigner == true, "Should only be called in design-mode!"); _innerText = text; }
internal static bool ObjectHasComponentSize(object obj) { Debug.Assert(obj != null); return(obj.EETypePtr.ComponentSize != 0); }
//private static bool _requestedPermission = false; public ContactPageModel() { Debug.WriteLine("ContactPageModel.ContactPageModel()"); }
public static MethodIL EmitIL(MethodDesc method) { Debug.Assert(((MetadataType)method.OwningType).Name == "Volatile"); bool isRead = method.Name == "Read"; if (!isRead && method.Name != "Write") { return(null); } // All interesting methods have a signature that starts with `ref location` if (method.Signature.Length == 0 || !method.Signature[0].IsByRef) { return(null); } ILOpcode opcode; switch (((ByRefType)method.Signature[0]).ParameterType.Category) { case TypeFlags.SignatureMethodVariable: opcode = isRead ? ILOpcode.ldind_ref : ILOpcode.stind_ref; break; case TypeFlags.Boolean: case TypeFlags.SByte: opcode = isRead ? ILOpcode.ldind_i1 : ILOpcode.stind_i1; break; case TypeFlags.Byte: opcode = isRead ? ILOpcode.ldind_u1 : ILOpcode.stind_i1; break; case TypeFlags.Int16: opcode = isRead ? ILOpcode.ldind_i2 : ILOpcode.stind_i2; break; case TypeFlags.UInt16: opcode = isRead ? ILOpcode.ldind_u2 : ILOpcode.stind_i2; break; case TypeFlags.Int32: opcode = isRead ? ILOpcode.ldind_i4 : ILOpcode.stind_i4; break; case TypeFlags.UInt32: opcode = isRead ? ILOpcode.ldind_u4 : ILOpcode.stind_i4; break; case TypeFlags.IntPtr: case TypeFlags.UIntPtr: opcode = isRead ? ILOpcode.ldind_i : ILOpcode.stind_i; break; case TypeFlags.Single: opcode = isRead ? ILOpcode.ldind_r4 : ILOpcode.stind_r4; break; // // Ordinary volatile loads and stores only guarantee atomicity for pointer-sized (or smaller) data. // So, on 32-bit platforms we must use Interlocked operations instead for the 64-bit types. // The implementation in mscorlib already does this, so we will only substitute a new // IL body if we're running on a 64-bit platform. // case TypeFlags.Int64 when method.Context.Target.PointerSize == 8: case TypeFlags.UInt64 when method.Context.Target.PointerSize == 8: opcode = isRead ? ILOpcode.ldind_i8 : ILOpcode.stind_i8; break; case TypeFlags.Double when method.Context.Target.PointerSize == 8: opcode = isRead ? ILOpcode.ldind_r8 : ILOpcode.stind_r8; break; default: return(null); } byte[] ilBytes; if (isRead) { ilBytes = new byte[] { (byte)ILOpcode.ldarg_0, (byte)ILOpcode.prefix1, unchecked ((byte)ILOpcode.volatile_), (byte)opcode, (byte)ILOpcode.ret }; } else { ilBytes = new byte[] { (byte)ILOpcode.ldarg_0, (byte)ILOpcode.ldarg_1, (byte)ILOpcode.prefix1, unchecked ((byte)ILOpcode.volatile_), (byte)opcode, (byte)ILOpcode.ret }; } return(new ILStubMethodIL(method, ilBytes, Array.Empty <LocalVariableDefinition>(), null)); }
protected override void OnUpdate(double progress, Gdk.Rectangle updatedBounds) { Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:ffff") + " LivePreviewManager.OnUpdate() progress: " + progress); PintaCore.Chrome.ProgressDialog.Progress = progress; manager.FireLivePreviewRenderUpdatedEvent(progress, updatedBounds); }
public RemoteSessionHyperVSocketServer(bool LoopbackMode) { // TODO: uncomment below code when .NET supports Hyper-V socket duplication /* * NamedPipeClientStream clientPipeStream; * byte[] buffer = new byte[1000]; * int bytesRead; */ _syncObject = new object(); Exception ex = null; try { // TODO: uncomment below code when .NET supports Hyper-V socket duplication /* * if (!LoopbackMode) * { * // * // Create named pipe client. * // * using (clientPipeStream = new NamedPipeClientStream(".", * "PS_VMSession", * PipeDirection.InOut, * PipeOptions.None, * TokenImpersonationLevel.None)) * { * // * // Connect to named pipe server. * // * clientPipeStream.Connect(10*1000); * * // * // Read LPWSAPROTOCOL_INFO. * // * bytesRead = clientPipeStream.Read(buffer, 0, 1000); * } * } * * // * // Create duplicate socket. * // * byte[] protocolInfo = new byte[bytesRead]; * Array.Copy(buffer, protocolInfo, bytesRead); * * SocketInformation sockInfo = new SocketInformation(); * sockInfo.ProtocolInformation = protocolInfo; * sockInfo.Options = SocketInformationOptions.Connected; * * socket = new Socket(sockInfo); * if (socket == null) * { * Dbg.Assert(false, "Unexpected error in RemoteSessionHyperVSocketServer."); * * tracer.WriteMessage("RemoteSessionHyperVSocketServer", "RemoteSessionHyperVSocketServer", Guid.Empty, * "Unexpected error in constructor: {0}", "socket duplication failure"); * } */ // TODO: remove below 6 lines of code when .NET supports Hyper-V socket duplication Guid serviceId = new Guid("a5201c21-2770-4c11-a68e-f182edb29220"); // HV_GUID_VM_SESSION_SERVICE_ID_2 HyperVSocketEndPoint endpoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, Guid.Empty, serviceId); Socket listenSocket = new Socket(endpoint.AddressFamily, SocketType.Stream, (System.Net.Sockets.ProtocolType) 1); listenSocket.Bind(endpoint); listenSocket.Listen(1); HyperVSocket = listenSocket.Accept(); Stream = new NetworkStream(HyperVSocket, true); // Create reader/writer streams. TextReader = new StreamReader(Stream); TextWriter = new StreamWriter(Stream); TextWriter.AutoFlush = true; // // listenSocket is not closed when it goes out of scope here. Sometimes it is // closed later in this thread, while other times it is not closed at all. This will // cause problem when we set up a second PowerShell Direct session. Let's // explicitly close listenSocket here for safe. // if (listenSocket != null) { try { listenSocket.Dispose(); } catch (ObjectDisposedException) { } } } catch (Exception e) { ex = e; } if (ex != null) { Dbg.Assert(false, "Unexpected error in RemoteSessionHyperVSocketServer."); // Unexpected error. string errorMessage = !string.IsNullOrEmpty(ex.Message) ? ex.Message : string.Empty; _tracer.WriteMessage("RemoteSessionHyperVSocketServer", "RemoteSessionHyperVSocketServer", Guid.Empty, "Unexpected error in constructor: {0}", errorMessage); throw new PSInvalidOperationException( PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.RemoteSessionHyperVSocketServerConstructorFailure), ex, PSRemotingErrorId.RemoteSessionHyperVSocketServerConstructorFailure.ToString(), ErrorCategory.InvalidOperation, null); } }
public static string Substring(StringIterator it1, StringIterator it2) { Debug.Assert(Object.ReferenceEquals(it1._string, it2._string)); return(it1._string.Substring(it1._index, it2._index - it1._index)); }