Пример #1
0
            public DynamicModuleManager(string moduleNamePrefix)
            {
                this.states             = new List <State>();
                this.islands            = new Dictionary <State, MethodInfo>();
                this.islandsWithPriming = new Dictionary <State, MethodInfo>();
                this.sourceDocuments    = new Dictionary <string, ISymbolDocumentWriter>();

                if (!PartialTrustHelpers.AppDomainFullyTrusted)
                {
                    moduleNamePrefix = State.ValidateIdentifierString(moduleNamePrefix);
                }

                InitDynamicModule(moduleNamePrefix);
            }
Пример #2
0
            public void Bake(string typeName, string typeNamePrefix, Dictionary <string, byte[]> checksumCache)
            {
                // In partial trust, validate the typeName and typeNamePrefix.
                if (!PartialTrustHelpers.AppDomainFullyTrusted)
                {
                    typeName       = State.ValidateIdentifierString(typeName);
                    typeNamePrefix = State.ValidateIdentifierString(typeNamePrefix);

                    if (checksumCache != null)
                    {
                        bool nullifyChecksumCache = false;
                        foreach (KeyValuePair <string, byte[]> kvpair in checksumCache)
                        {
                            // We use an MD5 hash for the checksum, so the byte array should be 16 elements long.
                            if (!SymbolHelper.ValidateChecksum(kvpair.Value))
                            {
                                nullifyChecksumCache = true;
                                Trace.WriteLine(SR.DebugSymbolChecksumValueInvalid);
                                break;
                            }
                        }

                        // If we found an invalid checksum, just don't use the cache.
                        if (nullifyChecksumCache)
                        {
                            checksumCache = null;
                        }
                    }
                }

                lock (this)
                {
                    if (this.indexLastBaked < this.states.Count)    // there are newly created states.
                    {
                        // Ensure typename is unique. Append a number if needed.
                        int suffix = 1;
                        while (this.dynamicModule.GetType(typeName) != null)
                        {
                            typeName = typeNamePrefix + "_" + suffix.ToString(CultureInfo.InvariantCulture);
                            ++suffix;
                        }

                        TypeBuilder typeBuilder = this.dynamicModule.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class);

                        for (int i = indexLastBaked; i < this.states.Count; i++)
                        {
                            // Only create the island if debugging is enabled for the state.
                            if (this.states[i].DebuggingEnabled)
                            {
                                MethodBuilder methodBuilder = this.CreateIsland(typeBuilder, this.states[i], false, checksumCache);
                                Fx.Assert(methodBuilder != null, "CreateIsland call should have succeeded");

                                // Always generate method with priming, for the following scenario:
                                //  1. Start debugging a workflow inside VS, workflow debug session 1 starts (debugStartedAtRoot = true, instrumentation is done)
                                //  2. Workflow persisted, workflow debug session 1 ends
                                //  3. Workflow continued, workflow debug session 2 starts (debugStartedAtRoot = false, instrumentation is skipped because the static dynamicModuleManager is being reused and the instrumentation is done)
                                //  4. PrimeCallStack is called to rebuild the call stack
                                //  5. NullReferenceException will be thrown if MethodInfo with prime is not available
                                MethodBuilder methodBuilderWithPriming = this.CreateIsland(typeBuilder, this.states[i], true, checksumCache);
                                Fx.Assert(methodBuilderWithPriming != null, "CreateIsland call should have succeeded");

                                // Save information needed to call Type.GetMethod() later.
                                this.states[i].CacheMethodInfo(typeBuilder, methodBuilder.Name);
                            }
                        }

                        // Actual baking.
                        typeBuilder.CreateType();

                        // Calling Type.GetMethod() is slow (10,000 calls can take ~1 minute).
                        // So defer that to later.

                        this.indexLastBaked = this.states.Count;
                    }
                }
            }