Add IAssembler seam (Assemble(text, origin)) with StubAssembler default backend. StubAssembler provides EmitU8/EmitU32/EmitU64 little-endian byte emitters (zero dep, no FASM). Assemble throws NotSupportedException on StubAssembler (text assembly deferred to IcedAssembler, Phase 8). 7 new tests: EmitU8, EmitU32 x2, EmitU64 x2, IS-A check, Assemble throws. All passing (total: 64).
50 lines
1.9 KiB
C#
50 lines
1.9 KiB
C#
namespace WhiteMagic.Assembly;
|
|
|
|
/// <summary>
|
|
/// The default <see cref="IAssembler"/> backend. Hand-emits calling-convention
|
|
/// trampolines and injection stubs using deterministic byte emitters
|
|
/// (<see cref="EmitU8"/>, <see cref="EmitU32"/>, <see cref="EmitU64"/>). Has
|
|
/// no native or third-party dependency — no FASM, no Iced.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <see cref="Assemble"/> is not supported by this backend (it is a parse-free
|
|
/// emitter, not a text assembler). Use <see cref="IcedAssembler"/> (Phase 8) for
|
|
/// arbitrary mnemonics.
|
|
/// </remarks>
|
|
public class StubAssembler : IAssembler
|
|
{
|
|
/// <inheritdoc />
|
|
/// <exception cref="NotSupportedException">Always thrown. StubAssembler does
|
|
/// not parse text assembly; use IcedAssembler for that.</exception>
|
|
public byte[] Assemble(string assemblyText, ulong origin = 0)
|
|
{
|
|
throw new NotSupportedException(
|
|
"StubAssembler does not parse text assembly. " +
|
|
"Use IcedAssembler (Phase 8) for arbitrary mnemonics.");
|
|
}
|
|
|
|
// ── Emit primitives ────────────────────────────────────────────────────
|
|
|
|
/// <summary>Appends a single byte to <paramref name="buffer"/>.</summary>
|
|
public void EmitU8(List<byte> buffer, byte value)
|
|
{
|
|
buffer.Add(value);
|
|
}
|
|
|
|
/// <summary>Appends <paramref name="value"/> as 4 little-endian bytes.</summary>
|
|
public void EmitU32(List<byte> buffer, uint value)
|
|
{
|
|
buffer.Add((byte)value);
|
|
buffer.Add((byte)(value >> 8));
|
|
buffer.Add((byte)(value >> 16));
|
|
buffer.Add((byte)(value >> 24));
|
|
}
|
|
|
|
/// <summary>Appends <paramref name="value"/> as 8 little-endian bytes.</summary>
|
|
public void EmitU64(List<byte> buffer, ulong value)
|
|
{
|
|
EmitU32(buffer, (uint)value);
|
|
EmitU32(buffer, (uint)(value >> 32));
|
|
}
|
|
}
|