internal static void CheckTypeForMethodSig(CILModule thisModule, ref CILTypeBase type) { if (TypeKind.MethodSignature == type.TypeKind && !Object.Equals(thisModule, type.Module)) { type = ((CILMethodSignature)type).CopyToOtherModule(thisModule); } }
internal ModuleWriter(CILModule module) { ArgumentValidator.ValidateNotNull("Module", module); this._context = (CILReflectionContextImpl)module.ReflectionContext; this._module = module; }
/// <summary> /// Tries to resolve given assembly name as if given module would reference it. /// </summary> /// <param name="thisModule">The <see cref="CILModule"/> loaded by this <see cref="CILAssemblyLoader"/>.</param> /// <param name="name">The <see cref="CILAssemblyName"/> of reference.</param> /// <param name="resolvedAssembly">This will hold the resolved assembly, if successful.</param> /// <returns><c>true</c> if successfully resolved reference; <c>false</c> otherwise.</returns> public Boolean TryResolveReference(CILModule thisModule, CILAssemblyName name, out CILAssembly resolvedAssembly) { String modPath = null; String libAssemblyPath = null; var retVal = thisModule != null && this._moduleResources.TryGetValue(thisModule, out modPath); if (retVal) { if (!this._callbacks.TryResolveAssemblyFilePath(modPath, name, out libAssemblyPath)) { // Have to deduce ourselves - most likely client assembly referencing system assembly var fwInfo = this.GetMonikerInfoFor(modPath, this._loadingArgs[thisModule]); if (!this._callbacks.TryGetFrameworkAssemblyPath(modPath, name, fwInfo.FrameworkName, fwInfo.FrameworkVersion, fwInfo.ProfileName, out libAssemblyPath)) { // TODO event libAssemblyPath = null; } } } retVal = libAssemblyPath != null; resolvedAssembly = retVal ? this.LoadModuleFrom(libAssemblyPath).Assembly : null; return(retVal); }
private static void CreateTypeStringCore(CILTypeBase type, CILModule moduleBeingEmitted, StringBuilder builder, Boolean appendGArgs) { var eKind = type.GetElementKind(); if (eKind.HasValue) { CreateTypeStringCore(type.GetElementType(), moduleBeingEmitted, builder, appendGArgs); CreateElementKindString(eKind.Value, ((CILType)type).ArrayInformation, builder); } else if (appendGArgs && type.IsGenericType() && !type.ContainsGenericParameters()) { var typee = (CILType)type; CreateTypeStringCore(typee.GenericDefinition, moduleBeingEmitted, builder, false); builder.Append('['); var gArgs = typee.GenericArguments; for (var i = 0; i < gArgs.Count; ++i) { CreateTypeString(gArgs[i], moduleBeingEmitted, builder, true, true); if (i < gArgs.Count - 1) { builder.Append(','); } } builder.Append(']'); } else { switch (type.TypeKind) { case TypeKind.Type: var typee = (CILType)type; var dt = typee.DeclaringType; if (dt == null) { var ns = typee.Namespace; if (!String.IsNullOrEmpty(ns)) { builder.Append(EscapeSomeString(ns)).Append(CILTypeImpl.NAMESPACE_SEPARATOR); } } else { CreateTypeStringCore(dt, moduleBeingEmitted, builder, false); builder.Append('+'); } builder.Append(EscapeSomeString(typee.Name)); break; case TypeKind.MethodSignature: builder.Append(type.ToString()); break; case TypeKind.TypeParameter: builder.Append(((CILTypeParameter)type).Name); break; } } }
private CILAssembly LoadLibAssembly(CILModule thisModule, CILAssemblyName name) { CILAssembly retVal; if (!this.TryResolveReference(thisModule, name, out retVal)) { throw new Exception("Failed to deduce path for " + name + " referenced from " + thisModule.Name + "."); } return(retVal); }
private CILAssembly LoadFunction(CILModule module, CILAssemblyName aName) { return(this._loadedAssemblies.GetOrAdd(this._portableLibDirectory + aName.Name + ".dll", pathArg => { using (var stream = this._streamOpener(pathArg)) { return module.ReflectionContext.LoadAssembly(stream, this._loadArgs); } })); }
/// <summary> /// Helper method to call <see cref="CILAssemblyLoader.TryGetResourceFor"/> method /// </summary> /// <param name="loader">The <see cref="CILAssemblyLoader"/>.</param> /// <param name="module">The <see cref="CILModule"/>.</param> /// <returns>The out parameter of <see cref="CILAssemblyLoader.TryGetResourceFor"/>.</returns> /// <exception cref="ArgumentException">If <see cref="CILAssemblyLoader.TryGetResourceFor"/> returns <c>false</c>.</exception> public static String GetResourceFor(this CILAssemblyLoader loader, CILModule module) { String retVal; if (!loader.TryGetResourceFor(module, out retVal)) { throw new ArgumentException("Module was not loaded with this loader."); } return(retVal); }
public RuntimeTypeFactory(CILAssembly cilAssembly, CILModule cilModule) { var assemblyName = new AssemblyName(cilAssembly.AssemblyName); var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); _assemblyBuilder = assemblyBuilder; var moduleBuilder = _assemblyBuilder.DefineDynamicModule(cilModule.ModuleName); _moduleBuilder = moduleBuilder; }
internal ModuleLoadedEventArgs(CILAssemblyLoader loader, CILModule module, String resource, EmittingArguments eArgs) { ArgumentValidator.ValidateNotNull("Assembly loader", loader); ArgumentValidator.ValidateNotNull("Module", module); ArgumentValidator.ValidateNotEmpty("Resource", resource); ArgumentValidator.ValidateNotNull("Emitting arguments", eArgs); this._loader = loader; this._module = module; this._resource = resource; this._eArgs = eArgs; }
private static void ForceLoadModule(CILModule module) { var dummy1 = module.Assembly; var dummy2 = module.AssociatedMSCorLibModule; var dummy3 = module.CustomAttributeData; var dummy4 = module.Name; var dummy5 = module.ModuleInitializer; foreach (var type in module.DefinedTypes) { ForceLoadType(type); } }
/// <summary> /// Gets a framework moniker information for a given module. /// </summary> /// <param name="module">The <see cref="CILModule"/> module.</param> /// <returns>The <see cref="FrameworkMonikerInfo"/> for given <paramref name="module"/>.</returns> /// <exception cref="ArgumentNullException">If <paramref name="module"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="module"/> was not loaded with this <see cref="CILAssemblyLoader"/>.</exception> public FrameworkMonikerInfo GetFrameworkInfoFor(CILModule module) { ArgumentValidator.ValidateNotNull("Module", module); EmittingArguments eArgs; if (this._loadingArgs.TryGetValue(module, out eArgs)) { return(this.GetMonikerInfoFor(this.GetThisModulePath(module), eArgs)); } else { throw new ArgumentException("The module " + module + " was not loaded with this loader."); } }
internal MethodILImpl(CILModule module) { ArgumentValidator.ValidateNotNull("Module", module); this._module = module; this.context = (CILReflectionContextImpl)module.ReflectionContext; this._opCodes = new List <OpCodeInfo>(); this._labelOffsets = new List <Int32>(); this._allExceptionBlocks = new List <ExceptionBlockInfo>(); this._currentExceptionBlocks = new Stack <ExceptionBlockInfo>(); this._locals = new List <LocalBuilder>(); this._branchTargetsCount = 0; this._initLocals = true; // Maybe set to false by default? }
private static void CreateTypeString(CILTypeBase type, CILModule moduleBeingEmitted, StringBuilder builder, Boolean appendGArgs, Boolean isGParam) { var needsAssembly = moduleBeingEmitted != null && !moduleBeingEmitted.Assembly.Equals(type.Module.Assembly); if (isGParam && needsAssembly) { builder.Append('['); } CreateTypeStringCore(type, moduleBeingEmitted, builder, appendGArgs); if (needsAssembly) { builder .Append(TYPE_ASSEMBLY_SEPARATOR) .Append(type.Module.Assembly.Name.ToString()); // Assembly name will be escaped. if (isGParam) { builder.Append(']'); } } }
internal static String CreateTypeString(CILType type, CILModule moduleBeingEmitted, Boolean appendGArgs) { if (moduleBeingEmitted == null) { moduleBeingEmitted = type.Module; } String typeString; if (type == null) { typeString = null; } else { // TODO probably should forbid whitespace characters to be within type and assembly names? var builder = new StringBuilder(); CreateTypeString(type, moduleBeingEmitted, builder, appendGArgs, false); typeString = builder.ToString(); } return(typeString); }
/// <summary> /// Gets the plain module name without '.dll', '.exe' or '.netmodule' extension. /// </summary> /// <param name="module">The module.</param> /// <returns>The value of <see cref="CILElementWithSimpleName.Name"/> of the <paramref name="module"/> without '.dll', '.exe' or '.netmodule' extension.</returns> /// <exception cref="ArgumentNullException">If <paramref name="module"/> is <c>null</c>.</exception> public static String GetPlainModuleName(this CILModule module) { ArgumentValidator.ValidateNotNull("Module", module); return(MODULE_NAME_WITHOUT_EXTENSION_REGEX.Replace(module.Name, "")); }
/// <summary> /// Creates new instance of <see cref="ModuleManifestResource"/>. /// </summary> /// <param name="attributes">The <see cref="ManifestResourceAttributes"/> associated with this manifest resource.</param> /// <param name="module">The module which acts as manifest resource.</param> /// <exception cref="ArgumentNullException">If <paramref name="module"/> is <c>null</c>.</exception> public ModuleManifestResource(ManifestResourceAttributes attributes, CILModule module) : base(attributes) { ArgumentValidator.ValidateNotNull("Module", module); this._module = new Lazy <CILModule>(() => module, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);; }
/// <summary> /// Creates a new <see cref="CILMethodSignature"/> which has all its information specified from the parameters of this method. /// </summary> /// <param name="ctx">The current <see cref="CILReflectionContext"/>.</param> /// <param name="currentModule">The current <see cref="CILModule"/>.</param> /// <param name="callingConventions">The <see cref="UnmanagedCallingConventions"/> for the method signature.</param> /// <param name="returnType">The return type for the method signature.</param> /// <param name="paramTypes">The types of the parameters.</param> /// <returns>A new <see cref="CILMethodSignature"/>.</returns> /// <exception cref="NullReferenceException">If <paramref name="ctx"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="currentModule"/>, <paramref name="returnType"/> or any of the types within <paramref name="paramTypes"/> is <c>null</c>.</exception> /// <seealso cref="CILMethodSignature"/> public static CILMethodSignature NewMethodSignature(this CILReflectionContext ctx, CILModule currentModule, UnmanagedCallingConventions callingConventions, CILTypeBase returnType, params CILTypeBase[] paramTypes) { return(NewMethodSignature(ctx, currentModule, callingConventions, returnType, null, paramTypes.Select(pt => Tuple.Create((CILCustomModifier[])null, pt)).ToArray())); }
/// <summary> /// Creates a new <see cref="CILMethodSignature"/> which has all its information specified from the parameters of this method. /// </summary> /// <param name="ctx">The current <see cref="CILReflectionContext"/>.</param> /// <param name="currentModule">The current <see cref="CILModule"/>.</param> /// <param name="callingConventions">The <see cref="UnmanagedCallingConventions"/> for the method signature.</param> /// <param name="returnType">The return type for the method signature.</param> /// <param name="returnParamMods">The <see cref="CILCustomModifier"/>s for the method signature. May be <c>null</c> if no modifiers should be used.</param> /// <param name="parameters">The parameter information for the method signature. Each element is a tuple containing <see cref="CILCustomModifier"/>s and type for the parameter. Custom modifiers array may be <c>null</c> if no modifiers should be used.</param> /// <returns>A new <see cref="CILMethodSignature"/>.</returns> /// <exception cref="NullReferenceException">If <paramref name="ctx"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="currentModule"/>, <paramref name="returnType"/> or any of the types within <paramref name="parameters"/> is <c>null</c>.</exception> /// <seealso cref="CILMethodSignature"/> public static CILMethodSignature NewMethodSignature(this CILReflectionContext ctx, CILModule currentModule, UnmanagedCallingConventions callingConventions, CILTypeBase returnType, CILCustomModifier[] returnParamMods, params Tuple <CILCustomModifier[], CILTypeBase>[] parameters) { if (ctx == null) { // Throw nullref explicitly for consistency (since it is 'this' parameter) // Because CILMethodSignatureImpl ctor throws ArgumentNullException throw new NullReferenceException(); } var cctx = (CILReflectionContextImpl)ctx; return(new CILMethodSignatureImpl(ctx, currentModule, callingConventions, returnParamMods == null ? null : cctx.CollectionsFactory.NewListProxyFromParams(returnParamMods), returnType, parameters.Select(t => Tuple.Create(t.Item1 == null ? null : cctx.CollectionsFactory.NewListProxyFromParams(t.Item1), t.Item2)).ToList(), null)); }
internal MethodILImpl(CILModule module, MethodBodyLoadArgs args) : this(module, args.InitLocals, args.IL, GetLocalsFromArgs((CILReflectionContextImpl)module.ReflectionContext, args), args.ExceptionInfos.Select(tuple => Tuple.Create(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5, tuple.Item6 == null ? null : tuple.Item6.NewWrapperAsType((CILReflectionContextImpl)module.ReflectionContext), tuple.Item7)).ToArray(), TokenResolverFromArgs((CILReflectionContextImpl)module.ReflectionContext, args)) { }
/// <summary> /// Tries to get resource of a loaded module. /// </summary> /// <param name="module">The <see cref="CILModule"/> to get resource for.</param> /// <param name="resource">The resource that the <paramref name="module"/> was loaded from, if it was loaded by this <see cref="CILAssemblyLoader"/>.</param> /// <returns><c>true</c> if <paramref name="module"/> was loaded by this <see cref="CILAssemblyLoader"/>; <c>false</c> otherwise.</returns> public Boolean TryGetResourceFor(CILModule module, out String resource) { resource = null; return(module != null && this._moduleResources.TryGetValue(module, out resource)); }
/// <summary> /// Adds a global method with the specified name, attributes, and calling conventions to <see cref="CILModule"/>. /// </summary> /// <param name="module">The module to add global method to.</param> /// <param name="name">The name of the global method.</param> /// <param name="attrs">The <see cref="MethodAttributes"/> of the global method.</param> /// <param name="callingConventions">The <see cref="CallingConventions"/> of the global method.</param> /// <returns>A newly created global method.</returns> /// <seealso cref="CILMethod"/> /// <see cref="CILModule.ModuleInitializer"/> public static CILMethod AddGlobalMethod(this CILModule module, String name, MethodAttributes attrs, CallingConventions callingConventions) { return(module.ModuleInitializer.AddMethod(name, attrs, callingConventions)); }
private String GetThisModulePath(CILModule thisModule) { return(this._moduleResources[thisModule]); }
/// <summary> /// Tries to get <see cref="EmittingArguments"/> of a loaded module. /// </summary> /// <param name="module">The <see cref="CILModule"/> to get emitting arguments for.</param> /// <param name="eArgs">The emitting arguments associated with <paramref name="module"/>, if it was loaded by this <see cref="CILAssemblyLoader"/>.</param> /// <returns><c>true</c> if <paramref name="module"/> was loaded by this <see cref="CILAssemblyLoader"/>; <c>false</c> otherwise.</returns> public Boolean TryGetEmittingArgumentsFor(CILModule module, out EmittingArguments eArgs) { eArgs = null; return(module != null && this._loadingArgs.TryGetValue(module, out eArgs)); }
/// <summary> /// Tries to get the module at specified resource without loading it, if it isn't loaded. /// </summary> /// <param name="resource">The resource.</param> /// <param name="module">This will contain the module, if it was loaded by this <see cref="CILAssemblyLoader"/> at given resource.</param> /// <returns><c>true</c> if this <see cref="CILAssemblyLoader"/> has module loaded at <paramref name="resource"/>; <c>false</c> otherwise.</returns> public Boolean TryGetLoadedModule(String resource, out CILModule module) { resource = this._callbacks.CleanResource(resource); return(this._allModules.TryGetValue(resource, out module)); }
/// <summary> /// Performs the emitting of the associated <see cref="CILModule"/> to <paramref name="stream"/>. See ECMA specification for more information about various PE and CLR header fields. /// </summary> /// <param name="module">The module to emit.</param> /// <param name="stream">The stream to emit the associated <see cref="CILModule"/> to.</param> /// <param name="emittingArgs">The <see cref="EmittingArguments"/>.</param> /// <exception cref="ArgumentNullException"> /// If <paramref name="module"/>, <paramref name="stream"/> or <see cref="EmittingArguments.MetaDataVersion"/> of <paramref name="emittingArgs"/> is <c>null</c>. /// Also if any of <see cref="EmittingArguments.CorLibName"/>, <see cref="EmittingArguments.ImportHintName"/> or <see cref="EmittingArguments.ImportDirectoryName"/> of <paramref name="emittingArgs"/> is used and is <c>null</c>. /// </exception> public static void EmitModule(this CILModule module, Stream stream, EmittingArguments emittingArgs) { new ModuleWriter(module) .PerformEmitting(stream, emittingArgs); }
/// <summary> /// Helper method to call <see cref="CILAssemblyLoader.TryGetEmittingArgumentsFor"/> method /// </summary> /// <param name="loader">The <see cref="CILAssemblyLoader"/>.</param> /// <param name="module">The <see cref="CILModule"/>.</param> /// <returns>The out parameter of <see cref="CILAssemblyLoader.TryGetEmittingArgumentsFor"/>.</returns> /// <exception cref="ArgumentException">If <see cref="CILAssemblyLoader.TryGetEmittingArgumentsFor"/> returns <c>false</c>.</exception> public static EmittingArguments GetEmittingArgumentsFor(this CILAssemblyLoader loader, CILModule module) { EmittingArguments retVal; if (!loader.TryGetEmittingArgumentsFor(module, out retVal)) { throw new ArgumentException("Module was not loaded with this loader."); } return(retVal); }
internal MethodILImpl(CILModule module, Boolean initLocals, Byte[] il, Tuple <Boolean, CILTypeBase>[] locals, Tuple <ExceptionBlockType, Int32, Int32, Int32, Int32, CILType, Int32>[] excBlocks, Func <Int32, ILResolveKind, Object> tokenResolver) : this( module ) { this._initLocals = initLocals; foreach (var lInfo in locals) { this.DeclareLocal(lInfo.Item2, lInfo.Item1); } var ilOffset = 0; var labelsDic = new Dictionary <Int32, ILLabel>(); var codeInfoILOffsets = new Dictionary <Int32, Int32>(); Func <ILLabel> ilLabelDefiner = () => this.DefineLabel(); while (ilOffset < il.Length) { codeInfoILOffsets.Add(ilOffset, this._opCodes.Count); var curInstruction = (Int32)il[ilOffset++]; if (curInstruction == OpCode.MAX_ONE_BYTE_INSTRUCTION) { curInstruction = (curInstruction << 8) | (Int32)il[ilOffset++]; } var code = OpCodes.Codes[(OpCodeEncoding)curInstruction]; Int32 int32; ILLabel label; Object resolvedToken; switch (code.OperandType) { case OperandType.InlineNone: this._opCodes.Add(OpCodes.CodeInfosWithNoOperand[(OpCodeEncoding)curInstruction]); break; case OperandType.ShortInlineBrTarget: int32 = ilOffset + 1 + (Int32)((SByte)il[ilOffset]); ++ilOffset; label = labelsDic.GetOrAdd_NotThreadSafe(int32, ilLabelDefiner); this._opCodes.Add(new OpCodeInfoForFixedBranchOrLeave(code, label)); // OpCodes.Leave_S == code ? (OpCodeInfo) new OpCodeInfoForLeave( label ) : new OpCodeInfoForBranch( code, true, label ) ); ++this._branchTargetsCount; break; case OperandType.ShortInlineI: this._opCodes.Add(new OpCodeInfoWithFixedSizeOperandInt32(code, (SByte)il[ilOffset++])); break; case OperandType.ShortInlineVar: this._opCodes.Add(new OpCodeInfoWithFixedSizeOperandUInt16(code, il[ilOffset++])); break; case OperandType.ShortInlineR: this._opCodes.Add(new OpCodeInfoWithFixedSizeOperandSingle(code, il.ReadSingleLEFromBytes(ref ilOffset))); break; case OperandType.InlineBrTarget: int32 = il.ReadInt32LEFromBytes(ref ilOffset); int32 += ilOffset; label = labelsDic.GetOrAdd_NotThreadSafe(int32, ilLabelDefiner); this._opCodes.Add(new OpCodeInfoForFixedBranchOrLeave(code, label)); // OpCodes.Leave == code ? (OpCodeInfo) new OpCodeInfoForLeave( label ) : new OpCodeInfoForBranch( code, false, label ) ); ++this._branchTargetsCount; break; case OperandType.InlineI: this._opCodes.Add(new OpCodeInfoWithFixedSizeOperandInt32(code, il.ReadInt32LEFromBytes(ref ilOffset))); break; case OperandType.InlineVar: this._opCodes.Add(new OpCodeInfoWithFixedSizeOperandUInt16(code, il.ReadInt16LEFromBytes(ref ilOffset))); break; case OperandType.InlineR: this._opCodes.Add(new OpCodeInfoWithFixedSizeOperandDouble(code, il.ReadDoubleLEFromBytes(ref ilOffset))); break; case OperandType.InlineI8: this._opCodes.Add(new OpCodeInfoWithFixedSizeOperandInt64(code, il.ReadInt64LEFromBytes(ref ilOffset))); break; case OperandType.InlineString: this._opCodes.Add(new OpCodeInfoWithFixedSizeOperandString((String)tokenResolver(il.ReadInt32LEFromBytes(ref ilOffset), ILResolveKind.String))); break; case OperandType.InlineField: this._opCodes.Add(new OpCodeInfoWithFieldToken(code, (CILField)tokenResolver(il.ReadInt32LEFromBytes(ref ilOffset), ILResolveKind.Field))); break; case OperandType.InlineMethod: resolvedToken = tokenResolver(il.ReadInt32LEFromBytes(ref ilOffset), ILResolveKind.MethodBase); // Because of base.X() calls to virtual methods, we can not use Call/Callvirt deduction here this._opCodes.Add(resolvedToken is CILMethod ? (OpCodeInfo) new OpCodeInfoWithMethodToken(code, (CILMethod)resolvedToken) : new OpCodeInfoWithCtorToken(code, (CILConstructor)resolvedToken)); //var isMethod = resolvedToken is CILMethod; //var canEmitNormalOrVirtual = isMethod && OpCodes.Callvirt.Equals( code ); //var isCallOrVirt = canEmitNormalOrVirtual; //if ( canEmitNormalOrVirtual ) //{ // canEmitNormalOrVirtual = this._opCodes.Count == 0; // if ( canEmitNormalOrVirtual ) // { // var last = this._opCodes[this._opCodes.Count - 1]; // canEmitNormalOrVirtual = !( last is OpCodeInfoWithTypeToken ) || !OpCodes.Constrained_.Equals( ( (OpCodeInfoWithTypeToken) last ).Code ); // } //} //else if ( isMethod ) //{ // isCallOrVirt = OpCodes.Call.Equals( code ); // canEmitNormalOrVirtual = isCallOrVirt || OpCodes.Ldftn.Equals( code ) || OpCodes.Ldvirtftn.Equals( code ); //} //this._opCodes.Add( // canEmitNormalOrVirtual ? // ( isCallOrVirt ? // OpCodeInfoForNormalOrVirtual.OpCodeInfoForCall( (CILMethod) resolvedToken ) : // OpCodeInfoForNormalOrVirtual.OpCodeInfoForLdFtn( (CILMethod) resolvedToken ) ) : // ( isMethod ? // (OpCodeInfo) new OpCodeInfoWithMethodToken( code, (CILMethod) resolvedToken ) : // new OpCodeInfoWithCtorToken( code, (CILConstructor) resolvedToken ) ) // ); break; case OperandType.InlineType: this._opCodes.Add(new OpCodeInfoWithTypeToken(code, (CILTypeBase)tokenResolver(il.ReadInt32LEFromBytes(ref ilOffset), ILResolveKind.Type))); break; case OperandType.InlineTok: int32 = il.ReadInt32LEFromBytes(ref ilOffset); Tables refTable; Int32 dummy; TokenUtils.DecodeToken(int32, out refTable, out dummy); ILResolveKind resolveKind; switch (refTable) { case Tables.TypeDef: case Tables.TypeRef: case Tables.TypeSpec: resolveKind = ILResolveKind.Type; break; case Tables.Field: resolveKind = ILResolveKind.Field; break; case Tables.MethodDef: case Tables.MethodSpec: resolveKind = ILResolveKind.MethodBase; break; case Tables.MemberRef: resolveKind = ILResolveKind.MethodBaseOrField; break; default: throw new BadImageFormatException("Unknown inline token in IL at offset " + ilOffset + " (" + new TableIndex(int32) + ")"); } resolvedToken = tokenResolver(int32, resolveKind); this._opCodes.Add(resolvedToken is CILTypeBase ? new OpCodeInfoWithTypeToken(code, (CILTypeBase)resolvedToken, (Tables.TypeDef == refTable || Tables.TypeRef == refTable)) : (resolvedToken is CILField ? new OpCodeInfoWithFieldToken(code, (CILField)resolvedToken, true) : // TODO the last boolean parameter properly (how?) (resolvedToken is CILMethod ? (OpCodeInfo) new OpCodeInfoWithMethodToken(code, (CILMethod)resolvedToken, (Tables.MemberRef == refTable || Tables.MethodDef == refTable)) : // TODO last boolean parameter propertly (how?) new OpCodeInfoWithCtorToken(code, (CILConstructor)resolvedToken, true) // TODO last boolean parameter propertly (how?) ) ) ); break; case OperandType.InlineSwitch: int32 = il.ReadInt32LEFromBytes(ref ilOffset); ILLabel[] labels = new ILLabel[int32]; for (var i = 0; i < int32; ++i) { var lTarget = il.ReadInt32LEFromBytes(ref ilOffset); lTarget += ilOffset + (int32 - i - 1) * 4; labels[i] = labelsDic.GetOrAdd_NotThreadSafe(lTarget, () => this.DefineLabel()); } this._opCodes.Add(new OpCodeInfoForSwitch(labels)); this._branchTargetsCount += int32; break; case OperandType.InlineSig: int32 = il.ReadInt32LEFromBytes(ref ilOffset); var methodSig = (Tuple <CILMethodSignature, Tuple <CILCustomModifier[], CILTypeBase>[]>)tokenResolver(int32, ILResolveKind.Signature); this._opCodes.Add(new OpCodeInfoWithMethodSig(methodSig.Item1, methodSig.Item2)); break; default: throw new ArgumentException("Unknown operand type: " + code.OperandType + " for " + code + "."); } } // Then, process labels foreach (var kvp in labelsDic) { this.MarkLabel(kvp.Value, codeInfoILOffsets[kvp.Key]); } // And exception blocks foreach (var block in excBlocks) { var info = new ExceptionBlockInfo(codeInfoILOffsets[block.Item2], labelsDic.GetOrAdd_NotThreadSafe(block.Item4 + block.Item5, () => { var result = this.DefineLabel(); this.MarkLabel(result, codeInfoILOffsets[block.Item4 + block.Item5]); return(result); })); info._blockType = block.Item1; info._tryLength = codeInfoILOffsets[block.Item2 + block.Item3] - info._tryOffset; info._handlerOffset = codeInfoILOffsets[block.Item4]; info._handlerLength = codeInfoILOffsets[block.Item4 + block.Item5] - info._handlerOffset; var excType = block.Item6; if (excType != null) { info._exceptionType = excType; } if (codeInfoILOffsets.ContainsKey(block.Item7)) { info._filterOffset = block.Item7; } this._allExceptionBlocks.Add(info); } }
private static CILAssemblyImpl LoadAssembly(CILReflectionContextImpl cctx, Stream stream, EmittingArguments eArgs, ModuleReader existingModuleReader, MetaDataReader existingMD, CILModule existingModule) { ArgumentValidator.ValidateNotNull("Reflection context", cctx); ArgumentValidator.ValidateNotNull("Emitting arguments", eArgs); var fileStreamOpener = eArgs.FileStreamOpener ?? THROW_INVALID_OPERATION; var moduleReader = existingModuleReader; var md = existingMD; var thisModule = existingModule; CILAssemblyImpl result = null; result = (CILAssemblyImpl)cctx.Cache.NewAssembly(id => new CILAssemblyImpl( cctx, id, new LazyWithLock <ListProxy <CILCustomAttribute> >(() => { // Force evaluation of module types ( to get stuff populated in module reader) var dummy = thisModule.DefinedTypes; return(moduleReader.ReadAssemblyCustomAttributes(id)); }), () => { var aRow = md.assembly[0]; var aFlags = aRow.Item6; if (!aRow.Item7.IsNullOrEmpty()) { aFlags |= AssemblyFlags.PublicKey; } return(new CILAssemblyName(aRow.Item8, aRow.Item2, aRow.Item3, aRow.Item4, aRow.Item5, aRow.Item1, aFlags, aRow.Item7, aRow.Item9)); }, () => { var list = new List <CILModule>(); list.Add(thisModule); list.AddRange(md.file .Where(f => f.Item1.ContainsMetadata()) .Select(f => { using (var strm = fileStreamOpener(thisModule, f.Item2)) { ModuleReader mRdr; MetaDataReader mdRdr; return(LoadModule(cctx, strm, eArgs, mod => result, out mRdr, out mdRdr)); } })); return(cctx.CollectionsFactory.NewListProxy(list)); }, () => cctx.CollectionsFactory.NewDictionaryProxy(md.exportedType .Where(eRow => eRow.Item1.IsTypeForwarder() && eRow.Item5.table == Tables.AssemblyRef || eRow.Item5.table == Tables.ExportedType) .Select(eRow => moduleReader.ResolveExportedType(eRow.Item5, (TypeAttributes)eRow.Item1, eRow.Item4, eRow.Item3)) .GroupBy(tf => Tuple.Create(tf.Name, tf.Namespace)) .ToDictionary(g => g.Key, g => g.First())), () => thisModule )); if (thisModule == null) { thisModule = LoadModule(cctx, stream, eArgs, mod => result, out moduleReader, out md); } if (md.assembly.Length != 1) { throw new BadImageFormatException("Assembly table had " + (md.assembly.Length == 0 ? "too few" : "too many") + " rows, exactly one expected, but had " + md.assembly.Length + "."); } return(result); }