-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add InstructionEncoder.Switch to enable emitting switch instructions with LabelHandles #40546
Comments
I think it should also have an overload for |
I have refactored the relevant SRM code to easily support emitting |
@tmat what do you think about this proposal? The main question is there a way to use |
Any updates? I would really like to see this proposal implemented! (I'd be very thankful if someone could provide a temporary workaround.) |
This is probably not the temporary workaround you're hoping for, but what I did was basically rip out and modify their flow control builder code. Here's the PR where I did that if you want some ideas SeeminglyScience/ILAssembler#19 |
@buyaa-n, @tmat can this move forward? And @SeeminglyScience can you also propose an overload that takes an |
I tried to keep the proposal as close to other APIs in the library as possible. If we were adding overloads for performance, I'd rather see |
Yeah, spans would not fit because they are nowhere else used in this library. |
We could add the proposed API that takes public readonly struct SwitchInstructionEncoder
{
private readonly ControlFlowBuilder _branchBuilder;
private readonly BlobBuilder _codeBuilder;
private readonly int _instructionEndOffset;
internal SwitchInstructionEncoder(ControlFlowBuilder branchBuilder, BlobBuilder codeBuilder, int instructionEndOffset) { ... }
public void Branch(Label label)
=> _branchBuilder.AddBranch(_instructionEndOffset, label, _codeBuilder);
}
public readonly struct InstructionEncoder
{
public SwitchInstructionEncoder Switch(int branchCount)
{
var branchBuilder = GetBranchBuilder();
OpCode(ILOpCodes.Switch);
CodeBuilder.WriteInt32(branchCount);
return new SwitchInstructionEncoder(branchBuilder, CodeBuilder, Offset + branchCount * sizeof(uint));
}
} |
namespace System.Reflection.Metadata.Ecma335
{
public readonly struct SwitchInstructionEncoder
{
public void Branch(LabelHandle label);
}
public partial struct InstructionEncoder
{
public SwitchInstructionEncoder Switch(int branchCount);
}
} |
I will do it in a couple of months in time for 8.0.0, if someone else wants to do it, feel free to. |
The original proposal had a clear usage example but the approved API leaves the intended functionality implicit. Am I correct in understanding the approved proposal as supposed to work in such a way that the originally suggested method is equivalent to the following public void SwitchOfLabelHandles(params LabelHandle[] labels)
{
var switchEncoder = Switch(labels.Length);
foreach (var label in labels)
{
switchEncoder.Branch(label);
}
} |
@August-Alm yes. |
Background and Motivation
It doesn't look like there's a way to use
InstructionEncoder.DefineLabel
'sLabelHandle
s with aswitch
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
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
The text was updated successfully, but these errors were encountered: