-
Notifications
You must be signed in to change notification settings - Fork 8
/
app.c
168 lines (162 loc) · 6.99 KB
/
app.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <toywasm/fileio.h>
#include <toywasm/load_context.h>
#include <toywasm/mem.h>
#include <toywasm/module.h>
#include <toywasm/name.h>
#include <toywasm/type.h>
#include <toywasm/xlog.h>
int
main(int argc, char **argv)
{
struct mem_context mctx;
mem_context_init(&mctx);
if (argc != 2) {
xlog_error("unexpected number of args");
exit(2);
}
const char *filename = argv[1];
struct module *m;
int ret;
uint8_t *p;
size_t sz;
ret = map_file(filename, (void **)&p, &sz);
if (ret != 0) {
xlog_error("map_file failed with %d", ret);
exit(1);
}
struct load_context ctx;
load_context_init(&ctx, &mctx);
ret = module_create(&m, p, p + sz, &ctx);
if (ret != 0) {
xlog_error("module_load failed with %d: %s", ret,
report_getmessage(&ctx.report));
exit(1);
}
load_context_clear(&ctx);
module_print_stats(m);
/* perform some investigations on the loaded module */
printf("module imports %" PRIu32 " functions\n", m->nimportedfuncs);
printf("module contains %" PRIu32 " functions\n", m->nfuncs);
uint32_t i;
uint32_t funcidx_with_most_locals = UINT32_MAX;
uint32_t nlocals = 0;
uint32_t funcidx_with_most_params = UINT32_MAX;
uint32_t nparams = 0;
uint32_t funcidx_with_most_results = UINT32_MAX;
uint32_t nresults = 0;
uint32_t funcidx_with_largest_jump_table = UINT32_MAX;
uint32_t largest_jump_table = 0;
#if defined(TOYWASM_USE_SMALL_CELLS)
uint32_t funcidx_with_largest_type_annotations = UINT32_MAX;
uint32_t largest_type_annotations = 0;
#endif
uint32_t funcidx_with_max_code_size = UINT32_MAX;
uint32_t max_code_size = 0;
for (i = 0; i < m->nfuncs; i++) {
const struct func *func = &m->funcs[i];
const struct localtype *lt = &func->localtype;
const struct expr_exec_info *ei = &func->e.ei;
if (funcidx_with_most_locals == UINT32_MAX ||
lt->nlocals > nlocals) {
funcidx_with_most_locals = i;
nlocals = lt->nlocals;
}
const struct functype *ft = &m->types[m->functypeidxes[i]];
if (funcidx_with_most_params == UINT32_MAX ||
ft->parameter.ntypes > nparams) {
funcidx_with_most_params = i;
nparams = ft->parameter.ntypes;
}
if (funcidx_with_most_results == UINT32_MAX ||
ft->result.ntypes > nresults) {
funcidx_with_most_results = i;
nresults = ft->result.ntypes;
}
if (funcidx_with_largest_jump_table == UINT32_MAX ||
ei->njumps > largest_jump_table) {
funcidx_with_largest_jump_table = i;
largest_jump_table = ei->njumps;
}
#if defined(TOYWASM_USE_SMALL_CELLS)
if (funcidx_with_largest_type_annotations == UINT32_MAX ||
ei->type_annotations.ntypes > largest_type_annotations) {
funcidx_with_largest_type_annotations = i;
largest_type_annotations = ei->type_annotations.ntypes;
}
#endif
uint32_t code_size = expr_end(&func->e) - func->e.start;
if (funcidx_with_max_code_size == UINT32_MAX ||
code_size > max_code_size) {
funcidx_with_max_code_size = i;
max_code_size = code_size;
}
}
struct nametable table;
nametable_init(&table);
if (funcidx_with_most_locals != UINT32_MAX) {
uint32_t funcidx =
m->nimportedfuncs + funcidx_with_most_locals;
struct name func_name;
nametable_lookup_func(&table, m, funcidx, &func_name);
printf("func %" PRIu32 " (%.*s) has the most locals (%" PRIu32
") in this module.\n",
funcidx, CSTR(&func_name), nlocals);
}
if (funcidx_with_most_params != UINT32_MAX) {
uint32_t funcidx =
m->nimportedfuncs + funcidx_with_most_params;
struct name func_name;
nametable_lookup_func(&table, m, funcidx, &func_name);
printf("func %" PRIu32
" (%.*s) has the most parameters (%" PRIu32
") in this module.\n",
funcidx, CSTR(&func_name), nparams);
}
if (funcidx_with_most_results != UINT32_MAX) {
uint32_t funcidx =
m->nimportedfuncs + funcidx_with_most_params;
struct name func_name;
nametable_lookup_func(&table, m, funcidx, &func_name);
printf("func %" PRIu32 " (%.*s) has the most results (%" PRIu32
") in this module.\n",
funcidx, CSTR(&func_name), nresults);
}
if (funcidx_with_largest_jump_table != UINT32_MAX) {
uint32_t funcidx =
m->nimportedfuncs + funcidx_with_largest_jump_table;
struct name func_name;
nametable_lookup_func(&table, m, funcidx, &func_name);
printf("func %" PRIu32
" (%.*s) has the largest jump table (%" PRIu32
" entries) in this module.\n",
funcidx, CSTR(&func_name), largest_jump_table);
}
#if defined(TOYWASM_USE_SMALL_CELLS)
if (funcidx_with_largest_type_annotations != UINT32_MAX) {
uint32_t funcidx = m->nimportedfuncs +
funcidx_with_largest_type_annotations;
struct name func_name;
nametable_lookup_func(&table, m, funcidx, &func_name);
printf("func %" PRIu32
" (%.*s) has the largest type annotations (%" PRIu32
" entries) in this module.\n",
funcidx, CSTR(&func_name), largest_type_annotations);
}
#endif
if (funcidx_with_max_code_size != UINT32_MAX) {
uint32_t funcidx =
m->nimportedfuncs + funcidx_with_max_code_size;
struct name func_name;
nametable_lookup_func(&table, m, funcidx, &func_name);
printf("func %" PRIu32 " (%.*s) is largest (%" PRIu32
" bytes) in this module.\n",
funcidx, CSTR(&func_name), max_code_size);
}
nametable_clear(&table);
module_destroy(&mctx, m);
mem_context_clear(&mctx);
exit(0);
}