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