return 0;
}
-#define INTERPRETER_USE_SWITCH
-
#ifdef INTERPRETER_USE_SWITCH
+/*
+ * Fallback for compilers that do not support taking address of labels.
+ */
+
#define START_OP \
start_pc = &bytecode->data[0]; \
for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
#else
-#define OP(name)
+/*
+ * Dispatch-table based interpreter.
+ */
+
+#define START_OP \
+ start_pc = &bytecode->data[0]; \
+ pc = next_pc = start_pc; \
+ if (unlikely(pc - start_pc >= bytecode->len)) \
+ goto end; \
+ goto *dispatch[*(filter_opcode_t *) pc];
+
+#define OP(name) \
+LABEL_##name
+
+#define PO \
+ pc = next_pc; \
+ goto *dispatch[*(filter_opcode_t *) pc];
+
+#define END_OP
#endif
struct reg reg[NR_REG];
#ifndef INTERPRETER_USE_SWITCH
static void *dispatch[NR_FILTER_OPS] = {
- [ FILTER_OP_UNKNOWN ] = &&LABEL_FILTER_OP_UNKNOWN = 0,
+ [ FILTER_OP_UNKNOWN ] = &&LABEL_FILTER_OP_UNKNOWN,
[ FILTER_OP_RETURN ] = &&LABEL_FILTER_OP_RETURN,
return retval;
}
+#undef START_OP
+#undef OP
+#undef PO
+#undef END_OP
+
static
int bin_op_compare_check(struct vreg reg[NR_REG], const char *str)
{