b84f6c8f2c63371bec2cc680546f11a505f5eda4
13 static inline void dump_level(int fd
, unsigned level
) {
14 dprintf(fd
, "%.*s", level
> 30 ? 30 : level
,
15 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t");
18 static inline void dump_decl_arg(int fd
, decl_arg
*darg
, unsigned level
);
19 static inline void dump_struct_args(int fd
, decl_args
*args
, unsigned level
);
20 static inline void dump_enum_items(int fd
, decl_enum_items
*items
, unsigned level
);
22 #define is_anon_type(name, type) !strncmp(name, type "@", sizeof(type))
24 static inline void dump_decl_type(int fd
, decl_type
*t
, unsigned level
) {
27 dprintf(fd
, "%s *", t
->name
);
31 dprintf(fd
, "struct ");
32 if (!strncmp(t
->name
, "struct@", sizeof("struct"))) {
33 dump_struct_args(fd
, t
->real
.strct
->args
, level
);
40 if (!strncmp(t
->name
, "enum@", sizeof("enum"))) {
41 dump_enum_items(fd
, t
->real
.enm
->items
, level
);
47 dprintf(fd
, "union ");
48 if (!strncmp(t
->name
, "union@", sizeof("union"))) {
49 dump_struct_args(fd
, t
->real
.unn
->args
, level
);
54 dprintf(fd
, "%s", t
->name
);
57 static inline void dump_decl_var(int fd
, decl_var
*v
) {
58 dprintf(fd
, "%.*s%s", v
->pointer_level
-!!v
->array_size
, "**********", v
->name
);
60 dprintf(fd
, "[%u]", v
->array_size
);
64 static inline void dump_decl_arg(int fd
, decl_arg
*a
, unsigned level
) {
65 if (a
->type
->type
== PSI_T_FUNCTION
) {
66 dump_decl_type(fd
, a
->type
->real
.func
->func
->type
, level
);
68 dump_decl_var(fd
, a
->var
);
70 if (a
->type
->real
.func
->args
) {
73 for (j
= 0; j
< a
->type
->real
.func
->args
->count
; ++j
) {
77 dump_decl_arg(fd
, a
->type
->real
.func
->args
->args
[j
], level
+1);
79 if (a
->type
->real
.func
->args
->varargs
) {
85 dump_decl_type(fd
, a
->type
, level
);
87 dump_decl_var(fd
, a
->var
);
91 static inline void dump_num_exp(int fd
, num_exp
*exp
) {
95 dprintf(fd
, "%s", exp
->u
.numb
);
98 dprintf(fd
, "%s", exp
->u
.cnst
->name
);
101 dump_decl_var(fd
, exp
->u
.dvar
);
104 dprintf(fd
, "%s", exp
->u
.enm
->name
);
106 EMPTY_SWITCH_DEFAULT_CASE();
111 switch (exp
->operator) {
112 case PSI_T_PLUS
: op
= '+'; break;
113 case PSI_T_MINUS
: op
= '-'; break;
114 case PSI_T_ASTERISK
:op
= '*'; break;
115 case PSI_T_SLASH
: op
= '/'; break;
116 EMPTY_SWITCH_DEFAULT_CASE();
118 dprintf(fd
, " %c ", op
);
124 static inline void dump_impl_set_value(int fd
, set_value
*set
, unsigned level
, int last
) {
128 /* only if not directly after `set ...` */
129 dump_level(fd
, level
);
132 if (set
->func
->type
== PSI_T_ELLIPSIS
) {
133 dprintf(fd
, "%s(", set
->outer
.set
->func
->name
);
135 dprintf(fd
, "%s(", set
->func
->name
);
138 for (i
= 0; i
< set
->vars
->count
; ++i
) {
139 decl_var
*svar
= set
->vars
->vars
[i
];
143 dump_decl_var(fd
, svar
);
146 if (set
->func
->type
== PSI_T_ELLIPSIS
) {
147 dprintf(fd
, ", ...");
151 dump_num_exp(fd
, set
->num
);
153 if (set
->inner
&& set
->inner
->vals
&& set
->func
->type
!= PSI_T_ELLIPSIS
) {
155 for (i
= 0; i
< set
->inner
->count
; ++i
) {
156 dump_impl_set_value(fd
, set
->inner
->vals
[i
], level
+1, i
== (set
->inner
->count
- 1));
158 /* only if inner stmts, i.e. with new lines, were dumped */
159 dump_level(fd
, level
);
162 dprintf(fd
, ")%s\n", last
? "" : ",");
168 static inline void dump_typedef(int fd
, decl_arg
*tdef
) {
169 dprintf(fd
, "typedef ");
170 dump_decl_arg(fd
, tdef
, 0);
174 static inline void dump_typedefs(int fd
, decl_typedefs
*defs
) {
177 for (i
= 0; i
< defs
->count
; ++i
) {
178 decl_arg
*tdef
= defs
->list
[i
];
180 dump_typedef(fd
, tdef
);
185 static inline void dump_struct_args(int fd
, decl_args
*args
, unsigned level
) {
191 for (j
= 0; j
< args
->count
; ++j
) {
192 decl_arg
*sarg
= args
->args
[j
];
194 dump_level(fd
, level
);
195 dump_decl_arg(fd
, sarg
, level
);
196 dprintf(fd
, "::(%zu, %zu);\n", sarg
->layout
->pos
, sarg
->layout
->len
);
200 dump_level(fd
, level
);
204 static inline void dump_struct(int fd
, decl_struct
*strct
) {
205 dprintf(fd
, "struct %s::(%zu, %zu)", strct
->name
, strct
->align
, strct
->size
);
206 if (strct
->args
&& strct
->args
->count
) {
207 dump_struct_args(fd
, strct
->args
, 0);
213 static inline void dump_structs(int fd
, decl_structs
*structs
) {
216 for (i
= 0; i
< structs
->count
; ++i
) {
217 decl_struct
*strct
= structs
->list
[i
];
219 if (!is_anon_type(strct
->name
, "struct")) {
220 dump_struct(fd
, strct
);
226 static inline void dump_union(int fd
, decl_union
*unn
) {
229 dprintf(fd
, "union %s::(%zu, %zu) {\n", unn
->name
, unn
->align
, unn
->size
);
230 for (j
= 0; j
< unn
->args
->count
; ++j
) {
231 decl_arg
*uarg
= unn
->args
->args
[j
];
234 dump_decl_arg(fd
, uarg
, 0);
235 dprintf(fd
, "::(%zu, %zu);\n", uarg
->layout
->pos
, uarg
->layout
->len
);
240 static inline void dump_unions(int fd
, decl_unions
*unions
) {
243 for (i
= 0; i
< unions
->count
; ++i
) {
244 decl_union
*unn
= unions
->list
[i
];
246 if (!is_anon_type(unn
->name
, "union")) {
253 static inline void dump_enum_items(int fd
, decl_enum_items
*items
, unsigned level
) {
258 for (j
= 0; j
< items
->count
; ++j
) {
259 decl_enum_item
*i
= items
->list
[j
];
264 dump_level(fd
, level
);
265 dprintf(fd
, "%s", i
->name
);
266 if (i
->num
&& i
->num
!= &i
->inc
) {
268 dump_num_exp(fd
, i
->num
);
275 static inline void dump_enum(int fd
, decl_enum
*e
) {
276 dprintf(fd
, "enum %s {\n", e
->name
);
277 dump_enum_items(fd
, e
->items
, 0);
281 static inline void dump_enums(int fd
, decl_enums
*enums
) {
284 for (i
= 0; i
< enums
->count
; ++i
) {
285 decl_enum
*e
= enums
->list
[i
];
287 if (!is_anon_type(e
->name
, "enum")) {
293 static inline void dump_constant(int fd
, constant
*cnst
) {
294 dprintf(fd
, "const %s %s = ", cnst
->type
->name
, cnst
->name
);
295 if (cnst
->val
->type
== PSI_T_QUOTED_STRING
) {
296 dprintf(fd
, "\"%s\";", cnst
->val
->text
);
298 dprintf(fd
, "%s;", cnst
->val
->text
);
302 static inline void dump_constants(int fd
, constants
*consts
) {
305 for (i
= 0; i
< consts
->count
; ++i
) {
306 constant
*cnst
= consts
->list
[i
];
308 dump_constant(fd
, cnst
);
313 static inline void dump_decl(int fd
, decl
*decl
) {
316 dprintf(fd
, "%s ", decl
->abi
->convention
);
317 dump_decl_arg(fd
, decl
->func
, 0);
320 for (j
= 0; j
< decl
->args
->count
; ++j
) {
324 dump_decl_arg(fd
, decl
->args
->args
[j
], 0);
326 if (decl
->args
->varargs
) {
327 dprintf(fd
, ", ...");
333 static inline void dump_decls(int fd
, decls
*decls
) {
336 for (i
= 0; i
< decls
->count
; ++i
) {
337 decl
*decl
= decls
->list
[i
];
344 static inline void dump_impl_func(int fd
, impl_func
*func
) {
347 dprintf(fd
, "function %s(", func
->name
);
349 for (j
= 0; j
< func
->args
->count
; ++j
) {
350 impl_arg
*iarg
= func
->args
->args
[j
];
352 dprintf(fd
, "%s%s %s%s",
355 iarg
->var
->reference
? "&" : "",
358 dprintf(fd
, " = %s", iarg
->def
->text
);
361 if (func
->args
->vararg
.name
) {
362 impl_arg
*vararg
= func
->args
->vararg
.name
;
364 dprintf(fd
, ", %s %s...%s",
366 vararg
->var
->reference
? "&" : "",
370 dprintf(fd
, ") : %s%s",
371 func
->return_reference
? "&":"",
372 func
->return_type
->name
);
375 static inline void dump_impl_let_func(int fd
, let_func
*func
, unsigned level
);
377 static inline void dump_impl_let_val(int fd
, let_val
*val
, unsigned level
, int last
) {
379 /* only if not directly after `set ...` */
380 dump_level(fd
, level
);
383 dprintf(fd
, "%s", val
->flags
.one
.is_reference
? "&" : "");
389 dump_decl_var(fd
, val
->data
.var
);
392 dprintf(fd
, "calloc(");
393 dump_num_exp(fd
, val
->data
.alloc
->nmemb
);
395 dump_num_exp(fd
, val
->data
.alloc
->size
);
398 case PSI_LET_CALLBACK
:
399 dprintf(fd
, "callback %s(%s(", val
->data
.callback
->func
->name
,
400 val
->data
.callback
->func
->var
->name
);
401 if (val
->data
.callback
->args
) {
402 size_t i
, c
= val
->data
.callback
->args
->count
;
405 for (i
= 0; i
< c
; ++i
) {
406 set_value
*set
= val
->data
.callback
->args
->vals
[i
];
408 dump_impl_set_value(fd
, set
, level
, i
+ 1 == c
);
411 dump_level(fd
, level
);
416 dump_impl_let_func(fd
, val
->data
.func
, level
);
419 dump_num_exp(fd
, val
->data
.num
);
422 EMPTY_SWITCH_DEFAULT_CASE();
433 static inline void dump_impl_let_func(int fd
, let_func
*func
, unsigned level
) {
434 dprintf(fd
, "%s(%s", func
->name
,
441 for (i
= 0; i
< func
->inner
->count
; ++i
) {
443 dump_impl_let_val(fd
, func
->inner
->vals
[i
], level
, i
+1 == func
->inner
->count
);
447 dump_level(fd
, level
);
451 static inline void dump_impl_let_stmt(int fd
, let_stmt
*let
) {
452 dprintf(fd
, "\tlet %s", let
->var
->name
);
455 dump_impl_let_val(fd
, let
->val
, 1, 1);
459 static inline void dump_impl_return_stmt(int fd
, return_stmt
*ret
) {
460 dprintf(fd
, "\treturn ");
461 dump_impl_set_value(fd
, ret
->set
, 1, 0);
464 static inline void dump_impl_set_stmt(int fd
, set_stmt
*set
) {
465 dprintf(fd
, "\tset %s = ", set
->var
->name
);
466 dump_impl_set_value(fd
, set
->val
, 1, 0);
469 static inline void dump_impl_free_call(int fd
, free_call
*call
) {
472 dprintf(fd
, "%s(", call
->func
);
473 for (l
= 0; l
< call
->vars
->count
; ++l
) {
474 decl_var
*fvar
= call
->vars
->vars
[l
];
476 dump_decl_var(fd
, fvar
);
481 static inline void dump_impl_free_stmt(int fd
, free_stmt
*fre
) {
484 dprintf(fd
, "\tfree ");
485 for (k
= 0; k
< fre
->calls
->count
; ++k
) {
486 free_call
*call
= fre
->calls
->list
[k
];
491 dump_impl_free_call(fd
, call
);
495 static inline void dump_impl_stmts(int fd
, impl_stmts
*stmts
) {
498 for (j
= 0; j
< stmts
->let
.count
; ++j
) {
499 let_stmt
*let
= stmts
->let
.list
[j
];
500 dump_impl_let_stmt(fd
, let
);
503 for (j
= 0; j
< stmts
->ret
.count
; ++j
) {
504 return_stmt
*ret
= stmts
->ret
.list
[j
];
505 dump_impl_return_stmt(fd
, ret
);
508 for (j
= 0; j
< stmts
->set
.count
; ++j
) {
509 set_stmt
*set
= stmts
->set
.list
[j
];
511 dump_impl_set_stmt(fd
, set
);
514 for (j
= 0; j
< stmts
->fre
.count
; ++j
) {
515 free_stmt
*fre
= stmts
->fre
.list
[j
];
517 dump_impl_free_stmt(fd
, fre
);
522 static inline void dump_impl(int fd
, impl
*impl
) {
524 dump_impl_func(fd
, impl
->func
);
527 dump_impl_stmts(fd
, impl
->stmts
);
532 static inline void dump_impls(int fd
, impls
*impls
) {
535 for (i
= 0; i
< impls
->count
; ++i
) {
536 impl
*impl
= impls
->list
[i
];
543 void psi_context_dump(struct psi_context
*C
, int fd
)
546 if (C
->ops
== psi_libjit_ops()) {
547 dprintf(fd
, "// psi.engine=jit\n");
551 if (C
->ops
== psi_libffi_ops()) {
552 dprintf(fd
, "// psi.engine=ffi\n");
558 dump_typedefs(fd
, C
->defs
);
562 dump_unions(fd
, C
->unions
);
566 dump_structs(fd
, C
->structs
);
570 dump_enums(fd
, C
->enums
);
574 dump_constants(fd
, C
->consts
);
578 dump_decls(fd
, C
->decls
);
582 dump_impls(fd
, C
->impls
);