Jurassic.Compiler.DynamicILGenerator.Complete C# (CSharp) Method

Complete() public method

Emits a return statement and finalizes the generated code. Do not emit any more instructions after calling this method.
public Complete ( ) : void
return void
        public override unsafe void Complete()
        {
            // Check there aren't any outstanding exception blocks.
            if (this.activeExceptionRegions != null && this.activeExceptionRegions.Count > 0)
                throw new InvalidOperationException("The current method contains unclosed exception blocks.");

            Return();
            FixLabels();
            fixed (byte* bytes = this.bytes)
                this.dynamicILInfo.SetCode(bytes, this.offset, this.maxStackSize);
            this.dynamicILInfo.SetLocalSignature(this.LocalSignature);

            if (this.exceptionRegions != null && this.exceptionRegions.Count > 0)
            {
                // Count the number of exception clauses.
                int clauseCount = 0;
                foreach (var exceptionRegion in this.exceptionRegions)
                    clauseCount += exceptionRegion.Clauses.Count;

                var exceptionBytes = new byte[4 + 24 * clauseCount];
                var writer = new System.IO.BinaryWriter(new System.IO.MemoryStream(exceptionBytes));

                // 4-byte header, see Partition II, section 25.4.5.
                writer.Write((byte)0x41);               // Flags: CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat
                writer.Write(exceptionBytes.Length);    // 3-byte data size.
                writer.Flush();
                writer.BaseStream.Seek(4, System.IO.SeekOrigin.Begin);

                // Exception clauses, see Partition II, section 25.4.6.
                foreach (var exceptionRegion in this.exceptionRegions)
                {
                    foreach (var clause in exceptionRegion.Clauses)
                    {
                        switch (clause.Type)
                        {
                            case ExceptionClauseType.Catch:
                                writer.Write(0);                                // Flags
                                break;
                            case ExceptionClauseType.Filter:
                                writer.Write(1);                                // Flags
                                break;
                            case ExceptionClauseType.Finally:
                                writer.Write(2);                                // Flags
                                break;
                            case ExceptionClauseType.Fault:
                                writer.Write(4);                                // Flags
                                break;
                        }
                        writer.Write(exceptionRegion.Start);                    // TryOffset
                        writer.Write(clause.ILStart - exceptionRegion.Start);   // TryLength
                        writer.Write(clause.ILStart);                           // HandlerOffset
                        writer.Write(clause.ILLength);                          // HandlerLength
                        if (clause.Type == ExceptionClauseType.Catch)
                            writer.Write(clause.CatchToken);                    // ClassToken
                        else if (clause.Type == ExceptionClauseType.Filter)
                            writer.Write(clause.FilterHandlerStart);            // FilterOffset
                        else
                            writer.Write(0);
                    }
                }
                writer.Flush();
                this.dynamicILInfo.SetExceptions(exceptionBytes);
            }
        }
DynamicILGenerator