Skip to content

ProcDecoder Refactor Redux#2651

Open
ike709 wants to merge 12 commits into
OpenDreamProject:masterfrom
ike709:cfg_part1_redux_procdecoder_refactor
Open

ProcDecoder Refactor Redux#2651
ike709 wants to merge 12 commits into
OpenDreamProject:masterfrom
ike709:cfg_part1_redux_procdecoder_refactor

Conversation

@ike709

@ike709 ike709 commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

This PR has a few main changes:

  • ProcDecoder was moved from the runtime to the compiler.
  • As a side effect of that, DMDisassembler now depends on the compiler instead of the runtime.
  • The ITuple is now a ProcInstruction comprised of ProcOperands that store the argument values.
  • Format() and DecodeInstruction() now utilize opcode metadata to figure out how to handle each opcode rather than using user-defined switch() cases for each opcode.

Most of that handling diverges depending on whether the opcode has a fixed-length argument count or a variable-length argument count (N-variant opcodes). There's also a fair bit of code repetition for the tradeoff of not having to do a ton of typechecking on what types the arguments actually are.

Tested with DM disassembly of /tg/station before and after this PR. Didn't see any non-whitespace diffs.

See my first comment below as well.

@boring-cyborg boring-cyborg Bot added Compiler Involves the OpenDream compiler Runtime Involves the OpenDream server/runtime labels Jun 29, 2026
Comment thread DMCompiler/Bytecode/ProcInstruction.cs
@ike709 ike709 requested a review from wixoaGit June 29, 2026 11:24
}
case ProcOperandShape.RepeatedString: {
string[] values = operand0.Strings!;
for (int i = 0; i < values.Length; i++) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we care?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why you wouldn't use a foreach here, though I'd be fine with disabling the inspection if others don't like it.

}
case ProcOperandShape.RepeatedResource: {
string[] values = operand0.Strings!;
for (int i = 0; i < values.Length; i++) {
}
case ProcOperandShape.RepeatedReference: {
DMReference[] values = operand0.References!;
for (int i = 0; i < values.Length; i++) {
@ike709 ike709 changed the title CFG Part 1: ProcDecoder Refactor Redux ProcDecoder Refactor Redux Jun 30, 2026
/// <summary>
/// Stringifies a <see cref="ProcInstruction"/> and its operands
/// </summary>
public static string Format(ProcInstruction instruction, Func<int, string> getTypePath) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't the caller call Format() on the instruction directly?

return instruction.Format(getTypePath);
}

public static int? GetJumpDestination(ProcInstruction instruction) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This too?

Comment on lines +75 to +78
ProcOperand operand0 = default,
ProcOperand operand1 = default,
ProcOperand operand2 = default,
ProcOperand operand3 = default) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be an array instead? I don't like how you have to write out behavior for every possible argument length.

opcodesBytes.AddRange(BitConverter.GetBytes(metadata.StackDelta));
opcodesBytes.Add((byte)(metadata.VariableArgs ? 1 : 0));
AddArgTypes(opcodesBytes, metadata.RequiredArgs);
AddArgTypes(opcodesBytes, metadata.RepeatedArgs);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather override OpcodeMetadata.GetHashCode() and use that here, so that it's clearer that this needs updated if the metadata's fields change.

using System.Text;
using DMCompiler.DM;

// ReSharper disable UnusedMember.Global

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this doing anything? Removing it isn't showing me any new warnings.

Comment on lines +155 to +156
foreach (var t in values)
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
foreach (var t in values)
{
foreach (var t in values) {

}
case ProcOperandShape.RepeatedString: {
string[] values = operand0.Strings!;
for (int i = 0; i < values.Length; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why you wouldn't use a foreach here, though I'd be fine with disabling the inspection if others don't like it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Compiler Involves the OpenDream compiler Runtime Involves the OpenDream server/runtime size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants