1
2
3
4
5
6
7
8
9
10 :(before "Rewrite Labels(segment code)")
11 check_label_types(code);
12 if (trace_contains_errors()) return;
13 :(code)
14 void check_label_types(const segment& code) {
15 trace(99, "transform") << "-- check label types" << end();
16 for (int i = 0; i < SIZE(code.lines); ++i)
17 check_label_types(code.lines.at(i));
18 }
19
20 void check_label_types(const line& inst) {
21 int idx = first_operand(inst);
22 if (idx >= SIZE(inst.words)) return;
23 const word& target = inst.words.at(idx);
24 if (is_number(target.data)) return;
25 if (is_jump(inst) && target.data.at(0) != '$')
26 raise << "'" << inst.original << "': jumps should always be to internal labels starting with '$'\n" << end();
27 if (is_call(inst) && target.data.at(0) == '$')
28 raise << "'" << inst.original << "': calls should always be to function labels (not starting with '$')\n" << end();
29 }
30
31 :(scenario catch_jump_to_function)
32 % Hide_errors = true;
33 == 0x1
34 main:
35 7e/jump-if foo/disp8
36 foo:
37 +error: '7e/jump-if foo/disp8': jumps should always be to internal labels starting with '$'
38
39 :(scenario catch_call_to_internal_label)
40 % Hide_errors = true;
41 == 0x1
42 main:
43 e8/call $foo/disp32
44 $foo:
45 +error: 'e8/call $foo/disp32': calls should always be to function labels (not starting with '$')