/// <summary> /// Emits unbox or cast when necessary. /// </summary> /// <param name="targetType">Type of the target.</param> public Instructions EmitUnboxOrCastIfNecessary(TypeReference targetType) { // for generics and some unknown reason, an unbox_any is needed if (targetType.IsGenericParameter) return Emit(OpCodes.Unbox_Any, targetType); if (targetType.IsValueType) return Emit(OpCodes.Unbox_Any, targetType); if (!targetType.SafeEquivalent(targetType.Module.SafeImport(typeof(object)))) return Emit(OpCodes.Castclass, targetType); return this; }
/// <summary> /// Determines whether the specified type reference is aspect. /// </summary> /// <param name="typeReference">The type reference.</param> /// <param name="markerInterface">The aspect marker interface.</param> /// <returns></returns> private bool IsMarker(TypeReference typeReference, TypeDefinition markerInterface) { lock (_isInterface) { var key = Tuple.Create(typeReference.FullName, markerInterface.FullName); // there is a cache, because the same attribute may be found several time // and we're in a hurry, the developper is waiting for his program to start! bool isMarker; if (_isInterface.TryGetValue(key, out isMarker)) return isMarker; // otherwise look for type or implemented interfaces (recursively) var interfaces = typeReference.Resolve().Interfaces; _isInterface[key] = isMarker = typeReference.SafeEquivalent(markerInterface) || interfaces.Any(i => IsMarker(i, markerInterface)); return isMarker; } }
/// <summary> /// Emits a stind. /// </summary> /// <param name="type">The type.</param> public Instructions EmitStind(TypeReference type) { if (type.IsValueType) { if (type.SafeEquivalent(type.Module.SafeImport(typeof(Byte))) || type.SafeEquivalent(type.Module.SafeImport(typeof(SByte)))) return Emit(OpCodes.Stind_I1); if (type.SafeEquivalent(type.Module.SafeImport(typeof(Int16))) || type.SafeEquivalent(type.Module.SafeImport(typeof(UInt16)))) return Emit(OpCodes.Stind_I2); if (type.SafeEquivalent(type.Module.SafeImport(typeof(Int32))) || type.SafeEquivalent(type.Module.SafeImport(typeof(UInt32)))) return Emit(OpCodes.Stind_I4); if (type.SafeEquivalent(type.Module.SafeImport(typeof(Int64))) || type.SafeEquivalent(type.Module.SafeImport(typeof(UInt64)))) return Emit(OpCodes.Stind_I8); if (type.SafeEquivalent(type.Module.SafeImport(typeof(Single)))) return Emit(OpCodes.Stind_R4); if (type.SafeEquivalent(type.Module.SafeImport(typeof(Double)))) return Emit(OpCodes.Stind_R8); return Emit(OpCodes.Stobj, type); } return Emit(OpCodes.Stind_Ref); }