Sunday 1 May 2011

Crazy JIT Prototype - resurrection!


Couple of weeks ago I've put Parrot's jit prototype on hold. One of the major issue was C macro preprocessor. Now, it's time to unhold it

Problems with C macro preprocessor

There is quite few problems with processing of C macros. All of them are based on “source level” preprocessing. And, in theory, C macros can change semantic of program very dramatically. For example ,code>foo(bar, baz) can be expanded to something awful like (bar*)baz->blerg->foo(thingy, baz). In this case we change semantic of bar from being “function argument“ to “type”, foo from “function name” to “struct field”.

And it's not “out of thin air” example. All VTABLE access wrapped in such macros. E.g. VTABLE_get_bool(interp, pmc) expanded as pmc->vtable->get_bool(interp, pmc). And we have quite few such macros in our codebase. As you can see we derive “get_bool” from “VTABLE_get_bool”. And added intermediate step to access “vtable” attribute of “pmc”.

There are more of such “interesting” things with C macros. “String concatenations” is another beautiful example. Etc, etc, etc. I don't blame C for it. For many-many years “source filters” serve same purpose in Perl. And now using of “source filters” is highly discouraged in Perl. Devel::Declare changed the landscape totally.

In previous episode of our “soap opera” I stuck in parsing this macros. I was trying to change NQP's parsing on-fly to reparse and reprocess C macros. I was running in circles pushing for something like “recursive parsing of C source code within constraints of my understanding of NQP”. EPIC FAIL. And then I decided to choose simpler path.

Simple C macro processing

Preamble: Parrot's style guide is prohibit many-many “clever C hackerish tricks”. And based on this I switched from solving “Parsing C macros” problem in general to “Parsing macros used in parrot”. And this is actually helped a lot.

There is 2 big things about it. No. Not “big”, but “BIG”:
  • Set of macros are mostly predefined.
  • Most of them have “function semantic”. E.g. VTABLE_foo() is parsed as function and I can handle macros in only one place.
So, instead of trying to “regenerate of source code” based on “currently available macros definitions” (which is kind of requirements for full featured C macro preprocessor) I decided to handle only macros which looks like functions. VTABLE_foo, CURRENT_CONTEXT, YOU_NAME_IT. In this case macros should just produce different AST tree. There is the code for current “prototype-within-prototype”. In future I (or someone who is willing to beat me) will implement generating of this file from original macro definitions. But it's a good start.

Next time — type analyses.

See ya!