D模板请求

时间:2012-07-16 19:55:19

标签: templates inline d

我刚刚在D编程语言中阅读了模板的整个文档,但似乎无法为我的简单任务找到一种方法,对于我需要在每个函数的开头插入3个汇编指令的函数,我想通过宏自动执行此操作,因此我不必每次都手动编写它。

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

    //bla bla bla

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

这样的东西应该被替换为

__gshared void jump()
{
    mixin starttemplate();

    //bla bla bla

    mixin endtemplate();
}

在C中我会做这样的事情

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

但如果我尝试这样的话

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

它会抛出一个错误,说我必须在模板上声明一个变量(我不想这样做,因为这里绝对需要性能)。

2 个答案:

答案 0 :(得分:2)

如何将asm命令保存为字符串,并使用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);
}

另一种选择是使用混合来创建整个函数,并将其签名和内容(= body)作为参数传递:

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*/
            })());

答案 1 :(得分:1)

模板mixins只能包含声明(as specified here)。如果你想插入任意代码,你需要字符串mixins:

enum startTemplate = "asm{...}";
enum endTemplate = "asm{...}";

__gshared void jump()
{
    mixin(startTemplate);
    ...etc...
    mixin(endTemplate);
}

您可以使用此机制插入可以使用简单D函数(executed at compile time by the compiler!)生成的自定义程序集:

string customAsm(string param1, bool param2)() @property
{
    string ret = "asm{";

    // append to ret, building up some code

    return ret ~ "}";
}

void myfunc()
{
    mixin(customAsm!("foo", false));
}