|
|
@@ -38,7 +38,7 @@ void provider_register(provider_t *prov)
|
|
38
|
38
|
|
|
39
|
39
|
typedef struct pass pass_t;
|
|
40
|
40
|
struct pass {
|
|
41
|
|
- int (*run)(pass_t *, prog_t *);
|
|
|
41
|
+ int (*run)(pass_t *, ctx_t *);
|
|
42
|
42
|
walk_fn pre;
|
|
43
|
43
|
walk_fn post;
|
|
44
|
44
|
};
|
|
|
@@ -47,19 +47,29 @@ struct pass {
|
|
47
|
47
|
symtab_t globals = { .sym = NULL, .len = 0 };
|
|
48
|
48
|
symtab_t locals = { .sym = NULL, .len = 0 };
|
|
49
|
49
|
|
|
50
|
|
-prog_t *prog_get(void)
|
|
|
50
|
+ctx_t *ctx_get(void)
|
|
51
|
51
|
{
|
|
|
52
|
+ ctx_t *ctx;
|
|
52
|
53
|
prog_t *prog;
|
|
53
|
54
|
|
|
54
|
|
- prog = calloc(1, sizeof(*prog));
|
|
|
55
|
+ ctx = calloc(1, sizeof(*ctx));
|
|
|
56
|
+ ctx->globals = calloc(1, sizeof(*ctx->globals));
|
|
|
57
|
+
|
|
|
58
|
+ ctx->progs = calloc(3, sizeof(*ctx->progs));
|
|
55
|
59
|
|
|
56
|
|
- prog->locals = &locals;
|
|
57
|
|
- prog->globals = &globals;
|
|
|
60
|
+ /* PROBE0 */
|
|
|
61
|
+ prog = calloc(1, sizeof(*prog));
|
|
|
62
|
+ prog->locals = calloc(1, sizeof(*prog->locals));
|
|
|
63
|
+ prog->globals = ctx->globals;
|
|
58
|
64
|
|
|
59
|
|
- /* (@ ([ reads ((pid))) (quantize arg2)) */
|
|
60
|
|
- prog->probe = "k:SyS_read"; /* { @reads[pid()] = quantize(arg2) } */
|
|
|
65
|
+ prog->probe = "k:SyS_read";
|
|
|
66
|
+ /* { t0 = time(); @reads[pid()] = quantize(arg2) } */
|
|
61
|
67
|
prog->ast =
|
|
62
|
|
- node_list(
|
|
|
68
|
+ node_vlist(
|
|
|
69
|
+ node_vlist(node_keyword('='),
|
|
|
70
|
+ node_ident("t0"),
|
|
|
71
|
+ node_list(node_ident("time")),
|
|
|
72
|
+ NULL),
|
|
63
|
73
|
node_vlist(node_keyword('='),
|
|
64
|
74
|
node_vlist(node_keyword('['),
|
|
65
|
75
|
node_ident("@reads"),
|
|
|
@@ -68,12 +78,42 @@ prog_t *prog_get(void)
|
|
68
|
78
|
node_vlist(node_ident("quantize"),
|
|
69
|
79
|
node_ident("arg2"),
|
|
70
|
80
|
NULL),
|
|
|
81
|
+ NULL),
|
|
|
82
|
+ NULL);
|
|
|
83
|
+
|
|
|
84
|
+ prog->provider = provider_get("k");
|
|
|
85
|
+ prog->provider->probe(prog);
|
|
|
86
|
+ ctx->progs[0] = prog;
|
|
|
87
|
+
|
|
|
88
|
+ /* PROBE1 */
|
|
|
89
|
+ prog = calloc(1, sizeof(*prog));
|
|
|
90
|
+ prog->locals = calloc(1, sizeof(*prog->locals));
|
|
|
91
|
+ prog->globals = ctx->globals;
|
|
|
92
|
+
|
|
|
93
|
+ /* TODO: k -> kret */
|
|
|
94
|
+ prog->probe = "k:SyS_read2";
|
|
|
95
|
+ /* { @times[pid()] = quantize(time() - t0) } */
|
|
|
96
|
+ prog->ast =
|
|
|
97
|
+ node_list(
|
|
|
98
|
+ node_vlist(node_keyword('='),
|
|
|
99
|
+ node_vlist(node_keyword('['),
|
|
|
100
|
+ node_ident("@times"),
|
|
|
101
|
+ node_list(node_ident("pid")),
|
|
|
102
|
+ NULL),
|
|
|
103
|
+ node_vlist(node_ident("quantize"),
|
|
|
104
|
+ node_vlist(node_keyword('-'),
|
|
|
105
|
+ node_list(node_ident("time")),
|
|
|
106
|
+ node_ident("t0"),
|
|
|
107
|
+ NULL),
|
|
|
108
|
+ NULL),
|
|
71
|
109
|
NULL)
|
|
72
|
110
|
);
|
|
73
|
111
|
|
|
74
|
112
|
prog->provider = provider_get("k");
|
|
75
|
113
|
prog->provider->probe(prog);
|
|
76
|
|
- return prog;
|
|
|
114
|
+ ctx->progs[1] = prog;
|
|
|
115
|
+
|
|
|
116
|
+ return ctx;
|
|
77
|
117
|
}
|
|
78
|
118
|
|
|
79
|
119
|
|
|
|
@@ -142,12 +182,32 @@ int infer_type_keyword(prog_t *prog, node_t *n)
|
|
142
|
182
|
if (!src->type)
|
|
143
|
183
|
return 0;
|
|
144
|
184
|
|
|
145
|
|
- if (!dst->type)
|
|
146
|
|
- dst->type = src->type;
|
|
147
|
|
-
|
|
148
|
185
|
/* TODO: assignment is statement for now. do we need
|
|
149
|
186
|
* c-style assignment expressions? e.g `a = b = 2;` */
|
|
150
|
187
|
n->type = &t_v;
|
|
|
188
|
+
|
|
|
189
|
+ if (dst->type)
|
|
|
190
|
+ return 0;
|
|
|
191
|
+
|
|
|
192
|
+ dst->type = src->type;
|
|
|
193
|
+
|
|
|
194
|
+ if (dst->ntype != N_IDENT)
|
|
|
195
|
+ return 0;
|
|
|
196
|
+
|
|
|
197
|
+ return sym_add(dst->sym->st, dst->ident, dst->type, NULL);
|
|
|
198
|
+
|
|
|
199
|
+ case KW_ADD:
|
|
|
200
|
+ case KW_SUB:
|
|
|
201
|
+ case KW_MUL:
|
|
|
202
|
+ case KW_DIV:
|
|
|
203
|
+ dst = node_next(n);
|
|
|
204
|
+ src = node_next(dst);
|
|
|
205
|
+ assert(dst && src);
|
|
|
206
|
+
|
|
|
207
|
+ if (!(src->type && dst->type && type_equal(src->type, dst->type)))
|
|
|
208
|
+ return 0;
|
|
|
209
|
+
|
|
|
210
|
+ n->type = dst->type;
|
|
151
|
211
|
return 0;
|
|
152
|
212
|
|
|
153
|
213
|
default:
|
|
|
@@ -161,8 +221,14 @@ int infer_type_sym(prog_t *prog, node_t *n)
|
|
161
|
221
|
{
|
|
162
|
222
|
node_t *parent, *key;
|
|
163
|
223
|
|
|
164
|
|
- if (n->sym->type)
|
|
|
224
|
+ if (n->sym->type) {
|
|
|
225
|
+ /* the symbol type could have been inferred in another
|
|
|
226
|
+ * probe, in that case copy the type to this node. */
|
|
|
227
|
+ if (!n->type)
|
|
|
228
|
+ n->type = n->sym->type;
|
|
|
229
|
+
|
|
165
|
230
|
return 0;
|
|
|
231
|
+ }
|
|
166
|
232
|
|
|
167
|
233
|
parent = node_up(n);
|
|
168
|
234
|
key = node_next(n);
|
|
|
@@ -203,39 +269,64 @@ int pass_infer_types(node_t *n, void *_prog)
|
|
203
|
269
|
return 0;
|
|
204
|
270
|
}
|
|
205
|
271
|
|
|
|
272
|
+/* int pass_walk(pass_t *pass, prog_t *prog) */
|
|
|
273
|
+/* { */
|
|
|
274
|
+/* return node_walk(prog->ast, pass->pre, pass->post, prog); */
|
|
|
275
|
+/* } */
|
|
206
|
276
|
|
|
207
|
|
-int pass_walk(pass_t *pass, prog_t *prog)
|
|
|
277
|
+int pass_validate_types(node_t *n, void *_prog)
|
|
208
|
278
|
{
|
|
209
|
|
- return node_walk(prog->ast, pass->pre, pass->post, prog);
|
|
|
279
|
+ prog_t *prog = _prog;
|
|
|
280
|
+
|
|
|
281
|
+
|
|
|
282
|
+ return 0;
|
|
|
283
|
+}
|
|
|
284
|
+
|
|
|
285
|
+int pass_walk(pass_t *pass, ctx_t *ctx)
|
|
|
286
|
+{
|
|
|
287
|
+ prog_t **prog;
|
|
|
288
|
+ int err;
|
|
|
289
|
+
|
|
|
290
|
+ for (prog = ctx->progs; *prog; prog++) {
|
|
|
291
|
+ err = node_walk((*prog)->ast, pass->pre, pass->post, *prog);
|
|
|
292
|
+ if (err)
|
|
|
293
|
+ return err;
|
|
|
294
|
+ }
|
|
|
295
|
+
|
|
|
296
|
+ return 0;
|
|
210
|
297
|
}
|
|
211
|
298
|
|
|
212
|
299
|
pass_t passes[] = {
|
|
213
|
300
|
{ .run = pass_walk, .post = pass_resolve_symbols },
|
|
214
|
301
|
{ .run = pass_walk, .post = pass_infer_types },
|
|
215
|
302
|
{ .run = pass_walk, .post = pass_infer_types },
|
|
|
303
|
+ { .run = pass_walk, .post = pass_infer_types },
|
|
|
304
|
+ { .run = pass_walk, .post = pass_validate_types },
|
|
216
|
305
|
|
|
217
|
306
|
{ NULL }
|
|
218
|
307
|
};
|
|
219
|
308
|
|
|
220
|
309
|
int main(void)
|
|
221
|
310
|
{
|
|
222
|
|
- prog_t *prog = prog_get();
|
|
|
311
|
+ ctx_t *ctx = ctx_get();
|
|
|
312
|
+ prog_t **prog;
|
|
223
|
313
|
pass_t *pass;
|
|
224
|
314
|
int err;
|
|
225
|
315
|
|
|
226
|
316
|
for (pass = passes; pass->run; pass++) {
|
|
227
|
|
- err = pass->run(pass, prog);
|
|
|
317
|
+ err = pass->run(pass, ctx);
|
|
228
|
318
|
if (err)
|
|
229
|
319
|
break;
|
|
230
|
320
|
}
|
|
231
|
321
|
|
|
232
|
|
- printf("AST\n===\n");
|
|
233
|
|
- node_dump(prog->ast, stdout);
|
|
234
|
|
- printf("\nLOCALS\n======\n");
|
|
235
|
|
- symtab_dump(prog->locals, stdout);
|
|
236
|
|
- printf("\nGLOBALS\n=======\n");
|
|
237
|
|
- symtab_dump(prog->globals, stdout);
|
|
238
|
|
- /* printf("\nTYPES\n=====\n"); */
|
|
239
|
|
- /* types_dump_cdecl(stdout); */
|
|
|
322
|
+ for (prog = ctx->progs; *prog; prog++) {
|
|
|
323
|
+ printf("\n\e[34m%s\e[0m\n", (*prog)->probe);
|
|
|
324
|
+ node_dump((*prog)->ast, stdout);
|
|
|
325
|
+ printf("\n-- locals\n");
|
|
|
326
|
+ symtab_dump((*prog)->locals, stdout);
|
|
|
327
|
+ }
|
|
|
328
|
+
|
|
|
329
|
+ printf("\n\n-- globals\n");
|
|
|
330
|
+ symtab_dump(ctx->globals, stdout);
|
|
240
|
331
|
return err;
|
|
241
|
332
|
}
|