Tobias Waldekranz.com 8 年之前
父节点
当前提交
9cc575d452
共有 6 个文件被更改,包括 195 次插入69 次删除
  1. 143 55
      global.c
  2. 10 0
      ir.c
  3. 2 0
      ir.h
  4. 34 11
      ply.c
  5. 4 2
      type.c
  6. 2 1
      type.h

+ 143 - 55
global.c

165
 
165
 
166
 /* :map */
166
 /* :map */
167
 
167
 
168
-static int global_map_ir_pre_key(struct node *n, struct prog *prog)
168
+static int map_ir_update(struct node *n, struct prog *prog)
169
+{
170
+	struct node *map = n->expr.args;
171
+
172
+	ir_emit_ldmap(prog->ir, BPF_REG_1, map->sym);
173
+	ir_emit_insn(prog->ir, MOV, BPF_REG_2, BPF_REG_BP);
174
+	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, map->sym->irs.stack), BPF_REG_2, 0);
175
+	ir_emit_insn(prog->ir, MOV, BPF_REG_3, BPF_REG_BP);
176
+	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, n->sym->irs.stack), BPF_REG_3, 0);
177
+	ir_emit_insn(prog->ir, MOV_IMM(0), BPF_REG_4, 0);
178
+	ir_emit_insn(prog->ir, CALL(BPF_FUNC_map_update_elem), 0, 0);
179
+	/* TODO: if (r0) exit(r0); */
180
+	return 0;
181
+}
182
+
183
+static int map_ir_pre_key(struct node *n, struct prog *prog)
169
 {
184
 {
170
 	struct node *map = n->expr.args, *arg;
185
 	struct node *map = n->expr.args, *arg;
171
 	struct type *ktype = type_base(map->sym->type->map.ktype);
186
 	struct type *ktype = type_base(map->sym->type->map.ktype);
198
 	return 0;
213
 	return 0;
199
 }
214
 }
200
 
215
 
201
-static int global_map_ir_pre(const struct func *func, struct node *n,
202
-			     struct prog *prog)
216
+static int map_ir_pre(const struct func *func, struct node *n,
217
+		      struct prog *prog)
203
 {
218
 {
204
 	struct irstate *kirs;
219
 	struct irstate *kirs;
205
 	struct node *map = n->expr.args;
220
 	struct node *map = n->expr.args;
210
 
225
 
211
 
226
 
212
 	if (ktype->ttype == T_STRUCT)
227
 	if (ktype->ttype == T_STRUCT)
213
-		return global_map_ir_pre_key(n, prog);
228
+		return map_ir_pre_key(n, prog);
214
 
229
 
215
 	kirs = &map->next->sym->irs;
230
 	kirs = &map->next->sym->irs;
216
 	if (!kirs->loc) {
231
 	if (!kirs->loc) {
220
 	return 0;
235
 	return 0;
221
 }
236
 }
222
 
237
 
223
-static int global_map_ir_post(const struct func *func, struct node *n,
224
-			      struct prog *prog)
238
+static int map_ir_post(const struct func *func, struct node *n,
239
+		       struct prog *prog)
225
 {
240
 {
226
 	struct node *map = n->expr.args, *arg;
241
 	struct node *map = n->expr.args, *arg;
227
 	struct type *ktype = type_base(map->sym->type->map.ktype);
242
 	struct type *ktype = type_base(map->sym->type->map.ktype);
231
 	int16_t lmiss, lhit;
246
 	int16_t lmiss, lhit;
232
 
247
 
233
 	arg = map->next;
248
 	arg = map->next;
234
-	tfields_foreach(f, ktype->sou.fields) {
235
-		offset = type_offsetof(ktype, f->name);
236
-		ir_emit_sym_to_stack(prog->ir, stack + offset, arg->sym);
237
-		arg = arg->next;
249
+
250
+	if (ktype->ttype == T_STRUCT) {
251
+		tfields_foreach(f, ktype->sou.fields) {
252
+			offset = type_offsetof(ktype, f->name);
253
+			ir_emit_sym_to_stack(prog->ir, stack + offset, arg->sym);
254
+			arg = arg->next;
255
+		}
256
+	} else {
257
+		ir_emit_sym_to_stack(prog->ir, stack, arg->sym);
258
+		assert(!arg->next);
238
 	}
259
 	}
239
 
260
 
240
 	n->sym->irs.hint.stack = 1;
261
 	n->sym->irs.hint.stack = 1;
264
 	return 0;
285
 	return 0;
265
 }
286
 }
266
 
287
 
267
-static struct type *global_map_ktype(struct node *n)
288
+static struct type *map_key_type(struct node *n)
268
 {
289
 {
269
 	struct node *map, *key;
290
 	struct node *map, *key;
270
 	struct type *ktype;
291
 	struct type *ktype;
296
 	return ktype;
317
 	return ktype;
297
 }
318
 }
298
 
319
 
299
-static int global_map_type_infer(const struct func *func, struct node *n)
320
+static int map_type_validate(struct node *n)
300
 {
321
 {
301
-	struct node *map = n->expr.args;
322
+	/* TODO */
323
+	return 0;
324
+}
302
 
325
 
303
-	if (!map->sym->type)
326
+static int map_type_infer(const struct func *func, struct node *n)
327
+{
328
+	struct node *map, *key;
329
+	struct type *ktype;
330
+
331
+	map = n->expr.args;
332
+	if (!map->sym)
304
 		return 0;
333
 		return 0;
305
 
334
 
306
-	/* TODO validate key against known type */
335
+	if (map->sym->type) {
336
+		if (!n->sym->type)
337
+			/* given `m[key]` where m's type is known,
338
+			 * infer that the expression's type is equal
339
+			 * to m's value type. */
340
+			n->sym->type = map->sym->type->map.vtype;
341
+
342
+		return map_type_validate(n);
343
+	}
307
 
344
 
308
-	/* given `m[key]` where m's type is known, infer that the
309
-	 * expression's type is equal to m's value type. */
310
-	n->sym->type = map->sym->type->map.vtype;
345
+	if (!n->sym->type)
346
+		return 0;
347
+
348
+	for (key = map->next; key; key = key->next) {
349
+		if (type_sizeof(key->sym->type) < 0)
350
+			return 0;
351
+	}
352
+
353
+	map->sym->type = type_map_of(map_key_type(n), n->sym->type);
311
 	return 0;
354
 	return 0;
312
 }
355
 }
313
 
356
 
314
-static int global_map_static_validate(const struct func *func, struct node *n)
357
+static int map_static_validate(const struct func *func, struct node *n)
315
 {
358
 {
316
 	if (n->expr.args->ntype != N_IDENT) {
359
 	if (n->expr.args->ntype != N_IDENT) {
317
 		_e("%#N: can't lookup a key in %N, which is not a map.\n",
360
 		_e("%#N: can't lookup a key in %N, which is not a map.\n",
347
 static int global_assign_ir_post(const struct func *func, struct node *n,
390
 static int global_assign_ir_post(const struct func *func, struct node *n,
348
 				 struct prog *prog)
391
 				 struct prog *prog)
349
 {
392
 {
350
-	struct node *lval, *rval, *map;
393
+	struct node *lval, *rval;
351
 
394
 
352
 	lval = n->expr.args;
395
 	lval = n->expr.args;
353
 	rval = lval->next;
396
 	rval = lval->next;
356
 	if (!node_is(lval, "{}"))
399
 	if (!node_is(lval, "{}"))
357
 		return 0;
400
 		return 0;
358
 
401
 
359
-	map = lval->expr.args;
360
-
361
-	ir_emit_ldmap(prog->ir, BPF_REG_1, map->sym);
362
-	ir_emit_insn(prog->ir, MOV, BPF_REG_2, BPF_REG_BP);
363
-	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, map->sym->irs.stack), BPF_REG_2, 0);
364
-	ir_emit_insn(prog->ir, MOV, BPF_REG_3, BPF_REG_BP);
365
-	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, lval->sym->irs.stack), BPF_REG_3, 0);
366
-	ir_emit_insn(prog->ir, MOV_IMM(0), BPF_REG_4, 0);
367
-	ir_emit_insn(prog->ir, CALL(BPF_FUNC_map_update_elem), 0, 0);
368
-	/* TODO: if (r0) exit(r0); */
369
-	return 0;
370
-}
371
-
372
-static int global_assign_type_infer_map(struct node *n)
373
-{
374
-	struct node *map, *key;
375
-	struct type *ktype;
376
-
377
-	map = n->expr.args;
378
-
379
-	for (key = map->next; key; key = key->next) {
380
-		if (type_sizeof(key->sym->type) < 0)
381
-			return 0;
382
-	}
383
-
384
-	map->sym->type = type_map_of(global_map_ktype(n), n->sym->type);
385
-	return 0;
402
+	return map_ir_update(lval, prog);
386
 }
403
 }
387
 
404
 
388
 static int global_assign_type_infer(const struct func *func, struct node *n)
405
 static int global_assign_type_infer(const struct func *func, struct node *n)
389
 {
406
 {
390
 	struct node *lval, *rval;
407
 	struct node *lval, *rval;
408
+	int err;
391
 
409
 
392
 	if (n->sym->type)
410
 	if (n->sym->type)
393
 		return 0;
411
 		return 0;
406
 		/* TODO do we need assignment expressions? */
424
 		/* TODO do we need assignment expressions? */
407
 		n->sym->type = &t_void;
425
 		n->sym->type = &t_void;
408
 		
426
 		
409
-		if (node_is(lval, "{}"))
410
-			return global_assign_type_infer_map(lval);
427
+		if (!node_is(lval, "{}"))
428
+			return 0;
411
 
429
 
412
-		return 0;
430
+		err = map_type_infer(lval->sym->func, lval);
431
+		if (err)
432
+			return err;
413
 	}
433
 	}
414
 
434
 
415
 	if (type_compatible(lval->sym->type, rval->sym->type))
435
 	if (type_compatible(lval->sym->type, rval->sym->type))
458
 	return 0;
478
 	return 0;
459
 }
479
 }
460
 
480
 
461
-/* :binop */
481
+
482
+/* count() */
483
+
484
+struct type t_count = {
485
+	.ttype = T_SCALAR,
486
+
487
+	.scalar = {
488
+		.name = ":count",
489
+		.size = sizeof(unsigned long),
490
+		.is_signed = 0,
491
+	},
492
+
493
+	.aggregation = 1,
494
+};
495
+
496
+static int count_ir_post(const struct func *func, struct node *n,
497
+			 struct prog *prog)
498
+{
499
+	struct node *mapop = n->expr.args;
500
+
501
+	ir_emit_sym_to_reg(prog->ir, BPF_REG_0, mapop->sym);
502
+	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, 1), BPF_REG_0, 0);
503
+	ir_emit_reg_to_sym(prog->ir, mapop->sym, BPF_REG_0);
504
+
505
+	return map_ir_update(mapop, prog);
506
+}
507
+
508
+static int count_type_infer(const struct func *func, struct node *n)
509
+{
510
+	struct node *mapop;
511
+	struct type *t;
512
+
513
+	mapop = n->expr.args;
514
+
515
+	if (n->sym->type)
516
+		return 0;
517
+
518
+	n->sym->type = &t_void;
519
+
520
+	if (!mapop->sym->type) {
521
+		mapop->sym->type = &t_count;
522
+		return map_type_infer(mapop->sym->func, mapop);
523
+	}
524
+
525
+	return 0;
526
+}
527
+
528
+static int count_static_validate(const struct func *func, struct node *n)
529
+{
530
+	struct node *mapop;
531
+
532
+	mapop = n->expr.args;
533
+
534
+	if (node_is(mapop, "{}"))
535
+		return 0;
536
+
537
+	_e("%#N: aggregation target must be a map, %N is not.\n", n, mapop);
538
+	return -EINVAL;
539
+}
540
+
541
+
542
+/* quantize */
462
 
543
 
463
 static int global_quantize_type_infer(const struct func *func, struct node *n)
544
 static int global_quantize_type_infer(const struct func *func, struct node *n)
464
 {
545
 {
640
 	{
721
 	{
641
 		.name = "{}",
722
 		.name = "{}",
642
 		/* .type = t_map_func, */
723
 		/* .type = t_map_func, */
643
-		.type_infer = global_map_type_infer,
644
-		.static_validate = global_map_static_validate,
724
+		.type_infer = map_type_infer,
725
+		.static_validate = map_static_validate,
645
 
726
 
646
-		.ir_pre  = global_map_ir_pre,
647
-		.ir_post = global_map_ir_post,
727
+		.ir_pre  = map_ir_pre,
728
+		.ir_post = map_ir_post,
648
 	},
729
 	},
730
+	{
731
+		.name = "count",
732
+		.type = &t_1arg_func,
733
+		.static_validate = count_static_validate,
734
+		.type_infer = count_type_infer,
649
 
735
 
736
+		.ir_post = count_ir_post,
737
+	},
650
 	{
738
 	{
651
 		.name = "pid",
739
 		.name = "pid",
652
 		.type = &t_pid_func,
740
 		.type = &t_pid_func,

+ 10 - 0
ir.c

180
 
180
 
181
 	if (BPF_CLASS(insn.code) == BPF_LDX || BPF_CLASS(insn.code) == BPF_STX)
181
 	if (BPF_CLASS(insn.code) == BPF_LDX || BPF_CLASS(insn.code) == BPF_STX)
182
 		goto reg_src;
182
 		goto reg_src;
183
+	else if (BPF_CLASS(insn.code) == BPF_ST)
184
+		goto imm_src;
183
 
185
 
184
 	switch (BPF_SRC(insn.code)) {
186
 	switch (BPF_SRC(insn.code)) {
185
 	case BPF_K:
187
 	case BPF_K:
188
+	imm_src:
186
 		fprintf(fp, "#%s0x%x", insn.imm < 0 ? "-" : "",
189
 		fprintf(fp, "#%s0x%x", insn.imm < 0 ? "-" : "",
187
 			insn.imm < 0 ? -insn.imm : insn.imm);
190
 			insn.imm < 0 ? -insn.imm : insn.imm);
188
 		break;
191
 		break;
530
 	ir->next_label = -1;
533
 	ir->next_label = -1;
531
 	return ir;
534
 	return ir;
532
 }
535
 }
536
+
537
+
538
+
539
+int ir_generate_bpf(struct ir *ir)
540
+{
541
+	return 0;
542
+}

+ 2 - 0
ir.h

153
 
153
 
154
 struct ir *ir_new(void);
154
 struct ir *ir_new(void);
155
 
155
 
156
+int ir_generate_bpf(struct ir *ir);
157
+
156
 #endif	/* _PLY_IR_H */
158
 #endif	/* _PLY_IR_H */

+ 34 - 11
ply.c

82
 			  /* 	    node_ident("us"), */
82
 			  /* 	    node_ident("us"), */
83
 			  /* 	    node_expr("pid", NULL), */
83
 			  /* 	    node_expr("pid", NULL), */
84
 			  /* 	    NULL), */
84
 			  /* 	    NULL), */
85
-			  node_expr("=",
86
-				    node_expr("{}",
87
-					      node_ident("t"),
88
-					      node_expr("pid", NULL),
89
-					      node_num("0x10000000"),
85
+			  /* node_expr("=", */
86
+			  /* 	    node_expr("{}", */
87
+			  /* 		      node_ident("t"), */
88
+			  /* 		      node_expr("pid", NULL), */
89
+			  /* 		      node_num("0x10000000"), */
90
+			  /* 		      NULL), */
91
+			  /* 	    node_expr("time", NULL), */
92
+			  /* 	    NULL), */
93
+			  node_expr("count",
94
+			  	    node_expr("{}",
95
+			  		      node_ident("reads"),
96
+			  		      node_expr("pid", NULL),
97
+					      node_ident("arg0"),
90
 					      NULL),
98
 					      NULL),
91
-				    node_expr("time", NULL),
92
-				    NULL),
99
+			  	    NULL),
93
 			  /* node_expr("=", */
100
 			  /* node_expr("=", */
94
 			  /* 	    node_expr("{}", */
101
 			  /* 	    node_expr("{}", */
95
 			  /* 		      node_ident("reads"), */
102
 			  /* 		      node_ident("reads"), */
213
 	return 0;
220
 	return 0;
214
 }
221
 }
215
 
222
 
223
+int run_walk(struct pass *pass, struct ctx *ctx)
224
+{
225
+	struct prog **prog;
226
+	int err;
227
+
228
+	for (prog = ctx->progs; *prog; prog++) {
229
+		err = node_walk((*prog)->ast, pass->pre, pass->post, *prog);
230
+		if (err)
231
+			return err;
232
+	}
233
+
234
+	return 0;
235
+}
236
+
216
 int run_ir(struct pass *pass, struct ctx *ctx)
237
 int run_ir(struct pass *pass, struct ctx *ctx)
217
 {
238
 {
218
 	struct prog **progp;
239
 	struct prog **progp;
241
 	return 0;
262
 	return 0;
242
 }
263
 }
243
 
264
 
244
-int run_walk(struct pass *pass, struct ctx *ctx)
265
+int run_bpf(struct pass *pass, struct ctx *ctx)
245
 {
266
 {
246
-	struct prog **prog;
267
+	struct prog **progp;
247
 	int err;
268
 	int err;
248
 
269
 
249
-	for (prog = ctx->progs; *prog; prog++) {
250
-		err = node_walk((*prog)->ast, pass->pre, pass->post, *prog);
270
+	for (progp = ctx->progs; *progp; progp++) {
271
+		struct prog *prog = *progp;
272
+
273
+		err = ir_generate_bpf(prog->ir);
251
 		if (err)
274
 		if (err)
252
 			return err;
275
 			return err;
253
 	}
276
 	}

+ 4 - 2
type.c

31
 	struct tfield *arg;
31
 	struct tfield *arg;
32
 
32
 
33
 	type_dump(t->func.type, NULL, fp);
33
 	type_dump(t->func.type, NULL, fp);
34
-	fprintf(fp, " %s(*\e[1m%s\e[0m)(",
35
-		t->func.aggregation ? "@" : "", name ? : "");
34
+	fprintf(fp, " (*\e[1m%s\e[0m)(", name ? : "");
36
 
35
 
37
 	if (!t->func.args) {
36
 	if (!t->func.args) {
38
 		__faint(fp, t->func.vargs ? "..." : "void");
37
 		__faint(fp, t->func.vargs ? "..." : "void");
60
 		goto print_name;
59
 		goto print_name;
61
 	}
60
 	}
62
 
61
 
62
+	if (t->aggregation)
63
+		fputc('@', fp);
64
+
63
 	switch (t->ttype){
65
 	switch (t->ttype){
64
 	case T_VOID:
66
 	case T_VOID:
65
 		__faint(fp, "void");
67
 		__faint(fp, "void");

+ 2 - 1
type.h

52
 	struct tfield *args;
52
 	struct tfield *args;
53
 
53
 
54
 	int vargs:1;
54
 	int vargs:1;
55
-	int aggregation:1;
56
 };
55
 };
57
 
56
 
58
 enum ttype {
57
 enum ttype {
78
 		struct tstruct sou;
77
 		struct tstruct sou;
79
 		struct tfunc func;
78
 		struct tfunc func;
80
 	};
79
 	};
80
+
81
+	int aggregation:1;
81
 };
82
 };
82
 
83
 
83
 int type_equal     (struct type *a, struct type *b);
84
 int type_equal     (struct type *a, struct type *b);