Skip to content
Concord

Class WrapperComposer

Namespace
Concord.Emit
Assembly
Concord.Emit.dll

Builds composed wrapper methods from an original target and ordered Concord injections.

public static class WrapperComposer
Inheritance
WrapperComposer
Inherited Members

Methods

Compose(MethodBase, IReadOnlyList<Injection>)

Creates a wrapper method for a target and a copy of the original body.

public static ComposeResult Compose(MethodBase target, IReadOnlyList<Injection> ordered)

Parameters

target MethodBase

The exact method to compose onto. Callers that mean to patch an async or iterator target's generated MoveNext resolve it with ResolveBodyTarget(MethodBase, PatchBody) first.

ordered IReadOnlyList<Injection>

The injections to compose, ordered by their caller.

Returns

ComposeResult

The generated wrapper method and original body copy.

ComposeDump(MethodBase, IReadOnlyList<Injection>)

Diagnostic variant of Compose(MethodBase, IReadOnlyList<Injection>): runs the full spine-copy and assembly pipeline but returns a textual dump of the composed wrapper body BEFORE JIT generation, for inspecting cross-module operands, the locals table, and per-instruction stack depth.

public static string ComposeDump(MethodBase target, IReadOnlyList<Injection> ordered)

Parameters

target MethodBase

The method to patch.

ordered IReadOnlyList<Injection>

The injections to compose.

Returns

string

A human-readable IL dump of the composed wrapper.

CreateStreamContext(MethodBase)

Creates a transpiler context for use with TransformStream(MethodBase, IReadOnlyList<CodeInstruction>, IReadOnlyList<Injection>, ITranspilerContext), in the virgin local-numbering state a supplied stream expects: no locals declared yet, so a caller's first DeclareLocal(Type) call returns index 0, the second returns index 1, and so on.

public static ITranspilerContext CreateStreamContext(MethodBase target)

Parameters

target MethodBase

The method the supplied stream's shape describes, already resolved by the caller through ResolveBodyTarget(MethodBase, PatchBody) when the stream is a state machine's MoveNext.

Returns

ITranspilerContext

A fresh transpiler context, not yet used to read or write any body.

RejectSharedGenericInstantiation(MethodBase)

Rejects a target that is a reference-type generic instantiation. The runtime shares one compiled body across all reference-type instantiations of a generic method, so a detour installed for one instantiation runs for every other one. Value-type instantiations each get their own body and are safe.

public static void RejectSharedGenericInstantiation(MethodBase target)

Parameters

target MethodBase

The method a detour is about to be installed for.

Exceptions

ConcordEmitException

Thrown with CONC061 when the target is a reference-type instantiation.

ResolveBodyTarget(MethodBase, PatchBody)

Picks the method an injection actually composes onto, given the body it asked for.

public static MethodBase ResolveBodyTarget(MethodBase target, PatchBody body)

Parameters

target MethodBase

The method named by the declaration.

body PatchBody

The body the injection selected.

Returns

MethodBase

The state-machine MoveNext when body is StateMachine and target is an async or iterator method; otherwise target unchanged.

ResolveStateMachineTarget(MethodBase)

Resolves async and iterator entry methods to their generated state-machine MoveNext method.

[SuppressMessage("Major Code Smell", "S3011", Justification = "Concord reaches the private state-machine MoveNext by design; validated at resolve time.")]
public static MethodBase ResolveStateMachineTarget(MethodBase target)

Parameters

target MethodBase

The method to inspect.

Returns

MethodBase

The state-machine MoveNext method when present; otherwise target.

TransformStream(MethodBase, IReadOnlyList<CodeInstruction>, IReadOnlyList<Injection>, ITranspilerContext)

Composes ordered injections onto a caller-supplied instruction stream instead of IL read from target itself. This is the seam a coexistence bridge - one that hands Concord another patching library's own transpiler stream - uses to compose Concord's injections onto it and hand the composed stream back.

public static List<CodeInstruction> TransformStream(MethodBase target, IReadOnlyList<CodeInstruction> source, IReadOnlyList<Injection> ordered, ITranspilerContext context)

Parameters

target MethodBase

The method that defines the composed body's shape (return type and parameters), already resolved by the caller through ResolveBodyTarget(MethodBase, PatchBody) where that applies.

source IReadOnlyList<CodeInstruction>

The instruction stream to compose the injections onto.

ordered IReadOnlyList<Injection>

The injections to compose, ordered by their caller.

context ITranspilerContext

The context source was produced against, obtained from CreateStreamContext(MethodBase). Locals a caller declared on it before this call land at the indices they were declared in.

Returns

List<CodeInstruction>

The composed instruction stream.

Exceptions

ConcordEmitException

Thrown with code CONC116 when context was not obtained from CreateStreamContext(MethodBase).

ValidateBodySelection(MethodBase, MethodBase, Injection)

Rejects an injection whose declared shape cannot work against the body it selected.

public static void ValidateBodySelection(MethodBase declared, MethodBase resolved, Injection injection)

Parameters

declared MethodBase

The method named by the declaration.

resolved MethodBase

The method composition will actually run against.

injection Injection

The injection to check.

Exceptions

ConcordEmitException

Thrown with CONC122 when a ControlHandle<T> is shaped against the declared return type but the injection selected StateMachine, and with CONC123 when a position that needs the body as written selected Declared on an async or iterator target, where only the compiler-generated stub exists.