// Various parsing functions for processing through the locals of a function and translating them to the // alternate form with new tokens. int ParseCompressedInt() { int value = _input.ReadCompressedInteger(); _output.WriteCompressedInteger(value); return(value); }
private unsafe static void ConvertConstantSignature(BlobBuilder builder, MetadataModel metadataModel, byte[] signature, object value) { fixed(byte *sigPtr = signature) { var sigReader = new BlobReader(sigPtr, signature.Length); // copy custom modifiers over: byte rawTypeCode; while (true) { rawTypeCode = sigReader.ReadByte(); if (rawTypeCode != (int)SignatureTypeCode.OptionalModifier && rawTypeCode != (int)SignatureTypeCode.RequiredModifier) { break; } builder.WriteByte(rawTypeCode); builder.WriteCompressedInteger(sigReader.ReadCompressedInteger()); } switch ((SignatureTypeCode)rawTypeCode) { case (SignatureTypeCode)SignatureTypeKind.Class: case (SignatureTypeCode)SignatureTypeKind.ValueType: int typeRefDefSpec = sigReader.ReadCompressedInteger(); if (value is decimal) { // GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <decimal> builder.WriteByte((byte)SignatureTypeKind.ValueType); builder.WriteCompressedInteger(typeRefDefSpec); builder.WriteDecimal((decimal)value); } else if (value is double d) { // GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <date-time> builder.WriteByte((byte)SignatureTypeKind.ValueType); builder.WriteCompressedInteger(typeRefDefSpec); builder.WriteDateTime(new DateTime(BitConverter.DoubleToInt64Bits(d))); } else if (value is 0 && rawTypeCode == (byte)SignatureTypeKind.Class) { // GeneralConstant: CLASS TypeDefOrRefOrSpecEncoded builder.WriteByte(rawTypeCode); builder.WriteCompressedInteger(typeRefDefSpec); } else { // EnumConstant ::= EnumTypeCode EnumValue EnumType // EnumTypeCode ::= BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 // EnumType ::= TypeDefOrRefOrSpecEncoded var enumTypeCode = AssemblyDisplayNameBuilder.GetConstantTypeCode(value); builder.WriteByte((byte)enumTypeCode); builder.WriteConstant(value); builder.WriteCompressedInteger(typeRefDefSpec); } break;
private void SerializeImport(BlobBuilder writer, AssemblyReferenceAlias alias) { // <import> ::= AliasAssemblyReference <alias> <target-assembly> writer.WriteByte((byte)ImportDefinitionKind.AliasAssemblyReference); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(alias.Name))); writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(GetOrAddAssemblyReferenceHandle(alias.Assembly))); }
private BlobHandle SerializeSpans( ImmutableArray <SourceSpan> spans, Dictionary <DebugSourceDocument, int> documentIndex) { if (spans.Length == 0) { return(default(BlobHandle)); } // 4 bytes per span plus a header, the builder expands by the same amount. var writer = new BlobBuilder(4 + spans.Length * 4); int previousStartLine = -1; int previousStartColumn = -1; DebugSourceDocument previousDocument = spans[0].Document; // header: writer.WriteCompressedInteger(GetOrAddDocument(previousDocument, documentIndex)); for (int i = 0; i < spans.Length; i++) { var currentDocument = spans[i].Document; if (previousDocument != currentDocument) { writer.WriteInt16(0); writer.WriteCompressedInteger(GetOrAddDocument(currentDocument, documentIndex)); previousDocument = currentDocument; } // Delta Lines & Columns: SerializeDeltaLinesAndColumns(writer, spans[i]); // delta Start Lines & Columns: if (previousStartLine < 0) { Debug.Assert(previousStartColumn < 0); writer.WriteCompressedInteger(spans[i].StartLine); writer.WriteCompressedInteger(spans[i].StartColumn); } else { writer.WriteCompressedSignedInteger(spans[i].StartLine - previousStartLine); writer.WriteCompressedSignedInteger(spans[i].StartColumn - previousStartColumn); } previousStartLine = spans[i].StartLine; previousStartColumn = spans[i].StartColumn; } return(GetOrAddBlob(writer)); }
internal void SerializeLocalSlots(BlobBuilder writer) { int syntaxOffsetBaseline = -1; foreach (LocalSlotDebugInfo localSlot in this.LocalSlots) { if (localSlot.Id.SyntaxOffset < syntaxOffsetBaseline) { syntaxOffsetBaseline = localSlot.Id.SyntaxOffset; } } if (syntaxOffsetBaseline != -1) { writer.WriteByte(SyntaxOffsetBaseline); writer.WriteCompressedInteger(-syntaxOffsetBaseline); } foreach (LocalSlotDebugInfo localSlot in this.LocalSlots) { SynthesizedLocalKind kind = localSlot.SynthesizedKind; Debug.Assert(kind <= SynthesizedLocalKind.MaxValidValueForLocalVariableSerializedToDebugInformation); if (!kind.IsLongLived()) { writer.WriteByte(0); continue; } byte b = (byte)(kind + 1); Debug.Assert((b & (1 << 7)) == 0); bool hasOrdinal = localSlot.Id.Ordinal > 0; if (hasOrdinal) { b |= 1 << 7; } writer.WriteByte(b); writer.WriteCompressedInteger(localSlot.Id.SyntaxOffset - syntaxOffsetBaseline); if (hasOrdinal) { writer.WriteCompressedInteger(localSlot.Id.Ordinal); } } }
void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig) { BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); int genericParameterCount = sig.GenericParameterCount; bool isInstanceMethod = !sig.IsStatic; SignatureCallingConvention sigCallingConvention = SignatureCallingConvention.Default; switch (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) { case MethodSignatureFlags.CallingConventionVarargs: sigCallingConvention = SignatureCallingConvention.VarArgs; break; case MethodSignatureFlags.UnmanagedCallingConventionCdecl: sigCallingConvention = SignatureCallingConvention.CDecl; break; case MethodSignatureFlags.UnmanagedCallingConventionStdCall: sigCallingConvention = SignatureCallingConvention.StdCall; break; case MethodSignatureFlags.UnmanagedCallingConventionThisCall: sigCallingConvention = SignatureCallingConvention.ThisCall; break; } signatureEncoder.MethodSignature(sigCallingConvention, genericParameterCount, isInstanceMethod); signatureBuilder.WriteCompressedInteger(sig.Length); // TODO Process custom modifiers in some way EncodeType(signatureBuilder, sig.ReturnType); for (int i = 0; i < sig.Length; i++) { EncodeType(signatureBuilder, sig[i]); } }
private static byte[] CompressUnsignedInteger(int value) { var writer = new BlobBuilder(); writer.WriteCompressedInteger((uint)value); return(writer.ToArray()); }
public void WriteSequencePoints(SequencePoint[] sequencePoints) { if (sequencePoints.Length == 0) { return; } BlobBuilder blobBuilder = Builder; int num = -1; int num2 = -1; blobBuilder.WriteCompressedInteger(LocalSignatureRowId); DocumentHandle debugSourceDocument = sequencePoints[0].Document; for (int i = 0; i < sequencePoints.Length; i++) { DocumentHandle document = sequencePoints[i].Document; if (debugSourceDocument != document) { if (debugSourceDocument != null) { blobBuilder.WriteCompressedInteger(0); } blobBuilder.WriteCompressedInteger(MetadataTokens.GetRowNumber(document)); debugSourceDocument = document; } if (i > 0) { if (sequencePoints[i].Offset - sequencePoints[i - 1].Offset < 1) { throw new InvalidOperationException("There must not be specified more sequence points per offset."); } blobBuilder.WriteCompressedInteger(sequencePoints[i].Offset - sequencePoints[i - 1].Offset); } else { blobBuilder.WriteCompressedInteger(sequencePoints[i].Offset); } if (sequencePoints[i].IsHidden) { blobBuilder.WriteInt16(0); } else { this.SerializeDeltaLinesAndColumns(blobBuilder, sequencePoints[i]); if (num < 0) { blobBuilder.WriteCompressedInteger(sequencePoints[i].StartLine); blobBuilder.WriteCompressedInteger(sequencePoints[i].StartColumn); } else { blobBuilder.WriteCompressedSignedInteger(sequencePoints[i].StartLine - num); blobBuilder.WriteCompressedSignedInteger(sequencePoints[i].StartColumn - num2); } num = sequencePoints[i].StartLine; num2 = sequencePoints[i].StartColumn; } } }
public void AllowUseOfAddGlobalMethod() { BlobBuilder noArgsNoReturnStaticMethodSig = new BlobBuilder(); BlobEncoder signatureEncoder = new BlobEncoder(noArgsNoReturnStaticMethodSig); signatureEncoder.MethodSignature(SignatureCallingConvention.Default, 0, false); noArgsNoReturnStaticMethodSig.WriteCompressedInteger(0); noArgsNoReturnStaticMethodSig.WriteByte((byte)SignatureTypeCode.Void); _noArgsVoidReturnStaticMethodSigHandle = _metadataBuilder.GetOrAddBlob(noArgsNoReturnStaticMethodSig); }
private static void SerializeDeltaLinesAndColumns(BlobBuilder writer, SymUnmanagedSequencePoint sequencePoint) { int deltaLines = sequencePoint.EndLine - sequencePoint.StartLine; int deltaColumns = sequencePoint.EndColumn - sequencePoint.StartColumn; // only hidden sequence points have zero width Debug.Assert(deltaLines != 0 || deltaColumns != 0 || sequencePoint.IsHidden); writer.WriteCompressedInteger(deltaLines); if (deltaLines == 0) { writer.WriteCompressedInteger(deltaColumns); } else { writer.WriteCompressedSignedInteger(deltaColumns); } }
private void SerializeDeltaLinesAndColumns(BlobBuilder writer, SourceSpan span) { int deltaLines = span.EndLine - span.StartLine; int deltaColumns = span.EndColumn - span.StartColumn; // spans can't have zero width Debug.Assert(deltaLines != 0 || deltaColumns != 0); writer.WriteCompressedInteger(deltaLines); if (deltaLines == 0) { writer.WriteCompressedInteger(deltaColumns); } else { writer.WriteCompressedSignedInteger(deltaColumns); } }
/// Just write the dictionary out to a blob as a count followed by /// a length-prefixed UTF8 encoding of each key and value private void ConvertDictionaryToBlob(IReadOnlyDictionary <string, string> properties, BlobBuilder builder) { int count = properties.Count; builder.WriteCompressedInteger(count); foreach (var kvp in properties) { builder.WriteSerializedString(kvp.Key); builder.WriteSerializedString(kvp.Value); } }
public void CompressUnsignedIntegersFromSpecExamples() { // These examples are straight from the CLI spec. TestCompressedUnsignedInteger(new byte[] { 0x00 }, 0); TestCompressedUnsignedInteger(new byte[] { 0x03 }, 0x03); TestCompressedUnsignedInteger(new byte[] { 0x7f }, 0x7F); TestCompressedUnsignedInteger(new byte[] { 0x80, 0x80 }, 0x80); TestCompressedUnsignedInteger(new byte[] { 0xAE, 0x57 }, 0x2E57); TestCompressedUnsignedInteger(new byte[] { 0xBF, 0xFF }, 0x3FFF); TestCompressedUnsignedInteger(new byte[] { 0xC0, 0x00, 0x40, 0x00 }, 0x4000); TestCompressedUnsignedInteger(new byte[] { 0xDF, 0xFF, 0xFF, 0xFF }, 0x1FFFFFFF); var writer = new BlobWriter(4); var builder = new BlobBuilder(); Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteCompressedInteger(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteCompressedInteger(BlobWriterImpl.MaxCompressedIntegerValue + 1)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteCompressedInteger(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteCompressedInteger(BlobWriterImpl.MaxCompressedIntegerValue + 1)); }
// TODO: // WriteBytes(byte*) // WriteBytes(stream) // WriteBytes(byte[]) // WriteBytes(IA<byte>) // WriteReference private static void TestCompressedUnsignedInteger(byte[] expected, int value) { var writer = new BlobWriter(4); writer.WriteCompressedInteger(value); AssertEx.Equal(expected, writer.ToArray()); var builder = new BlobBuilder(); builder.WriteCompressedInteger(value); AssertEx.Equal(expected, builder.ToArray()); }
public void EmitAtCurrentIndexStack(BlobBuilder signatureBuilder) { if (!Complete) { if (_embeddedDataIndex < _embeddedData.Length) { string indexData = string.Join(".", _indexStack); while ((_embeddedDataIndex < _embeddedData.Length) && _embeddedData[_embeddedDataIndex].index == indexData) { switch (_embeddedData[_embeddedDataIndex].kind) { case EmbeddedSignatureDataKind.OptionalCustomModifier: { signatureBuilder.WriteByte((byte)SignatureTypeCode.OptionalModifier); EntityHandle handle = _metadataEmitter.GetTypeRef((MetadataType)_embeddedData[_embeddedDataIndex].type); signatureBuilder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(handle)); } break; case EmbeddedSignatureDataKind.RequiredCustomModifier: { signatureBuilder.WriteByte((byte)SignatureTypeCode.RequiredModifier); EntityHandle handle = _metadataEmitter.GetTypeRef((MetadataType)_embeddedData[_embeddedDataIndex].type); signatureBuilder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(handle)); } break; case EmbeddedSignatureDataKind.ArrayShape: return; default: throw new NotImplementedException(); } _embeddedDataIndex++; } } } }
void SerializeDeltaLinesAndColumns(BlobBuilder writer, SequencePoint sequencePoint) { int deltaLines = sequencePoint.EndLine - sequencePoint.StartLine; int deltaColumns = sequencePoint.EndColumn - sequencePoint.StartColumn; // only hidden sequence points have zero width if (!(deltaLines != 0 || deltaColumns != 0 || sequencePoint.IsHidden)) { throw new InvalidOperationException("Only hidden sequence points have zero width "); } writer.WriteCompressedInteger(deltaLines); if (deltaLines == 0) { writer.WriteCompressedInteger(deltaColumns); } else { writer.WriteCompressedSignedInteger(deltaColumns); } }
internal BlobBuilder BuildBlob(MethodDefinitionHandle moveNext) { BlobBuilder blob = new BlobBuilder(); blob.WriteUInt32((uint)CatchHandlerOffset); foreach (var await in Awaits) { blob.WriteUInt32((uint)await.YieldOffset); blob.WriteUInt32((uint)await.ResumeOffset); blob.WriteCompressedInteger(MetadataTokens.GetToken(moveNext)); } return(blob); }
private static BlobHandle SerializeAsyncMethodSteppingInfo(MetadataBuilder metadataBuilder, ISymUnmanagedAsyncMethod symAsyncMethod, int moveNextMethodRowId) { var builder = new BlobBuilder(); builder.WriteUInt32((uint)((long)symAsyncMethod.GetCatchHandlerILOffset() + 1)); foreach (var stepInfo in symAsyncMethod.GetAsyncStepInfos()) { builder.WriteInt32(stepInfo.YieldOffset); builder.WriteInt32(stepInfo.ResumeOffset); builder.WriteCompressedInteger(moveNextMethodRowId); } return(metadataBuilder.GetOrAddBlob(builder)); }
public TypeSystemMetadataEmitter(AssemblyName assemblyName, TypeSystemContext context, AssemblyFlags flags = default(AssemblyFlags)) { _metadataBuilder = new MetadataBuilder(); _ilBuilder = new BlobBuilder(); _methodBodyStream = new MethodBodyStreamEncoder(_ilBuilder); StringHandle assemblyNameHandle = _metadataBuilder.GetOrAddString(assemblyName.Name); if (assemblyName.CultureName != null) { throw new ArgumentException("assemblyName"); } if (assemblyName.GetPublicKeyToken() != null) { throw new ArgumentException("assemblyName"); } var mvid = _metadataBuilder.ReserveGuid(); _mvidFixup = mvid.Content; _metadataBuilder.AddModule(0, assemblyNameHandle, mvid.Handle, default(GuidHandle), default(GuidHandle)); _metadataBuilder.AddAssembly(assemblyNameHandle, assemblyName.Version ?? new Version(0, 0, 0, 0), default(StringHandle), default(BlobHandle), flags, AssemblyHashAlgorithm.None); var canonAssemblyNameHandle = _metadataBuilder.GetOrAddString("System.Private.Canon"); var canonAssemblyRef = _metadataBuilder.AddAssemblyReference(canonAssemblyNameHandle, new Version(0, 0, 0, 0), default(StringHandle), default(BlobHandle), (AssemblyFlags)0, default(BlobHandle)); var systemStringHandle = _metadataBuilder.GetOrAddString("System"); var canonStringHandle = _metadataBuilder.GetOrAddString("__Canon"); var canonTypeRef = _metadataBuilder.AddTypeReference(canonAssemblyRef, systemStringHandle, canonStringHandle); _typeRefs.Add(context.CanonType, canonTypeRef); _metadataBuilder.AddTypeDefinition( default(TypeAttributes), default(StringHandle), _metadataBuilder.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); BlobBuilder noArgsNoReturnStaticMethodSig = new BlobBuilder(); BlobEncoder signatureEncoder = new BlobEncoder(noArgsNoReturnStaticMethodSig); signatureEncoder.MethodSignature(SignatureCallingConvention.Default, 0, false); noArgsNoReturnStaticMethodSig.WriteCompressedInteger(0); noArgsNoReturnStaticMethodSig.WriteByte((byte)SignatureTypeCode.Void); _noArgsVoidReturnStaticMethodSigHandle = _metadataBuilder.GetOrAddBlob(noArgsNoReturnStaticMethodSig); }
void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig, EmbeddedSignatureDataEmitter signatureDataEmitter) { signatureDataEmitter.Push(); BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); int genericParameterCount = sig.GenericParameterCount; bool isInstanceMethod = !sig.IsStatic; SignatureCallingConvention sigCallingConvention = SignatureCallingConvention.Default; switch (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) { case MethodSignatureFlags.CallingConventionVarargs: sigCallingConvention = SignatureCallingConvention.VarArgs; break; case MethodSignatureFlags.UnmanagedCallingConventionCdecl: sigCallingConvention = SignatureCallingConvention.CDecl; break; case MethodSignatureFlags.UnmanagedCallingConventionStdCall: sigCallingConvention = SignatureCallingConvention.StdCall; break; case MethodSignatureFlags.UnmanagedCallingConventionThisCall: sigCallingConvention = SignatureCallingConvention.ThisCall; break; case MethodSignatureFlags.UnmanagedCallingConvention: // [TODO] sigCallingConvention = SignatureCallingConvention.Unmanaged; sigCallingConvention = (SignatureCallingConvention)9; break; } signatureEncoder.MethodSignature(sigCallingConvention, genericParameterCount, isInstanceMethod); signatureBuilder.WriteCompressedInteger(sig.Length); EncodeType(signatureBuilder, sig.ReturnType, signatureDataEmitter); for (int i = 0; i < sig.Length; i++) { EncodeType(signatureBuilder, sig[i], signatureDataEmitter); } signatureDataEmitter.Pop(); }
private void SerializeAsyncMethodSteppingInfo(AsyncMoveNextBodyDebugInfo asyncInfo, MethodDefinitionHandle moveNextMethod) { Debug.Assert(asyncInfo.ResumeOffsets.Length == asyncInfo.YieldOffsets.Length); Debug.Assert(asyncInfo.CatchHandlerOffset >= -1); var writer = new BlobBuilder(); writer.WriteUInt32((uint)((long)asyncInfo.CatchHandlerOffset + 1)); for (int i = 0; i < asyncInfo.ResumeOffsets.Length; i++) { writer.WriteUInt32((uint)asyncInfo.YieldOffsets[i]); writer.WriteUInt32((uint)asyncInfo.ResumeOffsets[i]); writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(moveNextMethod)); } _debugMetadataOpt.AddCustomDebugInformation( parent: moveNextMethod, kind: _debugMetadataOpt.GetOrAddGuid(PortableCustomDebugInfoKinds.AsyncMethodSteppingInformationBlob), value: _debugMetadataOpt.GetOrAddBlob(writer)); }
/// <summary> /// Creates the signature for a MethodSpec from the given type arguments. /// </summary> /// <param name="typeArguments">The signatures of the type arguments used to instantiate the method.</param> /// <returns>A byte array containing the binary MethodSpec signature.</returns> private static byte[] _createSignature(ReadOnlySpan <TypeSignature> typeArguments) { int typeArgsByteLength = 0; for (int i = 0; i < typeArguments.Length; i++) { typeArgsByteLength += typeArguments[i].byteLength; } if (typeArguments.Length <= 127 && typeArgsByteLength <= 254) { Span <byte> buffer = stackalloc byte[typeArgsByteLength + 2]; buffer[0] = 0x0A; buffer[1] = (byte)typeArguments.Length; Span <byte> curSpan = buffer.Slice(2); for (int i = 0; i < typeArguments.Length; i++) { typeArguments[i].writeToSpan(curSpan); curSpan = curSpan.Slice(typeArguments[i].byteLength); } return(buffer.ToArray()); } else { var blobBuilder = new BlobBuilder(); blobBuilder.WriteByte(0x0A); blobBuilder.WriteCompressedInteger(typeArguments.Length); for (int i = 0; i < typeArguments.Length; i++) { typeArguments[i].writeToBlobBuilder(blobBuilder); } return(blobBuilder.ToArray()); } }
private BlobHandle SerializeDocumentName(string name) { Debug.Assert(name != null); int c1 = Count(name, s_separator1[0]); int c2 = Count(name, s_separator2[0]); char[] separator = (c1 >= c2) ? s_separator1 : s_separator2; // Estimate 2 bytes per part, if the blob heap gets big we expand the builder once. var writer = new BlobBuilder(1 + Math.Max(c1, c2) * 2); writer.WriteByte((byte)separator[0]); // TODO: avoid allocations foreach (var part in name.Split(separator)) { BlobHandle partIndex = GetOrAddBlob(ImmutableArray.Create(MetadataWriter.s_utf8Encoding.GetBytes(part))); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(partIndex)); } return(GetOrAddBlob(writer)); }
internal void SerializeLambdaMap(BlobBuilder writer) { Debug.Assert(this.MethodOrdinal >= -1); writer.WriteCompressedInteger(this.MethodOrdinal + 1); int syntaxOffsetBaseline = -1; foreach (ClosureDebugInfo info in this.Closures) { if (info.SyntaxOffset < syntaxOffsetBaseline) { syntaxOffsetBaseline = info.SyntaxOffset; } } foreach (LambdaDebugInfo info in this.Lambdas) { if (info.SyntaxOffset < syntaxOffsetBaseline) { syntaxOffsetBaseline = info.SyntaxOffset; } } writer.WriteCompressedInteger(-syntaxOffsetBaseline); writer.WriteCompressedInteger(this.Closures.Length); foreach (ClosureDebugInfo info in this.Closures) { writer.WriteCompressedInteger(info.SyntaxOffset - syntaxOffsetBaseline); } foreach (LambdaDebugInfo info in this.Lambdas) { Debug.Assert(info.ClosureOrdinal >= LambdaDebugInfo.MinClosureOrdinal); Debug.Assert(info.LambdaId.Generation == 0); writer.WriteCompressedInteger(info.SyntaxOffset - syntaxOffsetBaseline); writer.WriteCompressedInteger(info.ClosureOrdinal - LambdaDebugInfo.MinClosureOrdinal); } }
private void EncodeType(BlobBuilder blobBuilder, TypeDesc type) { if (type.IsPrimitive) { SignatureTypeCode primitiveCode; switch (type.Category) { case TypeFlags.Void: primitiveCode = SignatureTypeCode.Void; break; case TypeFlags.Boolean: primitiveCode = SignatureTypeCode.Boolean; break; case TypeFlags.Char: primitiveCode = SignatureTypeCode.Char; break; case TypeFlags.SByte: primitiveCode = SignatureTypeCode.SByte; break; case TypeFlags.Byte: primitiveCode = SignatureTypeCode.Byte; break; case TypeFlags.Int16: primitiveCode = SignatureTypeCode.Int16; break; case TypeFlags.UInt16: primitiveCode = SignatureTypeCode.UInt16; break; case TypeFlags.Int32: primitiveCode = SignatureTypeCode.Int32; break; case TypeFlags.UInt32: primitiveCode = SignatureTypeCode.UInt32; break; case TypeFlags.Int64: primitiveCode = SignatureTypeCode.Int64; break; case TypeFlags.UInt64: primitiveCode = SignatureTypeCode.UInt64; break; case TypeFlags.IntPtr: primitiveCode = SignatureTypeCode.IntPtr; break; case TypeFlags.UIntPtr: primitiveCode = SignatureTypeCode.UIntPtr; break; case TypeFlags.Single: primitiveCode = SignatureTypeCode.Single; break; case TypeFlags.Double: primitiveCode = SignatureTypeCode.Double; break; default: throw new Exception("Unknown primitive type"); } blobBuilder.WriteByte((byte)primitiveCode); } else if (type.IsSzArray) { blobBuilder.WriteByte((byte)SignatureTypeCode.SZArray); EncodeType(blobBuilder, type.GetParameterType()); } else if (type.IsArray) { var arrayType = (ArrayType)type; blobBuilder.WriteByte((byte)SignatureTypeCode.Array); EncodeType(blobBuilder, type.GetParameterType()); var shapeEncoder = new ArrayShapeEncoder(blobBuilder); // TODO Add support for non-standard array shapes shapeEncoder.Shape(arrayType.Rank, default(ImmutableArray <int>), default(ImmutableArray <int>)); } else if (type.IsPointer) { blobBuilder.WriteByte((byte)SignatureTypeCode.Pointer); EncodeType(blobBuilder, type.GetParameterType()); } else if (type.IsFunctionPointer) { FunctionPointerType fnptrType = (FunctionPointerType)type; EncodeMethodSignature(blobBuilder, fnptrType.Signature); } else if (type.IsByRef) { blobBuilder.WriteByte((byte)SignatureTypeCode.ByReference); EncodeType(blobBuilder, type.GetParameterType()); } else if (type.IsObject) { blobBuilder.WriteByte((byte)SignatureTypeCode.Object); } else if (type.IsString) { blobBuilder.WriteByte((byte)SignatureTypeCode.String); } else if (type.IsWellKnownType(WellKnownType.TypedReference)) { blobBuilder.WriteByte((byte)SignatureTypeCode.TypedReference); } else if (type.IsWellKnownType(WellKnownType.Void)) { blobBuilder.WriteByte((byte)SignatureTypeCode.Void); } else if (type is SignatureVariable) { SignatureVariable sigVar = (SignatureVariable)type; SignatureTypeCode code = sigVar.IsMethodSignatureVariable ? SignatureTypeCode.GenericMethodParameter : SignatureTypeCode.GenericTypeParameter; blobBuilder.WriteByte((byte)code); blobBuilder.WriteCompressedInteger(sigVar.Index); } else if (type is InstantiatedType) { blobBuilder.WriteByte((byte)SignatureTypeCode.GenericTypeInstance); EncodeType(blobBuilder, type.GetTypeDefinition()); blobBuilder.WriteCompressedInteger(type.Instantiation.Length); foreach (var instantiationArg in type.Instantiation) { EncodeType(blobBuilder, instantiationArg); } } else if (type is MetadataType) { var metadataType = (MetadataType)type; // Must be class or valuetype blobBuilder.WriteByte(type.IsValueType ? (byte)SignatureTypeKind.ValueType : (byte)SignatureTypeKind.Class); int codedIndex = CodedIndex.TypeDefOrRef(GetTypeRef(metadataType)); blobBuilder.WriteCompressedInteger(codedIndex); } else { throw new Exception("Unexpected type"); } }
public UserStringHandle GetUserString(string str) { int index; if (!_userStrings.TryGetValue(str, out index)) { Debug.Assert(!_streamsAreComplete); index = _userStringWriter.Position + _userStringHeapStartOffset; _userStrings.Add(str, index); _userStringWriter.WriteCompressedInteger(str.Length * 2 + 1); _userStringWriter.WriteUTF16(str); // Write out a trailing byte indicating if the string is really quite simple byte stringKind = 0; foreach (char ch in str) { if (ch >= 0x7F) { stringKind = 1; } else { switch ((int)ch) { case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: case 0x8: case 0xE: case 0xF: case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F: case 0x27: case 0x2D: stringKind = 1; break; default: continue; } } break; } _userStringWriter.WriteByte(stringKind); } return(MetadataTokens.UserStringHandle(index)); }
private static BlobHandle SerializeSequencePoints( MetadataBuilder metadataBuilder, int localSignatureRowId, ImmutableArray <SymUnmanagedSequencePoint> sequencePoints, Dictionary <string, DocumentHandle> documentIndex, out DocumentHandle singleDocumentHandle) { if (sequencePoints.Length == 0) { singleDocumentHandle = default(DocumentHandle); return(default(BlobHandle)); } var writer = new BlobBuilder(); int previousNonHiddenStartLine = -1; int previousNonHiddenStartColumn = -1; // header: writer.WriteCompressedInteger(localSignatureRowId); DocumentHandle previousDocument = TryGetSingleDocument(sequencePoints, documentIndex); singleDocumentHandle = previousDocument; for (int i = 0; i < sequencePoints.Length; i++) { var currentDocument = documentIndex[sequencePoints[i].Document.GetName()]; if (previousDocument != currentDocument) { // optional document in header or document record: if (!previousDocument.IsNil) { writer.WriteCompressedInteger(0); } writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(currentDocument)); previousDocument = currentDocument; } // delta IL offset: if (i > 0) { writer.WriteCompressedInteger((sequencePoints[i].Offset - sequencePoints[i - 1].Offset)); } else { writer.WriteCompressedInteger(sequencePoints[i].Offset); } if (sequencePoints[i].IsHidden) { writer.WriteInt16(0); continue; } // Delta Lines & Columns: SerializeDeltaLinesAndColumns(writer, sequencePoints[i]); // delta Start Lines & Columns: if (previousNonHiddenStartLine < 0) { Debug.Assert(previousNonHiddenStartColumn < 0); writer.WriteCompressedInteger(sequencePoints[i].StartLine); writer.WriteCompressedInteger(sequencePoints[i].StartColumn); } else { writer.WriteCompressedSignedInteger(sequencePoints[i].StartLine - previousNonHiddenStartLine); writer.WriteCompressedSignedInteger(sequencePoints[i].StartColumn - previousNonHiddenStartColumn); } previousNonHiddenStartLine = sequencePoints[i].StartLine; previousNonHiddenStartColumn = sequencePoints[i].StartColumn; } return(metadataBuilder.GetOrAddBlob(writer)); }
public static ReadyToRunStandaloneMethodMetadata Compute(EcmaMethod wrappedMethod) { var metadataReader = wrappedMethod.MetadataReader; var _module = wrappedMethod.Module; var rva = wrappedMethod.MetadataReader.GetMethodDefinition(wrappedMethod.Handle).RelativeVirtualAddress; var _methodBody = _module.PEReader.GetMethodBody(rva); byte[] _alternateILStream = _methodBody.GetILBytes(); var exceptionRegions = _methodBody.ExceptionRegions; ILExceptionRegion[] _exceptionRegions; int length = exceptionRegions.Length; if (length == 0) { _exceptionRegions = Array.Empty <ILExceptionRegion>(); } else { _exceptionRegions = new ILExceptionRegion[length]; for (int i = 0; i < length; i++) { var exceptionRegion = exceptionRegions[i]; _exceptionRegions[i] = new ILExceptionRegion( (ILExceptionRegionKind)exceptionRegion.Kind, // assumes that ILExceptionRegionKind and ExceptionRegionKind enums are in sync exceptionRegion.TryOffset, exceptionRegion.TryLength, exceptionRegion.HandlerOffset, exceptionRegion.HandlerLength, MetadataTokens.GetToken(exceptionRegion.CatchType), exceptionRegion.FilterOffset); } } BlobReader localsBlob = default(BlobReader); if (!_methodBody.LocalSignature.IsNil) { localsBlob = wrappedMethod.MetadataReader.GetBlobReader(wrappedMethod.MetadataReader.GetStandaloneSignature(_methodBody.LocalSignature).Signature); } AlternativeTypeRefProvider alternateTypes = new AlternativeTypeRefProvider(); EcmaSignatureEncoder <AlternativeTypeRefProvider> alternateEncoder = new EcmaSignatureEncoder <AlternativeTypeRefProvider>(alternateTypes); Dictionary <int, int> _alternateNonTokenStrings = new Dictionary <int, int>(); BlobBuilder _alternateNonTypeRefStream = new BlobBuilder(); BlobBuilder _nonCodeAlternateBlob = new BlobBuilder(); { // Generate alternate stream for exceptions. _nonCodeAlternateBlob.WriteCompressedInteger(_exceptionRegions.Length); for (int i = 0; i < _exceptionRegions.Length; i++) { var region = _exceptionRegions[i]; _nonCodeAlternateBlob.WriteCompressedInteger((int)region.Kind); _nonCodeAlternateBlob.WriteCompressedInteger((int)region.TryOffset); _nonCodeAlternateBlob.WriteCompressedInteger((int)region.TryLength); _nonCodeAlternateBlob.WriteCompressedInteger((int)region.HandlerOffset); _nonCodeAlternateBlob.WriteCompressedInteger((int)region.HandlerLength); if (region.Kind == ILExceptionRegionKind.Catch) { int alternateToken = GetAlternateStreamToken(region.ClassToken); int encodedToken = CodedIndex.TypeDefOrRefOrSpec(MetadataTokens.EntityHandle(alternateToken)); _nonCodeAlternateBlob.WriteCompressedInteger(encodedToken); } else if (region.Kind == ILExceptionRegionKind.Filter) { _nonCodeAlternateBlob.WriteCompressedInteger(region.FilterOffset); } } if (localsBlob.Length == 0) { // No locals. Encode a 2 to indicate this _nonCodeAlternateBlob.WriteByte(2); } else { _nonCodeAlternateBlob.WriteByte(_methodBody.LocalVariablesInitialized ? (byte)1 : (byte)0); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(localsBlob, _nonCodeAlternateBlob, GetAlternateStreamToken); sigTranslator.ParseLocalsSignature(); } } ILTokenReplacer.Replace(_alternateILStream, GetAlternateStreamToken); // Add all the streams together into the _nonCodeAlternateBlob int expectedFinalSize = _nonCodeAlternateBlob.Count + _alternateILStream.Length + _alternateNonTypeRefStream.Count; _nonCodeAlternateBlob.WriteBytes(_alternateILStream); _nonCodeAlternateBlob.LinkSuffix(_alternateNonTypeRefStream); Debug.Assert(expectedFinalSize == _nonCodeAlternateBlob.Count); ReadyToRunStandaloneMethodMetadata methodBlock = new ReadyToRunStandaloneMethodMetadata(); methodBlock.ConstantData = _nonCodeAlternateBlob.ToArray(); methodBlock.TypeRefs = alternateTypes._alternateTypeRefStream.ToArray(); return(methodBlock); ///// HELPER FUNCTIONS unsafe int GetAlternateStreamToken(int token) { if (token == 0 || !_alternateNonTokenStrings.TryGetValue(token, out int alternateToken)) { var handle = MetadataTokens.Handle(token); if (handle.Kind == HandleKind.TypeDefinition || handle.Kind == HandleKind.TypeReference) { EcmaType ecmaType = (EcmaType)wrappedMethod.Module.GetObject(MetadataTokens.EntityHandle(token)); alternateToken = MetadataTokens.GetToken(alternateTypes.GetTypeDefOrRefHandleForTypeDesc(ecmaType)); } else { BlobBuilder blob = new BlobBuilder(); int flag = 0; if (handle.Kind == HandleKind.UserString) { string strAlternate = metadataReader.GetUserString((UserStringHandle)handle); flag = 0x70000000; blob.WriteCompressedInteger(strAlternate.Length); fixed(char *charData = strAlternate) { blob.WriteBytes((byte *)charData, strAlternate.Length * 2); } // TODO: consider encoding via wtf-8, or possibly utf-8 } else if (handle.Kind == HandleKind.TypeSpecification) { flag = 0x1B000000; var sigBlob = metadataReader.GetBlobReader(metadataReader.GetTypeSpecification((TypeSpecificationHandle)handle).Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseType(); } else if (handle.Kind == HandleKind.MemberReference) { flag = 0x0a000000; var memberReference = metadataReader.GetMemberReference((MemberReferenceHandle)handle); var sigBlob = metadataReader.GetBlobReader(memberReference.Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseMemberRefSignature(); blob.WriteSerializedString(metadataReader.GetString(memberReference.Name)); blob.WriteCompressedInteger(CodedIndex.MemberRefParent(MetadataTokens.EntityHandle(GetAlternateStreamToken(MetadataTokens.GetToken(memberReference.Parent))))); } else if (handle.Kind == HandleKind.MethodDefinition) { flag = 0x0a000000; var methodDefinition = metadataReader.GetMethodDefinition((MethodDefinitionHandle)handle); var sigBlob = metadataReader.GetBlobReader(methodDefinition.Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseMethodSignature(); blob.WriteSerializedString(metadataReader.GetString(methodDefinition.Name)); blob.WriteCompressedInteger(CodedIndex.MemberRefParent(MetadataTokens.EntityHandle(GetAlternateStreamToken(MetadataTokens.GetToken(methodDefinition.GetDeclaringType()))))); } else if (handle.Kind == HandleKind.FieldDefinition) { flag = 0x0a000000; var fieldDefinition = metadataReader.GetFieldDefinition((FieldDefinitionHandle)handle); var sigBlob = metadataReader.GetBlobReader(fieldDefinition.Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseFieldSignature(); blob.WriteSerializedString(metadataReader.GetString(fieldDefinition.Name)); blob.WriteCompressedInteger(CodedIndex.MemberRefParent(MetadataTokens.EntityHandle(GetAlternateStreamToken(MetadataTokens.GetToken(fieldDefinition.GetDeclaringType()))))); } else if (handle.Kind == HandleKind.MethodSpecification) { flag = 0x2B000000; var methodSpecification = metadataReader.GetMethodSpecification((MethodSpecificationHandle)handle); var sigBlob = metadataReader.GetBlobReader(methodSpecification.Signature); blob.WriteCompressedInteger(MetadataTokens.GetRowNumber(MetadataTokens.EntityHandle(GetAlternateStreamToken(MetadataTokens.GetToken(methodSpecification.Method))))); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseMethodSpecSignature(); } else if (handle.Kind == HandleKind.StandaloneSignature) { flag = 0x11000000; var reader = wrappedMethod.Module.MetadataReader; var sigBlob = reader.GetBlobReader(reader.GetStandaloneSignature((StandaloneSignatureHandle)handle).Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseMethodSignature(); } _alternateNonTypeRefStream.WriteBytes(blob.ToArray()); alternateToken = (_alternateNonTokenStrings.Count + 1) | flag; } _alternateNonTokenStrings.Add(token, alternateToken); } return(alternateToken); } }
public unsafe static void Convert(BlobBuilder builder, MetadataModel metadataModel, byte[] signature, object value) { fixed(byte *sigPtr = signature) { var sigReader = new BlobReader(sigPtr, signature.Length); // copy custom modifiers over: byte rawTypeCode; while (true) { rawTypeCode = sigReader.ReadByte(); if (rawTypeCode != (int)SignatureTypeCode.OptionalModifier && rawTypeCode != (int)SignatureTypeCode.RequiredModifier) { break; } builder.WriteByte(rawTypeCode); builder.WriteCompressedInteger(sigReader.ReadCompressedInteger()); } switch ((SignatureTypeCode)rawTypeCode) { case (SignatureTypeCode)SignatureTypeKind.Class: case (SignatureTypeCode)SignatureTypeKind.ValueType: int typeRefDefSpec = sigReader.ReadCompressedInteger(); if (value is decimal) { // GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <decimal> builder.WriteByte((byte)SignatureTypeKind.ValueType); builder.WriteCompressedInteger(typeRefDefSpec); builder.WriteDecimal((decimal)value); } else if (value is DateTime) { // GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <date-time> builder.WriteByte((byte)SignatureTypeKind.ValueType); builder.WriteCompressedInteger(typeRefDefSpec); builder.WriteDateTime((DateTime)value); } else if (value == null) { // GeneralConstant: CLASS TypeDefOrRefOrSpecEncoded builder.WriteByte(rawTypeCode); builder.WriteCompressedInteger(typeRefDefSpec); } else { // EnumConstant ::= EnumTypeCode EnumValue EnumType // EnumTypeCode ::= BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 // EnumType ::= TypeDefOrRefOrSpecEncoded var enumTypeCode = MetadataHelpers.GetConstantTypeCode(value); builder.WriteByte((byte)enumTypeCode); builder.WriteConstant(value); builder.WriteCompressedInteger(typeRefDefSpec); } break; case SignatureTypeCode.Object: // null: Debug.Assert(value == null); builder.WriteByte((byte)SignatureTypeCode.Object); break; case SignatureTypeCode.Boolean: case SignatureTypeCode.Char: case SignatureTypeCode.SByte: case SignatureTypeCode.Byte: case SignatureTypeCode.Int16: case SignatureTypeCode.UInt16: case SignatureTypeCode.Int32: case SignatureTypeCode.UInt32: case SignatureTypeCode.Int64: case SignatureTypeCode.UInt64: case SignatureTypeCode.Single: case SignatureTypeCode.Double: case SignatureTypeCode.String: // PrimitiveConstant builder.WriteByte(rawTypeCode); builder.WriteConstant(value); break; case SignatureTypeCode.SZArray: case SignatureTypeCode.Array: case SignatureTypeCode.GenericTypeInstance: Debug.Assert(value == null); // Find an existing TypeSpec in metadata. // If there isn't one we can't represent the constant type in the Portable PDB, use Object. // +1/-1 for the type code we already read. var spec = new byte[sigReader.RemainingBytes + 1]; Buffer.BlockCopy(signature, sigReader.Offset - 1, spec, 0, spec.Length); TypeSpecificationHandle typeSpec; if (metadataModel.TryResolveTypeSpecification(spec, out typeSpec)) { builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(typeSpec)); } else { // TODO: warning - can't translate const type builder.WriteByte((byte)SignatureTypeCode.Object); } break; case SignatureTypeCode.GenericMethodParameter: case SignatureTypeCode.GenericTypeParameter: case SignatureTypeCode.FunctionPointer: case SignatureTypeCode.Pointer: // generic parameters, pointers are not valid types for constants: throw new BadImageFormatException(); } } }
private BlobHandle SerializeDocumentName(string name) { Debug.Assert(name != null); int c1 = Count(name, s_separator1[0]); int c2 = Count(name, s_separator2[0]); char[] separator = (c1 >= c2) ? s_separator1 : s_separator2; // Estimate 2 bytes per part, if the blob heap gets big we expand the builder once. var writer = new BlobBuilder(1 + Math.Max(c1, c2) * 2); writer.WriteByte((byte)separator[0]); // TODO: avoid allocations foreach (var part in name.Split(separator)) { BlobHandle partIndex = GetOrAddBlob(ImmutableArray.Create(MetadataWriter.s_utf8Encoding.GetBytes(part))); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(partIndex)); } return GetOrAddBlob(writer); }
private BlobHandle SerializeSpans( ImmutableArray<SourceSpan> spans, Dictionary<DebugSourceDocument, int> documentIndex) { if (spans.Length == 0) { return default(BlobHandle); } // 4 bytes per span plus a header, the builder expands by the same amount. var writer = new BlobBuilder(4 + spans.Length * 4); int previousStartLine = -1; int previousStartColumn = -1; DebugSourceDocument previousDocument = spans[0].Document; // header: writer.WriteCompressedInteger(GetOrAddDocument(previousDocument, documentIndex)); for (int i = 0; i < spans.Length; i++) { var currentDocument = spans[i].Document; if (previousDocument != currentDocument) { writer.WriteInt16(0); writer.WriteCompressedInteger(GetOrAddDocument(currentDocument, documentIndex)); previousDocument = currentDocument; } // Delta Lines & Columns: SerializeDeltaLinesAndColumns(writer, spans[i]); // delta Start Lines & Columns: if (previousStartLine < 0) { Debug.Assert(previousStartColumn < 0); writer.WriteCompressedInteger(spans[i].StartLine); writer.WriteCompressedInteger(spans[i].StartColumn); } else { writer.WriteCompressedSignedInteger(spans[i].StartLine - previousStartLine); writer.WriteCompressedSignedInteger(spans[i].StartColumn - previousStartColumn); } previousStartLine = spans[i].StartLine; previousStartColumn = spans[i].StartColumn; } return GetOrAddBlob(writer); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } ObjectDataBuilder objDataBuilder = new ObjectDataBuilder(factory, relocsOnly); // Emit number of dictionaries in table objDataBuilder.AddSymbol(this); IReadOnlyCollection <GenericDictionaryNode> dictionariesEmitted = factory.MetadataManager.GetCompiledGenericDictionaries(); objDataBuilder.EmitInt(dictionariesEmitted.Count); DebugInfoBlob signatureData = new DebugInfoBlob(); BlobBuilder signatureBlobBuilder = new BlobBuilder(); BlobBuilder signatureLenBuilder = new BlobBuilder(); ManagedBinaryEmitter pseudoAssembly = factory.WindowsDebugData.DebugPseudoAssemblySection.PseudoAssembly; foreach (GenericDictionaryNode dictionary in dictionariesEmitted) { objDataBuilder.EmitReloc(dictionary, RelocType.IMAGE_REL_BASED_ADDR32NB); objDataBuilder.EmitUInt(signatureData.Size()); signatureBlobBuilder.Clear(); int typeDictLen = dictionary.TypeInstantiation.IsNull ? 0 : dictionary.TypeInstantiation.Length; int methodDictLen = dictionary.MethodInstantiation.IsNull ? 0 : dictionary.MethodInstantiation.Length; signatureBlobBuilder.WriteCompressedInteger(typeDictLen + methodDictLen); if (typeDictLen != 0) { foreach (TypeDesc type in dictionary.TypeInstantiation) { pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder); } } if (methodDictLen != 0) { foreach (TypeDesc type in dictionary.MethodInstantiation) { pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder); } } int blobSize = signatureBlobBuilder.Count; signatureLenBuilder.Clear(); signatureLenBuilder.WriteCompressedInteger(blobSize); // Prepend the signature data with a length signatureData.WriteBuffer(signatureLenBuilder); // And then attach the actual signature data signatureData.WriteBuffer(signatureBlobBuilder); } // Attach signature information to end after all of the rva/offset pairs objDataBuilder.EmitBytes(signatureData.ToArray()); return(objDataBuilder.ToObjectData()); }
public void CompressUnsignedIntegersFromSpecExamples() { // These examples are straight from the CLI spec. TestCompressedUnsignedInteger(new byte[] { 0x00 }, 0); TestCompressedUnsignedInteger(new byte[] { 0x03 }, 0x03); TestCompressedUnsignedInteger(new byte[] { 0x7f }, 0x7F); TestCompressedUnsignedInteger(new byte[] { 0x80, 0x80 }, 0x80); TestCompressedUnsignedInteger(new byte[] { 0xAE, 0x57 }, 0x2E57); TestCompressedUnsignedInteger(new byte[] { 0xBF, 0xFF }, 0x3FFF); TestCompressedUnsignedInteger(new byte[] { 0xC0, 0x00, 0x40, 0x00 }, 0x4000); TestCompressedUnsignedInteger(new byte[] { 0xDF, 0xFF, 0xFF, 0xFF }, 0x1FFFFFFF); var writer = new BlobWriter(4); var builder = new BlobBuilder(); Assert.Throws<ArgumentOutOfRangeException>(() => writer.WriteCompressedInteger(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => writer.WriteCompressedInteger(BlobWriterImpl.MaxCompressedIntegerValue + 1)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteCompressedInteger(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteCompressedInteger(BlobWriterImpl.MaxCompressedIntegerValue + 1)); }