#include #include #include "func.h" #include "node.h" #include "ply.h" #include "sym.h" #if 0 /* pid */ int pid_generate_ir(prog_t *prog, node_t *node) { /* TODO */ return 0; } type_t t_pid_t = { .ttype = T_TYPEDEF, .t.tdef = { .name = "__ply_pid_t", .type = &t_u32, }, }; type_t t_pid_func = { .ttype = T_FUNC, .t.func = { .name = "pid", .type = &t_pid_t, .args = NULL, .generate_ir = pid_generate_ir, }, }; type_t *ts_pid[] = { &t_pid_t, &t_pid_func, NULL }; /* quantize */ int quantize_generate_ir(prog_t *prog, node_t *node) { /* TODO */ return 0; } type_t t_u64_64 = { .ttype = T_ARRAY, .t.array = { .type = &t_u64, .len = 64, }, }; type_t t_quantize_t = { .ttype = T_TYPEDEF, .t.tdef = { .name = "__ply_quantize_t", .type = &t_u64_64, }, }; field_t f_quantize_args[] = { { .type = &t_s64 }, { .type = NULL } }; type_t t_quantize_func = { .ttype = T_FUNC, .t.func = { .name = "quantize", .type = &t_quantize_t, .args = f_quantize_args, .generate_ir = quantize_generate_ir, }, }; type_t *ts_quantize[] = { &t_u64_64, &t_quantize_t, &t_quantize_func, NULL }; /* time */ int time_generate_ir(prog_t *prog, node_t *node) { ir_emit_call(prog->ir, BPF_FUNC_ktime_get_ns); irs_alloc_reg(&node->irs, prog->ir); ir_emit_insn(prog->ir, MOV(0, 0), node->irs.reg, BPF_REG_0); return 0; } type_t t_time_t = { .ttype = T_TYPEDEF, .t.tdef = { .name = "__ply_time_t", .type = &t_s64, }, }; type_t t_time_func = { .ttype = T_FUNC, .t.func = { .name = "time", .type = &t_time_t, .args = NULL, .generate_ir = time_generate_ir, }, }; type_t *ts_time[] = { &t_time_t, &t_time_func, NULL }; #endif /* int global_resolve(prog_t *prog, node_t *n) */ /* { */ /* type_t **ts = NULL; */ /* type_t *t; */ /* int err; */ /* if (!strcmp(n->ident, "pid")) { */ /* ts = ts_pid; */ /* t = &t_pid_func; */ /* } else if (!strcmp(n->ident, "quantize")) { */ /* ts = ts_quantize; */ /* t = &t_quantize_func; */ /* } else if (!strcmp(n->ident, "time")) { */ /* ts = ts_time; */ /* t = &t_time_func; */ /* } else { */ /* return -ENOENT; */ /* } */ /* if (ts) { */ /* err = type_add_list(ts); */ /* if (err) */ /* return err; */ /* } */ /* n->type = t; */ /* return sym_add(prog->locals, n->ident, t, &n->sym); */ /* } */ static const struct func global_funcs[] = { /* block */ { .name = "{}", }, { .name = "+", }, { .name = "-", }, { .name = "=", }, { .name = "[]", }, { .name = "pid", }, { .name = "time", }, { .name = "quantize", }, { .name = NULL } }; static const struct func global_num_func = { .name = ":num", }; static const struct func global_string_func = { .name = ":string", }; static const struct func global_ident_func = { .name = ":ident", }; int global_sym_alloc(struct prog *prog, struct node *n) { const struct func *func; switch (n->ntype) { case N_EXPR: for (func = global_funcs; func->name; func++) { if (strcmp(func->name, n->expr.func)) continue; n->sym = sym_alloc(prog->locals, n, func); return 0; } return -ENOENT; case N_IDENT: n->sym = sym_alloc(prog->globals, n, &global_ident_func); return 0; case N_NUM: n->sym = sym_alloc(prog->locals, n, &global_num_func); return 0; case N_STRING: n->sym = sym_alloc(prog->locals, n, &global_string_func); return 0; } return -ENOENT; } int global_probe(struct prog *prog) { return 0; } struct provider global = { .name = ":", .sym_alloc = global_sym_alloc, .probe = global_probe, }; __attribute__((constructor)) static void global_init(void) { provider_register(&global); }