public void PutSymbol(Symbol symbol) { if (moduleBeingBuilt != null) { writer.WriteUint(moduleBeingBuilt.GetFakeSymbolTokenForIL(moduleBeingBuilt.Translate(symbol))); } }
public void PutOpcode(Microsoft.Cci.OperationCode opcode, Symbol symbol) { PutOpcode(opcode); var opcodeInfo = Microsoft.Cci.PeWriter.OperationCodeInfo(opcode); switch (opcodeInfo.OperandType) { case OperandType.InlineField: case OperandType.InlineMethod: case OperandType.InlineTok: case OperandType.InlineType: writer.WriteUint(moduleBeingBuilt.GetFakeSymbolTokenForIL(moduleBeingBuilt.Translate(symbol))); break; default: throw new NotImplementedException(); } }
public void Serialize(Microsoft.Cci.BinaryWriter to) { switch (this.Discriminator) { case ConstantValueTypeDiscriminator.Boolean: to.WriteBool(this.BooleanValue); break; case ConstantValueTypeDiscriminator.SByte: to.WriteSbyte(this.SByteValue); break; case ConstantValueTypeDiscriminator.Byte: to.WriteByte(this.ByteValue); break; case ConstantValueTypeDiscriminator.Char: case ConstantValueTypeDiscriminator.Int16: to.WriteShort(this.Int16Value); break; case ConstantValueTypeDiscriminator.UInt16: to.WriteUshort(this.UInt16Value); break; case ConstantValueTypeDiscriminator.Single: to.WriteFloat(this.SingleValue); break; case ConstantValueTypeDiscriminator.Int32: to.WriteInt(this.Int32Value); break; case ConstantValueTypeDiscriminator.UInt32: to.WriteUint(this.UInt32Value); break; case ConstantValueTypeDiscriminator.Double: to.WriteDouble(this.DoubleValue); break; case ConstantValueTypeDiscriminator.Int64: to.WriteLong(this.Int64Value); break; case ConstantValueTypeDiscriminator.UInt64: to.WriteUlong(this.UInt64Value); break; default: throw ExceptionUtilities.UnexpectedValue(this.Discriminator); } }
private void RealizeBlocks() { // drop dead code. // We do not want to deal with unreachable code even when not optimizing. // sometimes dead code may have subtle verification violations // for example illegal fall-through in unreachable code is still illegal, // but compiler will not enforce returning from dead code. // it is easier to just remove dead code than make sure it is all valid MarkReachableBlocks(); RewriteSpecialBlocks(); DropUnreachableBlocks(); if (isOptimizing && OptimizeLabels()) { // redo unreachable code elimination if some labels were optimized // as that could result in more more dead code. MarkAllBlocksUnreachable(); MarkReachableBlocks(); DropUnreachableBlocks(); } // some gotos must become leaves RewriteBranchesAcrossExceptionHandlers(); // now we can compute block offsets and adjust branches while (ComputeOffsetsAndAdjustBranches()) { // if branches were optimized, we may have more unreachable code // redo unreachable code elimination and if anything was dropped redo adjusting. MarkAllBlocksUnreachable(); MarkReachableBlocks(); if (!DropUnreachableBlocks()) { // nothing was dropped, we are done adjusting break; } } // Now linearize everything with computed offsets. var realizedIlBitStream = Microsoft.Cci.MemoryStream.GetInstance(); var writer = new Microsoft.Cci.BinaryWriter(realizedIlBitStream); for (var block = leaderBlock; block != null; block = block.NextBlock) { // If the block has any IL markers, we can calculate their real IL offsets now int blockFirstMarker = block.FirstILMarker; if (blockFirstMarker >= 0) { int blockLastMarker = block.LastILMarker; Debug.Assert(blockLastMarker >= blockFirstMarker); for (int i = blockFirstMarker; i <= blockLastMarker; i++) { int blockOffset = this.allocatedILMarkers[i].BlockOffset; int absoluteOffset = (int)realizedIlBitStream.Position + blockOffset; this.allocatedILMarkers[i] = new ILMarker() { BlockOffset = blockOffset, AbsoluteOffset = absoluteOffset }; } } var bits = block.RegularInstructions; if (bits != null) { bits.WriteTo(realizedIlBitStream); } switch (block.BranchCode) { case ILOpCode.Nop: break; case ILOpCode.Switch: // switch (N, t1, t2... tN) // IL ==> ILOpCode.Switch < unsigned int32 > < int32 >... < int32 > WriteOpCode(writer, ILOpCode.Switch); var switchBlock = (SwitchBlock)block; writer.WriteUint(switchBlock.BranchesCount); int switchBlockEnd = switchBlock.Start + switchBlock.TotalSize; var blockBuilder = ArrayBuilder<BasicBlock>.GetInstance(); switchBlock.GetBranchBlocks(blockBuilder); foreach (var branchBlock in blockBuilder) { writer.WriteInt(branchBlock.Start - switchBlockEnd); } blockBuilder.Free(); break; default: WriteOpCode(writer, block.BranchCode); if (block.BranchLabel != null) { int target = block.BranchBlock.Start; int curBlockEnd = block.Start + block.TotalSize; int offset = target - curBlockEnd; if (block.BranchCode.BranchOperandSize() == 1) { sbyte btOffset = (sbyte)offset; Debug.Assert(btOffset == offset); writer.WriteSbyte(btOffset); } else { writer.WriteInt(offset); } } break; } } this.RealizedIL = realizedIlBitStream.ToArray(); realizedIlBitStream.Free(); RealizeSequencePoints(); this.RealizedExceptionHandlers = scopeManager.GetExceptionHandlerRegions(); }
private void RealizeBlocks() { // drop dead code. // We do not want to deal with unreachable code even when not optimizing. // sometimes dead code may have subtle verification violations // for example illegal fall-through in unreachable code is still illegal, // but compiler will not enforce returning from dead code. // it is easier to just remove dead code than make sure it is all valid MarkReachableBlocks(); RewriteSpecialBlocks(); DropUnreachableBlocks(); if (isOptimizing && OptimizeLabels()) { // redo unreachable code elimination if some labels were optimized // as that could result in more more dead code. MarkAllBlocksUnreachable(); MarkReachableBlocks(); DropUnreachableBlocks(); } // some gotos must become leaves RewriteBranchesAcrossExceptionHandlers(); // now we can compute block offsets and adjust branches while (ComputeOffsetsAndAdjustBranches()) { // if branches were optimized, we may have more unreachable code // redo unreachable code elimination and if anything was dropped redo adjusting. MarkAllBlocksUnreachable(); MarkReachableBlocks(); if (!DropUnreachableBlocks()) { // nothing was dropped, we are done adjusting break; } } // Now linearize everything with computed offsets. var realizedIlBitStream = Microsoft.Cci.MemoryStream.GetInstance(); var writer = new Microsoft.Cci.BinaryWriter(realizedIlBitStream); for (var block = leaderBlock; block != null; block = block.NextBlock) { // If the block has any IL markers, we can calculate their real IL offsets now int blockFirstMarker = block.FirstILMarker; if (blockFirstMarker >= 0) { int blockLastMarker = block.LastILMarker; Debug.Assert(blockLastMarker >= blockFirstMarker); for (int i = blockFirstMarker; i <= blockLastMarker; i++) { int blockOffset = this.allocatedILMarkers[i].BlockOffset; int absoluteOffset = (int)realizedIlBitStream.Position + blockOffset; this.allocatedILMarkers[i] = new ILMarker() { BlockOffset = blockOffset, AbsoluteOffset = absoluteOffset }; } } var bits = block.RegularInstructions; if (bits != null) { bits.WriteTo(realizedIlBitStream); } switch (block.BranchCode) { case ILOpCode.Nop: break; case ILOpCode.Switch: // switch (N, t1, t2... tN) // IL ==> ILOpCode.Switch < unsigned int32 > < int32 >... < int32 > WriteOpCode(writer, ILOpCode.Switch); var switchBlock = (SwitchBlock)block; writer.WriteUint(switchBlock.BranchesCount); int switchBlockEnd = switchBlock.Start + switchBlock.TotalSize; var blockBuilder = ArrayBuilder <BasicBlock> .GetInstance(); switchBlock.GetBranchBlocks(blockBuilder); foreach (var branchBlock in blockBuilder) { writer.WriteInt(branchBlock.Start - switchBlockEnd); } blockBuilder.Free(); break; default: WriteOpCode(writer, block.BranchCode); if (block.BranchLabel != null) { int target = block.BranchBlock.Start; int curBlockEnd = block.Start + block.TotalSize; int offset = target - curBlockEnd; if (block.BranchCode.BranchOperandSize() == 1) { sbyte btOffset = (sbyte)offset; Debug.Assert(btOffset == offset); writer.WriteSbyte(btOffset); } else { writer.WriteInt(offset); } } break; } } this.RealizedIL = realizedIlBitStream.ToArray(); realizedIlBitStream.Free(); RealizeSequencePoints(); this.RealizedExceptionHandlers = scopeManager.GetExceptionHandlerRegions(); }