コード例 #1
0
ファイル: Commons.cs プロジェクト: PlumpMath/CAM
 internal static void CheckTypeForMethodSig(CILModule thisModule, ref CILTypeBase type)
 {
     if (TypeKind.MethodSignature == type.TypeKind && !Object.Equals(thisModule, type.Module))
     {
         type = ((CILMethodSignature)type).CopyToOtherModule(thisModule);
     }
 }
コード例 #2
0
        internal ModuleWriter(CILModule module)
        {
            ArgumentValidator.ValidateNotNull("Module", module);

            this._context = (CILReflectionContextImpl)module.ReflectionContext;
            this._module  = module;
        }
コード例 #3
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
        /// <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);
        }
コード例 #4
0
        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;
                }
            }
        }
コード例 #5
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
        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);
        }
コード例 #6
0
 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);
         }
     }));
 }
コード例 #7
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
    /// <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);
    }
コード例 #8
0
ファイル: RuntimeTypeFactory.cs プロジェクト: arlm/CILantro
        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;
        }
コード例 #9
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
        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;
        }
コード例 #10
0
    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);
        }
    }
コード例 #11
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
        /// <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.");
            }
        }
コード例 #12
0
        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?
        }
コード例 #13
0
        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(']');
                }
            }
        }
コード例 #14
0
        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);
        }
コード例 #15
0
 /// <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, ""));
 }
コード例 #16
0
 /// <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);;
 }
コード例 #17
0
 /// <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()));
 }
コード例 #18
0
    /// <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));
    }
コード例 #19
0
 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))
 {
 }
コード例 #20
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
 /// <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));
 }
コード例 #21
0
 /// <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));
 }
コード例 #22
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
 private String GetThisModulePath(CILModule thisModule)
 {
     return(this._moduleResources[thisModule]);
 }
コード例 #23
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
 /// <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));
 }
コード例 #24
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
 /// <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));
 }
コード例 #25
0
 /// <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);
 }
コード例 #26
0
ファイル: CILAssemblyLoader.cs プロジェクト: PlumpMath/CAM
    /// <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);
    }
コード例 #27
0
        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);
            }
        }
コード例 #28
0
    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);
    }