1
2
3
4
5
6
7
8 :(after "Begin Transforms")
9
10 Transform.push_back(create_test_function);
11
12
13 :(scenario run_test)
14 % Reg[ESP].u = 0x100;
15 == 0x1
16 main:
17 e8/call run_tests/disp32
18 f4/halt
19
20 test_foo:
21 01 d8
22 c3/return
23
24
25 +run: inst: 0x00000007
26
27 :(code)
28 void create_test_function(program& p) {
29 if (p.segments.empty()) return;
30 segment& code = p.segments.at(0);
31 trace(99, "transform") << "-- create 'run_tests'" << end();
32 vector<line> new_insts;
33 for (int i = 0; i < SIZE(code.lines); ++i) {
34 line& inst = code.lines.at(i);
35 for (int j = 0; j < SIZE(inst.words); ++j) {
36 const word& curr = inst.words.at(j);
37 if (*curr.data.rbegin() != ':') continue;
38 if (!starts_with(curr.data, "test_")) continue;
39 string fn = drop_last(curr.data);
40 new_insts.push_back(call(fn));
41 }
42 }
43 if (new_insts.empty()) return;
44 code.lines.push_back(label("run_tests"));
45 code.lines.insert(code.lines.end(), new_insts.begin(), new_insts.end());
46 code.lines.push_back(ret());
47 }
48
49 string to_string(const segment& s) {
50 ostringstream out;
51 for (int i = 0; i < SIZE(s.lines); ++i) {
52 const line& l = s.lines.at(i);
53 for (int j = 0; j < SIZE(l.words); ++j) {
54 if (j > 0) out << ' ';
55 out << to_string(l.words.at(j));
56 }
57 out << '\n';
58 }
59 return out.str();
60 }
61
62 string to_string(const word& w) {
63 ostringstream out;
64 out << w.data;
65 for (int i = 0; i < SIZE(w.metadata); ++i)
66 out << '/' << w.metadata.at(i);
67 return out.str();
68 }
69
70 line label(string s) {
71 line result;
72 result.words.push_back(word());
73 result.words.back().data = (s+":");
74 return result;
75 }
76
77 line call(string s) {
78 line result;
79 result.words.push_back(call());
80 result.words.push_back(disp32(s));
81 return result;
82 }
83
84 word call() {
85 word result;
86 result.data = "e8";
87 result.metadata.push_back("call");
88 return result;
89 }
90
91 word disp32(string s) {
92 word result;
93 result.data = s;
94 result.metadata.push_back("disp32");
95 return result;
96 }
97
98 line ret() {
99 line result;
100 result.words.push_back(word());
101 result.words.back().data = "c3";
102 result.words.back().metadata.push_back("return");
103 return result;
104 }