Search code examples
templatesinlined

D Templates Request


I just read the whole documentation of Templates in the D programming language but cant seem to find a way for my very simple task, for functions I need 3 assembler instructions to be inserted at the beginning of each function, I would like to automate this through a macro so I dont have to manually write it each time.

__gshared void jump()
{
    asm{db START_KEY;}

    //bla bla bla

    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}

something like this should get replaced with

__gshared void jump()
{
    mixin starttemplate();

    //bla bla bla

    mixin endtemplate();
}

In C I would have done something like this

#define STARTASM() asm{.......}

but if I try something like this

template endtemplate()
{
    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}

it will throw an error saying that I have to declare a variable at a template (which I dont want to, since performance is absolutely needed here).


Solution

  • How about saving the asm command as a string, and using a mixin?

    immutable string ASM_START=q{
        asm{db START_KEY;}
    }
    immutable string ASM_END=q{
        asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
    }
    
    __gshared void jump()
    {
        mixin(ASM_START);
        //bla bla bla
        mixin(ASM_END);
    }
    

    Another option is to use the mixing to create the entire function, and pass it's signature and content(=body) as arguments:

    string functionWithAsm(string signature,string content)(){
        return Format!(q{
            %s
            {
                asm{db START_KEY;}
                %s
                asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
            }
            },signature,content);
    }
    
    mixin(functionWithAsm!("__gshared void jump()",q{
                /*some actual code*/
                })());