为什么在“案例”中使用预处理器指令?声明?

时间:2016-08-09 22:04:23

标签: c++

我正在浏览SpiderMonkey引擎源,并在解释器中看到了一些引起我兴趣的代码。

window.location.href=url

(来源: https://dxr.mozilla.org/mozilla-b2g44_v2_5/source/js/src/vm/Interpreter.cpp#1579

// Portable switch-based dispatch. # define INTERPRETER_LOOP() the_switch: switch (switchOp) # define CASE(OP) case OP: # define DEFAULT() default: 定义为case OP:这样的内容是否有任何非风格上的好处?

2 个答案:

答案 0 :(得分:11)

半个屏幕

Look up

#if (defined(__GNUC__) ||                                                         \
     (__IBMC__ >= 700 && defined __IBM_COMPUTED_GOTO) ||                      \
     __SUNPRO_C >= 0x570)
// Non-standard but faster indirect-goto-based dispatch.
# define INTERPRETER_LOOP()
# define CASE(OP)                 label_##OP:
// ... <snip>
#else
// Portable switch-based dispatch.
# define INTERPRETER_LOOP()       the_switch: switch (switchOp)
# define CASE(OP)                 case OP:
// ... <snip>
#endif

GCC和其他一些编译器支持"computed goto" faster than a loop-switch for an interpreter loop,但它是非标准的,因此不可移植。

如果编译器支持计算goto,则此#if的第一个分支定义INTERPRETER_LOOPCASE(OP)等以使用计算的goto;否则,#else分支根据标准设施定义它们。

答案 1 :(得分:7)

如果你在相同的源代码中看起来更高,那么对于不同的编译器语法,这些相同的宏有不同的定义:

/*
 * Define macros for an interpreter loop. Opcode dispatch may be either by a
 * switch statement or by indirect goto (aka a threaded interpreter), depending
 * on compiler support.
 *
 * Threaded interpretation appears to be well-supported by GCC 3 and higher.
 * IBM's C compiler when run with the right options (e.g., -qlanglvl=extended)
 * also supports threading. Ditto the SunPro C compiler.
 */
#if (defined(__GNUC__) ||                                                         \
     (__IBMC__ >= 700 && defined __IBM_COMPUTED_GOTO) ||                      \
     __SUNPRO_C >= 0x570)
// Non-standard but faster indirect-goto-based dispatch.
# define INTERPRETER_LOOP()
# define CASE(OP)                 label_##OP:
# define DEFAULT()                label_default:
# define DISPATCH_TO(OP)          goto* addresses[(OP)]

//...

#else
// Portable switch-based dispatch.
# define INTERPRETER_LOOP()       the_switch: switch (switchOp)
# define CASE(OP)                 case OP:
# define DEFAULT()                default:
# define DISPATCH_TO(OP)                                                      \
    JS_BEGIN_MACRO                                                            \
        switchOp = (OP);                                                      \
        goto the_switch;                                                      \
    JS_END_MACRO

// ...

#endif

如果你在同一个源中进一步查看,你会看到实际使用这些宏:

INTERPRETER_LOOP() {

CASE(EnableInterruptsPseudoOpcode)
{
    //...
    DISPATCH_TO(op);
}

* Various 1-byte no-ops. */
CASE(JSOP_NOP)
CASE(JSOP_UNUSED14)
CASE(JSOP_BACKPATCH)
//...
{
    //...
    ADVANCE_AND_DISPATCH(1);
}

CASE(JSOP_LOOPHEAD)
END_CASE(JSOP_LOOPHEAD)

//...

DEFAULT()
{
    //...
    goto error;
}

} /* interpreter loop */

根据编译器的不同,该代码将编译为:

static const void* const addresses[EnableInterruptsPseudoOpcode + 1] = {
    ...
};

...

{

label_EnableInterruptsPseudoOpcode:
{
    //...
    goto* addresses[op];
}

* Various 1-byte no-ops. */
label_JSOP_NOP:
label_JSOP_UNUSED14:
label_JSOP_BACKPATCH:
//...
{
    //...
    REGS.pc += 1;
    SANITY_CHECKS();
    goto* addresses[*REGS.pc | activation.opMask()];
}

label_JSOP_LOOPHEAD:
    goto* addresses[JSOP_LOOPHEAD_LENGTH];

//...

label_default:
{
    //...
    goto error;
}

} /* interpreter loop */

或者对此:

jsbytecode switchOp;

...

the_switch:
switch (switchOp) {

case EnableInterruptsPseudoOpcode:
{
    //...
    switchOp = op;
    goto the_switch;
}

* Various 1-byte no-ops. */
case JSOP_NOP:
case JSOP_UNUSED14:
case JSOP_BACKPATCH:
//...
{
    //...
    REGS.pc += 1;
    SANITY_CHECKS();
    switchOp = *REGS.pc | activation.opMask;
    goto the_switch;
}

case JSOP_LOOPHEAD:
    REGS.pc += JSOP_LOOPHEAD_LENGTH;
    SANITY_CHECKS();
    switchOp = *REGS.pc | activation.opMask();
    goto the_switch;  

//...

default:
{
    //...
    goto error;
}

} /* interpreter loop */