Hey folks! Sorry for the long delay. Goodness, this has been active, though!
Anyway, some random thoughts: I do currently have a build where it’s possible to switch between function-mode and switch-mode just by changing some preprocessor defines. And in fact, I’ve published the branch! It’s at:
Please note, this is very much an experimental branch; feel free to check it out, clone it, whatever, but I’ve been playing fast and loose with my own git history, so be aware there may be rebases and force-pushes in your future if you base anything off of it. With that said, here’s a quick walkthrough:
- VMI instruction “functions” are now accompanied by VMH helper “functions”, with callsite-based arguments. Since this is still based around the transfer-of-control model the switch mode introduced, this is performed using a macro
VMH_GOTO()
as opposed to VMH_CALL()
or anything like that. VMH_GOTO
takes the name of the helper, along with the arguments; in switch_mode, this uses struct definitions and struct initializer syntax to mimic “argument passing”, which is easily optimized away by the compiler. This completely eliminates the SHAREDVARS
mechanism, and also helpfully centralizes the list of "what shared-state variables exist in PL_next_solution()
. As a result, a macro invocation like VMH_GOTO(foo,1,2,*bar)
gets turned into:
{ struct helper_foo_args __args = {1,2,&bar};
global_helper_foo_args = __args;
goto helper_foo;
}
- The VMH definitions look a little weird, because of the limitations of macro processing. The argument types and argument names are listed separately, so the
foo
helper above might be defined:
VMH(foo, 3, (int, int, int*), (x, y, pointer))
{ *pointer = x + y;
NEXT_INSTRUCTION;
}
END_VMH
- Speaking of
END_VMH
and the parallel END_VMI
, I originally modified VMI()
so that the macro invocation encompassed the body, like below. And, while this had the lovely effect of allowing you to include the file in a mode that suppresses the code itself, becoming effectively a header file, it had a pretty major downside: due to what the GCC team considers a “bug” that they have “intended to fix in the near future” for a little under two decades, anything produced by macro expansion all gets concatenated onto one line, which is, shall we say, Not Great For Debugging. So, we have instead moved to this model where we’ve got a start and an end macro for functions. Technically, we could have a starting macro and an extra close brace at the end, but I am very much not a fan of unbalanced braces in the source, so no.
VMI(H_FIRSTVAR, 0, 1, (CA1_FVAR),
{ etc etc...
})
- The
mkvmi
helper utility now creates the generated header in src/
rather than the build output directory. The intent here is to have it committed into the git repo, like a package lock file for a Node project, so that it’s obvious when and where anyone changes the VMI signature. The generated file is pl-vmi.ih
, and it both gets included directly into pl-wam.c
in a few places, and also forms the data source for some other newly-checked-in header files that used to be autogenerated by mkvmi
, but now are just renderings of the macros in pl-vmi.ih
.
That about sums it up for me, for now - I’m afraid I don’t have the energy to go through the whole discussion above, so if you have any other specific questions for me, please feel free to ask!