* offsets are absolute from start of bytecode.
*/
-enum filter_register {
- REG_R0 = 0,
- REG_R1 = 1,
- REG_ERROR,
-};
-
struct field_ref {
/* Initially, symbol offset. After link, field offset. */
uint16_t offset;
struct load_op {
filter_opcode_t op;
- uint8_t reg; /* enum filter_register */
char data[0];
/* data to load. Size known by enum filter_opcode and null-term char. */
} __attribute__((packed));
struct unary_op {
filter_opcode_t op;
- uint8_t reg; /* enum filter_register */
} __attribute__((packed));
/* skip_offset is absolute from start of bytecode */
struct cast_op {
filter_opcode_t op;
- uint8_t reg; /* enum filter_register */
} __attribute__((packed));
struct return_op {
return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
}
-static
-enum filter_register reg_sel(struct ir_op *node)
-{
- switch (node->side) {
- case IR_SIDE_UNKNOWN:
- default:
- fprintf(stderr, "[error] Unknown node side in %s\n",
- __func__);
- return REG_ERROR;
- case IR_LEFT:
- return REG_R0;
- case IR_RIGHT:
- return REG_R1;
- }
-}
-
static
int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
{
if (!insn)
return -ENOMEM;
insn->op = FILTER_OP_LOAD_STRING;
- insn->reg = reg_sel(node);
- if (insn->reg == REG_ERROR)
- return -EINVAL;
strcpy(insn->data, node->u.load.u.string);
ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
free(insn);
if (!insn)
return -ENOMEM;
insn->op = FILTER_OP_LOAD_S64;
- insn->reg = reg_sel(node);
- if (insn->reg == REG_ERROR)
- return -EINVAL;
*(int64_t *) insn->data = node->u.load.u.num;
ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
free(insn);
if (!insn)
return -ENOMEM;
insn->op = FILTER_OP_LOAD_DOUBLE;
- insn->reg = reg_sel(node);
- if (insn->reg == REG_ERROR)
- return -EINVAL;
*(double *) insn->data = node->u.load.u.flt;
ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
free(insn);
if (!insn)
return -ENOMEM;
insn->op = FILTER_OP_LOAD_FIELD_REF;
- insn->reg = reg_sel(node);
ref_offset.offset = (uint16_t) -1U;
memcpy(insn->data, &ref_offset, sizeof(ref_offset));
- if (insn->reg == REG_ERROR)
- return -EINVAL;
/* reloc_offset points to struct load_op */
reloc_offset = bytecode_get_len(&ctx->bytecode->b);
ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
return 0;
case AST_UNARY_MINUS:
insn.op = FILTER_OP_UNARY_MINUS;
- insn.reg = reg_sel(node);
- if (insn.reg == REG_ERROR)
- return -EINVAL;
return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
case AST_UNARY_NOT:
insn.op = FILTER_OP_UNARY_NOT;
- insn.reg = reg_sel(node);
- if (insn.reg == REG_ERROR)
- return -EINVAL;
return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
}
}
} else {
cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64;
}
- cast_insn.reg = REG_R0;
ret = bytecode_push(&ctx->bytecode, &cast_insn,
1, sizeof(cast_insn));
if (ret)
} else {
cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64;
}
- cast_insn.reg = REG_R0;
ret = bytecode_push(&ctx->bytecode, &cast_insn,
1, sizeof(cast_insn));
if (ret)