/// <summary> /// Encodes a method body and adds it to the method body stream. /// </summary> /// <param name="codeSize">Number of bytes to be reserved for instructions.</param> /// <param name="maxStack">Max stack.</param> /// <param name="exceptionRegionCount">Number of exception regions.</param> /// <param name="hasSmallExceptionRegions">True if the exception regions should be encoded in 'small' format.</param> /// <param name="localVariablesSignature">Local variables signature handle.</param> /// <param name="attributes">Attributes.</param> /// <returns>The offset of the encoded body within the method body stream.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="codeSize"/>, <paramref name="exceptionRegionCount"/>, or <paramref name="maxStack"/> is out of allowed range. /// </exception> public MethodBody AddMethodBody( int codeSize, int maxStack = 8, int exceptionRegionCount = 0, bool hasSmallExceptionRegions = true, StandaloneSignatureHandle localVariablesSignature = default(StandaloneSignatureHandle), MethodBodyAttributes attributes = MethodBodyAttributes.InitLocals) { if (codeSize < 0) { Throw.ArgumentOutOfRange(nameof(codeSize)); } if (unchecked((uint)maxStack) > ushort.MaxValue) { Throw.ArgumentOutOfRange(nameof(maxStack)); } if (!ExceptionRegionEncoder.IsExceptionRegionCountInBounds(exceptionRegionCount)) { Throw.ArgumentOutOfRange(nameof(exceptionRegionCount)); } int bodyOffset = SerializeHeader(codeSize, (ushort)maxStack, exceptionRegionCount, attributes, localVariablesSignature); var instructions = Builder.ReserveBytes(codeSize); var regionEncoder = (exceptionRegionCount > 0) ? ExceptionRegionEncoder.SerializeTableHeader(Builder, exceptionRegionCount, hasSmallExceptionRegions) : default(ExceptionRegionEncoder); return new MethodBody(bodyOffset, instructions, regionEncoder); }
internal StandaloneSignature(MetadataReader reader, StandaloneSignatureHandle handle) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(!handle.IsNil); this.reader = reader; this.rowId = handle.RowId; }
internal MethodBodyEncoder( BlobBuilder builder, ushort maxStack, int exceptionRegionCount, StandaloneSignatureHandle localVariablesSignature, MethodBodyAttributes attributes) { Builder = builder; _maxStack = maxStack; _localVariablesSignature = localVariablesSignature; _attributes = (byte)attributes; _exceptionRegionCount = exceptionRegionCount; }
private MethodBodyBlock( bool localVariablesInitialized, ushort maxStack, StandaloneSignatureHandle localSignatureHandle, MemoryBlock il, ImmutableArray<ExceptionRegion> exceptionRegions, int size) { Debug.Assert(!exceptionRegions.IsDefault); this.localVariablesInitialized = localVariablesInitialized; this.maxStack = maxStack; this.localSignature = localSignatureHandle; this.il = il; this.exceptionRegions = exceptionRegions; this.size = size; }
public MethodBodyEncoder AddMethodBody( int maxStack = 8, int exceptionRegionCount = 0, StandaloneSignatureHandle localVariablesSignature = default(StandaloneSignatureHandle), MethodBodyAttributes attributes = MethodBodyAttributes.InitLocals) { if (unchecked((ushort)maxStack) > ushort.MaxValue) { throw new ArgumentOutOfRangeException(nameof(maxStack)); } if (exceptionRegionCount < 0) { throw new ArgumentOutOfRangeException(nameof(exceptionRegionCount)); } return new MethodBodyEncoder(Builder, (ushort)maxStack, exceptionRegionCount, localVariablesSignature, attributes); }
private void SerializeMethodDebugInfo(IMethodBody bodyOpt, int methodRid, int aggregateMethodRid, StandaloneSignatureHandle localSignatureHandleOpt, ref LocalVariableHandle lastLocalVariableHandle, ref LocalConstantHandle lastLocalConstantHandle) { if (bodyOpt == null) { _debugMetadataOpt.AddMethodDebugInformation(document: default, sequencePoints: default);
private void DefineLocalScopes(ImmutableArray<LocalScope> scopes, StandaloneSignatureHandle localSignatureHandleOpt) { // VB scope ranges are end-inclusive bool endInclusive = this.Module.GenerateVisualBasicStylePdb; // The order of OpenScope and CloseScope calls must follow the scope nesting. var scopeStack = ArrayBuilder<LocalScope>.GetInstance(); for (int i = 1; i < scopes.Length; i++) { var currentScope = scopes[i]; // Close any scopes that have finished. while (scopeStack.Count > 0) { LocalScope topScope = scopeStack.Last(); if (currentScope.StartOffset < topScope.StartOffset + topScope.Length) { break; } scopeStack.RemoveLast(); CloseScope(endInclusive ? topScope.EndOffset - 1 : topScope.EndOffset); } // Open this scope. scopeStack.Add(currentScope); OpenScope(currentScope.StartOffset); this.DefineScopeLocals(currentScope, localSignatureHandleOpt); } // Close remaining scopes. for (int i = scopeStack.Count - 1; i >= 0; i--) { LocalScope scope = scopeStack[i]; CloseScope(endInclusive ? scope.EndOffset - 1 : scope.EndOffset); } scopeStack.Free(); }
private void DefineLocalVariable(uint index, string name, LocalVariableAttributes attributes, StandaloneSignatureHandle localSignatureHandleOpt) { uint localSignatureToken = localSignatureHandleOpt.IsNil ? 0 : (uint)MetadataTokens.GetToken(localSignatureHandleOpt); const uint ADDR_IL_OFFSET = 1; try { _symWriter.DefineLocalVariable2(name, (uint)attributes, localSignatureToken, ADDR_IL_OFFSET, index, 0, 0, 0, 0); if (_callLogger.LogOperation(OP.DefineLocalVariable2)) { _callLogger.LogArgument(name); _callLogger.LogArgument((uint)attributes); _callLogger.LogArgument(localSignatureToken); _callLogger.LogArgument(ADDR_IL_OFFSET); _callLogger.LogArgument(index); _callLogger.LogArgument((uint)0); _callLogger.LogArgument((uint)0); _callLogger.LogArgument((uint)0); _callLogger.LogArgument((uint)0); } } catch (Exception ex) { throw new PdbWritingException(ex); } }
protected abstract ImmutableArray <EncLocalInfo> GetLocalSlotMapFromMetadata(StandaloneSignatureHandle handle, EditAndContinueMethodDebugInformation debugInfo);
private int SerializeHeader(int codeSize, ushort maxStack, int exceptionRegionCount, MethodBodyAttributes attributes, StandaloneSignatureHandle localVariablesSignature) { const int TinyFormat = 2; const int FatFormat = 3; const int MoreSections = 8; const byte InitLocals = 0x10; int offset; bool isTiny = codeSize < 64 && maxStack <= 8 && localVariablesSignature.IsNil && exceptionRegionCount == 0; if (isTiny) { offset = Builder.Count; Builder.WriteByte((byte)((codeSize << 2) | TinyFormat)); } else { Builder.Align(4); offset = Builder.Count; ushort flags = (3 << 12) | FatFormat; if (exceptionRegionCount > 0) { flags |= MoreSections; } if ((attributes & MethodBodyAttributes.InitLocals) != 0) { flags |= InitLocals; } Builder.WriteUInt16((ushort)((int)attributes | flags)); Builder.WriteUInt16(maxStack); Builder.WriteInt32(codeSize); Builder.WriteInt32(localVariablesSignature.IsNil ? 0 : MetadataTokens.GetToken(localVariablesSignature)); } return(offset); }
private BlobHandle SerializeSequencePoints( StandaloneSignatureHandle localSignatureHandleOpt, ImmutableArray <SequencePoint> sequencePoints, Dictionary <DebugSourceDocument, 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(MetadataTokens.GetRowNumber(localSignatureHandleOpt)); var previousDocument = TryGetSingleDocument(sequencePoints); singleDocumentHandle = (previousDocument != null) ? GetOrAddDocument(previousDocument, documentIndex) : default(DocumentHandle); for (int i = 0; i < sequencePoints.Length; i++) { var currentDocument = sequencePoints[i].Document; if (previousDocument != currentDocument) { var documentHandle = GetOrAddDocument(currentDocument, documentIndex); // optional document in header or document record: if (previousDocument != null) { writer.WriteCompressedInteger(0); } writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(documentHandle)); 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(_debugMetadataOpt.GetOrAddBlob(writer)); }
private void SerializeMethodDebugInfo(IMethodBody bodyOpt, int methodRid, StandaloneSignatureHandle localSignatureHandleOpt, ref LocalVariableHandle lastLocalVariableHandle, ref LocalConstantHandle lastLocalConstantHandle) { if (bodyOpt == null) { _debugMetadataOpt.AddMethodDebugInformation(default(DocumentHandle), default(BlobHandle)); return; } bool isKickoffMethod = bodyOpt.StateMachineTypeName != null; bool emitDebugInfo = isKickoffMethod || !bodyOpt.SequencePoints.IsEmpty; if (!emitDebugInfo) { _debugMetadataOpt.AddMethodDebugInformation(default(DocumentHandle), default(BlobHandle)); return; } var methodHandle = MetadataTokens.MethodDefinitionHandle(methodRid); var bodyImportScope = bodyOpt.ImportScope; var importScopeHandle = (bodyImportScope != null) ? GetImportScopeIndex(bodyImportScope, _scopeIndex) : default(ImportScopeHandle); // documents & sequence points: DocumentHandle singleDocumentHandle; BlobHandle sequencePointsBlob = SerializeSequencePoints(localSignatureHandleOpt, bodyOpt.SequencePoints, _documentIndex, out singleDocumentHandle); _debugMetadataOpt.AddMethodDebugInformation(document: singleDocumentHandle, sequencePoints: sequencePointsBlob); // Unlike native PDB we don't emit an empty root scope. // scopes are already ordered by StartOffset ascending then by EndOffset descending (the longest scope first). if (bodyOpt.LocalScopes.Length == 0) { // TODO: the compiler should produce a scope for each debuggable method _debugMetadataOpt.AddLocalScope( method: methodHandle, importScope: importScopeHandle, variableList: NextHandle(lastLocalVariableHandle), constantList: NextHandle(lastLocalConstantHandle), startOffset: 0, length: bodyOpt.IL.Length); } else { foreach (LocalScope scope in bodyOpt.LocalScopes) { _debugMetadataOpt.AddLocalScope( method: methodHandle, importScope: importScopeHandle, variableList: NextHandle(lastLocalVariableHandle), constantList: NextHandle(lastLocalConstantHandle), startOffset: scope.StartOffset, length: scope.Length); foreach (ILocalDefinition local in scope.Variables) { Debug.Assert(local.SlotIndex >= 0); lastLocalVariableHandle = _debugMetadataOpt.AddLocalVariable( attributes: local.PdbAttributes, index: local.SlotIndex, name: _debugMetadataOpt.GetOrAddString(local.Name)); SerializeLocalInfo(local, lastLocalVariableHandle); } foreach (ILocalDefinition constant in scope.Constants) { var mdConstant = constant.CompileTimeValue; Debug.Assert(mdConstant != null); lastLocalConstantHandle = _debugMetadataOpt.AddLocalConstant( name: _debugMetadataOpt.GetOrAddString(constant.Name), signature: SerializeLocalConstantSignature(constant)); SerializeLocalInfo(constant, lastLocalConstantHandle); } } } var moveNextBodyInfo = bodyOpt.MoveNextBodyInfo; if (moveNextBodyInfo != null) { _debugMetadataOpt.AddStateMachineMethod( moveNextMethod: methodHandle, kickoffMethod: GetMethodDefinitionHandle(moveNextBodyInfo.KickoffMethod)); if (moveNextBodyInfo is AsyncMoveNextBodyDebugInfo asyncInfo) { SerializeAsyncMethodSteppingInfo(asyncInfo, methodHandle); } } SerializeStateMachineLocalScopes(bodyOpt, methodHandle); // delta doesn't need this information - we use information recorded by previous generation emit if (Context.Module.CommonCompilation.Options.EnableEditAndContinue && IsFullMetadata) { SerializeEncMethodDebugInformation(bodyOpt, methodHandle); } }
private BlobHandle GetLocalSignature(StandaloneSignatureHandle handle) { return(Get(handle, (reader, h) => reader.GetStandaloneSignature((StandaloneSignatureHandle)h).Signature)); }
public void IsNil() { Assert.False(ModuleDefinitionHandle.FromRowId(1).IsNil); Assert.False(AssemblyDefinitionHandle.FromRowId(1).IsNil); Assert.False(InterfaceImplementationHandle.FromRowId(1).IsNil); Assert.False(MethodDefinitionHandle.FromRowId(1).IsNil); Assert.False(MethodSpecificationHandle.FromRowId(1).IsNil); Assert.False(TypeDefinitionHandle.FromRowId(1).IsNil); Assert.False(ExportedTypeHandle.FromRowId(1).IsNil); Assert.False(TypeReferenceHandle.FromRowId(1).IsNil); Assert.False(TypeSpecificationHandle.FromRowId(1).IsNil); Assert.False(MemberReferenceHandle.FromRowId(1).IsNil); Assert.False(FieldDefinitionHandle.FromRowId(1).IsNil); Assert.False(EventDefinitionHandle.FromRowId(1).IsNil); Assert.False(PropertyDefinitionHandle.FromRowId(1).IsNil); Assert.False(StandaloneSignatureHandle.FromRowId(1).IsNil); Assert.False(MemberReferenceHandle.FromRowId(1).IsNil); Assert.False(FieldDefinitionHandle.FromRowId(1).IsNil); Assert.False(EventDefinitionHandle.FromRowId(1).IsNil); Assert.False(PropertyDefinitionHandle.FromRowId(1).IsNil); Assert.False(ParameterHandle.FromRowId(1).IsNil); Assert.False(GenericParameterHandle.FromRowId(1).IsNil); Assert.False(GenericParameterConstraintHandle.FromRowId(1).IsNil); Assert.False(ModuleReferenceHandle.FromRowId(1).IsNil); Assert.False(CustomAttributeHandle.FromRowId(1).IsNil); Assert.False(DeclarativeSecurityAttributeHandle.FromRowId(1).IsNil); Assert.False(ManifestResourceHandle.FromRowId(1).IsNil); Assert.False(ConstantHandle.FromRowId(1).IsNil); Assert.False(ManifestResourceHandle.FromRowId(1).IsNil); Assert.False(AssemblyFileHandle.FromRowId(1).IsNil); Assert.False(MethodImplementationHandle.FromRowId(1).IsNil); Assert.False(AssemblyReferenceHandle.FromRowId(1).IsNil); Assert.False(((EntityHandle)ModuleDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)AssemblyDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)InterfaceImplementationHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)MethodDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)MethodSpecificationHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)TypeDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)ExportedTypeHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)TypeReferenceHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)TypeSpecificationHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)MemberReferenceHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)FieldDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)EventDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)PropertyDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)StandaloneSignatureHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)MemberReferenceHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)FieldDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)EventDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)PropertyDefinitionHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)ParameterHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)GenericParameterHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)GenericParameterConstraintHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)ModuleReferenceHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)CustomAttributeHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)DeclarativeSecurityAttributeHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)ManifestResourceHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)ConstantHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)ManifestResourceHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)AssemblyFileHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)MethodImplementationHandle.FromRowId(1)).IsNil); Assert.False(((EntityHandle)AssemblyReferenceHandle.FromRowId(1)).IsNil); Assert.False(StringHandle.FromOffset(1).IsNil); Assert.False(BlobHandle.FromOffset(1).IsNil); Assert.False(UserStringHandle.FromOffset(1).IsNil); Assert.False(GuidHandle.FromIndex(1).IsNil); Assert.False(DocumentNameBlobHandle.FromOffset(1).IsNil); Assert.False(((Handle)StringHandle.FromOffset(1)).IsNil); Assert.False(((Handle)BlobHandle.FromOffset(1)).IsNil); Assert.False(((Handle)UserStringHandle.FromOffset(1)).IsNil); Assert.False(((Handle)GuidHandle.FromIndex(1)).IsNil); Assert.False(((BlobHandle)DocumentNameBlobHandle.FromOffset(1)).IsNil); Assert.True(ModuleDefinitionHandle.FromRowId(0).IsNil); Assert.True(AssemblyDefinitionHandle.FromRowId(0).IsNil); Assert.True(InterfaceImplementationHandle.FromRowId(0).IsNil); Assert.True(MethodDefinitionHandle.FromRowId(0).IsNil); Assert.True(MethodSpecificationHandle.FromRowId(0).IsNil); Assert.True(TypeDefinitionHandle.FromRowId(0).IsNil); Assert.True(ExportedTypeHandle.FromRowId(0).IsNil); Assert.True(TypeReferenceHandle.FromRowId(0).IsNil); Assert.True(TypeSpecificationHandle.FromRowId(0).IsNil); Assert.True(MemberReferenceHandle.FromRowId(0).IsNil); Assert.True(FieldDefinitionHandle.FromRowId(0).IsNil); Assert.True(EventDefinitionHandle.FromRowId(0).IsNil); Assert.True(PropertyDefinitionHandle.FromRowId(0).IsNil); Assert.True(StandaloneSignatureHandle.FromRowId(0).IsNil); Assert.True(MemberReferenceHandle.FromRowId(0).IsNil); Assert.True(FieldDefinitionHandle.FromRowId(0).IsNil); Assert.True(EventDefinitionHandle.FromRowId(0).IsNil); Assert.True(PropertyDefinitionHandle.FromRowId(0).IsNil); Assert.True(ParameterHandle.FromRowId(0).IsNil); Assert.True(GenericParameterHandle.FromRowId(0).IsNil); Assert.True(GenericParameterConstraintHandle.FromRowId(0).IsNil); Assert.True(ModuleReferenceHandle.FromRowId(0).IsNil); Assert.True(CustomAttributeHandle.FromRowId(0).IsNil); Assert.True(DeclarativeSecurityAttributeHandle.FromRowId(0).IsNil); Assert.True(ManifestResourceHandle.FromRowId(0).IsNil); Assert.True(ConstantHandle.FromRowId(0).IsNil); Assert.True(ManifestResourceHandle.FromRowId(0).IsNil); Assert.True(AssemblyFileHandle.FromRowId(0).IsNil); Assert.True(MethodImplementationHandle.FromRowId(0).IsNil); Assert.True(AssemblyReferenceHandle.FromRowId(0).IsNil); Assert.True(((EntityHandle)ModuleDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)AssemblyDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)InterfaceImplementationHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)MethodDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)MethodSpecificationHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)TypeDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)ExportedTypeHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)TypeReferenceHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)TypeSpecificationHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)MemberReferenceHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)FieldDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)EventDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)PropertyDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)StandaloneSignatureHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)MemberReferenceHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)FieldDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)EventDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)PropertyDefinitionHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)ParameterHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)GenericParameterHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)GenericParameterConstraintHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)ModuleReferenceHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)CustomAttributeHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)DeclarativeSecurityAttributeHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)ManifestResourceHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)ConstantHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)ManifestResourceHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)AssemblyFileHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)MethodImplementationHandle.FromRowId(0)).IsNil); Assert.True(((EntityHandle)AssemblyReferenceHandle.FromRowId(0)).IsNil); // heaps: Assert.True(StringHandle.FromOffset(0).IsNil); Assert.True(BlobHandle.FromOffset(0).IsNil); Assert.True(UserStringHandle.FromOffset(0).IsNil); Assert.True(GuidHandle.FromIndex(0).IsNil); Assert.True(DocumentNameBlobHandle.FromOffset(0).IsNil); Assert.True(((Handle)StringHandle.FromOffset(0)).IsNil); Assert.True(((Handle)BlobHandle.FromOffset(0)).IsNil); Assert.True(((Handle)UserStringHandle.FromOffset(0)).IsNil); Assert.True(((Handle)GuidHandle.FromIndex(0)).IsNil); Assert.True(((BlobHandle)DocumentNameBlobHandle.FromOffset(0)).IsNil); // virtual: Assert.False(AssemblyReferenceHandle.FromVirtualIndex(0).IsNil); Assert.False(StringHandle.FromVirtualIndex(0).IsNil); Assert.False(BlobHandle.FromVirtualIndex(0, 0).IsNil); Assert.False(((Handle)AssemblyReferenceHandle.FromVirtualIndex(0)).IsNil); Assert.False(((Handle)StringHandle.FromVirtualIndex(0)).IsNil); Assert.False(((Handle)BlobHandle.FromVirtualIndex(0, 0)).IsNil); }
public void CallIndirect(StandaloneSignatureHandle signature) { OpCode(ILOpCode.Calli); Token(signature); }
internal static ImmutableArray<CilType> DecodeLocalSignature(StandaloneSignatureHandle handle, CilTypeProvider provider) { var standaloneSignature = provider.Reader.GetStandaloneSignature(handle); var blobReader = provider.Reader.GetBlobReader(standaloneSignature.Signature); return NewDecoder(provider).DecodeLocalSignature(ref blobReader); }
public Mapping<StandaloneSignatureHandle> MapStandaloneSignature(StandaloneSignatureHandle handle) { return _standaloneSignatures.GetOrAdd(handle, MapStandaloneSignatureImpl); }
private void DefineLocalConstant(string name, object value, PrimitiveTypeCode typeCode, StandaloneSignatureHandle constantSignatureHandle) { uint constantSignatureToken = (uint)MetadataTokens.GetToken(constantSignatureHandle); if (value == null) { // ISymUnmanagedWriter2.DefineConstant2 throws an ArgumentException // if you pass in null - Dev10 appears to use 0 instead. // (See EMITTER::VariantFromConstVal) value = 0; typeCode = PrimitiveTypeCode.Int32; } if (typeCode == PrimitiveTypeCode.String) { DefineLocalStringConstant(name, (string)value, constantSignatureToken); } else if (value is DateTime) { // Marshal.GetNativeVariantForObject would create a variant with type VT_DATE and value equal to the // number of days since 1899/12/30. However, ConstantValue::VariantFromConstant in the native VB // compiler actually created a variant with type VT_DATE and value equal to the tick count. // http://blogs.msdn.com/b/ericlippert/archive/2003/09/16/eric-s-complete-guide-to-vt-date.aspx var dt = (DateTime)value; _symWriter.DefineConstant2(name, new VariantStructure(dt), constantSignatureToken); if (_callLogger.LogOperation(OP.DefineConstant2)) { _callLogger.LogArgument(name); _callLogger.LogArgument(constantSignatureToken); _callLogger.LogArgument(dt.ToBinary()); } } else { try { DefineLocalConstantImpl(name, value, constantSignatureToken); if (_callLogger.LogOperation(OP.DefineConstant2)) { _callLogger.LogArgument(name); _callLogger.LogArgument(constantSignatureToken); _callLogger.LogArgument(value); } } catch (Exception ex) { throw new PdbWritingException(ex); } } }
private Mapping<StandaloneSignatureHandle> MapStandaloneSignatureImpl(StandaloneSignatureHandle handle) { throw new NotImplementedException(); }
public void SerializeDebugInfo(IMethodBody methodBody, StandaloneSignatureHandle localSignatureHandleOpt, CustomDebugInfoWriter customDebugInfoWriter) { Debug.Assert(_metadataWriter != null); bool isIterator = methodBody.StateMachineTypeName != null; bool emitDebugInfo = isIterator || methodBody.HasAnySequencePoints; if (!emitDebugInfo) { return; } int methodToken = MetadataTokens.GetToken(_metadataWriter.GetMethodHandle(methodBody.MethodDefinition)); OpenMethod(methodToken, methodBody.MethodDefinition); var localScopes = methodBody.LocalScopes; // Define locals, constants and namespaces in the outermost local scope (opened in OpenMethod): if (localScopes.Length > 0) { this.DefineScopeLocals(localScopes[0], localSignatureHandleOpt); } // NOTE: This is an attempt to match Dev10's apparent behavior. For iterator methods (i.e. the method // that appears in source, not the synthesized ones), Dev10 only emits the ForwardIterator and IteratorLocal // custom debug info (e.g. there will be no information about the usings that were in scope). if (!isIterator && methodBody.ImportScope != null) { IMethodDefinition forwardToMethod; if (customDebugInfoWriter.ShouldForwardNamespaceScopes(Context, methodBody, methodToken, out forwardToMethod)) { if (forwardToMethod != null) { UsingNamespace("@" + MetadataTokens.GetToken(_metadataWriter.GetMethodHandle(forwardToMethod)), methodBody.MethodDefinition); } // otherwise, the forwarding is done via custom debug info } else { this.DefineNamespaceScopes(methodBody); } } DefineLocalScopes(localScopes, localSignatureHandleOpt); ArrayBuilder<Cci.SequencePoint> sequencePoints = ArrayBuilder<Cci.SequencePoint>.GetInstance(); methodBody.GetSequencePoints(sequencePoints); EmitSequencePoints(sequencePoints); sequencePoints.Free(); AsyncMethodBodyDebugInfo asyncDebugInfo = methodBody.AsyncDebugInfo; if (asyncDebugInfo != null) { SetAsyncInfo( methodToken, MetadataTokens.GetToken(_metadataWriter.GetMethodHandle(asyncDebugInfo.KickoffMethod)), asyncDebugInfo.CatchHandlerOffset, asyncDebugInfo.YieldOffsets, asyncDebugInfo.ResumeOffsets); } var compilationOptions = Context.Module.CommonCompilation.Options; // We need to avoid emitting CDI DynamicLocals = 5 and EditAndContinueLocalSlotMap = 6 for files processed by WinMDExp until // bug #1067635 is fixed and available in SDK. bool suppressNewCustomDebugInfo = !compilationOptions.ExtendedCustomDebugInformation || (compilationOptions.OutputKind == OutputKind.WindowsRuntimeMetadata); bool emitEncInfo = compilationOptions.EnableEditAndContinue && !_metadataWriter.IsFullMetadata; bool emitExternNamespaces; byte[] blob = customDebugInfoWriter.SerializeMethodDebugInfo(Context, methodBody, methodToken, emitEncInfo, suppressNewCustomDebugInfo, out emitExternNamespaces); if (blob != null) { DefineCustomMetadata("MD2", blob); } if (emitExternNamespaces) { this.DefineAssemblyReferenceAliases(); } CloseMethod(methodBody.IL.Length); }
/// <summary> /// Encodes a method body and adds it to the method body stream. /// </summary> /// <param name="instructionEncoder">Instruction encoder.</param> /// <param name="maxStack">Max stack.</param> /// <param name="localVariablesSignature">Local variables signature handle.</param> /// <param name="attributes">Attributes.</param> /// <returns>The offset of the encoded body within the method body stream.</returns> /// <exception cref="ArgumentNullException"><paramref name="instructionEncoder"/> has default value.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxStack"/> is out of range [0, <see cref="ushort.MaxValue"/>].</exception> /// <exception cref="InvalidOperationException"> /// A label targeted by a branch in the instruction stream has not been marked, /// or the distance between a branch instruction and the target label is doesn't fit the size of the instruction operand. /// </exception> public int AddMethodBody( InstructionEncoder instructionEncoder, int maxStack = 8, StandaloneSignatureHandle localVariablesSignature = default(StandaloneSignatureHandle), MethodBodyAttributes attributes = MethodBodyAttributes.InitLocals) { if (unchecked((uint)maxStack) > ushort.MaxValue) { Throw.ArgumentOutOfRange(nameof(maxStack)); } // The branch fixup code expects the operands of branch instructions in the code builder to be contiguous. // That's true when we emit thru InstructionEncoder. Taking it as a parameter instead of separate // code and flow builder parameters ensures they match each other. var codeBuilder = instructionEncoder.CodeBuilder; var flowBuilder = instructionEncoder.ControlFlowBuilder; if (codeBuilder == null) { Throw.ArgumentNull(nameof(instructionEncoder)); } int exceptionRegionCount = flowBuilder?.ExceptionHandlerCount ?? 0; if (!ExceptionRegionEncoder.IsExceptionRegionCountInBounds(exceptionRegionCount)) { Throw.ArgumentOutOfRange(nameof(instructionEncoder), SR.TooManyExceptionRegions); } int bodyOffset = SerializeHeader(codeBuilder.Count, (ushort)maxStack, exceptionRegionCount, attributes, localVariablesSignature); if (flowBuilder?.BranchCount > 0) { flowBuilder.CopyCodeAndFixupBranches(codeBuilder, Builder); } else { codeBuilder.WriteContentTo(Builder); } flowBuilder?.SerializeExceptionTable(Builder); return bodyOffset; }
private void DefineScopeLocals(LocalScope currentScope, StandaloneSignatureHandle localSignatureHandleOpt) { foreach (ILocalDefinition scopeConstant in currentScope.Constants) { var signatureHandle = _metadataWriter.SerializeLocalConstantStandAloneSignature(scopeConstant); if (!_metadataWriter.IsLocalNameTooLong(scopeConstant)) { DefineLocalConstant(scopeConstant.Name, scopeConstant.CompileTimeValue.Value, _metadataWriter.GetConstantTypeCode(scopeConstant), signatureHandle); } } foreach (ILocalDefinition scopeLocal in currentScope.Variables) { if (!_metadataWriter.IsLocalNameTooLong(scopeLocal)) { Debug.Assert(scopeLocal.SlotIndex >= 0); DefineLocalVariable((uint)scopeLocal.SlotIndex, scopeLocal.Name, scopeLocal.PdbAttributes, localSignatureHandleOpt); } } }
private int SerializeHeader(int codeSize, ushort maxStack, int exceptionRegionCount, MethodBodyAttributes attributes, StandaloneSignatureHandle localVariablesSignature) { const int TinyFormat = 2; const int FatFormat = 3; const int MoreSections = 8; const byte InitLocals = 0x10; int offset; bool isTiny = codeSize < 64 && maxStack <= 8 && localVariablesSignature.IsNil && exceptionRegionCount == 0; if (isTiny) { offset = Builder.Count; Builder.WriteByte((byte)((codeSize << 2) | TinyFormat)); } else { Builder.Align(4); offset = Builder.Count; ushort flags = (3 << 12) | FatFormat; if (exceptionRegionCount > 0) { flags |= MoreSections; } if ((attributes & MethodBodyAttributes.InitLocals) != 0) { flags |= InitLocals; } Builder.WriteUInt16((ushort)((int)attributes | flags)); Builder.WriteUInt16(maxStack); Builder.WriteInt32(codeSize); Builder.WriteInt32(localVariablesSignature.IsNil ? 0 : MetadataTokens.GetToken(localVariablesSignature)); } return offset; }
public StandaloneSignature GetStandaloneSignature(StandaloneSignatureHandle handle) { return new StandaloneSignature(this, handle); }
/// <summary> /// Encodes <code>calli</code> instruction and its operand. /// </summary> public void CallIndirect(StandaloneSignatureHandle signature) { OpCode(ILOpCode.Calli); Token(signature); }