Skip to content

Add InstructionEncoder.Switch to enable emitting switch instructions with LabelHandles #40546

Closed
@SeeminglyScience

Description

@SeeminglyScience

Background and Motivation

It doesn't look like there's a way to use InstructionEncoder.DefineLabel's LabelHandles with a switch instruction. I'm mainly asking if there is a way to do it that I'm missing, but if not here's a basic API proposal to enable it.

Proposed API

namespace System.Reflection.Metadata.Ecma335
{
    public readonly struct InstructionEncoder
    {
+       public void Switch(params LabelHandle[] label);
    }
}

Usage Examples

var ie = new InstructionEncoder(new BlobBuilder(), new ControlFlowBuilder());
var case0 = ie.DefineLabel();
var case1 = ie.DefineLabel();
var case2 = ie.DefineLabel();
var afterCases = ie.DefineLabel();

ie.OpCode(ILOpCode.Ldc_i4_0);
ie.Switch(case0, case1, case2);
ie.Branch(ILOpCode.Br_s, afterCases);

ie.MarkLabel(case0);
ie.OpCode(ILOpCode.Ldc_i4_0);
ie.OpCode(ILOpCode.Ret);

ie.MarkLabel(case1);
ie.OpCode(ILOpCode.Ldc_i4_1);
ie.OpCode(ILOpCode.Ret);

ie.MarkLabel(case2);
ie.OpCode(ILOpCode.Ldc_i4_2);
ie.OpCode(ILOpCode.Ret);

ie.MarkLabel(afterCases);
ie.OpCode(ILOpCode.Ldc_i4_s);
ie.CodeBuilder.WriteCompressedSignedInteger(10);
ie.OpCode(ILOpCode.Ret);

new MethodBodyStreamEncoder(new BlobBuilder())
    .AddMethodBody(ie, maxStack: 8, localVariablesSignature: default, MethodBodyAttributes.None);

Alternative Designs

Originally this proposal was based on emitting the label by itself:

namespace System.Reflection.Metadata.Ecma335
{
    public readonly struct InstructionEncoder
    {
+       public void Label(LabelHandle label);
    }
}

This won't work because the target offset is based on the end of the switch instruction, not the offset of the label.

Also for it to work with switch like intended, it would need to only emit int32 offsets. That's not super clear from the name and would generate bad IL if someone were to do OpCode(ILOpCode.Br_s); Label(label);, even if it were based on the label's offset.

Risks

Metadata

Metadata

Assignees

Type

No type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions