Skip to main content

Module signatures

Module signatures 

Expand description

Implementation of method and type signatures Method and type signature parsing for .NET metadata according to ECMA-335.

This module provides comprehensive parsing of .NET metadata signatures, which encode type information, method parameters, generic constraints, and calling conventions in a compact binary format. Signatures are fundamental to the .NET type system and are used throughout assembly metadata to describe types, methods, and their relationships.

§.NET Signature System Overview

The .NET metadata format defines signatures as binary-encoded type descriptions that provide complete type information for methods, fields, properties, and local variables. These signatures enable the CLR to understand type relationships, perform type checking, and support generic type instantiation.

§Signature Categories

The .NET metadata format defines several signature types, each serving specific purposes:

§Method Signatures

  • Purpose: Describe method parameter types, return types, and calling conventions
  • Usage: Method definitions, method references, and method specifications
  • Features: Support for instance methods, static methods, generic methods, and varargs
  • Calling Conventions: Default, varargs, C calling convention, stdcall, fastcall

§Field Signatures

  • Purpose: Describe field type information and custom modifiers
  • Usage: Field definitions and field references
  • Features: Support for custom modifiers (modreq/modopt), array types, and generic types
  • Modifiers: Required and optional custom modifiers for advanced type scenarios

§Property Signatures

  • Purpose: Describe property type and indexer parameter information
  • Usage: Property definitions with getter/setter methods
  • Features: Support for indexed properties, instance properties, and generic property types
  • Indexers: Multi-dimensional indexers with complex parameter types

§Local Variable Signatures

  • Purpose: Describe local variable types within method bodies
  • Usage: Method body metadata for JIT compilation and debugging
  • Features: Support for pinned variables, byref variables, and complex local types
  • Memory Management: Pinned locals for interop scenarios and unsafe code

§Type Specification Signatures

  • Purpose: Define generic type instantiations and complex type references
  • Usage: Generic type instantiations like List<int> or Dictionary<string, object>
  • Features: Nested generic types, generic method instantiations, and type constraints
  • Instantiation: Runtime type creation from generic type definitions

§Method Specification Signatures

  • Purpose: Provide type arguments for generic method instantiations
  • Usage: Generic method calls with specific type arguments
  • Features: Multiple type arguments, nested generic types, and method constraints
  • Resolution: Runtime method resolution for generic method calls

§Binary Encoding Format

Signatures use a compressed binary encoding optimized for space efficiency while maintaining complete type information. The encoding follows ECMA-335 specifications and includes several key characteristics:

§Encoding Characteristics

  • Calling Conventions: Encoded as single-byte prefixes (0x00-0x0F range)
  • Parameter Counts: Use compressed integer encoding for space efficiency
  • Type References: Element type tokens and metadata table references
  • Generic Parameters: Positional indices into generic parameter lists
  • Custom Modifiers: Inline encoding with type information for advanced scenarios

§Compression Techniques

  • Compressed Integers: Variable-length encoding for counts and indices
  • Element Types: Single-byte encoding for primitive types (int32, string, etc.)
  • Token Compression: Compressed encoding for metadata table references
  • Recursive Encoding: Nested type information for complex generic types

§Common Usage Patterns

§Basic Method Signature Analysis

use dotscope::metadata::signatures::parse_method_signature;

// Parse a simple method signature: void Method()
let signature_data = &[0x00, 0x00, 0x01]; // DEFAULT, 0 params, VOID return
let method_sig = parse_method_signature(signature_data)?;

println!("Method has {} parameters", method_sig.params.len());
println!("Return type: {:?}", method_sig.return_type.base);
println!("Has 'this' parameter: {}", method_sig.has_this);
println!("Generic parameter count: {}", method_sig.param_count_generic);

§Generic Method Signature Analysis

use dotscope::metadata::signatures::{parse_method_signature, TypeSignature};

// Parse generic method: T Method<T>(T item)
let signature_data = &[
    0x30, // HASTHIS | GENERIC
    0x01, // 1 generic parameter
    0x01, // 1 method parameter  
    0x13, 0x00, // GenericParam(0) - return type
    0x13, 0x00, // GenericParam(0) - parameter type
];
let method_sig = parse_method_signature(signature_data)?;

if method_sig.param_count_generic > 0 {
    println!("Generic method with {} type parameters", method_sig.param_count_generic);
}

// Check if return type is a generic parameter
if let TypeSignature::GenericParamType(index) = method_sig.return_type.base {
    println!("Return type is generic parameter {}", index);
}

§Field Type Analysis

use dotscope::metadata::signatures::{parse_field_signature, TypeSignature};

// Parse array field signature: string[] field
let signature_data = &[0x06, 0x1D, 0x0E]; // FIELD, SZARRAY, String
let field_sig = parse_field_signature(signature_data)?;

match &field_sig.base {
    TypeSignature::SzArray(element_type) => {
        println!("Array field with element type: {:?}", element_type.base);
    },
    TypeSignature::String => {
        println!("String field");
    },
    TypeSignature::I4 => {
        println!("Integer field");
    },
    _ => {
        println!("Other field type: {:?}", field_sig.base);
    }
}

if !field_sig.modifiers.is_empty() {
    println!("Field has {} custom modifiers", field_sig.modifiers.len());
}

§Local Variable Analysis

use dotscope::metadata::signatures::parse_local_var_signature;

// Parse locals: int a; ref string b; pinned byte* c;
let signature_data = &[
    0x07, // LOCAL_SIG
    0x03, // 3 variables
    0x08, // I4 (int)
    0x10, 0x0E, // BYREF String (ref string)
    0x45, 0x0F, // PINNED PTR (pinned byte*)
];
let locals_sig = parse_local_var_signature(signature_data)?;

for (i, local) in locals_sig.locals.iter().enumerate() {
    println!("Local {}: {:?}", i, local.base);
     
    if local.is_byref {
        println!("  -> Passed by reference");
    }
    if local.is_pinned {
        println!("  -> Pinned in memory (for interop)");
    }
}

§Generic Type Instantiation Analysis

use dotscope::metadata::signatures::{parse_type_spec_signature, TypeSignature};

// Parse List<int> type specification
let signature_data = &[
    0x15, // GENERICINST
    0x12, 0x49, // Class token reference
    0x01, // 1 type argument
    0x08, // I4 (int)
];
let type_spec = parse_type_spec_signature(signature_data)?;

if let TypeSignature::GenericInst(class_type, args) = &type_spec.base {
    println!("Generic type instantiation:");
    println!("  Base type: {:?}", class_type);
    println!("  Type arguments: {} types", args.len());
     
    for (i, arg) in args.iter().enumerate() {
        println!("    [{}]: {:?}", i, arg);
    }
}

§Advanced Features

§Custom Modifiers (modreq/modopt)

Custom modifiers provide additional type information for advanced scenarios:

  • modreq: Required modifiers that affect type identity and compatibility
  • modopt: Optional modifiers that provide hints but don’t affect compatibility
  • Usage: C++/CLI interop, volatile fields, const fields, and custom type constraints

§Calling Conventions

Different calling conventions are supported for platform interop:

  • DEFAULT: Standard managed calling convention
  • VARARG: Variable argument lists (params arrays)
  • C: C-style calling convention for P/Invoke
  • STDCALL: Windows standard calling convention
  • FASTCALL: Fast calling convention for performance-critical code

§Memory Layout Specifications

Signatures include information for memory management:

  • Pinned Variables: Fixed memory location for interop scenarios
  • ByRef Parameters: Reference semantics for value types
  • Pointer Types: Unsafe pointer types for low-level operations
  • Array Bounds: Multi-dimensional array layout information

§Thread Safety

All parsing functions in this module are thread-safe:

  • Stateless parsing functions can be called concurrently
  • Parsed signature structures are immutable and shareable
  • No global state or shared mutable data

§Error Handling

Parsing can fail for several reasons:

  • Malformed Data: Invalid signature encoding or truncated data
  • Unsupported Features: Unknown element types or calling conventions
  • Version Incompatibility: Signatures from newer .NET versions
  • Corrupted Metadata: Damaged assembly files or invalid token references

§ECMA-335 Compliance

This implementation follows ECMA-335 6th Edition specifications:

  • Partition II, Section 23.2: Blobs and signature encoding formats
  • Partition II, Section 23.1: Metadata validation and well-formedness rules
  • Partition I, Section 8: Type system fundamentals and signature semantics
  • Partition III, Section 1.6: Calling conventions and method signatures

The implementation handles all standard signature types and element types defined in the specification, including legacy formats for backward compatibility.

Modules§

CALLING_CONVENTION
Calling convention flags as defined in ECMA-335 II.23.2.1 for method signature encoding.
SIGNATURE_HEADER
Signature marker bytes as defined in ECMA-335 II.23.2.

Structs§

CustomModifier
Represents a custom modifier with its required/optional flag and type reference.
FieldSignatureBuilder
Builder for constructing field signatures with fluent API.
LocalVariableSignatureBuilder
Builder for constructing local variable signatures with fluent API.
MethodSignatureBuilder
Builder for constructing method signatures with fluent API.
PropertySignatureBuilder
Builder for constructing property signatures with fluent API.
SignatureArray
Multi-dimensional array signature with bounds and dimension information.
SignatureField
Field signature with type information and custom modifiers.
SignatureLocalVariable
Individual local variable declaration with type and attributes.
SignatureLocalVariables
Local variable signature collection for method bodies.
SignatureMethod
Method signature with calling conventions, parameters, and return types.
SignatureMethodSpec
Method specification signature for generic method instantiations.
SignatureParameter
Method parameter signature with modifiers and reference semantics.
SignatureParser
Binary signature parser for all .NET metadata signature types according to ECMA-335.
SignaturePointer
Unmanaged pointer signature with custom modifiers.
SignatureProperty
Property signature with indexer support and custom modifiers.
SignatureSzArray
Single-dimensional array signature with custom modifiers.
SignatureTypeSpec
Type specification signature for complex and generic types.
TypeSpecSignatureBuilder
Builder for constructing type specification signatures with fluent API.

Enums§

TypeSignature
Complete .NET type signature representation supporting all ECMA-335 type encodings.

Functions§

encode_field_signature
Encodes a field signature into binary format according to ECMA-335.
encode_local_var_signature
Encodes a local variable signature into binary format according to ECMA-335.
encode_method_signature
Encodes a method signature into binary format according to ECMA-335.
encode_property_signature
Encodes a property signature into binary format according to ECMA-335.
encode_typespec_signature
Encodes a type specification signature into binary format according to ECMA-335.
parse_field_signature
Parse a field signature from binary signature data.
parse_local_var_signature
Parse a local variable signature from binary signature data.
parse_method_signature
Parse a method signature from binary signature data.
parse_method_spec_signature
Parse a method specification signature from binary signature data.
parse_property_signature
Parse a property signature from binary signature data.
parse_type_spec_signature
Parse a type specification signature from binary signature data.

Type Aliases§

CustomModifiers
A collection of custom modifiers applied to a type or type component.